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