[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/lib/libsoftap/softap_api.c b/ap/lib/libsoftap/softap_api.c
new file mode 100755
index 0000000..d76371c
--- /dev/null
+++ b/ap/lib/libsoftap/softap_api.c
@@ -0,0 +1,496 @@
+/**
+ * @file softap_api.c
+ * @brief Implementation of Sanechips
+ *
+ * Copyright (C) 2017 Sanechips Technology Co., Ltd.
+ * @author linxu Gebin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <syslog.h>
+#include <sys/klog.h>
+#include <sys/msg.h>
+#include <sys/socket.h>
+#include <linux/sockios.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/msg.h>
+#include <limits.h>
+#include "softap_api.h"
+
+
+/* ƽ̨»ù´¡Ó¦Ó㬼´: ËùÓÐÐͺŻú¶¼ÐèÒªÆô¶¯µÄÓ¦Óà */
+static int basic_apps[] = {
+ MODULE_ID_AT_CTL, // AT
+ MODULE_ID_MAIN_CTRL, // Ö÷¿Ø
+ MODULE_ID_RTC_SERVICE, // rtc
+ MODULE_ID_CODEC // audio ctrl
+};
+
+static int is_basic_app(int module_id)
+{
+ int i = 0;
+
+ for (i = 0; i < sizeof(basic_apps) / sizeof(basic_apps[0]); i++) {
+ if (module_id == basic_apps[i]) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+//»ñÈ¡¶àºË»ù׼ʱ¼ä
+long long int get_time_us()
+{
+ int fd;
+ char buf[128] = {0};
+
+ fd = open("/proc/persistent_time", O_RDWR);
+ if (fd < 0) {
+ printf("fail to open\n");
+ return -1;
+ }
+#if 1
+ int len = read(fd, buf, sizeof(buf)-1);
+ long long time = 0;
+
+ if(len < 0 ){
+ close(fd);
+ return -1;
+ }else{
+ close(fd);
+ time = atoll(buf);
+ if(time < 0 || time > LLONG_MAX-1)
+ {
+ time = 0;
+ }
+
+ return time;
+ }
+#else
+ if (read(fd, buf, 127) > 0) {
+ close(fd);
+ return atoll(buf);
+ } else {
+ close(fd);
+ return -1;
+ }
+#endif
+}
+
+/**************************************************************************
+* º¯ÊýÃû³Æ£º soc_send_condition_check
+* ¹¦ÄÜÃèÊö£º ¼ì²âÊÇ·ñÂú×ãSOCÏûÏ¢·¢ËÍÌõ¼þ£¬Èç¹ûÊÇ´ÓAP·¢Ë͵½CP£¬Ôòsrc_id±ØÐëΪAP²àµÄmoduleid£¬dst_id±ØÐëΪ
+* moduleid; Èç¹ûÊÇ´ÓCP·¢Ë͵½AP£¬Ôòsrc_id±ØÐëΪCP²àµÄmoduleid£¬dst_id±ØÐëΪAP²àµÄmoduleid.
+* ²ÎÊý˵Ã÷£ºsrc_id:ÏûÏ¢·¢ËÍÄ£¿éID dest_id:ÏûÏ¢½ÓÊÕÄ£¿éID
+* ·µ »Ø Öµ£º 1:·ûºÏÌõ¼þ0:²»·ûºÏÌõ¼þ
+* ÆäËü˵Ã÷£º
+**************************************************************************/
+static int soc_send_condition_check(int src_id, int dst_id)
+{
+#if (APP_OS_TYPE == APP_OS_TOS)
+ if ((src_id <= MODULE_ID_CPBASE) || (src_id >= MODULE_ID_MAX)) { //¼ì²âsrc_idÊÇ·ñΪCPºËÄ£¿éºÅ
+ return 0;
+ } else if ((dst_id <= MODULE_ID_APBASE) || (dst_id >= MODULE_ID_CPBASE)) { //¼ì²âdst_idÊÇ·ñΪAPºËÄ£¿éºÅ
+ return 0;
+ }
+
+ return 1;
+#endif
+
+#if (APP_OS_TYPE == APP_OS_LINUX)
+ if ((src_id <= MODULE_ID_APBASE) || (src_id >= MODULE_ID_CPBASE)) { //¼ì²âsrc_idÊÇ·ñΪAPºËÄ£¿éºÅ
+ return 0;
+ } else if ((dst_id <= MODULE_ID_CPBASE) || (dst_id >= MODULE_ID_MAX)) { //¼ì²âdst_idÊÇ·ñΪCPºËÄ£¿éºÅ
+ return 0;
+ }
+
+ return 1;
+
+#endif
+}
+
+/************************ Ó¦Óü乫¹²º¯ÊýʵÏÖ ************************/
+/*·µ»ØÖµ 0 ³É¹¦ ·Ç0ʧ°Ü£¬
+Èç¹û·µ»ØÖµµÈÓÚENOENT£¬±íʾ½ÓÊÕ¶ÓÁв»´æÔÚ£¬Ó¦ÓÃ×ÔÐÐÅжϽÓÊÕÄ£¿éÊÇ·ñÒ»¶¨Æô¶¯£¬Èç¹ûÊÇ£¬µ÷ÓÃipc_send_message2·¢ËÍ*/
+int ipc_send_message(int src_id, int dst_id, unsigned short Msg_cmd, unsigned short us_DataLen, unsigned char *pData, int msgflag)
+{
+ MSG_BUF stMsg;
+ int lRet = 0;
+ int lTgtMsgID = 0;
+ LONG msgSize = offsetof(MSG_BUF, aucDataBuf) - sizeof(LONG) + us_DataLen;
+ int errNo = 0;
+
+ memset(&stMsg, 0, sizeof(MSG_BUF));
+
+ lTgtMsgID = msgget(dst_id, 0);
+ if (-1 == lTgtMsgID) {
+ errNo = errno;
+ slog(NET_PRINT, SLOG_ERR, "send_message failed:can not get target msg id, src:0x%x, target:0x%x, cmd:0x%x, errNo:%d! \n", src_id, dst_id, Msg_cmd, errNo); /*lint !e26*/
+
+ /* »ù´¡Ó¦ÓñØÐë·¢Ëͳɹ¦£¬Èç¹ûÓ¦Óû¹Ã»Æð¾ÍÖ±½ÓÏÈ´´½¨ÏûÏ¢½ÓÊÕ¶ÓÁУ¬Æô¶¯ºóÔÙ´¦Àí */
+ if (is_basic_app(dst_id)) {
+ slog(NET_PRINT, SLOG_ERR, "send_message failed, basic app \n");
+ return ipc_send_message2(src_id, dst_id, Msg_cmd, us_DataLen, pData, msgflag);
+ }
+ return errNo;
+ }
+
+ if (us_DataLen >= MSG_DATA_MAX_LEN) {
+ slog(NET_PRINT, SLOG_ERR, "send_message failed:us_DataLen %d is too big, src:0x%x, target:0x%x, cmd:0x%x! \n", us_DataLen, src_id, dst_id, Msg_cmd); /*lint !e26*/
+ softap_assert("send_message failed:us_DataLen %d is too big!", us_DataLen);
+ return EINVAL;
+ }
+
+ if ((us_DataLen > 0) && (NULL == pData)) {
+ slog(NET_PRINT, SLOG_ERR, "send_message failed:us_DataLen is %d, but pData is NULL! \n", us_DataLen); /*lint !e26*/
+ softap_assert("send_message failed:us_DataLen is %d, but pData is NULL!", us_DataLen);
+ return EINVAL;
+ }
+
+ stMsg.ulMagic = MSG_MAGIC_WORD;
+ stMsg.lMsgType = MSG_TYPE_DEFAULT;
+ stMsg.src_id = src_id;
+ stMsg.dst_id = dst_id;
+ stMsg.usMsgCmd = Msg_cmd;
+ stMsg.usDataLen = us_DataLen;
+
+ if (us_DataLen > 0) {
+ memcpy(stMsg.aucDataBuf, pData, us_DataLen);
+ }
+
+AGAIN:
+ lRet = msgsnd(lTgtMsgID, &stMsg, msgSize, msgflag);
+ if (lRet < 0) {
+ if (errno == EINTR) {
+ goto AGAIN;
+ }
+ errNo = errno;
+ slog(NET_PRINT, SLOG_ERR, "send_message failed: msgsnd error code %d!, errNo:%d \n", lRet, errNo); /*lint !e26*/
+ if (msgflag != IPC_NOWAIT) {
+ softap_assert("send_message failed: msgsnd error code errNo:%d! \n", errNo);
+ }
+ return errNo;
+ }
+ return 0;
+}
+
+int ipc_send_message2(int src_id, int dst_id, unsigned short Msg_cmd, unsigned short us_DataLen, unsigned char *pData, int msgflag)
+{
+ MSG_BUF stMsg;
+ int lRet = 0;
+ int lTgtMsgID = 0;
+ LONG msgSize = offsetof(MSG_BUF, aucDataBuf) - sizeof(LONG) + us_DataLen;
+ int errNo = 0;
+
+ memset(&stMsg, 0, sizeof(MSG_BUF));
+
+ lTgtMsgID = msgget(dst_id, IPC_CREAT | 0600);
+ if (-1 == lTgtMsgID) {
+ errNo = errno;
+ slog(NET_PRINT, SLOG_ERR, "send_message2 failed:can not get target id, src:0x%x, target:0x%x, cmd:0x%x, errNo:%d!", src_id, dst_id, Msg_cmd, errNo); /*lint !e26*/
+ softap_assert("send_message2 failed:can not get target msg id 0x%04x!", dst_id);
+ return errNo;
+ }
+
+ if (us_DataLen >= MSG_DATA_MAX_LEN) {
+ slog(NET_PRINT, SLOG_ERR, "send_message2 failed:us_DataLen %d is too big, src:0x%x, target:0x%x, cmd:0x%x!", us_DataLen, src_id, dst_id, Msg_cmd); /*lint !e26*/
+ softap_assert("send_message2 failed:us_DataLen %d is too big!", us_DataLen);
+ return EINVAL;
+ }
+
+ if ((us_DataLen > 0) && (NULL == pData)) {
+ slog(NET_PRINT, SLOG_ERR, "send_message2 failed:us_DataLen is %d, but pData is NULL!", us_DataLen); /*lint !e26*/
+ softap_assert("send_message2 failed:us_DataLen is %d, but pData is NULL!", us_DataLen);
+ return EINVAL;
+ }
+
+ stMsg.ulMagic = MSG_MAGIC_WORD;
+ stMsg.lMsgType = MSG_TYPE_DEFAULT;
+ stMsg.src_id = src_id;
+ stMsg.dst_id = dst_id;
+ stMsg.usMsgCmd = Msg_cmd;
+ stMsg.usDataLen = us_DataLen;
+
+ if (us_DataLen > 0) {
+ memcpy(stMsg.aucDataBuf, pData, us_DataLen);
+ }
+
+AGAIN:
+ lRet = msgsnd(lTgtMsgID, &stMsg, msgSize, msgflag);
+ if (lRet < 0) {
+ errNo = errno;
+ if (errNo == EINTR) {
+ goto AGAIN;
+ }
+ if (errNo == EAGAIN) {
+ slog(NET_PRINT, SLOG_ERR, "send_message2 EAGAIN! src=0x%x dst=0x%x msg=0x%x\n",src_id,dst_id,Msg_cmd);
+ goto AGAIN;
+ }
+ slog(NET_PRINT, SLOG_ERR, "send_message failed: msgsnd error code %d, errNo:%d!", lRet, errNo); /*lint !e26*/
+ if (msgflag != IPC_NOWAIT) {
+ softap_assert("send_message failed: msgsnd error code errNo:%d!", errNo);
+ }
+ return errNo;
+ }
+ return 0;
+}
+
+int send_soc_msg(unsigned short position, int dst_id, unsigned short msg_cmd, unsigned short len, void *msg)
+{
+ T_Soc_Msg socMsgInfo = {0};
+ int Msgsize = offsetof(T_Soc_Msg, msg) + len;
+ int ret = -1;
+
+ if ((len > 0) && (NULL == msg)) {
+ assert(0);
+ return EINVAL;
+ }
+
+ if (len >= SOC_MSG_MAX_LEN) {
+ assert(0);
+ return EINVAL;
+ }
+
+ //¿çºË·¢Ë͵½at_ctlµÄÏûÏ¢£¬ÄÚ²¿½øÐÐÈÝ´í
+ switch (dst_id) {
+ case MODULE_ID_AT_CTL:
+ dst_id = MODULE_ID_EXTERNAL_AT_CTL;
+ break;
+ case MODULE_ID_RTC_SERVICE:
+ dst_id = MODULE_ID_EXTERNAL_RTC_SERVICE;
+ break;
+ default:
+ break;
+ }
+
+ socMsgInfo.position = position;
+ socMsgInfo.targetId = dst_id;
+ socMsgInfo.msg_cmd = msg_cmd;
+ socMsgInfo.len = len;
+ if (len > 0) {
+ memcpy(socMsgInfo.msg, msg, len);
+ }
+
+ //´Ë´¦½«Ô´Ä£¿éÉèÖÃΪMODULE_ID_AT_CTL£¬socÊÇAT·â×°´¦Àí½Ó¿Ú
+ ret = ipc_send_message(MODULE_ID_AT_CTL, MODULE_ID_AT_CTL, MSG_CMD_SOC_MSG_REQ, Msgsize, &socMsgInfo, 0);
+ if (ret != 0)
+ assert(0);
+
+ return ret;
+}
+
+/*ƽ̨¼¶ÏûÏ¢·¢Ëͽӿڣ¬ÄÚ²¿Ò»Í³ipc_send_messageºÍsend_soc_msg½Ó¿Ú¡£µ±Ä¿±êÄ£¿éºÍÔ´Ä£¿é²»ÔÚÒ»¸öºËʱ£¬½øÐк˼äÏûÏ¢·¢ËÍ*/
+int platform_send_msg(int src_id, int dst_id, unsigned short msg_cmd, unsigned short datalen, unsigned char *pData)
+{
+ int position;
+
+ if (datalen >= SOC_MSG_MAX_LEN) {
+ softap_assert("platform_send_msg failed:datalen %d is too big!", datalen);
+ return EINVAL;
+ }
+
+ if ((datalen > 0) && (NULL == pData)) {
+ softap_assert("platform_send_msg failed:datalen is %d, but pData is NULL!", datalen);
+ return EINVAL;
+ }
+
+ //䶨ÒåÔ´Ä£¿éID£¬Ôò·Ö±ð¸³¶ÔÓ¦ºËµÄĬÈÏÖµ
+ if (src_id == 0) {
+#if (APP_OS_TYPE == APP_OS_LINUX)
+ src_id = MODULE_ID_APBASE;
+#else
+ src_id = MODULE_ID_CPBASE;
+#endif
+ }
+
+ if (dst_id == 0)
+ softap_assert("platform_send_msg failed:src_id = %d, dst_id = %d!", src_id, dst_id);
+
+ //Ô´Ä£¿éIDÓëÄ¿±êÄ£¿éID²»ÔÚÒ»¸öºËÄÚ£¬Ôò×é×°²¢·¢Ëͺ˼äÏûÏ¢
+ if (((src_id & MODULE_ID_APBASE) != (dst_id & MODULE_ID_APBASE)) && ((src_id & MODULE_ID_CPBASE) != (dst_id & MODULE_ID_CPBASE))) {
+ int msglen = offsetof(T_Soc_Msg, msg) + datalen;
+ int ret = -1;
+ T_Soc_Msg socMsgInfo = {0};
+
+ //¼ì²âsrc_id,dst_idÊÇ·ñÂú×ãºË¼äͨѶµÄÌõ¼þ
+ if (0 == soc_send_condition_check(src_id, dst_id))
+ softap_assert("platform_send_msg failed: confition check failed, src_id = %d, dst_id = %d!", src_id, dst_id);
+
+ position = (dst_id & MODULE_ID_APBASE) ? FAR_PS : NEAR_PS;
+
+ socMsgInfo.position = position;
+ socMsgInfo.srcId = src_id;
+ socMsgInfo.targetId = dst_id;
+ socMsgInfo.msg_cmd = msg_cmd;
+ socMsgInfo.len = datalen;
+ if (datalen > 0) {
+ memcpy(socMsgInfo.msg, pData, datalen);
+ }
+
+ ret = ipc_send_message(src_id, MODULE_ID_AT_CTL, MSG_CMD_SOC_MSG_REQ, msglen, &socMsgInfo, 0);
+ if (ret != 0) //·¢Ë͵½at_ctlµÄÏûÏ¢²»ÔÊÐí·¢ËÍʧ°Ü
+ softap_assert("platform_send_msg failed: ipc_send_message MSG_CMD_SOC_MSG_REQ errNo:%d!", errno);
+ return ret;
+ } else {
+ //ºËÄÚÏûÏ¢´æÔÚÒòÄ¿±êÏûÏ¢¶ÓÁл¹Î´´´½¨µ¼Ö·¢ËÍʧ°ÜµÄÇé¿ö£¬¹Ê¸Ã´¦²»¶ÏÑÔ
+ return ipc_send_message(src_id, dst_id, msg_cmd, datalen, pData, 0);
+ }
+}
+
+int poweroff_request(int src_id)
+{
+ return platform_send_msg(src_id, MODULE_ID_MAIN_CTRL, MSG_CMD_POWEROFF_REQUEST, 0, NULL);
+}
+
+int restart_request(int src_id)
+{
+ return platform_send_msg(src_id, MODULE_ID_MAIN_CTRL, MSG_CMD_RESTART_REQUEST, 0, NULL);
+}
+
+int reset_request(int src_id)
+{
+ return platform_send_msg(src_id, MODULE_ID_MAIN_CTRL, MSG_CMD_RESET_REQUEST, 0, NULL);
+}
+
+typedef struct system_cmd_proc
+{
+ const char * str;
+ int (* proc)(const char * cmd, const char * str);
+}
+system_cmd_proc_t;
+
+//awkÌ«¸´ÔÓ£¬¾ßÌåÎÊÌâ¾ßÌå·ÖÎö
+//·Ö¸ô·û|ºóÃæ¿ÉÒÔ´æÔÚµÄÃüÁ´ýÍêÉÆ
+const static const char * separator_whitelist[]={
+ "grep ","sort ","head "
+};
+
+//·µ»Ø×Ö·û´®¼°ÒÔǰµÄ³¤¶È£¬Ã»ÓÐÕÒµ½·µ»Ø0
+static int system_cmd_used_curr(const char * cmd, const char * str)
+{
+ char *tmp_str = NULL;
+ tmp_str = strstr(cmd, str);
+ if(tmp_str)
+ {
+ int len = tmp_str - cmd + strlen(str);
+ tmp_str = tmp_str + strlen(str);
+ while((*tmp_str)!='\0' && (*tmp_str)==' ')
+ {
+ tmp_str++;
+ }
+ if((*tmp_str) == '\0' || (*(tmp_str+1)) == '\0')
+ {//¹æ±Ü2>&1
+ return 0;
+ }
+ return len;
+ }
+ else
+ return 0;
+}
+
+//·µ»Ø³ý×Ö·û´®ÒÔǰµÄ³¤¶È£¬Ã»ÓÐÕÒµ½·µ»Ø0
+static int system_cmd_used_before(const char * cmd, const char * str)
+{
+ char *tmp_str = NULL;
+ tmp_str = strstr(cmd, str);
+ if(tmp_str)
+ return tmp_str -cmd;
+ else
+ return 0;
+}
+
+//¶Ô·Ö¸ô·û|µÄÌØÊâ´¦Àí£¬Ã»ÓÐÕÒµ½»òÔÊÐíÖ´Ðзµ»Ø0
+static int system_cmd_separator_proc(const char * cmd, const char * str)
+{
+ char *tmp_str = NULL;
+ tmp_str = strstr(cmd, str);
+ if(tmp_str)
+ {
+ int i = 0;
+ int len = tmp_str -cmd;
+ tmp_str = tmp_str + strlen(str);
+ while((*tmp_str)!='\0' && (*tmp_str)==' ')
+ {
+ tmp_str++;
+ }
+ for(i = 0; i < sizeof(separator_whitelist) / sizeof(const char *); i++)
+ {
+ if(strncmp(tmp_str, separator_whitelist[i], strlen(separator_whitelist[i])) == 0)
+ {
+ return 0;
+ }
+ }
+ return len;
+ }
+ else
+ return 0;
+}
+
+const static system_cmd_proc_t system_chack[]={
+ {"&",system_cmd_used_curr},
+ {"|",system_cmd_separator_proc},
+ {";",system_cmd_used_before},
+ {"\r",system_cmd_used_before},
+ {"\n",system_cmd_used_before}
+};
+
+int soft_system(const char *command)
+{
+ int i = 0;
+ int flag = 0;
+ int len = strlen(command);
+
+ for(i = 0; i < sizeof(system_chack) / sizeof(system_cmd_proc_t); i++)
+ {
+ int offset = system_chack[i].proc(command,system_chack[i].str);
+ if(offset != 0 && offset < len)
+ {
+ len = offset;
+ flag = 1;
+ }
+ }
+ if(flag && len > 0 && len < strlen(command))
+ {
+ char *cmd = (char *)malloc(len+1);
+ int ret = 0;
+ if(cmd == NULL)
+ {
+ slog(NET_PRINT, SLOG_ERR, "@system@ malloc fail!\n");
+ return -1;
+ }
+ memset(cmd, 0, len+1);
+ strncpy(cmd, command, len);
+ slog(NET_PRINT, SLOG_ERR, "@system@ %s is inject!\n",command);
+ ret = system(cmd);
+ slog(NET_PRINT, SLOG_ERR, "@system@ %s is now,ret=%d!\n",cmd,ret);
+ free(cmd);
+ return ret;
+ }
+ else
+ return system(command);
+}
+
+long get_sys_uptime()
+{
+ struct sysinfo info;
+ if(sysinfo(&info))
+ {
+ printf("Failed to get sysinfo failed\n");
+ return -1;
+ }
+
+ return info.uptime;
+}
+
+