blob: faf77b226508e139d789de153f7b7945b7009d44 [file] [log] [blame]
lhe3922f92024-11-05 02:40:56 -08001#include <stdio.h>
2#include <sys/types.h>
3#include <sys/socket.h>
4#include <arpa/inet.h>
5#include <string.h>
6#include <unistd.h>
7#include <binder/Parcel.h>
8#include <log/log.h>
9#include <cutils/jstring.h>
10#include <pthread.h>
11#include <sys/socket.h>
12#include <netinet/in.h>
13#include <arpa/inet.h>
14#include <errno.h>
15#include <include/lynq_uci.h>
16#include <lynq_misc/lynq_misc.h>
17#include <stdlib.h>
18#include <fcntl.h>
19#include <assert.h>
20#include "lynq_sdk_ready.h"
21
22#define LOG_TAG "LYNQ_SDK_READY"
23#define DEST_PORT 8088
24#define LYNQ_BRODCAST_PORT 8086
25
26#define SDK_READY_PORT 8157
27#define DSET_IP_ADDRESS "127.0.0.1"
28#define RIL_REQUEST_DEVICE_IDENTITY 98
29#define MAX_LEN 1024
30#define TIMER 30
31#define LOG_UCI_FILE "lynq_uci"
32#define LOG_UCI_MODULE "debug_mode"
33#define update_ril_digit 0x7 //The last three digits are reserved for RIL service,0x111
34#define update_userdata_digit 1<<3
35#define update_gnss_digit 1<<4
36
37#define DEFAULT_PERIOD_RIL 30
38#define DEFAULT_PERIOD_GNSS 300
39#define DEFAULT_PERIOD_MD 60
40#define DEFAULT_PERIOD_PTN 120
41#define DEFAULT_PERIOD_SYS 120
42#define DEFAULT_PERIOD_BOOT 60
43
44#define MIN_PERIOD_RIL 10
45#define MIN_PERIOD_GNSS 60
46#define MIN_PERIOD_MD 30
47#define MIN_PERIOD_PTN 120
48#define MIN_PERIOD_SYS 120
49#define RIL_UNSOL_TELEPHONY_RESTART 3113
50
51#define GET_CPU_NUM "cat /proc/cpuinfo | grep processor | wc -l"
52#define GET_LOAD_AVG_INFO "/proc/loadavg"
53#define GET_INTR_INFO "/proc/stat"
54#define GET_MEM_INFO "/proc/meminfo"
55#define GET_MIN_FREE "/proc/sys/vm/min_free_kbytes"
56
57#define BIT_EXCPT_RIL 1
58#define BIT_EXCPT_MD 1 << 1
59#define BIT_EXCPT_GNSS 1 << 2
60#define BIT_EXCPT_PTN 1 << 3
61#define BIT_EXCPT_SYS 1 << 4
62
63using ::android::Parcel;
64
65static pthread_mutex_t g_lynq_sim_sendto_mutex;
66static pthread_mutex_t lock;
67static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
68static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER;
69
70// 全局变量
71static lynq_sdk_check_param_t *global_param = NULL;
72static lynq_sdk_status_cb global_sdk_status_cb = NULL;
73static lynq_sdk_ready_t global_sdk_status;
74static int utoken = 0;
75static int global_sdk_ready_status = 1;
76static int s_ril_started = 0;
77static int s_sys_started = 0;
78static int s_ptn_started = 0;
79static int s_gnss_started = 0;
80static int boot_ril_check_timer[8] = {2,2,4,4,8,8,16,16};
81enum in_ril_excpt {
82 RIL_REQUEST_SUCCESS=0,
83 RIL_MODEM_BOOT_EXCPT=1,
84 RIL_RESP_ERROR_FAIL=2,
85 RIL_SOCKET_CREATE_FAIL=3,
86 RIL_SOCKET_SEND_REC_FAIL=4,
87};
88
89typedef struct{
90 int uToken;
91 int request;
92 int paramLen;
93 char param[MAX_LEN];
94}lynq_client_t;
95
96
97void unlock_with_s_start(int *s_start)
98{
99 pthread_mutex_lock(&s_startupMutex);
100 *s_start = 1;
101 pthread_cond_broadcast(&s_startupCond);
102 pthread_mutex_unlock(&s_startupMutex);
103}
104long get_uptime()
105{
106 struct timespec start_time;
107 clock_gettime(CLOCK_MONOTONIC, &start_time);
108 return start_time.tv_sec;
109}
110const char * sdk_status_excpt_to_string(lynq_sdk_status_t excpt)
111{
112 switch(excpt)
113 {
114 case LYNQ_SDK_READY: return "LYNQ_SDK_READY";
115 case LYNQ_SDK_MD_EXCPT: return "LYNQ_SDK_MD_EXCPT";
116 case LYNQ_SDK_MD_REBOOT_EXCPT: return "LYNQ_SDK_MD_REBOOT_EXCPT";
117 case LYNQ_SDK_RIL_EXCPT: return "LYNQ_SDK_RIL_EXCPT";
118 case LYNQ_SDK_PARTITION_EXCPT: return "LYNQ_SDK_PARTITION_EXCPT";
119 case LYNQ_SDK_MIN_FREE_EXCPT: return "LYNQ_SDK_MIN_FREE_EXCPT";
120 case LYNQ_SDK_INTR_EXCPT: return "LYNQ_ACTION_INTR_EXCPT";
121 case LYNQ_SDK_LOAD_AVG_EXCPT: return "LYNQ_SDK_LOAD_AVG_EXCPT";
122 case LYNQ_SDK_NET_CHANNEL_EXCPT: return "LYNQ_SDK_NET_CHANNEL_EXCPT";
123 case LYNQ_SDK_GNSS_EXCPT: return "LYNQ_SDK_GNSS_EXCPT";
124 default: return "<unknown excpt>";
125 }
126}
127const char * sdk_status_action_to_string(lynq_sdk_ref_action_t action)
128{
129 switch(action)
130 {
131 case LYNQ_ACTION_NOTHING: return "LYNQ_ACTION_NOTHING";
132 case LYNQ_ACTION_REBOOT: return "LYNQ_ACTION_REBOOT";
133 case LYNQ_ACTION_RESET_MD: return "LYNQ_ACTION_RESET_MD";
134 case LYNQ_ACTION_RETRY_DATA_CALL: return "LYNQ_ACTION_RETRY_DATA_CALL";
135 case LYNQ_ACTION_PTN_CLEAN: return "LYNQ_ACTION_PTN_CLEAN";
136 case LYNQ_ACTION_SYS_WARNING: return "LYNQ_ACTION_SYS_WARNING";
137 default: return "<unknown action>";
138 }
139}
140void reset_sdk_ready_status()
141{
142 global_sdk_status.sdk_ready_status = LYNQ_SDK_READY;
143 global_sdk_status.ref_action = LYNQ_ACTION_NOTHING;
144}
145void trigger_sdk_ready_cb(lynq_sdk_status_t excpt, lynq_sdk_ref_action_t action)
146{
147 pthread_mutex_lock(&lock);
148 RLOGI("trigger sdk ready cb excpt:%s,action:%s",sdk_status_excpt_to_string(excpt),sdk_status_action_to_string(action));
149 long uptime = get_uptime();
150 if((excpt != LYNQ_SDK_READY) && (uptime < global_param->period.BOOT))
151 {
152 goto end;
153 }
154 //if((global_sdk_status.sdk_ready_status == excpt) && (global_sdk_status.ref_action == action))
155 //{
156 // goto end;
157 //}
158 global_sdk_status.sdk_ready_status = excpt;
159 global_sdk_status.ref_action = action;
160 global_sdk_status_cb(&global_sdk_status,NULL);
161end:
162 pthread_mutex_unlock(&lock);
163 return;
164}
165//maybe uci,or other
166void set_sdk_ready_nv(int value)
167{
168 char cmd[64] = {0};
169 RLOGI("set_sdk_ready_nv:%d",value);
170 sprintf(cmd,"uci set lynq_uci.sdk_ready=%d",value);//set uci
171 system(cmd);
172 return;
173}
174void set_sdk_ready_status_bit(int bit,int status)
175{
176 pthread_mutex_lock(&lock);
177 int old = 1;
178 if((global_sdk_ready_status & bit) == 0)
179 {
180 old = 0;
181 }
182 if(old == status)
183 {
184 goto end;
185 }
186 if(status == 1)
187 {
188 global_sdk_ready_status |= bit;
189 }
190 else
191 {
192 global_sdk_ready_status &= ~bit;
193 }
194 set_sdk_ready_nv(global_sdk_ready_status);
195end:
196 pthread_mutex_unlock(&lock);
197 return;
198}
199static int get_md_sta(void)
200{
201 FILE *fp;
202 char buffer[64]={};
203 fp = popen("cat /sys/kernel/ccci/boot","r");
204 if(fp == NULL)
205 {
206 RLOGD("function %s fp is null\n", __FUNCTION__);
207 return 0;
208 }
209 fgets(buffer,sizeof(buffer),fp);
210 if(!strlen(buffer))
211 {
212 RLOGD("function %s line %d\n", __FUNCTION__, __LINE__);
213 pclose(fp);
214 return 0;
215 }
216 if(buffer[4] == '4')
217 {
218 pclose(fp);
219 return 1;
220 }
221 RLOGD("function %s line %d\n", __FUNCTION__, __LINE__);
222 pclose(fp);
223 return 0;
224}
225
226static int check_service(const char *service)
227{
228 FILE *fp = NULL;
229 char buffer[1024]={};
230 if(!strcmp(service, "/usr/sbin/mtkfusionrild"))
231 {
232 fp = popen("ps -ef|grep rild","r");
233 }
234 else if(!strcmp(service, "lynq-ril-service"))
235 {
236 fp = popen("ps -ef|grep ril-service","r");
237 }
238 if(fp == NULL)
239 {
240 RLOGD("function %s fp is null\n", __FUNCTION__);
241 return 0;
242 }
243 while(NULL != fgets(buffer,sizeof(buffer),fp))
244 {
245 if(strstr(buffer,service))
246 {
247 pclose(fp);
248 RLOGD("check_service 1\n");
249 return 1;
250 }
251 }
252 RLOGD("check_service 0\n");
253 pclose(fp);
254 return 0;
255}
256
257/**
258 * @brief find partition zhengshu for exzample 5.7M,get value 5
259 *
260 * @param arg
261 * @return
262 */
263static void removeSpaces(char* str)
264{
265 char* dest = str;
266 while (*str) {
267 if (*str != ' ') {
268 *dest++ = *str;
269 }
270 str++;
271 }
272 *dest = '\0';
273 return ;
274}
275void check_ril_sleep(int count)
276{
277 if((count < sizeof(boot_ril_check_timer)/sizeof(int)) && ((global_sdk_ready_status & 1) == 1))// total 60s
278 {
279 sleep(boot_ril_check_timer[count]);
280 }
281 else
282 {
283 sleep(global_param->period.RIL);
284 }
285 return;
286}
287void update_ril_value(int value)
288{
289 switch (value)
290 {
291 case RIL_REQUEST_SUCCESS:
292 {
293 trigger_sdk_ready_cb(LYNQ_SDK_READY, LYNQ_ACTION_NOTHING);
294 set_sdk_ready_status_bit(BIT_EXCPT_RIL,0);
lh3d17a392024-11-07 22:20:18 -0800295 set_sdk_ready_status_bit(BIT_EXCPT_MD, 0);
lhe3922f92024-11-05 02:40:56 -0800296 break;
297 }
298 case RIL_MODEM_BOOT_EXCPT:
299 {
300 set_sdk_ready_status_bit(BIT_EXCPT_RIL,1);
301 trigger_sdk_ready_cb(LYNQ_SDK_MD_EXCPT,LYNQ_ACTION_REBOOT);
302 break;
303 }
304 case RIL_RESP_ERROR_FAIL:
305 {
306 set_sdk_ready_status_bit(BIT_EXCPT_RIL,1);
307 trigger_sdk_ready_cb(LYNQ_SDK_RIL_EXCPT,LYNQ_ACTION_NOTHING);
308 break;
309 }
310 case RIL_SOCKET_CREATE_FAIL:
311 case RIL_SOCKET_SEND_REC_FAIL:
312 {
313 set_sdk_ready_status_bit(BIT_EXCPT_RIL,1);
314 trigger_sdk_ready_cb(LYNQ_SDK_RIL_EXCPT,LYNQ_ACTION_REBOOT);
315 break;
316 }
317 default:
318 RLOGE("Not this case:%d",value);
319 }
320 return;
321}
322
323void update_userdata_value()
324{
325 pthread_mutex_lock(&lock);
326 trigger_sdk_ready_cb(LYNQ_SDK_PARTITION_EXCPT, LYNQ_ACTION_REBOOT);
327 set_sdk_ready_status_bit(BIT_EXCPT_PTN,1);
328 pthread_mutex_unlock(&lock);
329 return;
330}
331
332void update_gnss_value()
333{
334 pthread_mutex_lock(&lock);
335 trigger_sdk_ready_cb(LYNQ_SDK_GNSS_EXCPT, LYNQ_ACTION_REBOOT);
336 set_sdk_ready_status_bit(BIT_EXCPT_GNSS,1);
337 pthread_mutex_unlock(&lock);
338 return;
339}
340/**
341 * @brief send request imei
342 *
343 * @param arg
344 * 线程run起来后前两个60s 不做异常上报,这段时间是模组就绪时间因此只报ready 状态,60s 以后如果还是检测到异常,说明是真异常
345 * @return void*
346 */
347void * timer_request_imei(void * arg)
348{
349 unlock_with_s_start(&s_ril_started);
350 int send_num = -1;
351 int recv_num = -1;
352 int resp_type = -1;
353 int request = -1;
354 int slot_id = -1;
355 int token = -1;
356 int res_error = -1;
357 int count = 0;
358 Parcel p;
359 struct sockaddr_in addr_serv;
360 struct sockaddr_in liblynq_sdk_ready_socket;
361 memset(&liblynq_sdk_ready_socket, 0,sizeof(liblynq_sdk_ready_socket));
362 memset(&addr_serv, 0, sizeof(addr_serv));
363 addr_serv.sin_family = AF_INET;
364 addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
365 addr_serv.sin_port = htons(DEST_PORT);
366 liblynq_sdk_ready_socket.sin_family = AF_INET;
367 liblynq_sdk_ready_socket.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
368 int len_addr_serv = sizeof(addr_serv);
369
370 lynq_client_t client_t;
371 char res_data[MAX_LEN] = {0};
372 client_t.request = RIL_REQUEST_DEVICE_IDENTITY;
373 client_t.paramLen = 0;
374 client_t.uToken = utoken;
375 memset(client_t.param, 0, sizeof(client_t.param));
376
377 struct timeval timeOut;
378 timeOut.tv_sec = 3;//timeout time 3s
379 timeOut.tv_usec = 0;
380
381 int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
382 if (-1 == sock_fd)
383 {
384 RLOGD("__FUNCTION__ %s create sock_fd failed %s\n", __FUNCTION__, strerror(errno));
385 exit(EXIT_FAILURE);
386 return NULL;
387 }
388 int ret = bind(sock_fd, (struct sockaddr *)&liblynq_sdk_ready_socket, sizeof(liblynq_sdk_ready_socket));
389 if (-1 == ret)
390 {
391 RLOGE("liblynq_data_socket bind fail,errno:%d",errno);
392 return NULL;
393 }
394
395 if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &timeOut, sizeof(timeOut)) < 0)
396 {
397 RLOGD("__FUNCTION__ %s time out setting failed %s\n", __FUNCTION__, strerror(errno));
398 exit(EXIT_FAILURE);
399 return NULL;
400 }
401 while (1)
402 {
403 bzero(res_data, MAX_LEN);
404 pthread_mutex_lock(&g_lynq_sim_sendto_mutex);
405 send_num = sendto(sock_fd, &client_t, sizeof(client_t), 0, (struct sockaddr *)&addr_serv, len_addr_serv);
406 RLOGD("send_num %d\n", send_num);
407 if(send_num == 0)
408 {
409 RLOGD("__FUNCTION__ %s Close to end %s\n", __FUNCTION__, strerror(errno));
410 //unknow
411 update_ril_value(RIL_SOCKET_SEND_REC_FAIL);
412 pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
413 continue;
414 }
415 if(send_num < 0)
416 {
417 RLOGD("__FUNCTION__ %s sendto error %s\n", __FUNCTION__, strerror(errno));
418 //unknow
419 update_ril_value(RIL_SOCKET_SEND_REC_FAIL);
420 pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
421 continue;
422 }
423 //get data msg
424 recv_num = recvfrom(sock_fd,res_data,sizeof(char)*MAX_LEN,0,(struct sockaddr *)&addr_serv,(socklen_t*)&len_addr_serv);
425 RLOGD("recv_num %d\n", recv_num);
426 if(recv_num == -1 && errno == EAGAIN)
427 {
428 RLOGD("__FUNCTION__ %srecvfrom fail because timeout\n", __FUNCTION__);
429 /*set uci*/
430 if(!get_md_sta())
431 {
432 update_ril_value(RIL_MODEM_BOOT_EXCPT);
433 }
434 else
435 {
436 if(check_service("/usr/sbin/mtkfusionrild"))//rild work
437 {
438 if(!check_service("lynq-ril-service"))//not find,must be socket error
439 {
440 update_ril_value(RIL_SOCKET_CREATE_FAIL);
441 }
442 else
443 {
444 //unknow error
445 update_ril_value(RIL_SOCKET_SEND_REC_FAIL);
446 }
447 }
448 else//rild no work
449 {
450 //unknow
451 update_ril_value(RIL_SOCKET_SEND_REC_FAIL);
452 }
453 }
454 pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
455 check_ril_sleep(count);
456 count++;
457 continue;
458 }
459 if(recv_num <= 0)
460 {
461 RLOGD("__FUNCTION__ %s recvfrom fail %s\n", __FUNCTION__, strerror(errno));
462 update_ril_value(RIL_SOCKET_SEND_REC_FAIL);
463 pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
464 check_ril_sleep(count);
465 count++;
466 continue;
467 }
468 p.setData((uint8_t *)res_data,sizeof(char)*recv_num);
469 p.setDataPosition(0);
470 if(p.dataAvail() > 0)
471 {
472 p.readInt32(&resp_type);
473 p.readInt32(&token);
474 p.readInt32(&request);
475 p.readInt32(&slot_id);
476 p.readInt32(&res_error);
477 }
478 /*judge the res_error*/
479 if(!res_error)
480 {
481 update_ril_value(RIL_REQUEST_SUCCESS);
482 }
483 else
484 {
485 update_ril_value(RIL_RESP_ERROR_FAIL);
486 }
487 count = 0;
488 RLOGD("__FUNCTION__ %s res_error %d\n", __FUNCTION__, res_error);
489 /*judge the res_error*/
490 pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
491 check_ril_sleep(sizeof(boot_ril_check_timer)/sizeof(int));
492 }
493 return NULL;
494}
495
496void * wait_ril_event(void * arg)
497{
498 unlock_with_s_start(&s_ril_started);
499 int REC_BUFF_LEN = 64;
500 int recv_num = 0;
501 char rec_data[REC_BUFF_LEN] = {0};
502 int count = 0;
503 struct sockaddr_in wait_ril_event_socket;
504 struct sockaddr_in addr_client;
505 memset(&wait_ril_event_socket, 0,sizeof(wait_ril_event_socket));
506 memset(&addr_client, 0, sizeof(addr_client));
507 wait_ril_event_socket.sin_family = AF_INET;
508 wait_ril_event_socket.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
509 wait_ril_event_socket.sin_port = htons(SDK_READY_PORT);
510 int len_addr_serv = sizeof(addr_client);
511
512 int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
513 if (-1 == sock_fd)
514 {
515 RLOGD("__FUNCTION__ %s create sock_fd failed %s\n", __FUNCTION__, strerror(errno));
516 exit(EXIT_FAILURE);
517 return NULL;
518 }
519 int ret = bind(sock_fd, (struct sockaddr *)&wait_ril_event_socket, sizeof(wait_ril_event_socket));
520 if (-1 == ret)
521 {
522 RLOGE("liblynq_data_socket bind fail,errno:%d",errno);
523 exit(EXIT_FAILURE);
524 return NULL;
525 }
526 while(1)
527 {
528 memset(rec_data,0,REC_BUFF_LEN);
529 recv_num = recvfrom(sock_fd,rec_data,sizeof(char)*REC_BUFF_LEN,0,(struct sockaddr *)&addr_client,(socklen_t*)&len_addr_serv);
530 if(recv_num <= 0)
531 {
532 RLOGD("__FUNCTION__ %s Close to end\n", __FUNCTION__);
533 update_ril_value(RIL_SOCKET_SEND_REC_FAIL);
534 continue;
535 }
536 rec_data[recv_num] = '\0';
537 if((atoi(rec_data) == RIL_UNSOL_TELEPHONY_RESTART) && (count%2 == 0))//this urc will be reported twice in a row
538 {
539 set_sdk_ready_status_bit(BIT_EXCPT_MD, 1);
540 trigger_sdk_ready_cb(LYNQ_SDK_MD_REBOOT_EXCPT,LYNQ_ACTION_RETRY_DATA_CALL);
541 count = 0;
542 }
543 count ++;
544 }
545 close(sock_fd);
546}
547
548
549void delete_enter(char data[])
550{
551 char *find = strchr(data, '\n');
552 if(find)
553 *find = '\0';
554 return ;
555}
556
557unsigned long long get_interrupts(int fd,char *buffer,int size)
558{
559 char *line = NULL;
560 unsigned long long intr_value = 0;
561 memset(buffer,0,size);
562 lseek(fd, 0, SEEK_SET);
563 ssize_t bytes_intr_read = read(fd,buffer, size - 1);
564 buffer[bytes_intr_read] = '\0';
565 line = strstr(buffer, "intr");
566 if (line == NULL)
567 {
568 RLOGE("get intr fail");
569 }
570 else
571 {
572 line += 5;
573 sscanf(line,"%llu",&intr_value);
574 }
575 return intr_value;
576}
577unsigned long long get_mem_free(int fd,char *buffer,int size)
578{
579 char *line = NULL;
580 unsigned long long mem_value = 0;
581 lseek(fd, 0, SEEK_SET);
582 memset(buffer,0,size);
583 ssize_t bytes_mem_read = read(fd, buffer, size - 1);
584 buffer[bytes_mem_read] = '\0';
585 line = strstr(buffer, "MemFree:");
586 if (line == NULL)
587 {
588 RLOGE("get MemFree fail");
589 }
590 else
591 {
592 line += 9;
593 while (*line == ' ')
594 {
595 line++;
596 }
597 sscanf(line,"%llu",&mem_value);
598 }
599 return mem_value;
600}
601
602void *check_system(void * arg)
603{
604 int fd_mem = 0;
605 int fd_intr = 0;
606 int fd_avg = 0;
607 int fd_free = 0;
608 int BUFFER_SIZE = 512;
609 unsigned long long min_free = 0;
610 unsigned long long mem_value = 0;
611 unsigned long long intr_value_old = 0;
612 unsigned long long intr_value_new = 0;
613 float avg_value = 0;
614 int excpt_flag = 0;
615 char sys_buffer[BUFFER_SIZE];
616 char min_free_buffer[BUFFER_SIZE];
617 unlock_with_s_start(&s_sys_started);
618 fd_mem = open(GET_MEM_INFO,O_RDONLY);
619 fd_free = open(GET_MIN_FREE,O_RDONLY);
620 fd_intr = open(GET_INTR_INFO,O_RDONLY);
621 fd_avg = open(GET_LOAD_AVG_INFO,O_RDONLY);
622 if((fd_mem < 0) || (fd_intr < 0) || (fd_avg < 0) || (fd_free < 0))
623 {
624 RLOGE("check system open fail");
625 exit(EXIT_FAILURE);
626 }
627 memset(min_free_buffer,0,BUFFER_SIZE);
628 ssize_t bytes_min_free_read = read(fd_free, min_free_buffer, BUFFER_SIZE - 1);
629 if(bytes_min_free_read == -1)
630 {
631 RLOGE("get min free fail");
632 exit(EXIT_FAILURE);
633 }
634 min_free = atoi(min_free_buffer);
635 close(fd_free);
636 ssize_t bytes_avg_read = 0;
637 intr_value_old = get_interrupts(fd_intr, sys_buffer, BUFFER_SIZE);
638 while(1)
639 {
640 memset(sys_buffer,0,BUFFER_SIZE);
641 lseek(fd_avg, 0, SEEK_SET);
642 bytes_avg_read = read(fd_avg, sys_buffer, BUFFER_SIZE - 1);
643 sys_buffer[bytes_avg_read] = '\0';
644 sscanf(sys_buffer,"%*f %f",&avg_value);
645
646 mem_value = get_mem_free(fd_mem, sys_buffer, BUFFER_SIZE);
647 intr_value_new = get_interrupts(fd_intr, sys_buffer, BUFFER_SIZE);
648 //pages_min = /proc/sys/vm/min_free_kbytes
649 //pages_low = pages_min*5/4
650 //pages_high = pages_min*3/2
651 if((mem_value >= min_free) && (mem_value < min_free*1.25))//pages_min-pages_low
652 {
653 trigger_sdk_ready_cb(LYNQ_SDK_MIN_FREE_EXCPT,LYNQ_ACTION_SYS_WARNING);
654 excpt_flag = 1;
655 }
656 if(mem_value < min_free)
657 {
658 trigger_sdk_ready_cb(LYNQ_SDK_MIN_FREE_EXCPT,LYNQ_ACTION_REBOOT);
659 excpt_flag = 1;
660 }
661 if(avg_value > global_param->threshold.load_average)
662 {
663 trigger_sdk_ready_cb(LYNQ_SDK_LOAD_AVG_EXCPT,LYNQ_ACTION_SYS_WARNING);
664 excpt_flag = 1;
665 }
666 if((intr_value_new - intr_value_old) > global_param->threshold.interrupts)
667 {
668 trigger_sdk_ready_cb(LYNQ_SDK_INTR_EXCPT,LYNQ_ACTION_SYS_WARNING);
669 excpt_flag = 1;
670 }
671 set_sdk_ready_status_bit(BIT_EXCPT_SYS,excpt_flag);
672 RLOGI("memfree:%llu,intr_old:%llu,intr_new:%llu,intr_delat:%llu,avg:%.2f\n",mem_value,intr_value_old,intr_value_new,(intr_value_new - intr_value_old),avg_value);
673 intr_value_old = intr_value_new;
674 excpt_flag = 0;
675 sleep(global_param->period.SYS);
676 }
677 close(fd_mem);
678 close(fd_intr);
679 close(fd_avg);
680}
681
682/* old code 2024/11/04 close
683void *check(void * arg)
684{
685
686 char pid[200][8];
687 char ffd[200][4];
688 char buf[64];
689 char check_time[4];
690 char timebuf[32];
691 int num = 1;
692 int i=0;
693 int j;
694 FILE *fp,*fp_1;
695 int ret;
696
697 RLOGD("check cpu/pid/interrupts/fd!!!\n");
698 system("mkdir /media/check_file");
699 system("touch /media/check_time");
700 fp_1 = popen("cat /media/check_time","r");
701 if(fgets(check_time, 4, fp_1) != NULL)
702 {
703 num = atoi(check_time);
704 }
705 pclose(fp_1);
706 while(1)
707 {
708 i = 0;
709 system("date >>/media/check_file/cpu_moniter.txt");
710 ret = system("top -b |head -n 25 >>/media/check_file/cpu_moniter.txt");
711 RLOGD("cpu ret %d", ret);
712 system("date >>/media/check_file/inter_moniter.txt");
713 ret = system("cat /proc/interrupts |grep -v \": 0 0\" >>/media/check_file/inter_moniter.txt");
714 RLOGD("interrupts ret %d", ret);
715
716 system("date >>/media/check_file/pid_moniter.txt");
717 ret = system("ps -eo \"%p %a\" | grep -v \"\\[\" >>/media/check_file/pid_moniter.txt");
718 RLOGD("pid ret %d", ret);
719
720 system("date >>/media/check_file/meminfo_moniter.txt");
721 ret = system("cat /proc/meminfo >>/media/check_file/meminfo_moniter.txt");
722 RLOGD("meminfo ret %d", ret);
723
724 system("date >>/media/check_file/buddyinfo_moniter.txt");
725 ret = system("cat /proc/buddyinfo >>/media/check_file/buddyinfo_moniter.txt");
726 RLOGD("buddyinfo ret %d", ret);
727
728 system("date >>/media/check_file/ps_auxw_moniter.txt");
729 ret = system("ps -auxw|grep -v \"0.0 0.0\"|grep -v \"0.1 0.0\"|grep -v \"0.0 0.1\" >>/media/check_file/ps_auxw_moniter.txt");
730 RLOGD("ps_auxw ret %d", ret);
731
732 system("date >>/media/check_file/cur_freq_moniter.txt");
733 ret = system("cat /sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq >>/media/check_file/cur_freq_moniter.txt");
734 RLOGD("cur_freq ret %d", ret);
735
736 system("date >>/media/check_file/available_frequencies_moniter.txt");
737 ret = system("cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies >>/media/check_file/available_frequencies_moniter.txt");
738 RLOGD("available_frequencies ret %d", ret);
739
740 system("date >>/media/check_file/fd_moniter.txt");
741 fp = popen("ps -eo \"%p %a\" | grep -v \"\\[\"|awk '{print $1}'","r");
742 while(fgets(pid[i], 8, fp) != NULL)
743 {
744 delete_enter(pid[i]);
745 i++;
746 }
747 pclose(fp);
748
749 for(j=1;j<i;j++)
750 {
751 sprintf(buf, "ls /proc/%s/fd | wc -l", pid[j]);
752 fp = popen(buf, "r");
753 fgets(ffd[j], 4, fp);
754 sprintf(buf,"echo \"pid: %s, fd_num: %s\" >>/media/check_file/fd_moniter.txt",pid[j], ffd[j]);
755 system(buf);
756 pclose(fp);
757 }
758
759 if(num > 228)
760 {
761 system("cp /media/check_file/cpu_moniter.txt /media/check_file/cpu_moniter_1.txt");
762 system("cp /media/check_file/inter_moniter.txt /media/check_file/inter_moniter_1.txt");
763 system("cp /media/check_file/pid_moniter.txt /media/check_file/pid_moniter_1.txt");
764 system("cp /media/check_file/fd_moniter.txt /media/check_file/fd_moniter_1.txt");
765 system("cp /media/check_file/fd_moniter.txt /media/check_file/meminfo_moniter_1.txt");
766 system("cp /media/check_file/fd_moniter.txt /media/check_file/buddyinfo_moniter_1.txt");
767 system("cp /media/check_file/fd_moniter.txt /media/check_file/ps_auxw_moniter_1.txt");
768 system("cp /media/check_file/fd_moniter.txt /media/check_file/cur_freq_moniter_1.txt");
769 system("cp /media/check_file/fd_moniter.txt /media/check_file/available_frequencies_moniter_1.txt");
770
771
772 system("rm -rf /media/check_file/cpu_moniter.txt");
773 system("rm -rf /media/check_file/inter_moniter.txt");
774 system("rm -rf /media/check_file/pid_moniter.txt");
775 system("rm -rf /media/check_file/fd_moniter.txt");
776 system("rm -rf /media/check_file/meminfo_moniter.txt");
777 system("rm -rf /media/check_file/buddyinfo_moniter.txt");
778 system("rm -rf /media/check_file/ps_auxw_moniter.txt");
779 system("rm -rf /media/check_file/cur_freq_moniter.txt");
780 system("rm -rf /media/check_file/available_frequencies_moniter.txt");
781
782 num = 0;
783 }
784 num++;
785 sprintf(timebuf, "echo \"%d\" >/media/check_time", num);
786 ret = system(timebuf);
787 sleep(300);
788 }
789 return NULL;
790
791}
792
793int num = 0;
794void *check_uci(void * arg)
795{
796 int ret[6];
797 int result = 0;
798 int flag = 0;
799
800 char uci_0[]="/etc/config/lynq_uci";
801 char uci_1[]="/etc/config/lynq_uci_ro";
802 char uci_2[]="/etc/config/mdlog";
803 char uci_3[]="/etc/config/radio_property";
804 char uci_4[]="/etc/config/service";
805 char uci_5[]="/etc/config/usb";
806 RLOGD("start check uci\n");
807 while(num++ < 4)
808 {
809 RLOGD("@@@@@@@num=%d\n", num);
810 flag = 0;
811 ret[0] = system("uci show | grep \"lynq_uci.lynq_ril\" > /dev/null");
812 if(ret[0] != 0)
813 {
814 RLOGD("lynq_uci unload\n");
815 flag = 1;
816 }
817
818 ret[1] = system("uci show | grep \"^lynq_uci_ro\.\" > /dev/null");
819 if(ret[1] != 0)
820 {
821 RLOGD("lynq_uci_ro unload\n");
822 flag = 1;
823 }
824
825 ret[2] = system("uci show | grep \"^mdlog\.\"");
826 if(ret[2] != 0)
827 {
828 RLOGD("mdlog unload\n");
829 flag = 1;
830 }
831
832 ret[3] = system("uci show | grep \"^radio_property\.\" > /dev/null");
833 if(ret[3] != 0)
834 {
835 RLOGD("radio_property unload\n");
836 flag = 1;
837 }
838
839 ret[4] = system("uci show | grep \"^service\.\" > /dev/null");
840 if(ret[4] != 0)
841 {
842 RLOGD("service unload\n");
843 flag = 1;
844 }
845
846 ret[5] = system("uci show | grep \"^usb\.\" > /dev/null");
847 if(ret[5] != 0)
848 {
849 RLOGD("usb unload\n");
850 flag = 1;
851 }
852
853 RLOGD("flag=%d\n",flag);
854 if(flag != 0)
855 {
856 RLOGD("config reload\n");
857 result = chdir("/data_backup/");
858 result =system("tar -zxvf userdata.tar.gz -C /STATE/ >/dev/null");
859 if(result!= 0)
860 {
861 RLOGD("cp config fail\n");
862 }
863 if(ret[0] != 0)
864 {
865 lynq_load_config(uci_0);
866 RLOGD("reload lynq_uci\n");
867 system("systemctl start autosuspend");
868 }
869 if(ret[1] != 0)
870 {
871 lynq_load_config(uci_1);
872 RLOGD("reload lynq_uci_ro\n");
873 }
874 if(ret[2] != 0)
875 {
876 lynq_load_config(uci_2);
877 RLOGD("reload mdlog\n");
878 }
879 if(ret[3] != 0)
880 {
881 lynq_load_config(uci_3);
882 RLOGD("reload radio_property\n");
883 system("systemctl restart mtkfusionrild");
884 }
885 if(ret[4] != 0)
886 {
887 lynq_load_config(uci_4);
888 RLOGD("reload service\n");
889 }
890 if(ret[5] != 0)
891 {
892 lynq_load_config(uci_5);
893 RLOGD("reload usb\n");
894 }
895 }
896 else
897 {
898 RLOGD("uci check success, exit check!\n");
899 break;
900 }
901 sleep(2);
902 }
903 return NULL;
904}
905old code 2024/11/04 close*/
906
907static void t800_check_partition()
908{
909 char buf[64] = {0};
910 FILE *fp = NULL;
911 int q = 22*1024;
912 int ubisize = 0;
913
914 fp = popen("df -l| grep '/data$' | awk '{print $3}'","r");
915 if(fp == NULL)
916 {
917 RLOGD("Failed to run command\n");
918 return;
919 }
920 fgets(buf, sizeof(buf) - 1, fp);
921 RLOGD("buf is: %s\n",buf);
922 ubisize = atoi(buf);
923 if(ubisize >= q)
924 {
925 RLOGD(">set ready 5,userdata size is %d M\n",ubisize);
926 update_userdata_value();
927 }
928 else
929 {
930 set_sdk_ready_status_bit(BIT_EXCPT_PTN, 0);
931 }
lh3d17a392024-11-07 22:20:18 -0800932 pclose(fp);
lhe3922f92024-11-05 02:40:56 -0800933 return;
934}
935void t800_check_mnld()
936{
lh3d17a392024-11-07 22:20:18 -0800937 FILE *fp = NULL;
lhe3922f92024-11-05 02:40:56 -0800938 const char *symble = "NRestarts=";
939 const char *cmd = "systemctl show -p NRestarts mnld.service";
940 char buf[64];
941 int count_old = 0;
942 int count_new = 0;
943 while(1)
944 {
945 fp = popen(cmd,"r");
lh3d17a392024-11-07 22:20:18 -0800946 if(NULL == fp)
947 {
948 RLOGE("run cmd:%s fail",cmd);
949 sleep(1);
950 continue;
951 }
lhe3922f92024-11-05 02:40:56 -0800952 while(fgets(buf, sizeof(buf) - 1, fp) != NULL)
953 {
954 if(strncmp(buf,symble,strlen(symble)) == 0)
955 count_new = atoi(buf+strlen(symble));
956 memset(buf,0,sizeof(buf));
957 }
958 if((count_new - count_old) > 1)
959 {
960 update_gnss_value();//out put mnld severe abnormal state
961 RLOGD("mnld is severe abnormal state = %d\n",count_new - count_old);
962 }
963 else
964 {
965 set_sdk_ready_status_bit(BIT_EXCPT_GNSS,0);
966 }
967 pclose(fp);
968 count_old = count_new;
969 sleep(global_param->period.GNSS);
970 }
971 return;
972}
973void *check_partition(void *arg)
974{
975 unlock_with_s_start(&s_ptn_started);
976 while(1)
977 {
978 t800_check_partition();
979 sleep(global_param->period.PTN);
980 }
981 return NULL;
982}
983
984void *check_gnss(void * arg)
985{
986 unlock_with_s_start(&s_gnss_started);
987 t800_check_mnld();
988 return NULL;
989}
990int get_cpu_info()
991{
992 FILE *CPU_FD = NULL;
993 int cpu_num = 0;
994 char cpu_info[8];
995 CPU_FD = popen(GET_CPU_NUM,"r");
996 if(CPU_FD == NULL)
997 {
998 RLOGD("get cpu info fail:%s",GET_CPU_NUM);
999 return -1;
1000 }
1001 fgets(cpu_info, sizeof(cpu_info) - 1, CPU_FD);
1002 cpu_num = atoi(cpu_info);
1003 pclose(CPU_FD);
1004 return cpu_num;
1005}
1006int set_default_sdk_check_param(lynq_sdk_check_param_t *param)
1007{
1008 int cpu_num = 0;
1009 param->period.RIL = DEFAULT_PERIOD_RIL;
1010 param->period.GNSS = DEFAULT_PERIOD_GNSS;
1011 param->period.MD = DEFAULT_PERIOD_MD;
1012 param->period.PTN = DEFAULT_PERIOD_PTN;
1013 param->period.SYS = DEFAULT_PERIOD_SYS;
1014 param->period.BOOT = DEFAULT_PERIOD_BOOT;
1015 cpu_num = get_cpu_info();
1016 if(cpu_num <= 0)
1017 {
1018 RLOGE("set default sdk check param fail");
1019 return -1;
1020 }
1021 param->threshold.interrupts = (DEFAULT_PERIOD_SYS/30)*cpu_num*5000;
1022 param->threshold.load_average = cpu_num*2;
1023 return 0;
1024}
1025int create_check_threads(void)
1026{
1027 pthread_t thid,thid_1,thid_2,thid_3,thid_4;
1028 pthread_attr_t attr;
1029 pthread_attr_init(&attr);
1030 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1031 int ret;
1032 pthread_mutex_lock(&s_startupMutex);
1033 ret = pthread_create(&thid, &attr, timer_request_imei, NULL);
1034 if(ret != 0)
1035 {
1036 RLOGE("timer_request_imei error!!!");
1037 goto excp;
1038 }
1039 while (s_ril_started == 0)
1040 {
1041 pthread_cond_wait(&s_startupCond, &s_startupMutex);
1042 }
1043 ret = pthread_create(&thid_1, &attr, check_system, NULL);
1044 if(ret != 0)
1045 {
1046 RLOGE("check_system error!!!");
1047 goto excp;
1048 }
1049 while (s_sys_started == 0)
1050 {
1051 pthread_cond_wait(&s_startupCond, &s_startupMutex);
1052 }
1053
1054 ret = pthread_create(&thid_2, &attr,check_gnss,NULL);
1055 if(ret != 0)
1056 {
1057 RLOGD("check_gnss error!!!");
1058 goto excp;
1059 }
1060 while (s_gnss_started == 0)
1061 {
1062 pthread_cond_wait(&s_startupCond, &s_startupMutex);
1063 }
1064 ret = pthread_create(&thid_3, &attr,check_partition,NULL);
1065 if(ret != 0)
1066 {
1067 RLOGD("check_partition error!!!");
1068 goto excp;
1069 }
1070 while (s_ptn_started == 0)
1071 {
1072 pthread_cond_wait(&s_startupCond, &s_startupMutex);
1073 }
1074 s_ril_started = 0;
1075 ret = pthread_create(&thid_4, &attr,wait_ril_event,NULL);
1076 if(ret != 0)
1077 {
1078 RLOGD("wait_ril_event error!!!");
1079 goto excp;
1080 }
1081 while (s_ril_started == 0)
1082 {
1083 pthread_cond_wait(&s_startupCond, &s_startupMutex);
1084 }
1085 pthread_mutex_unlock(&s_startupMutex);
1086 return 0;
1087excp:
1088 pthread_mutex_unlock(&s_startupMutex);
1089 return LYNQ_E_NORMAL;
1090}
1091int lynq_sdk_ready_register(const int uToken,const lynq_sdk_check_param_t* param,lynq_sdk_status_cb sdk_status_cb)
1092{
1093 int ret = 0;
1094 if (param == NULL || sdk_status_cb == NULL)
1095 {
1096 RLOGE("input null");
1097 return LYNQ_E_NULL_ANONALY;
1098 }
1099 utoken = uToken;
1100 global_param = (lynq_sdk_check_param_t *)malloc(sizeof(lynq_sdk_check_param_t));
1101 if(global_param == NULL)
1102 {
1103 RLOGE("malloc global_param fail");
1104 goto end;
1105 }
1106 memset(global_param,0,sizeof(lynq_sdk_check_param_t));
1107 if(param->isvalid == 0)
1108 {
1109 ret = set_default_sdk_check_param(global_param);
1110 if (ret < 0)
1111 {
1112 RLOGE("get default param fail");
1113 goto end;
1114 }
1115 }
1116 else
1117 {
1118 if((param->period.RIL < MIN_PERIOD_RIL) || (param->period.GNSS < MIN_PERIOD_GNSS) || (param->period.MD < MIN_PERIOD_MD)
1119 || (param->period.PTN < MIN_PERIOD_PTN) || (param->period.SYS < MIN_PERIOD_SYS))
1120 {
1121 RLOGE("param excption");
1122 goto end;
1123 }
1124 global_param->period.RIL = param->period.RIL;
1125 global_param->period.GNSS = param->period.GNSS;
1126 global_param->period.MD = param->period.MD;
1127 global_param->period.PTN = param->period.PTN;
1128 global_param->period.SYS = param->period.SYS;
1129 global_param->period.BOOT = param->period.BOOT;
1130 global_param->threshold.interrupts = param->threshold.interrupts;
1131 global_param->threshold.load_average = param->threshold.load_average;
1132 }
1133 RLOGI("period.RIL:%d,period.GNSS:%d,period.MD:%d,period.PTN:%d,period.SYS:%d,threshold.interrupts:%llu,threshold.load_average:%d",
1134 global_param->period.RIL,global_param->period.GNSS,global_param->period.MD,global_param->period.PTN,
1135 global_param->period.SYS,global_param->threshold.interrupts,global_param->threshold.load_average);
1136 global_sdk_status_cb = sdk_status_cb;
1137 global_sdk_status.sdk_ready_status = (lynq_sdk_status_t)-1;
1138 global_sdk_status.ref_action = (lynq_sdk_ref_action_t)-1;
1139 set_sdk_ready_nv(1);//开机默认RIL 异常,第一次检测完成之后更新正确值
1140 ret = create_check_threads();
1141 if(ret != 0)
1142 {
1143 goto end;
1144 }
1145 return ret;
1146end:
1147 exit(EXIT_FAILURE);
1148}
1149int lynq_get_sdk_ready_status(int *status)
1150{
1151 if (status == NULL)
1152 {
1153 RLOGE("sdk_ready_status is null");
1154 return LYNQ_E_NULL_ANONALY;
1155 }
1156 *status = global_sdk_ready_status;
1157 return 0;
1158}