blob: 3d61daf2a2cbb1b105ff6b4f931090c2fbc2bcff [file] [log] [blame]
liubin281ac462023-07-19 14:22:54 +08001#include <stdio.h>
2#include <time.h>
3#include <sys/time.h>
4#include <unistd.h>
5#include <sys/un.h>
6#include <sys/socket.h>
7#include <netinet/in.h>
8#include <arpa/inet.h>
9#include <errno.h>
10#include <sys/ioctl.h>
11#include <net/if.h>
12#include <string.h>
13#include <fcntl.h>
14#include <signal.h>
15
16#include "mbtk_type.h"
17#include "mbtk_utils.h"
18#ifdef LOG_TAG
19#undef LOG_TAG
20#endif
21#define LOG_TAG "mbtk_utils"
22#include "mbtk_log.h"
23
24#define MBTK_AT_BUF_SIZE 2048
25#define MBTK_AT_CLIENT_SOCKET "/data/sock_mbtk_at"
26#define PROC_CMDLINE "/proc/cmdline"
27#define TIME_FORMAT "%F %T"
28
29static int at_fd = -1;
30static bool at_timeout = FALSE;
31
32static void
33at_timer_alrm(int signo)
34{
35 LOGW("AT Timeout.[%d]\n",signo);
36 at_timeout = TRUE;
37}
38
39
40/*
41* Exec shell command.
42*/
43bool mbtk_cmd_line
44(
45 const char *cmd,
46 char *buf,
47 int buf_size
48)
49{
50 FILE *fcmd;
51 bool result = FALSE;
52 fcmd = popen(cmd, "r");
53 memset(buf, 0, buf_size);
54 if(fcmd)
55 {
56 int pos = 0;
57 int len = 0;
58
59 while(!ferror(fcmd) && !feof(fcmd))
60 {
61 if(buf_size - pos == 0)
62 {
63 break;
64 }
65 len = fread(buf + pos,1,buf_size - pos,fcmd);
66 if(len > 0)
67 pos += len;
68 }
69
70 if(buf_size == pos)
71 buf[buf_size - 1] = '\0';
72
73 pclose(fcmd);
74 result = TRUE;
75 }
76
77 LOGV("%s [result:%d]: %s",cmd,result,buf);
78
79 return result;
80}
81
82bool mbtk_cmd_line_ex
83(
84 const char *cmd,
85 mbtk_cmd_cb_func cb
86)
87{
88#define BUFF_SIZE 1024
89 FILE *fcmd;
90 bool result = FALSE;
91 // Get stdout and stderr data.
92 // xxx 2>&1
93 char buff[BUFF_SIZE + 1] = {0};
94 snprintf(buff, BUFF_SIZE + 1, "%s 2>&1", cmd);
95 fcmd = popen(buff, "r");
96 if(!cb)
97 {
98 return FALSE;
99 }
100 if(fcmd)
101 {
102 int len = 0;
103 if(setvbuf(fcmd, NULL, _IOLBF, BUFF_SIZE)) {
104 LOGE("setvbuf() fail:%d", errno);
105 }
106 errno = 0;
107 LOGI("ferror - %d,feof - %d",ferror(fcmd),feof(fcmd));
108 while(!ferror(fcmd) && !feof(fcmd))
109 {
110 memset(buff, 0, BUFF_SIZE + 1);
111 len = fread(buff,1,BUFF_SIZE,fcmd);
112 if(len > 0)
113 {
114 cb(buff,len);
115 }
116 else
117 {
118 LOGE("len - %d,errno - %d",len,errno);
119 }
120 }
121
122 pclose(fcmd);
123 result = TRUE;
124
125 cb(NULL,0);
126 }
127 else
128 {
129 LOGE("popen() fail.[errno=%d]",errno);
130 cb(NULL,0);
131 }
132
133 return result;
134}
135
136
137
138#if 1
139// Send msg to stanet_daemon
140int mbtk_send_at(const void *at_req,void* at_rsp,int rsp_size,int timeout)
141{
142 if(at_fd < 0)
143 {
144 struct sockaddr_un servaddr;
145 at_fd = socket(AF_LOCAL,SOCK_STREAM,0);
146 if(at_fd < 0)
147 {
148 LOGE("socket fail.(%d)\n",errno);
149 at_fd = -1;
150 return -1;
151 }
152
153 // Set O_NONBLOCK
154// int flags = fcntl(at_fd, F_GETFL, 0);
155// if (flags < 0) {
156// LOGE("Get flags error:%s\n", strerror(errno));
157// return -1;
158// }
159// flags |= O_NONBLOCK;
160// if (fcntl(at_fd, F_SETFL, flags) < 0) {
161// LOGE("Set flags error:%s\n", strerror(errno));
162// return -1;
163// }
164
165 memset(&servaddr,0x0,sizeof(servaddr));
166 servaddr.sun_family = AF_LOCAL;
167 strcpy(servaddr.sun_path,MBTK_AT_CLIENT_SOCKET);
168
169 if(connect(at_fd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
170 {
171 LOGE("connect fail.(%d)\n",errno);
172 close(at_fd);
173 at_fd = -1;
174 return -1;
175 }
176 }
177
178 at_timeout = FALSE;
179 int n = write(at_fd,at_req,strlen((char*)at_req));
180 if(n == -1)
181 {
182 LOGE("write fail[%d].\n",errno);
183 close(at_fd);
184 at_fd = -1;
185 return -1;
186 }
187
188 // Set timer
189 signal(SIGALRM, at_timer_alrm);
190 struct itimerval val;
191 // Only time
192 val.it_interval.tv_sec = 0;
193 val.it_interval.tv_usec = 0;
194 // Time
195 if(timeout >= 1000)
196 {
197 val.it_value.tv_sec = timeout/1000;
198 val.it_value.tv_usec = timeout%1000;
199 }
200 else
201 {
202 val.it_value.tv_sec = 0;
203 val.it_value.tv_usec = timeout;
204 }
205 if (setitimer(ITIMER_REAL, &val, NULL) == -1)
206 {
207 LOGE("setitimer fail.[%d]",errno);
208 return -1;
209 }
210
211 memset(at_rsp,0x0,rsp_size);
212 while(!at_timeout)
213 {
214 n = read(at_fd,at_rsp,rsp_size);
215 if(n < 0)
216 {
217 if(errno == EWOULDBLOCK)
218 {
219 usleep(50000);
220 continue;
221 }
222 else
223 {
224 LOGW("read error.[%d]",errno);
225 break;
226 }
227 }
228 else if (n > 0)
229 {
230 LOGI("RSP:%s",(char*)at_rsp);
231 break;
232 }
233 else
234 {
235 LOGW("read error.[%d]",errno);
236 break;
237 }
238 }
239
240 val.it_value.tv_sec = 0;
241 val.it_value.tv_usec = 0;
242 val.it_interval = val.it_value;
243 setitimer(ITIMER_REAL, &val, NULL);
244
245 if(n > 0)
246 return 0;
247
248 return -1;
249}
250#else
251int mbtk_send_at(const void *at_req,void* at_rsp,int rsp_size,int timeout)
252{
253 if(!at_req || !at_rsp || rsp_size <= 0)
254 {
255 LOGE("ARG error.");
256 return -1;
257 }
258
259 // Return "ERROR" if AT fail.
260 const char* result = sendCmd(0,(const char*)at_req);
261 memset(at_rsp,0x0,rsp_size);
262 snprintf(at_rsp,rsp_size,"%s",result);
263
264 return 0;
265}
266#endif
267
268/*
269* Set timer as microseconds.
270*/
271int mbtk_timer_set(mbtk_timer_alrm_func func,uint32 timeout_ms)
272{
273 signal(SIGALRM, func);
274 struct itimerval val;
275 // Only time
276 val.it_interval.tv_sec = 0;
277 val.it_interval.tv_usec = 0;
278 // Time
279 if(timeout_ms >= 1000)
280 {
281 val.it_value.tv_sec = timeout_ms/1000;
282 val.it_value.tv_usec = timeout_ms%1000;
283 }
284 else
285 {
286 val.it_value.tv_sec = 0;
287 val.it_value.tv_usec = timeout_ms;
288 }
289 if (setitimer(ITIMER_REAL, &val, NULL) == -1)
290 {
291 LOGE("setitimer fail.[errno - %d]",errno);
292 return -1;
293 }
294
295 return 0;
296}
297
298/**
299* Clear current timer.
300*/
301int mbtk_timer_clear()
302{
303 struct itimerval value;
304 value.it_value.tv_sec = 0;
305 value.it_value.tv_usec = 0;
306 value.it_interval = value.it_value;
307 if (setitimer(ITIMER_REAL, &value, NULL) == -1)
308 {
309 LOGE("setitimer fail.[errno - %d]",errno);
310 return -1;
311 }
312
313 return 0;
314}
315
316/* MRD still need to read /proc/cmdline after we drop root permission,
317 * so cache it in this function */
318int mbtk_get_kernel_cmdline(char *buf, int len)
319{
320 static char cmdline[MBTK_CMDLINE_LEN];
321 static int is_init = 0;
322 int ret = -1;
323 int fd;
324
325 if(!buf || len <= 0) return -1;
326
327 if(is_init)
328 goto INITED;
329
330 fd = open(PROC_CMDLINE, O_RDONLY);
331 if (fd < 0)
332 goto ERR_RET;
333
334 ret = read(fd, cmdline, MBTK_CMDLINE_LEN);
335 close(fd);
336
337 if(ret <= 0 || ret > MBTK_CMDLINE_LEN)
338 goto ERR_RET;
339 cmdline[ret - 1] = '\0';
340
341INITED:
342 ret = strlen(cmdline) + 1;
343 if(ret > len)
344 ret = len;
345
346 strncpy(buf, cmdline, ret);
347 buf[ret - 1] = '\0';
348
349 is_init = 1;
350
351 return ret;
352
353ERR_RET:
354 return -1;
355}
356
357/** returns 1 if line starts with prefix, 0 if it does not */
358int strStartsWith(const char *line, const char *prefix)
359{
360 if(prefix == NULL || strlen(prefix) == 0) {
361 return 1;
362 }
363
364 for ( ; *line != '\0' && *prefix != '\0' ; line++, prefix++) {
365 if (*line != *prefix) {
366 return 0;
367 }
368 }
369
370 return *prefix == '\0';
371}
372
373char* mbtk_time_text_get(char *buff, size_t buff_size)
374{
375 long now_nsec = 0;
376 if(buff == NULL || buff_size <= 0) {
377 return NULL;
378 }
379 memset(buff, 0x0, buff_size);
380#if 0
381 time_t now;
382 now = time(&now);
383 if(now == -1) {
384 LOGE("time() fail.");
385 return NULL;
386 }
387 struct tm *now_tm = gmtime(&now);
388#else
389 struct timespec now;
390 if(-1 == clock_gettime(CLOCK_REALTIME, &now)) {
391 LOGE("clock_gettime() fail.");
392 return NULL;
393 }
394
395 struct tm *now_tm = gmtime((time_t*)(&(now.tv_sec)));
396 now_nsec = now.tv_nsec;
397#endif
398
399 if(now_tm == NULL) {
400 LOGE("gmtime() fail.");
401 return NULL;
402 }
403
404 if(0 == strftime(buff, buff_size, TIME_FORMAT, now_tm)) {
405 LOGE("strftime() fail.");
406 return NULL;
407 }
408
409 snprintf(buff + strlen(buff), buff_size - strlen(buff),
410 "-%03ld", now_nsec / 1000000);
411
412 return buff;
413}
414
415mbtk_byteorder_enum mbtk_byteorder_get()
416{
417 union {
418 short a;
419 char c[sizeof(short)];
420 } un;
421 un.a = 0x0102;
422 if(sizeof(short) == 2) {
423 if(un.c[0] == 1 && un.c[1] == 2) {
424 return MBTK_BYTEORDER_BIG;
425 } else if(un.c[0] == 2 && un.c[1] == 1) {
426 return MBTK_BYTEORDER_LITTLE;
427 } else {
428 return MBTK_BYTEORDER_UNKNOWN;
429 }
430 } else {
431 LOGE("Unknown byte order.");
432 return MBTK_BYTEORDER_UNKNOWN;
433 }
434}
435
436uint16 byte_2_uint16(const void *buff, bool big_endian)
437{
438 const uint8* ptr = (const uint8*)buff;
439 if(big_endian) {
440 return (uint16)((ptr[0] << 8) | ptr[1]);
441 } else {
442 return (uint16)((ptr[1] << 8) | ptr[0]);
443 }
444}
445
446int uint16_2_byte(uint16 a, void *buff, bool big_endian)
447{
448 uint8* ptr = (uint8*)buff;
449 if(big_endian) {
450 ptr[0] = (uint8)(a >> 8);
451 ptr[1] = (uint8)a;
452 } else {
453 ptr[1] = (uint8)(a >> 8);
454 ptr[0] = (uint8)a;
455 }
456 return sizeof(uint16);
457}
458
459uint32 byte_2_uint32(const void *buff, bool big_endian)
460{
461 const uint8* ptr = (const uint8*)buff;
462 if(big_endian) {
463 return (uint32)((ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3]);
464 } else {
465 return (uint32)((ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0]);
466 }
467}
468
469int uint32_2_byte(uint32 a, void *buff, bool big_endian)
470{
471 uint8* ptr = (uint8*)buff;
472 if(big_endian) {
473 ptr[0] = (uint8)(a >> 24);
474 ptr[1] = (uint8)(a >> 16);
475 ptr[2] = (uint8)(a >> 8);
476 ptr[3] = (uint8)a;
477 } else {
478 ptr[3] = (uint8)(a >> 24);
479 ptr[2] = (uint8)(a >> 16);
480 ptr[1] = (uint8)(a >> 8);
481 ptr[0] = (uint8)a;
482 }
483 return sizeof(uint32);
484}
485
486uint64 byte_2_uint64(const void *buff, bool big_endian)
487{
488 const uint8* ptr = (const uint8*)buff;
489 if(big_endian) {
490 return (uint64)(((uint64)ptr[0] << 56) | ((uint64)ptr[1] << 48) | ((uint64)ptr[2] << 40) | ((uint64)ptr[3] << 32) | (ptr[4] << 24) | (ptr[5] << 16) | (ptr[6] << 8) | ptr[7]);
491 } else {
492 return (uint64)(uint64)(((uint64)ptr[7] << 56) | ((uint64)ptr[6] << 48) | ((uint64)ptr[5] << 40) | ((uint64)ptr[4] << 32) | (ptr[3] << 24) | (ptr[2] << 16) | (ptr[1] << 8) | ptr[0]);
493 }
494}
495
496int uint64_2_byte(uint64 a, void *buff, bool big_endian)
497{
498 uint8* ptr = (uint8*)buff;
499 if(big_endian) {
500 ptr[0] = (uint8)(a >> 56);
501 ptr[1] = (uint8)(a >> 48);
502 ptr[2] = (uint8)(a >> 40);
503 ptr[3] = (uint8)(a >> 32);
504 ptr[4] = (uint8)(a >> 24);
505 ptr[5] = (uint8)(a >> 16);
506 ptr[6] = (uint8)(a >> 8);
507 ptr[7] = (uint8)a;
508 } else {
509 ptr[7] = (uint8)(a >> 56);
510 ptr[6] = (uint8)(a >> 48);
511 ptr[5] = (uint8)(a >> 40);
512 ptr[4] = (uint8)(a >> 32);
513 ptr[3] = (uint8)(a >> 24);
514 ptr[2] = (uint8)(a >> 16);
515 ptr[1] = (uint8)(a >> 8);
516 ptr[0] = (uint8)a;
517 }
518 return sizeof(uint64);
519}
520
521void* memdup(const void* data, int data_len)
522{
523 if(data && data_len > 0)
524 {
525 uint8* result = (uint8*)malloc(data_len);
526 if(result == NULL)
527 {
528 return NULL;
529 }
530 memcpy(result, data, data_len);
531 return result;
532 }
533 else
534 {
535 return NULL;
536 }
537}
538
539