[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;
+}
+
+