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