blob: 111bf1117958739a881cd578c12a26e8177cbe6e [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/**
2 * @file softap_api.c
3 * @brief Implementation of Sanechips
4 *
5 * Copyright (C) 2017 Sanechips Technology Co., Ltd.
6 * @author linxu Gebin
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <stdio.h>
15#include <string.h>
16#include <stdlib.h>
17#include <assert.h>
18#include <syslog.h>
19#include <sys/klog.h>
20#include <sys/msg.h>
21#include <sys/socket.h>
22#include <linux/sockios.h>
23#include <sys/un.h>
24#include <errno.h>
25#include <sys/types.h>
26#include <sys/wait.h>
27#include <sys/msg.h>
28#include "softap_api.h"
29
30
31/* ƽ̨»ù´¡Ó¦Ó㬼´: ËùÓÐÐͺŻú¶¼ÐèÒªÆô¶¯µÄÓ¦Óà */
32static int basic_apps[] = {
33 MODULE_ID_AT_CTL, // AT
34 MODULE_ID_MAIN_CTRL, // Ö÷¿Ø
35 MODULE_ID_RTC_SERVICE, // rtc
36 MODULE_ID_CODEC // audio ctrl
37};
38
39static int is_basic_app(int module_id)
40{
41 int i = 0;
42
43 for (i = 0; i < sizeof(basic_apps) / sizeof(basic_apps[0]); i++) {
44 if (module_id == basic_apps[i]) {
45 return 1;
46 }
47 }
48 return 0;
49}
50
51//»ñÈ¡¶àºË»ù׼ʱ¼ä
52long long int get_time_us()
53{
54 int fd;
55 char buf[128] = {0};
56
57 fd = open("/proc/persistent_time", O_RDWR);
58 if (fd < 0) {
59 printf("fail to open\n");
60 return -1;
61 }
62#if 1
63 int len = read(fd, buf, sizeof(buf)-1);
64 long long time = 0;
65
66 if(len < 0 ){
67 close(fd);
68 return -1;
69 }else{
70 close(fd);
71 time = atoll(buf);
72 if(time < 0 || time > LLONG_MAX-1)
73 {
74 time = 0;
75 }
76
77 return time;
78 }
79#else
80 if (read(fd, buf, 127) > 0) {
81 close(fd);
82 return atoll(buf);
83 } else {
84 close(fd);
85 return -1;
86 }
87#endif
88}
89
90/**************************************************************************
91* º¯ÊýÃû³Æ£º soc_send_condition_check
92* ¹¦ÄÜÃèÊö£º ¼ì²âÊÇ·ñÂú×ãSOCÏûÏ¢·¢ËÍÌõ¼þ£¬Èç¹ûÊÇ´ÓAP·¢Ë͵½CP£¬Ôòsrc_id±ØÐëΪAP²àµÄmoduleid£¬dst_id±ØÐëΪ
93* moduleid; Èç¹ûÊÇ´ÓCP·¢Ë͵½AP£¬Ôòsrc_id±ØÐëΪCP²àµÄmoduleid£¬dst_id±ØÐëΪAP²àµÄmoduleid.
94* ²ÎÊý˵Ã÷£ºsrc_id:ÏûÏ¢·¢ËÍÄ£¿éID dest_id:ÏûÏ¢½ÓÊÕÄ£¿éID
95* ·µ »Ø Öµ£º 1:·ûºÏÌõ¼þ0:²»·ûºÏÌõ¼þ
96* ÆäËü˵Ã÷£º
97**************************************************************************/
98static int soc_send_condition_check(int src_id, int dst_id)
99{
100#if (APP_OS_TYPE == APP_OS_TOS)
101 if ((src_id <= MODULE_ID_CPBASE) || (src_id >= MODULE_ID_MAX)) { //¼ì²âsrc_idÊÇ·ñΪCPºËÄ£¿éºÅ
102 return 0;
103 } else if ((dst_id <= MODULE_ID_APBASE) || (dst_id >= MODULE_ID_CPBASE)) { //¼ì²âdst_idÊÇ·ñΪAPºËÄ£¿éºÅ
104 return 0;
105 }
106
107 return 1;
108#endif
109
110#if (APP_OS_TYPE == APP_OS_LINUX)
111 if ((src_id <= MODULE_ID_APBASE) || (src_id >= MODULE_ID_CPBASE)) { //¼ì²âsrc_idÊÇ·ñΪAPºËÄ£¿éºÅ
112 return 0;
113 } else if ((dst_id <= MODULE_ID_CPBASE) || (dst_id >= MODULE_ID_MAX)) { //¼ì²âdst_idÊÇ·ñΪCPºËÄ£¿éºÅ
114 return 0;
115 }
116
117 return 1;
118
119#endif
120}
121
122/************************ Ó¦Óü乫¹²º¯ÊýʵÏÖ ************************/
123/*·µ»ØÖµ 0 ³É¹¦ ·Ç0ʧ°Ü£¬
124Èç¹û·µ»ØÖµµÈÓÚENOENT£¬±íʾ½ÓÊÕ¶ÓÁв»´æÔÚ£¬Ó¦ÓÃ×ÔÐÐÅжϽÓÊÕÄ£¿éÊÇ·ñÒ»¶¨Æô¶¯£¬Èç¹ûÊÇ£¬µ÷ÓÃipc_send_message2·¢ËÍ*/
125int ipc_send_message(int src_id, int dst_id, unsigned short Msg_cmd, unsigned short us_DataLen, unsigned char *pData, int msgflag)
126{
127 MSG_BUF stMsg;
128 int lRet = 0;
129 int lTgtMsgID = 0;
130 LONG msgSize = offsetof(MSG_BUF, aucDataBuf) - sizeof(LONG) + us_DataLen;
131 int errNo = 0;
132
133 memset(&stMsg, 0, sizeof(MSG_BUF));
134
135 lTgtMsgID = msgget(dst_id, 0);
136 if (-1 == lTgtMsgID) {
137 errNo = errno;
138 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*/
139
140 /* »ù´¡Ó¦ÓñØÐë·¢Ëͳɹ¦£¬Èç¹ûÓ¦Óû¹Ã»Æð¾ÍÖ±½ÓÏÈ´´½¨ÏûÏ¢½ÓÊÕ¶ÓÁУ¬Æô¶¯ºóÔÙ´¦Àí */
141 if (is_basic_app(dst_id)) {
142 slog(NET_PRINT, SLOG_ERR, "send_message failed, basic app \n");
143 return ipc_send_message2(src_id, dst_id, Msg_cmd, us_DataLen, pData, msgflag);
144 }
145 return errNo;
146 }
147
148 if (us_DataLen >= MSG_DATA_MAX_LEN) {
149 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*/
150 softap_assert("send_message failed:us_DataLen %d is too big!", us_DataLen);
151 return EINVAL;
152 }
153
154 if ((us_DataLen > 0) && (NULL == pData)) {
155 slog(NET_PRINT, SLOG_ERR, "send_message failed:us_DataLen is %d, but pData is NULL! \n", us_DataLen); /*lint !e26*/
156 softap_assert("send_message failed:us_DataLen is %d, but pData is NULL!", us_DataLen);
157 return EINVAL;
158 }
159
160 stMsg.ulMagic = MSG_MAGIC_WORD;
161 stMsg.lMsgType = MSG_TYPE_DEFAULT;
162 stMsg.src_id = src_id;
163 stMsg.dst_id = dst_id;
164 stMsg.usMsgCmd = Msg_cmd;
165 stMsg.usDataLen = us_DataLen;
166
167 if (us_DataLen > 0) {
168 memcpy(stMsg.aucDataBuf, pData, us_DataLen);
169 }
170
171AGAIN:
172 lRet = msgsnd(lTgtMsgID, &stMsg, msgSize, msgflag);
173 if (lRet < 0) {
174 if (errno == EINTR) {
175 goto AGAIN;
176 }
177 errNo = errno;
178 slog(NET_PRINT, SLOG_ERR, "send_message failed: msgsnd error code %d!, errNo:%d \n", lRet, errNo); /*lint !e26*/
179 if (msgflag != IPC_NOWAIT) {
180 softap_assert("send_message failed: msgsnd error code errNo:%d! \n", errNo);
181 }
182 return errNo;
183 }
184 return 0;
185}
186
187int ipc_send_message2(int src_id, int dst_id, unsigned short Msg_cmd, unsigned short us_DataLen, unsigned char *pData, int msgflag)
188{
189 MSG_BUF stMsg;
190 int lRet = 0;
191 int lTgtMsgID = 0;
192 LONG msgSize = offsetof(MSG_BUF, aucDataBuf) - sizeof(LONG) + us_DataLen;
193 int errNo = 0;
194
195 memset(&stMsg, 0, sizeof(MSG_BUF));
196
197 lTgtMsgID = msgget(dst_id, IPC_CREAT | 0600);
198 if (-1 == lTgtMsgID) {
199 errNo = errno;
200 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*/
201 softap_assert("send_message2 failed:can not get target msg id 0x%04x!", dst_id);
202 return errNo;
203 }
204
205 if (us_DataLen >= MSG_DATA_MAX_LEN) {
206 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*/
207 softap_assert("send_message2 failed:us_DataLen %d is too big!", us_DataLen);
208 return EINVAL;
209 }
210
211 if ((us_DataLen > 0) && (NULL == pData)) {
212 slog(NET_PRINT, SLOG_ERR, "send_message2 failed:us_DataLen is %d, but pData is NULL!", us_DataLen); /*lint !e26*/
213 softap_assert("send_message2 failed:us_DataLen is %d, but pData is NULL!", us_DataLen);
214 return EINVAL;
215 }
216
217 stMsg.ulMagic = MSG_MAGIC_WORD;
218 stMsg.lMsgType = MSG_TYPE_DEFAULT;
219 stMsg.src_id = src_id;
220 stMsg.dst_id = dst_id;
221 stMsg.usMsgCmd = Msg_cmd;
222 stMsg.usDataLen = us_DataLen;
223
224 if (us_DataLen > 0) {
225 memcpy(stMsg.aucDataBuf, pData, us_DataLen);
226 }
227
228AGAIN:
229 lRet = msgsnd(lTgtMsgID, &stMsg, msgSize, msgflag);
230 if (lRet < 0) {
231 errNo = errno;
232 if (errNo == EINTR) {
233 goto AGAIN;
234 }
235 if (errNo == EAGAIN) {
236 slog(NET_PRINT, SLOG_ERR, "send_message2 EAGAIN! src=0x%x dst=0x%x msg=0x%x\n",src_id,dst_id,Msg_cmd);
237 goto AGAIN;
238 }
239 slog(NET_PRINT, SLOG_ERR, "send_message failed: msgsnd error code %d, errNo:%d!", lRet, errNo); /*lint !e26*/
240 if (msgflag != IPC_NOWAIT) {
241 softap_assert("send_message failed: msgsnd error code errNo:%d!", errNo);
242 }
243 return errNo;
244 }
245 return 0;
246}
247
248int send_soc_msg(unsigned short position, int dst_id, unsigned short msg_cmd, unsigned short len, void *msg)
249{
250 T_Soc_Msg socMsgInfo = {0};
251 int Msgsize = offsetof(T_Soc_Msg, msg) + len;
252 int ret = -1;
253
254 if ((len > 0) && (NULL == msg)) {
255 assert(0);
256 return EINVAL;
257 }
258
259 if (len >= SOC_MSG_MAX_LEN) {
260 assert(0);
261 return EINVAL;
262 }
263
264 //¿çºË·¢Ë͵½at_ctlµÄÏûÏ¢£¬ÄÚ²¿½øÐÐÈÝ´í
265 switch (dst_id) {
266 case MODULE_ID_AT_CTL:
267 dst_id = MODULE_ID_EXTERNAL_AT_CTL;
268 break;
269 case MODULE_ID_RTC_SERVICE:
270 dst_id = MODULE_ID_EXTERNAL_RTC_SERVICE;
271 break;
272 default:
273 break;
274 }
275
276 socMsgInfo.position = position;
277 socMsgInfo.targetId = dst_id;
278 socMsgInfo.msg_cmd = msg_cmd;
279 socMsgInfo.len = len;
280 if (len > 0) {
281 memcpy(socMsgInfo.msg, msg, len);
282 }
283
284 //´Ë´¦½«Ô´Ä£¿éÉèÖÃΪMODULE_ID_AT_CTL£¬socÊÇAT·â×°´¦Àí½Ó¿Ú
285 ret = ipc_send_message(MODULE_ID_AT_CTL, MODULE_ID_AT_CTL, MSG_CMD_SOC_MSG_REQ, Msgsize, &socMsgInfo, 0);
286 if (ret != 0)
287 assert(0);
288
289 return ret;
290}
291
292/*ƽ̨¼¶ÏûÏ¢·¢Ëͽӿڣ¬ÄÚ²¿Ò»Í³ipc_send_messageºÍsend_soc_msg½Ó¿Ú¡£µ±Ä¿±êÄ£¿éºÍÔ´Ä£¿é²»ÔÚÒ»¸öºËʱ£¬½øÐк˼äÏûÏ¢·¢ËÍ*/
293int platform_send_msg(int src_id, int dst_id, unsigned short msg_cmd, unsigned short datalen, unsigned char *pData)
294{
295 int position;
296
297 if (datalen >= SOC_MSG_MAX_LEN) {
298 softap_assert("platform_send_msg failed:datalen %d is too big!", datalen);
299 return EINVAL;
300 }
301
302 if ((datalen > 0) && (NULL == pData)) {
303 softap_assert("platform_send_msg failed:datalen is %d, but pData is NULL!", datalen);
304 return EINVAL;
305 }
306
307 //䶨ÒåÔ´Ä£¿éID£¬Ôò·Ö±ð¸³¶ÔÓ¦ºËµÄĬÈÏÖµ
308 if (src_id == 0) {
309#if (APP_OS_TYPE == APP_OS_LINUX)
310 src_id = MODULE_ID_APBASE;
311#else
312 src_id = MODULE_ID_CPBASE;
313#endif
314 }
315
316 if (dst_id == 0)
317 softap_assert("platform_send_msg failed:src_id = %d, dst_id = %d!", src_id, dst_id);
318
319 //Ô´Ä£¿éIDÓëÄ¿±êÄ£¿éID²»ÔÚÒ»¸öºËÄÚ£¬Ôò×é×°²¢·¢Ëͺ˼äÏûÏ¢
320 if (((src_id & MODULE_ID_APBASE) != (dst_id & MODULE_ID_APBASE)) && ((src_id & MODULE_ID_CPBASE) != (dst_id & MODULE_ID_CPBASE))) {
321 int msglen = offsetof(T_Soc_Msg, msg) + datalen;
322 int ret = -1;
323 T_Soc_Msg socMsgInfo = {0};
324
325 //¼ì²âsrc_id,dst_idÊÇ·ñÂú×ãºË¼äͨѶµÄÌõ¼þ
326 if (0 == soc_send_condition_check(src_id, dst_id))
327 softap_assert("platform_send_msg failed: confition check failed, src_id = %d, dst_id = %d!", src_id, dst_id);
328
329 position = (dst_id & MODULE_ID_APBASE) ? FAR_PS : NEAR_PS;
330
331 socMsgInfo.position = position;
332 socMsgInfo.srcId = src_id;
333 socMsgInfo.targetId = dst_id;
334 socMsgInfo.msg_cmd = msg_cmd;
335 socMsgInfo.len = datalen;
336 if (datalen > 0) {
337 memcpy(socMsgInfo.msg, pData, datalen);
338 }
339
340 ret = ipc_send_message(src_id, MODULE_ID_AT_CTL, MSG_CMD_SOC_MSG_REQ, msglen, &socMsgInfo, 0);
341 if (ret != 0) //·¢Ë͵½at_ctlµÄÏûÏ¢²»ÔÊÐí·¢ËÍʧ°Ü
342 softap_assert("platform_send_msg failed: ipc_send_message MSG_CMD_SOC_MSG_REQ errNo:%d!", errno);
343 return ret;
344 } else {
345 //ºËÄÚÏûÏ¢´æÔÚÒòÄ¿±êÏûÏ¢¶ÓÁл¹Î´´´½¨µ¼Ö·¢ËÍʧ°ÜµÄÇé¿ö£¬¹Ê¸Ã´¦²»¶ÏÑÔ
346 return ipc_send_message(src_id, dst_id, msg_cmd, datalen, pData, 0);
347 }
348}
349
350int poweroff_request(int src_id)
351{
352 return platform_send_msg(src_id, MODULE_ID_MAIN_CTRL, MSG_CMD_POWEROFF_REQUEST, 0, NULL);
353}
354
355int restart_request(int src_id)
356{
357 return platform_send_msg(src_id, MODULE_ID_MAIN_CTRL, MSG_CMD_RESTART_REQUEST, 0, NULL);
358}
359
360int reset_request(int src_id)
361{
362 return platform_send_msg(src_id, MODULE_ID_MAIN_CTRL, MSG_CMD_RESET_REQUEST, 0, NULL);
363}
364
365typedef struct system_cmd_proc
366{
367 const char * str;
368 int (* proc)(const char * cmd, const char * str);
369}
370system_cmd_proc_t;
371
372//awkÌ«¸´ÔÓ£¬¾ßÌåÎÊÌâ¾ßÌå·ÖÎö
373//·Ö¸ô·û|ºóÃæ¿ÉÒÔ´æÔÚµÄÃüÁ´ýÍêÉÆ
374const static const char * separator_whitelist[]={
375 "grep ","sort ","head "
376};
377
378//·µ»Ø×Ö·û´®¼°ÒÔǰµÄ³¤¶È£¬Ã»ÓÐÕÒµ½·µ»Ø0
379static int system_cmd_used_curr(const char * cmd, const char * str)
380{
381 char *tmp_str = NULL;
382 tmp_str = strstr(cmd, str);
383 if(tmp_str)
384 {
385 int len = tmp_str - cmd + strlen(str);
386 tmp_str = tmp_str + strlen(str);
387 while((*tmp_str)!='\0' && (*tmp_str)==' ')
388 {
389 tmp_str++;
390 }
391 if((*tmp_str) == '\0' || (*(tmp_str+1)) == '\0')
392 {//¹æ±Ü2>&1
393 return 0;
394 }
395 return len;
396 }
397 else
398 return 0;
399}
400
401//·µ»Ø³ý×Ö·û´®ÒÔǰµÄ³¤¶È£¬Ã»ÓÐÕÒµ½·µ»Ø0
402static int system_cmd_used_before(const char * cmd, const char * str)
403{
404 char *tmp_str = NULL;
405 tmp_str = strstr(cmd, str);
406 if(tmp_str)
407 return tmp_str -cmd;
408 else
409 return 0;
410}
411
412//¶Ô·Ö¸ô·û|µÄÌØÊâ´¦Àí£¬Ã»ÓÐÕÒµ½»òÔÊÐíÖ´Ðзµ»Ø0
413static int system_cmd_separator_proc(const char * cmd, const char * str)
414{
415 char *tmp_str = NULL;
416 tmp_str = strstr(cmd, str);
417 if(tmp_str)
418 {
419 int i = 0;
420 int len = tmp_str -cmd;
421 tmp_str = tmp_str + strlen(str);
422 while((*tmp_str)!='\0' && (*tmp_str)==' ')
423 {
424 tmp_str++;
425 }
426 for(i = 0; i < sizeof(separator_whitelist) / sizeof(const char *); i++)
427 {
428 if(strncmp(tmp_str, separator_whitelist[i], strlen(separator_whitelist[i])) == 0)
429 {
430 return 0;
431 }
432 }
433 return len;
434 }
435 else
436 return 0;
437}
438
439const static system_cmd_proc_t system_chack[]={
440 {"&",system_cmd_used_curr},
441 {"|",system_cmd_separator_proc},
442 {";",system_cmd_used_before},
443 {"\r",system_cmd_used_before},
444 {"\n",system_cmd_used_before}
445};
446
447int soft_system(const char *command)
448{
449 int i = 0;
450 int flag = 0;
451 int len = strlen(command);
452
453 for(i = 0; i < sizeof(system_chack) / sizeof(system_cmd_proc_t); i++)
454 {
455 int offset = system_chack[i].proc(command,system_chack[i].str);
456 if(offset != 0 && offset < len)
457 {
458 len = offset;
459 flag = 1;
460 }
461 }
462 if(flag && len > 0 && len < strlen(command))
463 {
464 char *cmd = (char *)malloc(len+1);
465 int ret = 0;
466 if(cmd == NULL)
467 {
468 slog(NET_PRINT, SLOG_ERR, "@system@ malloc fail!\n");
469 return -1;
470 }
471 memset(cmd, 0, len+1);
472 strncpy(cmd, command, len);
473 slog(NET_PRINT, SLOG_ERR, "@system@ %s is inject!\n",command);
474 ret = system(cmd);
475 slog(NET_PRINT, SLOG_ERR, "@system@ %s is now,ret=%d!\n",cmd,ret);
476 free(cmd);
477 return ret;
478 }
479 else
480 return system(command);
481}
482
483long get_sys_uptime()
484{
485 struct sysinfo info;
486 if(sysinfo(&info))
487 {
488 printf("Failed to get sysinfo failed\n");
489 return -1;
490 }
491
492 return info.uptime;
493}
494
495