| #include <stdio.h>
|
| #include <sys/types.h>
|
| #include <sys/socket.h>
|
| #include <arpa/inet.h>
|
| #include <string.h>
|
| #include <unistd.h>
|
| #include <binder/Parcel.h>
|
| #include <log/log.h>
|
| #include <cutils/jstring.h>
|
| #include <pthread.h>
|
| #include <sys/socket.h>
|
| #include <netinet/in.h>
|
| #include <arpa/inet.h>
|
| #include <errno.h>
|
| #include <include/lynq_uci.h>
|
| #include <lynq_misc/lynq_misc.h> |
| #include <stdlib.h> |
| #include <fcntl.h> |
| #include <assert.h>
|
| #include "lynq_sdk_ready.h"
|
|
|
| #define LOG_TAG "LYNQ_SDK_READY"
|
| #define DEST_PORT 8088
|
| #define LYNQ_BRODCAST_PORT 8086
|
|
|
| #define SDK_READY_PORT 8157
|
| #define DSET_IP_ADDRESS "127.0.0.1"
|
| #define RIL_REQUEST_DEVICE_IDENTITY 98
|
| #define MAX_LEN 1024
|
| #define TIMER 30
|
| #define LOG_UCI_FILE "lynq_uci"
|
| #define LOG_UCI_MODULE "debug_mode"
|
| #define update_ril_digit 0x7 //The last three digits are reserved for RIL service,0x111
|
| #define update_userdata_digit 1<<3
|
| #define update_gnss_digit 1<<4
|
|
|
| #define DEFAULT_PERIOD_RIL 30
|
| #define DEFAULT_PERIOD_GNSS 300
|
| #define DEFAULT_PERIOD_MD 60
|
| #define DEFAULT_PERIOD_PTN 120
|
| #define DEFAULT_PERIOD_SYS 120
|
| #define DEFAULT_PERIOD_BOOT 60
|
|
|
| #define MIN_PERIOD_RIL 10
|
| #define MIN_PERIOD_GNSS 60
|
| #define MIN_PERIOD_MD 30
|
| #define MIN_PERIOD_PTN 120
|
| #define MIN_PERIOD_SYS 120
|
| #define RIL_UNSOL_TELEPHONY_RESTART 3113
|
|
|
| #define GET_CPU_NUM "cat /proc/cpuinfo | grep processor | wc -l"
|
| #define GET_LOAD_AVG_INFO "/proc/loadavg"
|
| #define GET_INTR_INFO "/proc/stat"
|
| #define GET_MEM_INFO "/proc/meminfo"
|
| #define GET_MIN_FREE "/proc/sys/vm/min_free_kbytes"
|
|
|
| #define BIT_EXCPT_RIL 1
|
| #define BIT_EXCPT_MD 1 << 1
|
| #define BIT_EXCPT_GNSS 1 << 2
|
| #define BIT_EXCPT_PTN 1 << 3
|
| #define BIT_EXCPT_SYS 1 << 4
|
|
|
| using ::android::Parcel;
|
|
|
| static pthread_mutex_t g_lynq_sim_sendto_mutex;
|
| static pthread_mutex_t lock;
|
| static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER; |
| static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER;
|
|
|
| // 全局变量
|
| static lynq_sdk_check_param_t *global_param = NULL;
|
| static lynq_sdk_status_cb global_sdk_status_cb = NULL;
|
| static lynq_sdk_ready_t global_sdk_status;
|
| static int utoken = 0;
|
| static int global_sdk_ready_status = 1;
|
| static int s_ril_started = 0;
|
| static int s_sys_started = 0;
|
| static int s_ptn_started = 0;
|
| static int s_gnss_started = 0;
|
| static int boot_ril_check_timer[8] = {2,2,4,4,8,8,16,16};
|
| enum in_ril_excpt {
|
| RIL_REQUEST_SUCCESS=0,
|
| RIL_MODEM_BOOT_EXCPT=1,
|
| RIL_RESP_ERROR_FAIL=2,
|
| RIL_SOCKET_CREATE_FAIL=3,
|
| RIL_SOCKET_SEND_REC_FAIL=4,
|
| };
|
|
|
| typedef struct{
|
| int uToken;
|
| int request;
|
| int paramLen;
|
| char param[MAX_LEN];
|
| }lynq_client_t;
|
|
|
|
|
| void unlock_with_s_start(int *s_start)
|
| {
|
| pthread_mutex_lock(&s_startupMutex);
|
| *s_start = 1;
|
| pthread_cond_broadcast(&s_startupCond); |
| pthread_mutex_unlock(&s_startupMutex);
|
| }
|
| long get_uptime()
|
| {
|
| struct timespec start_time;
|
| clock_gettime(CLOCK_MONOTONIC, &start_time);
|
| return start_time.tv_sec;
|
| }
|
| const char * sdk_status_excpt_to_string(lynq_sdk_status_t excpt)
|
| {
|
| switch(excpt)
|
| {
|
| case LYNQ_SDK_READY: return "LYNQ_SDK_READY";
|
| case LYNQ_SDK_MD_EXCPT: return "LYNQ_SDK_MD_EXCPT";
|
| case LYNQ_SDK_MD_REBOOT_EXCPT: return "LYNQ_SDK_MD_REBOOT_EXCPT";
|
| case LYNQ_SDK_RIL_EXCPT: return "LYNQ_SDK_RIL_EXCPT";
|
| case LYNQ_SDK_PARTITION_EXCPT: return "LYNQ_SDK_PARTITION_EXCPT";
|
| case LYNQ_SDK_MIN_FREE_EXCPT: return "LYNQ_SDK_MIN_FREE_EXCPT";
|
| case LYNQ_SDK_INTR_EXCPT: return "LYNQ_ACTION_INTR_EXCPT";
|
| case LYNQ_SDK_LOAD_AVG_EXCPT: return "LYNQ_SDK_LOAD_AVG_EXCPT";
|
| case LYNQ_SDK_NET_CHANNEL_EXCPT: return "LYNQ_SDK_NET_CHANNEL_EXCPT";
|
| case LYNQ_SDK_GNSS_EXCPT: return "LYNQ_SDK_GNSS_EXCPT";
|
| default: return "<unknown excpt>";
|
| }
|
| }
|
| const char * sdk_status_action_to_string(lynq_sdk_ref_action_t action)
|
| {
|
| switch(action)
|
| {
|
| case LYNQ_ACTION_NOTHING: return "LYNQ_ACTION_NOTHING";
|
| case LYNQ_ACTION_REBOOT: return "LYNQ_ACTION_REBOOT";
|
| case LYNQ_ACTION_RESET_MD: return "LYNQ_ACTION_RESET_MD";
|
| case LYNQ_ACTION_RETRY_DATA_CALL: return "LYNQ_ACTION_RETRY_DATA_CALL";
|
| case LYNQ_ACTION_PTN_CLEAN: return "LYNQ_ACTION_PTN_CLEAN";
|
| case LYNQ_ACTION_SYS_WARNING: return "LYNQ_ACTION_SYS_WARNING";
|
| default: return "<unknown action>";
|
| }
|
| }
|
| void reset_sdk_ready_status()
|
| {
|
| global_sdk_status.sdk_ready_status = LYNQ_SDK_READY;
|
| global_sdk_status.ref_action = LYNQ_ACTION_NOTHING;
|
| }
|
| void trigger_sdk_ready_cb(lynq_sdk_status_t excpt, lynq_sdk_ref_action_t action)
|
| {
|
| pthread_mutex_lock(&lock);
|
| RLOGI("trigger sdk ready cb excpt:%s,action:%s",sdk_status_excpt_to_string(excpt),sdk_status_action_to_string(action));
|
| long uptime = get_uptime();
|
| if((excpt != LYNQ_SDK_READY) && (uptime < global_param->period.BOOT))
|
| {
|
| goto end;
|
| }
|
| //if((global_sdk_status.sdk_ready_status == excpt) && (global_sdk_status.ref_action == action))
|
| //{
|
| // goto end;
|
| //}
|
| global_sdk_status.sdk_ready_status = excpt;
|
| global_sdk_status.ref_action = action;
|
| global_sdk_status_cb(&global_sdk_status,NULL);
|
| end:
|
| pthread_mutex_unlock(&lock);
|
| return;
|
| }
|
| //maybe uci,or other
|
| void set_sdk_ready_nv(int value)
|
| {
|
| char cmd[64] = {0};
|
| RLOGI("set_sdk_ready_nv:%d",value);
|
| sprintf(cmd,"uci set lynq_uci.sdk_ready=%d",value);//set uci
|
| system(cmd);
|
| return;
|
| }
|
| void set_sdk_ready_status_bit(int bit,int status)
|
| {
|
| pthread_mutex_lock(&lock);
|
| int old = 1;
|
| if((global_sdk_ready_status & bit) == 0)
|
| {
|
| old = 0;
|
| }
|
| if(old == status)
|
| {
|
| goto end;
|
| }
|
| if(status == 1)
|
| {
|
| global_sdk_ready_status |= bit;
|
| }
|
| else
|
| {
|
| global_sdk_ready_status &= ~bit;
|
| }
|
| set_sdk_ready_nv(global_sdk_ready_status);
|
| end:
|
| pthread_mutex_unlock(&lock);
|
| return;
|
| }
|
| static int get_md_sta(void)
|
| {
|
| FILE *fp;
|
| char buffer[64]={};
|
| fp = popen("cat /sys/kernel/ccci/boot","r");
|
| if(fp == NULL)
|
| {
|
| RLOGD("function %s fp is null\n", __FUNCTION__);
|
| return 0;
|
| }
|
| fgets(buffer,sizeof(buffer),fp);
|
| if(!strlen(buffer))
|
| {
|
| RLOGD("function %s line %d\n", __FUNCTION__, __LINE__);
|
| pclose(fp);
|
| return 0;
|
| }
|
| if(buffer[4] == '4')
|
| {
|
| pclose(fp);
|
| return 1;
|
| }
|
| RLOGD("function %s line %d\n", __FUNCTION__, __LINE__);
|
| pclose(fp);
|
| return 0;
|
| }
|
|
|
| static int check_service(const char *service)
|
| {
|
| FILE *fp = NULL;
|
| char buffer[1024]={};
|
| if(!strcmp(service, "/usr/sbin/mtkfusionrild"))
|
| {
|
| fp = popen("ps -ef|grep rild","r");
|
| }
|
| else if(!strcmp(service, "lynq-ril-service"))
|
| {
|
| fp = popen("ps -ef|grep ril-service","r");
|
| }
|
| if(fp == NULL)
|
| {
|
| RLOGD("function %s fp is null\n", __FUNCTION__);
|
| return 0;
|
| }
|
| while(NULL != fgets(buffer,sizeof(buffer),fp))
|
| {
|
| if(strstr(buffer,service))
|
| {
|
| pclose(fp);
|
| RLOGD("check_service 1\n");
|
| return 1;
|
| }
|
| }
|
| RLOGD("check_service 0\n");
|
| pclose(fp);
|
| return 0;
|
| }
|
|
|
| /** |
| * @brief find partition zhengshu for exzample 5.7M,get value 5 |
| * |
| * @param arg |
| * @return |
| */ |
| static void removeSpaces(char* str) |
| { |
| char* dest = str; |
| while (*str) { |
| if (*str != ' ') { |
| *dest++ = *str; |
| } |
| str++; |
| } |
| *dest = '\0'; |
| return ; |
| } |
| void check_ril_sleep(int count)
|
| {
|
| if((count < sizeof(boot_ril_check_timer)/sizeof(int)) && ((global_sdk_ready_status & 1) == 1))// total 60s
|
| {
|
| sleep(boot_ril_check_timer[count]);
|
| }
|
| else
|
| {
|
| sleep(global_param->period.RIL);
|
| }
|
| return;
|
| }
|
| void update_ril_value(int value)
|
| {
|
| switch (value)
|
| {
|
| case RIL_REQUEST_SUCCESS:
|
| {
|
| trigger_sdk_ready_cb(LYNQ_SDK_READY, LYNQ_ACTION_NOTHING);
|
| set_sdk_ready_status_bit(BIT_EXCPT_RIL,0);
|
| set_sdk_ready_status_bit(BIT_EXCPT_MD, 0);
|
| break;
|
| }
|
| case RIL_MODEM_BOOT_EXCPT:
|
| {
|
| set_sdk_ready_status_bit(BIT_EXCPT_RIL,1);
|
| trigger_sdk_ready_cb(LYNQ_SDK_MD_EXCPT,LYNQ_ACTION_REBOOT);
|
| break;
|
| }
|
| case RIL_RESP_ERROR_FAIL:
|
| {
|
| set_sdk_ready_status_bit(BIT_EXCPT_RIL,1);
|
| trigger_sdk_ready_cb(LYNQ_SDK_RIL_EXCPT,LYNQ_ACTION_NOTHING);
|
| break;
|
| }
|
| case RIL_SOCKET_CREATE_FAIL:
|
| case RIL_SOCKET_SEND_REC_FAIL:
|
| {
|
| set_sdk_ready_status_bit(BIT_EXCPT_RIL,1);
|
| trigger_sdk_ready_cb(LYNQ_SDK_RIL_EXCPT,LYNQ_ACTION_REBOOT);
|
| break;
|
| }
|
| default:
|
| RLOGE("Not this case:%d",value);
|
| }
|
| return;
|
| }
|
|
|
| void update_userdata_value()
|
| {
|
| pthread_mutex_lock(&lock);
|
| trigger_sdk_ready_cb(LYNQ_SDK_PARTITION_EXCPT, LYNQ_ACTION_REBOOT);
|
| set_sdk_ready_status_bit(BIT_EXCPT_PTN,1);
|
| pthread_mutex_unlock(&lock);
|
| return;
|
| }
|
|
|
| void update_gnss_value()
|
| {
|
| pthread_mutex_lock(&lock);
|
| trigger_sdk_ready_cb(LYNQ_SDK_GNSS_EXCPT, LYNQ_ACTION_REBOOT);
|
| set_sdk_ready_status_bit(BIT_EXCPT_GNSS,1);
|
| pthread_mutex_unlock(&lock);
|
| return;
|
| }
|
| /**
|
| * @brief send request imei
|
| *
|
| * @param arg
|
| * 线程run起来后前两个60s 不做异常上报,这段时间是模组就绪时间因此只报ready 状态,60s 以后如果还是检测到异常,说明是真异常
|
| * @return void*
|
| */
|
| void * timer_request_imei(void * arg)
|
| {
|
| unlock_with_s_start(&s_ril_started);
|
| int send_num = -1;
|
| int recv_num = -1;
|
| int resp_type = -1;
|
| int request = -1;
|
| int slot_id = -1;
|
| int token = -1;
|
| int res_error = -1;
|
| int count = 0;
|
| Parcel p;
|
| struct sockaddr_in addr_serv;
|
| struct sockaddr_in liblynq_sdk_ready_socket;
|
| memset(&liblynq_sdk_ready_socket, 0,sizeof(liblynq_sdk_ready_socket));
|
| memset(&addr_serv, 0, sizeof(addr_serv));
|
| addr_serv.sin_family = AF_INET;
|
| addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
|
| addr_serv.sin_port = htons(DEST_PORT);
|
| liblynq_sdk_ready_socket.sin_family = AF_INET;
|
| liblynq_sdk_ready_socket.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
|
| int len_addr_serv = sizeof(addr_serv);
|
|
|
| lynq_client_t client_t;
|
| char res_data[MAX_LEN] = {0};
|
| client_t.request = RIL_REQUEST_DEVICE_IDENTITY;
|
| client_t.paramLen = 0;
|
| client_t.uToken = utoken;
|
| memset(client_t.param, 0, sizeof(client_t.param));
|
|
|
| struct timeval timeOut;
|
| timeOut.tv_sec = 3;//timeout time 3s
|
| timeOut.tv_usec = 0;
|
|
|
| int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
| if (-1 == sock_fd)
|
| {
|
| RLOGD("__FUNCTION__ %s create sock_fd failed %s\n", __FUNCTION__, strerror(errno));
|
| exit(EXIT_FAILURE);
|
| return NULL;
|
| }
|
| int ret = bind(sock_fd, (struct sockaddr *)&liblynq_sdk_ready_socket, sizeof(liblynq_sdk_ready_socket));
|
| if (-1 == ret)
|
| {
|
| RLOGE("liblynq_data_socket bind fail,errno:%d",errno);
|
| return NULL;
|
| }
|
|
|
| if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &timeOut, sizeof(timeOut)) < 0)
|
| {
|
| RLOGD("__FUNCTION__ %s time out setting failed %s\n", __FUNCTION__, strerror(errno));
|
| exit(EXIT_FAILURE);
|
| return NULL;
|
| }
|
| while (1)
|
| {
|
| bzero(res_data, MAX_LEN);
|
| pthread_mutex_lock(&g_lynq_sim_sendto_mutex);
|
| send_num = sendto(sock_fd, &client_t, sizeof(client_t), 0, (struct sockaddr *)&addr_serv, len_addr_serv);
|
| RLOGD("send_num %d\n", send_num);
|
| if(send_num == 0)
|
| {
|
| RLOGD("__FUNCTION__ %s Close to end %s\n", __FUNCTION__, strerror(errno));
|
| //unknow
|
| update_ril_value(RIL_SOCKET_SEND_REC_FAIL);
|
| pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
|
| continue;
|
| }
|
| if(send_num < 0)
|
| {
|
| RLOGD("__FUNCTION__ %s sendto error %s\n", __FUNCTION__, strerror(errno));
|
| //unknow
|
| update_ril_value(RIL_SOCKET_SEND_REC_FAIL);
|
| pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
|
| continue;
|
| }
|
| //get data msg
|
| recv_num = recvfrom(sock_fd,res_data,sizeof(char)*MAX_LEN,0,(struct sockaddr *)&addr_serv,(socklen_t*)&len_addr_serv);
|
| RLOGD("recv_num %d\n", recv_num);
|
| if(recv_num == -1 && errno == EAGAIN)
|
| {
|
| RLOGD("__FUNCTION__ %srecvfrom fail because timeout\n", __FUNCTION__);
|
| /*set uci*/
|
| if(!get_md_sta())
|
| {
|
| update_ril_value(RIL_MODEM_BOOT_EXCPT);
|
| }
|
| else
|
| {
|
| if(check_service("/usr/sbin/mtkfusionrild"))//rild work
|
| {
|
| if(!check_service("lynq-ril-service"))//not find,must be socket error
|
| {
|
| update_ril_value(RIL_SOCKET_CREATE_FAIL);
|
| }
|
| else
|
| {
|
| //unknow error
|
| update_ril_value(RIL_SOCKET_SEND_REC_FAIL);
|
| }
|
| }
|
| else//rild no work
|
| {
|
| //unknow
|
| update_ril_value(RIL_SOCKET_SEND_REC_FAIL);
|
| }
|
| }
|
| pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
|
| check_ril_sleep(count);
|
| count++;
|
| continue;
|
| }
|
| if(recv_num <= 0)
|
| {
|
| RLOGD("__FUNCTION__ %s recvfrom fail %s\n", __FUNCTION__, strerror(errno));
|
| update_ril_value(RIL_SOCKET_SEND_REC_FAIL);
|
| pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
|
| check_ril_sleep(count);
|
| count++;
|
| continue;
|
| }
|
| p.setData((uint8_t *)res_data,sizeof(char)*recv_num);
|
| p.setDataPosition(0);
|
| if(p.dataAvail() > 0)
|
| {
|
| p.readInt32(&resp_type);
|
| p.readInt32(&token);
|
| p.readInt32(&request);
|
| p.readInt32(&slot_id);
|
| p.readInt32(&res_error);
|
| }
|
| /*judge the res_error*/
|
| if(!res_error)
|
| {
|
| update_ril_value(RIL_REQUEST_SUCCESS);
|
| }
|
| else
|
| {
|
| update_ril_value(RIL_RESP_ERROR_FAIL);
|
| }
|
| count = 0;
|
| RLOGD("__FUNCTION__ %s res_error %d\n", __FUNCTION__, res_error);
|
| /*judge the res_error*/
|
| pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
|
| check_ril_sleep(sizeof(boot_ril_check_timer)/sizeof(int));
|
| }
|
| return NULL;
|
| }
|
|
|
| void * wait_ril_event(void * arg)
|
| {
|
| unlock_with_s_start(&s_ril_started);
|
| int REC_BUFF_LEN = 64;
|
| int recv_num = 0;
|
| char rec_data[REC_BUFF_LEN] = {0};
|
| int count = 0;
|
| struct sockaddr_in wait_ril_event_socket;
|
| struct sockaddr_in addr_client;
|
| memset(&wait_ril_event_socket, 0,sizeof(wait_ril_event_socket));
|
| memset(&addr_client, 0, sizeof(addr_client));
|
| wait_ril_event_socket.sin_family = AF_INET;
|
| wait_ril_event_socket.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
|
| wait_ril_event_socket.sin_port = htons(SDK_READY_PORT);
|
| int len_addr_serv = sizeof(addr_client);
|
|
|
| int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
| if (-1 == sock_fd)
|
| {
|
| RLOGD("__FUNCTION__ %s create sock_fd failed %s\n", __FUNCTION__, strerror(errno));
|
| exit(EXIT_FAILURE);
|
| return NULL;
|
| }
|
| int ret = bind(sock_fd, (struct sockaddr *)&wait_ril_event_socket, sizeof(wait_ril_event_socket));
|
| if (-1 == ret)
|
| {
|
| RLOGE("liblynq_data_socket bind fail,errno:%d",errno);
|
| exit(EXIT_FAILURE);
|
| return NULL;
|
| }
|
| while(1)
|
| {
|
| memset(rec_data,0,REC_BUFF_LEN);
|
| recv_num = recvfrom(sock_fd,rec_data,sizeof(char)*REC_BUFF_LEN,0,(struct sockaddr *)&addr_client,(socklen_t*)&len_addr_serv);
|
| if(recv_num <= 0)
|
| {
|
| RLOGD("__FUNCTION__ %s Close to end\n", __FUNCTION__);
|
| update_ril_value(RIL_SOCKET_SEND_REC_FAIL);
|
| continue;
|
| }
|
| rec_data[recv_num] = '\0';
|
| if((atoi(rec_data) == RIL_UNSOL_TELEPHONY_RESTART) && (count%2 == 0))//this urc will be reported twice in a row
|
| {
|
| set_sdk_ready_status_bit(BIT_EXCPT_MD, 1);
|
| trigger_sdk_ready_cb(LYNQ_SDK_MD_REBOOT_EXCPT,LYNQ_ACTION_RETRY_DATA_CALL);
|
| count = 0;
|
| }
|
| count ++;
|
| }
|
| close(sock_fd);
|
| }
|
|
|
|
|
| void delete_enter(char data[])
|
| {
|
| char *find = strchr(data, '\n');
|
| if(find)
|
| *find = '\0';
|
| return ;
|
| }
|
|
|
| unsigned long long get_interrupts(int fd,char *buffer,int size)
|
| {
|
| char *line = NULL;
|
| unsigned long long intr_value = 0;
|
| memset(buffer,0,size);
|
| lseek(fd, 0, SEEK_SET);
|
| ssize_t bytes_intr_read = read(fd,buffer, size - 1);
|
| buffer[bytes_intr_read] = '\0';
|
| line = strstr(buffer, "intr");
|
| if (line == NULL)
|
| {
|
| RLOGE("get intr fail");
|
| }
|
| else
|
| {
|
| line += 5;
|
| sscanf(line,"%llu",&intr_value);
|
| }
|
| return intr_value;
|
| }
|
| unsigned long long get_mem_free(int fd,char *buffer,int size)
|
| {
|
| char *line = NULL;
|
| unsigned long long mem_value = 0;
|
| lseek(fd, 0, SEEK_SET);
|
| memset(buffer,0,size);
|
| ssize_t bytes_mem_read = read(fd, buffer, size - 1);
|
| buffer[bytes_mem_read] = '\0';
|
| line = strstr(buffer, "MemFree:");
|
| if (line == NULL)
|
| {
|
| RLOGE("get MemFree fail");
|
| }
|
| else
|
| {
|
| line += 9;
|
| while (*line == ' ')
|
| {
|
| line++;
|
| }
|
| sscanf(line,"%llu",&mem_value);
|
| }
|
| return mem_value;
|
| }
|
|
|
| void *check_system(void * arg)
|
| {
|
| int fd_mem = 0;
|
| int fd_intr = 0;
|
| int fd_avg = 0;
|
| int fd_free = 0;
|
| int BUFFER_SIZE = 512;
|
| unsigned long long min_free = 0;
|
| unsigned long long mem_value = 0;
|
| unsigned long long intr_value_old = 0;
|
| unsigned long long intr_value_new = 0;
|
| float avg_value = 0;
|
| int excpt_flag = 0;
|
| char sys_buffer[BUFFER_SIZE];
|
| char min_free_buffer[BUFFER_SIZE];
|
| unlock_with_s_start(&s_sys_started);
|
| fd_mem = open(GET_MEM_INFO,O_RDONLY);
|
| fd_free = open(GET_MIN_FREE,O_RDONLY);
|
| fd_intr = open(GET_INTR_INFO,O_RDONLY);
|
| fd_avg = open(GET_LOAD_AVG_INFO,O_RDONLY);
|
| if((fd_mem < 0) || (fd_intr < 0) || (fd_avg < 0) || (fd_free < 0))
|
| {
|
| RLOGE("check system open fail");
|
| exit(EXIT_FAILURE);
|
| }
|
| memset(min_free_buffer,0,BUFFER_SIZE);
|
| ssize_t bytes_min_free_read = read(fd_free, min_free_buffer, BUFFER_SIZE - 1);
|
| if(bytes_min_free_read == -1)
|
| {
|
| RLOGE("get min free fail");
|
| exit(EXIT_FAILURE);
|
| }
|
| min_free = atoi(min_free_buffer);
|
| close(fd_free);
|
| ssize_t bytes_avg_read = 0;
|
| intr_value_old = get_interrupts(fd_intr, sys_buffer, BUFFER_SIZE);
|
| while(1)
|
| {
|
| memset(sys_buffer,0,BUFFER_SIZE);
|
| lseek(fd_avg, 0, SEEK_SET);
|
| bytes_avg_read = read(fd_avg, sys_buffer, BUFFER_SIZE - 1);
|
| sys_buffer[bytes_avg_read] = '\0';
|
| sscanf(sys_buffer,"%*f %f",&avg_value);
|
|
|
| mem_value = get_mem_free(fd_mem, sys_buffer, BUFFER_SIZE);
|
| intr_value_new = get_interrupts(fd_intr, sys_buffer, BUFFER_SIZE);
|
| //pages_min = /proc/sys/vm/min_free_kbytes
|
| //pages_low = pages_min*5/4
|
| //pages_high = pages_min*3/2
|
| if((mem_value >= min_free) && (mem_value < min_free*1.25))//pages_min-pages_low
|
| {
|
| trigger_sdk_ready_cb(LYNQ_SDK_MIN_FREE_EXCPT,LYNQ_ACTION_SYS_WARNING);
|
| excpt_flag = 1;
|
| }
|
| if(mem_value < min_free)
|
| {
|
| trigger_sdk_ready_cb(LYNQ_SDK_MIN_FREE_EXCPT,LYNQ_ACTION_REBOOT);
|
| excpt_flag = 1;
|
| }
|
| if(avg_value > global_param->threshold.load_average)
|
| {
|
| trigger_sdk_ready_cb(LYNQ_SDK_LOAD_AVG_EXCPT,LYNQ_ACTION_SYS_WARNING);
|
| excpt_flag = 1;
|
| }
|
| if((intr_value_new - intr_value_old) > global_param->threshold.interrupts)
|
| {
|
| trigger_sdk_ready_cb(LYNQ_SDK_INTR_EXCPT,LYNQ_ACTION_SYS_WARNING);
|
| excpt_flag = 1;
|
| }
|
| set_sdk_ready_status_bit(BIT_EXCPT_SYS,excpt_flag);
|
| 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);
|
| intr_value_old = intr_value_new;
|
| excpt_flag = 0;
|
| sleep(global_param->period.SYS);
|
| }
|
| close(fd_mem);
|
| close(fd_intr);
|
| close(fd_avg);
|
| }
|
|
|
| /* old code 2024/11/04 close
|
| void *check(void * arg)
|
| {
|
|
|
| char pid[200][8];
|
| char ffd[200][4];
|
| char buf[64];
|
| char check_time[4];
|
| char timebuf[32];
|
| int num = 1;
|
| int i=0;
|
| int j;
|
| FILE *fp,*fp_1;
|
| int ret;
|
|
|
| RLOGD("check cpu/pid/interrupts/fd!!!\n");
|
| system("mkdir /media/check_file");
|
| system("touch /media/check_time");
|
| fp_1 = popen("cat /media/check_time","r");
|
| if(fgets(check_time, 4, fp_1) != NULL)
|
| {
|
| num = atoi(check_time);
|
| }
|
| pclose(fp_1);
|
| while(1)
|
| {
|
| i = 0;
|
| system("date >>/media/check_file/cpu_moniter.txt");
|
| ret = system("top -b |head -n 25 >>/media/check_file/cpu_moniter.txt");
|
| RLOGD("cpu ret %d", ret);
|
| system("date >>/media/check_file/inter_moniter.txt");
|
| ret = system("cat /proc/interrupts |grep -v \": 0 0\" >>/media/check_file/inter_moniter.txt");
|
| RLOGD("interrupts ret %d", ret);
|
|
|
| system("date >>/media/check_file/pid_moniter.txt");
|
| ret = system("ps -eo \"%p %a\" | grep -v \"\\[\" >>/media/check_file/pid_moniter.txt");
|
| RLOGD("pid ret %d", ret);
|
|
|
| system("date >>/media/check_file/meminfo_moniter.txt");
|
| ret = system("cat /proc/meminfo >>/media/check_file/meminfo_moniter.txt");
|
| RLOGD("meminfo ret %d", ret);
|
|
|
| system("date >>/media/check_file/buddyinfo_moniter.txt");
|
| ret = system("cat /proc/buddyinfo >>/media/check_file/buddyinfo_moniter.txt");
|
| RLOGD("buddyinfo ret %d", ret);
|
|
|
| system("date >>/media/check_file/ps_auxw_moniter.txt");
|
| 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");
|
| RLOGD("ps_auxw ret %d", ret);
|
|
|
| system("date >>/media/check_file/cur_freq_moniter.txt");
|
| ret = system("cat /sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq >>/media/check_file/cur_freq_moniter.txt");
|
| RLOGD("cur_freq ret %d", ret);
|
|
|
| system("date >>/media/check_file/available_frequencies_moniter.txt");
|
| ret = system("cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies >>/media/check_file/available_frequencies_moniter.txt");
|
| RLOGD("available_frequencies ret %d", ret);
|
|
|
| system("date >>/media/check_file/fd_moniter.txt");
|
| fp = popen("ps -eo \"%p %a\" | grep -v \"\\[\"|awk '{print $1}'","r");
|
| while(fgets(pid[i], 8, fp) != NULL)
|
| {
|
| delete_enter(pid[i]);
|
| i++;
|
| }
|
| pclose(fp);
|
|
|
| for(j=1;j<i;j++)
|
| {
|
| sprintf(buf, "ls /proc/%s/fd | wc -l", pid[j]);
|
| fp = popen(buf, "r");
|
| fgets(ffd[j], 4, fp);
|
| sprintf(buf,"echo \"pid: %s, fd_num: %s\" >>/media/check_file/fd_moniter.txt",pid[j], ffd[j]);
|
| system(buf);
|
| pclose(fp);
|
| }
|
|
|
| if(num > 228)
|
| {
|
| system("cp /media/check_file/cpu_moniter.txt /media/check_file/cpu_moniter_1.txt");
|
| system("cp /media/check_file/inter_moniter.txt /media/check_file/inter_moniter_1.txt");
|
| system("cp /media/check_file/pid_moniter.txt /media/check_file/pid_moniter_1.txt");
|
| system("cp /media/check_file/fd_moniter.txt /media/check_file/fd_moniter_1.txt");
|
| system("cp /media/check_file/fd_moniter.txt /media/check_file/meminfo_moniter_1.txt");
|
| system("cp /media/check_file/fd_moniter.txt /media/check_file/buddyinfo_moniter_1.txt");
|
| system("cp /media/check_file/fd_moniter.txt /media/check_file/ps_auxw_moniter_1.txt");
|
| system("cp /media/check_file/fd_moniter.txt /media/check_file/cur_freq_moniter_1.txt");
|
| system("cp /media/check_file/fd_moniter.txt /media/check_file/available_frequencies_moniter_1.txt");
|
|
|
|
|
| system("rm -rf /media/check_file/cpu_moniter.txt");
|
| system("rm -rf /media/check_file/inter_moniter.txt");
|
| system("rm -rf /media/check_file/pid_moniter.txt");
|
| system("rm -rf /media/check_file/fd_moniter.txt");
|
| system("rm -rf /media/check_file/meminfo_moniter.txt");
|
| system("rm -rf /media/check_file/buddyinfo_moniter.txt");
|
| system("rm -rf /media/check_file/ps_auxw_moniter.txt");
|
| system("rm -rf /media/check_file/cur_freq_moniter.txt");
|
| system("rm -rf /media/check_file/available_frequencies_moniter.txt");
|
|
|
| num = 0;
|
| }
|
| num++;
|
| sprintf(timebuf, "echo \"%d\" >/media/check_time", num);
|
| ret = system(timebuf);
|
| sleep(300);
|
| }
|
| return NULL;
|
|
|
| }
|
|
|
| int num = 0;
|
| void *check_uci(void * arg)
|
| {
|
| int ret[6];
|
| int result = 0;
|
| int flag = 0;
|
|
|
| char uci_0[]="/etc/config/lynq_uci";
|
| char uci_1[]="/etc/config/lynq_uci_ro";
|
| char uci_2[]="/etc/config/mdlog";
|
| char uci_3[]="/etc/config/radio_property";
|
| char uci_4[]="/etc/config/service";
|
| char uci_5[]="/etc/config/usb";
|
| RLOGD("start check uci\n");
|
| while(num++ < 4)
|
| {
|
| RLOGD("@@@@@@@num=%d\n", num);
|
| flag = 0;
|
| ret[0] = system("uci show | grep \"lynq_uci.lynq_ril\" > /dev/null");
|
| if(ret[0] != 0)
|
| {
|
| RLOGD("lynq_uci unload\n");
|
| flag = 1;
|
| }
|
|
|
| ret[1] = system("uci show | grep \"^lynq_uci_ro\.\" > /dev/null");
|
| if(ret[1] != 0)
|
| {
|
| RLOGD("lynq_uci_ro unload\n");
|
| flag = 1;
|
| }
|
|
|
| ret[2] = system("uci show | grep \"^mdlog\.\"");
|
| if(ret[2] != 0)
|
| {
|
| RLOGD("mdlog unload\n");
|
| flag = 1;
|
| }
|
|
|
| ret[3] = system("uci show | grep \"^radio_property\.\" > /dev/null");
|
| if(ret[3] != 0)
|
| {
|
| RLOGD("radio_property unload\n");
|
| flag = 1;
|
| }
|
|
|
| ret[4] = system("uci show | grep \"^service\.\" > /dev/null");
|
| if(ret[4] != 0)
|
| {
|
| RLOGD("service unload\n");
|
| flag = 1;
|
| }
|
|
|
| ret[5] = system("uci show | grep \"^usb\.\" > /dev/null");
|
| if(ret[5] != 0)
|
| {
|
| RLOGD("usb unload\n");
|
| flag = 1;
|
| }
|
|
|
| RLOGD("flag=%d\n",flag);
|
| if(flag != 0)
|
| {
|
| RLOGD("config reload\n");
|
| result = chdir("/data_backup/");
|
| result =system("tar -zxvf userdata.tar.gz -C /STATE/ >/dev/null");
|
| if(result!= 0)
|
| {
|
| RLOGD("cp config fail\n");
|
| }
|
| if(ret[0] != 0)
|
| {
|
| lynq_load_config(uci_0);
|
| RLOGD("reload lynq_uci\n");
|
| system("systemctl start autosuspend");
|
| }
|
| if(ret[1] != 0)
|
| {
|
| lynq_load_config(uci_1);
|
| RLOGD("reload lynq_uci_ro\n");
|
| }
|
| if(ret[2] != 0)
|
| {
|
| lynq_load_config(uci_2);
|
| RLOGD("reload mdlog\n");
|
| }
|
| if(ret[3] != 0)
|
| {
|
| lynq_load_config(uci_3);
|
| RLOGD("reload radio_property\n");
|
| system("systemctl restart mtkfusionrild");
|
| }
|
| if(ret[4] != 0)
|
| {
|
| lynq_load_config(uci_4);
|
| RLOGD("reload service\n");
|
| }
|
| if(ret[5] != 0)
|
| {
|
| lynq_load_config(uci_5);
|
| RLOGD("reload usb\n");
|
| }
|
| }
|
| else
|
| {
|
| RLOGD("uci check success, exit check!\n");
|
| break;
|
| }
|
| sleep(2);
|
| }
|
| return NULL;
|
| }
|
| old code 2024/11/04 close*/
|
|
|
| static void t800_check_partition()
|
| { |
| char buf[64] = {0};
|
| FILE *fp = NULL;
|
| int q = 22*1024;
|
| int ubisize = 0;
|
| |
| fp = popen("df -l| grep '/data$' | awk '{print $3}'","r"); |
| if(fp == NULL) |
| { |
| RLOGD("Failed to run command\n"); |
| return; |
| }
|
| fgets(buf, sizeof(buf) - 1, fp); |
| RLOGD("buf is: %s\n",buf); |
| ubisize = atoi(buf);
|
| if(ubisize >= q)
|
| {
|
| RLOGD(">set ready 5,userdata size is %d M\n",ubisize);
|
| update_userdata_value();
|
| }
|
| else
|
| {
|
| set_sdk_ready_status_bit(BIT_EXCPT_PTN, 0);
|
| }
|
| pclose(fp);
|
| return;
|
| }
|
| void t800_check_mnld()
|
| { |
| FILE *fp = NULL;
|
| const char *symble = "NRestarts="; |
| const char *cmd = "systemctl show -p NRestarts mnld.service";
|
| char buf[64];
|
| int count_old = 0;
|
| int count_new = 0;
|
| while(1)
|
| {
|
| fp = popen(cmd,"r");
|
| if(NULL == fp)
|
| {
|
| RLOGE("run cmd:%s fail",cmd);
|
| sleep(1);
|
| continue;
|
| }
|
| while(fgets(buf, sizeof(buf) - 1, fp) != NULL)
|
| {
|
| if(strncmp(buf,symble,strlen(symble)) == 0)
|
| count_new = atoi(buf+strlen(symble));
|
| memset(buf,0,sizeof(buf));
|
| }
|
| if((count_new - count_old) > 1)
|
| {
|
| update_gnss_value();//out put mnld severe abnormal state
|
| RLOGD("mnld is severe abnormal state = %d\n",count_new - count_old);
|
| }
|
| else
|
| {
|
| set_sdk_ready_status_bit(BIT_EXCPT_GNSS,0);
|
| }
|
| pclose(fp);
|
| count_old = count_new;
|
| sleep(global_param->period.GNSS);
|
| }
|
| return;
|
| } |
| void *check_partition(void *arg)
|
| {
|
| unlock_with_s_start(&s_ptn_started);
|
| while(1)
|
| {
|
| t800_check_partition();
|
| sleep(global_param->period.PTN);
|
| }
|
| return NULL;
|
| }
|
|
|
| void *check_gnss(void * arg)
|
| {
|
| unlock_with_s_start(&s_gnss_started);
|
| t800_check_mnld();
|
| return NULL;
|
| }
|
| int get_cpu_info()
|
| {
|
| FILE *CPU_FD = NULL;
|
| int cpu_num = 0;
|
| char cpu_info[8];
|
| CPU_FD = popen(GET_CPU_NUM,"r");
|
| if(CPU_FD == NULL)
|
| { |
| RLOGD("get cpu info fail:%s",GET_CPU_NUM);
|
| return -1;
|
| }
|
| fgets(cpu_info, sizeof(cpu_info) - 1, CPU_FD);
|
| cpu_num = atoi(cpu_info);
|
| pclose(CPU_FD);
|
| return cpu_num;
|
| }
|
| int set_default_sdk_check_param(lynq_sdk_check_param_t *param)
|
| {
|
| int cpu_num = 0;
|
| param->period.RIL = DEFAULT_PERIOD_RIL;
|
| param->period.GNSS = DEFAULT_PERIOD_GNSS;
|
| param->period.MD = DEFAULT_PERIOD_MD;
|
| param->period.PTN = DEFAULT_PERIOD_PTN;
|
| param->period.SYS = DEFAULT_PERIOD_SYS;
|
| param->period.BOOT = DEFAULT_PERIOD_BOOT;
|
| cpu_num = get_cpu_info();
|
| if(cpu_num <= 0)
|
| {
|
| RLOGE("set default sdk check param fail");
|
| return -1;
|
| }
|
| param->threshold.interrupts = (DEFAULT_PERIOD_SYS/30)*cpu_num*5000;
|
| param->threshold.load_average = cpu_num*2;
|
| return 0;
|
| }
|
| int create_check_threads(void)
|
| {
|
| pthread_t thid,thid_1,thid_2,thid_3,thid_4;
|
| pthread_attr_t attr;
|
| pthread_attr_init(&attr);
|
| pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
| int ret;
|
| pthread_mutex_lock(&s_startupMutex);
|
| ret = pthread_create(&thid, &attr, timer_request_imei, NULL);
|
| if(ret != 0)
|
| {
|
| RLOGE("timer_request_imei error!!!");
|
| goto excp;
|
| }
|
| while (s_ril_started == 0)
|
| {
|
| pthread_cond_wait(&s_startupCond, &s_startupMutex); |
| }
|
| ret = pthread_create(&thid_1, &attr, check_system, NULL);
|
| if(ret != 0)
|
| {
|
| RLOGE("check_system error!!!");
|
| goto excp;
|
| }
|
| while (s_sys_started == 0)
|
| {
|
| pthread_cond_wait(&s_startupCond, &s_startupMutex); |
| }
|
|
|
| ret = pthread_create(&thid_2, &attr,check_gnss,NULL);
|
| if(ret != 0) |
| { |
| RLOGD("check_gnss error!!!");
|
| goto excp;
|
| }
|
| while (s_gnss_started == 0)
|
| {
|
| pthread_cond_wait(&s_startupCond, &s_startupMutex); |
| }
|
| ret = pthread_create(&thid_3, &attr,check_partition,NULL);
|
| if(ret != 0) |
| { |
| RLOGD("check_partition error!!!");
|
| goto excp;
|
| }
|
| while (s_ptn_started == 0)
|
| {
|
| pthread_cond_wait(&s_startupCond, &s_startupMutex); |
| }
|
| s_ril_started = 0;
|
| ret = pthread_create(&thid_4, &attr,wait_ril_event,NULL);
|
| if(ret != 0) |
| { |
| RLOGD("wait_ril_event error!!!");
|
| goto excp;
|
| }
|
| while (s_ril_started == 0)
|
| {
|
| pthread_cond_wait(&s_startupCond, &s_startupMutex); |
| }
|
| pthread_mutex_unlock(&s_startupMutex);
|
| return 0;
|
| excp:
|
| pthread_mutex_unlock(&s_startupMutex);
|
| return LYNQ_E_NORMAL;
|
| }
|
| int lynq_sdk_ready_register(const int uToken,const lynq_sdk_check_param_t* param,lynq_sdk_status_cb sdk_status_cb)
|
| {
|
| int ret = 0;
|
| if (param == NULL || sdk_status_cb == NULL)
|
| {
|
| RLOGE("input null");
|
| return LYNQ_E_NULL_ANONALY;
|
| }
|
| utoken = uToken;
|
| global_param = (lynq_sdk_check_param_t *)malloc(sizeof(lynq_sdk_check_param_t));
|
| if(global_param == NULL)
|
| {
|
| RLOGE("malloc global_param fail");
|
| goto end;
|
| }
|
| memset(global_param,0,sizeof(lynq_sdk_check_param_t));
|
| if(param->isvalid == 0)
|
| {
|
| ret = set_default_sdk_check_param(global_param);
|
| if (ret < 0)
|
| {
|
| RLOGE("get default param fail");
|
| goto end;
|
| }
|
| }
|
| else
|
| {
|
| if((param->period.RIL < MIN_PERIOD_RIL) || (param->period.GNSS < MIN_PERIOD_GNSS) || (param->period.MD < MIN_PERIOD_MD)
|
| || (param->period.PTN < MIN_PERIOD_PTN) || (param->period.SYS < MIN_PERIOD_SYS))
|
| {
|
| RLOGE("param excption");
|
| goto end;
|
| }
|
| global_param->period.RIL = param->period.RIL;
|
| global_param->period.GNSS = param->period.GNSS;
|
| global_param->period.MD = param->period.MD;
|
| global_param->period.PTN = param->period.PTN;
|
| global_param->period.SYS = param->period.SYS;
|
| global_param->period.BOOT = param->period.BOOT;
|
| global_param->threshold.interrupts = param->threshold.interrupts;
|
| global_param->threshold.load_average = param->threshold.load_average;
|
| }
|
| RLOGI("period.RIL:%d,period.GNSS:%d,period.MD:%d,period.PTN:%d,period.SYS:%d,threshold.interrupts:%llu,threshold.load_average:%d",
|
| global_param->period.RIL,global_param->period.GNSS,global_param->period.MD,global_param->period.PTN,
|
| global_param->period.SYS,global_param->threshold.interrupts,global_param->threshold.load_average);
|
| global_sdk_status_cb = sdk_status_cb;
|
| global_sdk_status.sdk_ready_status = (lynq_sdk_status_t)-1;
|
| global_sdk_status.ref_action = (lynq_sdk_ref_action_t)-1;
|
| set_sdk_ready_nv(1);//开机默认RIL 异常,第一次检测完成之后更新正确值
|
| ret = create_check_threads();
|
| if(ret != 0)
|
| {
|
| goto end;
|
| }
|
| return ret;
|
| end:
|
| exit(EXIT_FAILURE);
|
| }
|
| int lynq_get_sdk_ready_status(int *status)
|
| {
|
| if (status == NULL)
|
| {
|
| RLOGE("sdk_ready_status is null");
|
| return LYNQ_E_NULL_ANONALY;
|
| }
|
| *status = global_sdk_ready_status;
|
| return 0;
|
| }
|