-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqmi_dms_sender_qlinkdatanode.c
403 lines (337 loc) · 12 KB
/
qmi_dms_sender_qlinkdatanode.c
1
#include <pthread.h>#include <errno.h>#include <stdlib.h>#include <string.h>#include <sys/select.h>#include <unistd.h>#include <fcntl.h>#include <qmi.h>#include <qmi_client.h>#include <device_management_service_v01.h>#include "common_qlinkdatanode.h"#include "feature_macro_qlinkdatanode.h"/******************************External Variables*******************************/extern int qmi_handle;extern qmi_client_type dms_client_handle_2;extern Net_Info rsmp_net_info;extern bool isOnlineMode;extern bool isRstRf;extern bool isRfRsted;extern pthread_mutex_t rst_rf_mtx;extern pthread_cond_t rst_rf_cond;extern unsigned long thread_id_array[THD_IDX_MAX];/******************************Local Variables*******************************/static pthread_t qmi_dms_sender_tid;static pthread_mutex_t dms_sender_mutex = PTHREAD_MUTEX_INITIALIZER;static pthread_cond_t dms_sender_cond = PTHREAD_COND_INITIALIZER;static int dmssenderStarted = 0;static int dms_sender_pipe_rd_fd = -1;/******************************Global Variables*******************************/static int dms_sender_pipe_wr_fd = -1;pthread_mutex_t acq_dms_inf_mtx = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t acq_dms_inf_cnd = PTHREAD_COND_INITIALIZER;int dms_inf_acqed = 0;static void dms_sender_cnsmod(void){ qmi_client_error_type rc; dms_qmi_cnsmod_resp_msg_v01 resp_msg; print_cur_gm_time(" App->QMI (CNSMOD) "); rc = qmi_client_send_msg_sync(dms_client_handle_2, QMI_DMS_CMD_AT_CNSMOD_REQ_V01, NULL, 0, &resp_msg, sizeof(resp_msg), 15000); if(rc != QMI_NO_ERR || resp_msg.resp.result != QMI_RESULT_SUCCESS_V01){ LOG("ERROR: qmi_client_send_msg_sync() failed. rc=%d, resp_msg.resp.error=%d.\n", rc, resp_msg.resp.error); }else{ rsmp_net_info.cnsmod_val = resp_msg.mode; LOG("sys mode is %d.\n", resp_msg.mode); }}static void dms_sender_cxreg(void){ qmi_client_error_type rc; dms_qmi_cxreg_resp_msg_v01 resp_msg; print_cur_gm_time(" App->QMI (CXREG) "); rc = qmi_client_send_msg_sync(dms_client_handle_2, QMI_DMS_CMD_AT_CXREG_REQ_V01, NULL, 0, &resp_msg, sizeof(resp_msg), 15000); if(rc != QMI_NO_ERR || resp_msg.resp.result != QMI_RESULT_SUCCESS_V01){ LOG("ERROR: qmi_client_send_msg_sync() failed. rc=%d, resp_msg.resp.error=%d.\n", rc, resp_msg.resp.error); }else{ //High 8-bit of cxreg_val_struct is stored by value cereg_state. //Low 8-bit of cxreg_val_struct is stored by value cgreg_state. rsmp_net_info.cgreg_val = (char)(resp_msg.cxreg_val_struct & 0x00ff); rsmp_net_info.cereg_val = (char)((resp_msg.cxreg_val_struct & 0xff00) >> 8); LOG("cgreg stat: %d, cereg stat: %d.\n", rsmp_net_info.cgreg_val, rsmp_net_info.cereg_val); }}static void dms_sender_cnmp(void){ qmi_client_error_type rc; dms_qmi_cnmp_resp_msg_v01 resp_msg; print_cur_gm_time(" App->QMI (CNMP) "); rc = qmi_client_send_msg_sync(dms_client_handle_2, QMI_DMS_CMD_AT_CNMP_REQ_V01, NULL, 0, &resp_msg, sizeof(resp_msg), 15000); if(rc != QMI_NO_ERR || resp_msg.resp.result != QMI_RESULT_SUCCESS_V01){ LOG("ERROR: qmi_client_send_msg_sync() failed. rc=%d, resp_msg.resp.error=%d.\n", rc, resp_msg.resp.error); }else{ rsmp_net_info.cnmp_val = resp_msg.pref_mode; LOG("cnmp prefer mode: %d.\n", rsmp_net_info.cnmp_val); }}static void dms_sender_cregrej(void){ qmi_client_error_type rc; dms_qmi_cregrej_resp_msg_v01 resp_msg; print_cur_gm_time(" App->QMI (CREGREJ) "); rc = qmi_client_send_msg_sync(dms_client_handle_2, QMI_DMS_CMD_AT_CREGREJ_REQ_V01, NULL, 0, &resp_msg, sizeof(resp_msg), 15000); if (rc != QMI_NO_ERR || resp_msg.resp.result != QMI_RESULT_SUCCESS_V01){ LOG("ERROR: qmi_client_send_msg_sync() failed. rc=%d, resp_msg.resp.error=%d.\n", rc, resp_msg.resp.error); }else{ rsmp_net_info.cregrej_val = resp_msg.rej_cause; LOG("rej cause: %d.\n", rsmp_net_info.cregrej_val); } return;}static void dms_sender_cfun4(void){ qmi_client_error_type rc; dms_set_operating_mode_req_msg_v01 req_msg; dms_set_operating_mode_resp_msg_v01 resp_msg; req_msg.operating_mode = DMS_OP_MODE_LOW_POWER_V01; print_cur_gm_time(" App->QMI (Set offline mode) "); rc = qmi_client_send_msg_sync(dms_client_handle_2, QMI_DMS_SET_OPERATING_MODE_REQ_V01, &req_msg, sizeof(req_msg), &resp_msg, sizeof(resp_msg), 300000); if (rc != QMI_NO_ERR || resp_msg.resp.result != QMI_RESULT_SUCCESS_V01){ LOG("ERROR: qmi_client_send_msg_sync() failed. rc=%d, resp_msg.resp.error=%d.\n", rc, resp_msg.resp.error); }else{ isOnlineMode = false; if(isRstRf){ isRstRf = false; //Rst pthread_mutex_lock(&rst_rf_mtx); isRfRsted = true; pthread_cond_broadcast(&rst_rf_cond); pthread_mutex_unlock(&rst_rf_mtx); } LOG("Setting offline mode Completes.\n"); }}static void dms_sender_acq_mdm_inf(void){ qmi_client_error_type rc; dms_qmi_cnsmod_resp_msg_v01 resp_msg_1; dms_qmi_cxreg_resp_msg_v01 resp_msg_2; print_cur_gm_time(" App->QMI (Acq mdm inf) "); rc = qmi_client_send_msg_sync(dms_client_handle_2, QMI_DMS_CMD_AT_CNSMOD_REQ_V01, NULL, 0, &resp_msg_1, sizeof(resp_msg_1), 15000); if (rc != QMI_NO_ERR || resp_msg_1.resp.result != QMI_RESULT_SUCCESS_V01){ LOG("ERROR: qmi_client_send_msg_sync() failed. rc=%d, resp_msg.resp.error=%d.\n", rc, resp_msg_1.resp.error);#ifdef FEATURE_ENABLE_REBOOT_DEBUG LOG("ERROR: QMI error system reboot.\n"); //system("reboot"); msq_send_dev_rst_req(1);#endif }else{ rsmp_net_info.cnsmod_val = resp_msg_1.mode; LOG("sys mode is %d.\n", resp_msg_1.mode); } rc = qmi_client_send_msg_sync(dms_client_handle_2, QMI_DMS_CMD_AT_CXREG_REQ_V01, NULL, 0, &resp_msg_2, sizeof(resp_msg_2), 15000); if(rc != QMI_NO_ERR || resp_msg_2.resp.result != QMI_RESULT_SUCCESS_V01){ LOG("ERROR: qmi_client_send_msg_sync() failed. rc=%d, resp_msg_2.resp.error=%d.\n", rc, resp_msg_2.resp.error); }else{ //High 8-bit of cxreg_val_struct is stored by value cereg_state. //Low 8-bit of cxreg_val_struct is stored by value cgreg_state. rsmp_net_info.cgreg_val = (char)(resp_msg_2.cxreg_val_struct & 0x00ff); rsmp_net_info.cereg_val = (char)((resp_msg_2.cxreg_val_struct & 0xff00) >> 8); LOG("cgreg stat: %d, cereg stat: %d.\n", rsmp_net_info.cgreg_val, rsmp_net_info.cereg_val); } return;}// Param:// opt:// 0x00 : Equivalent to AT cmd "AT+CNSMOD?".// 0x01 : Equivalent to AT cmd "AT+CGREG?" and "AT+CEREG?".// 0x02 : Equivalent to AT cmd "AT+CNMP?"// 0x03 : Equivalent to AT cmd "AT+CREGREJ".// 0x04 : Equivalent to AT cmd "AT+CFUN=4".// 0x05 : For status info upload. Equivalent to AT cmd "AT+CNSMOD?", "AT+CGREG?" and "AT+CEREG?".//Notice:// The app must acquire acq_dms_inf_mtx and wait for acq_dms_inf_cnd before calling this when opt is not// 0x04!//Modification Records:// 2015-10-15 : Add opt 0x04.// 2015-10-23 : Add opt 0x05.void notify_DmsSender(char opt){ int n = -1; LOG6("~~~~ notify_DmsSender start (%02x) ~~~~\n", opt); if(opt < 0x00 || opt > 0x05){ LOG("ERROR: Wrong param input. opt=%02x.\n", opt); goto __EXIT_OF_NOTIFY_DMSSENDER__; } do{ if(n == 0) LOG("write() failed. n=%d.\n", n); n = write(dms_sender_pipe_wr_fd, (void *)(&opt), 1); }while ((n<0 && errno==EINTR) || n==0); if(n<0){ LOG("ERROR: write() failed. n=%d. errno=%d.\n", n, errno); } __EXIT_OF_NOTIFY_DMSSENDER__: LOG6("~~~~ notify_DmsSender end (%02x) ~~~~\n", opt); return;}void DmsSenderLoop(void){ int n; int fdp1; fd_set rfd; char buf = 0xff; FD_ZERO(&rfd); FD_SET(dms_sender_pipe_rd_fd, &rfd); fdp1 = dms_sender_pipe_rd_fd+1; for(;;){ n = select(fdp1, &rfd, NULL, NULL, NULL); if (n < 0){ if (errno == EINTR) continue; LOG("ERROR: select() error. errno=%d.\n", errno); continue; }else if(n == 0) continue; do{ n = read(dms_sender_pipe_rd_fd, (void *)(&buf), sizeof(buf)); }while((n<0 && (errno==EINTR || errno==EAGAIN)) || (n == 0)); if(n > 0){ if(buf == 0x00){ dms_sender_cnsmod(); }else if(buf == 0x01){ dms_sender_cxreg(); } else if(buf == 0x02){ dms_sender_cnmp(); } else if(buf == 0x03){ dms_sender_cregrej(); } else if(buf == 0x04){ dms_sender_cfun4(); } else if(buf == 0x05){ dms_sender_acq_mdm_inf(); } else{ LOG("ERROR: Wrong buf (%02x) found!\n", buf); } if(buf != 0x04){ pthread_mutex_lock(&acq_dms_inf_mtx); dms_inf_acqed = 1; pthread_cond_broadcast(&acq_dms_inf_cnd); pthread_mutex_unlock(&acq_dms_inf_mtx); } LOG("QMI DMS sender completes. buf=%02x.\n", buf); } } LOG("ERROR: Unexpected error. DmsSenderLoop() ended.\n");}static void *initDmsSender(void *user_data){ int ret; int dms_sender_pipe[2]; ret = pipe(dms_sender_pipe); *((int *)user_data) = ret; pthread_mutex_lock(&dms_sender_mutex); dmssenderStarted = 1; pthread_cond_broadcast(&dms_sender_cond); pthread_mutex_unlock(&dms_sender_mutex); if (ret < 0) { LOG("ERROR: pipe() error. errno=%d.\n", errno); return NULL; } dms_sender_pipe_wr_fd = dms_sender_pipe[1]; dms_sender_pipe_rd_fd = dms_sender_pipe[0]; fcntl(dms_sender_pipe_rd_fd, F_SETFL, O_NONBLOCK); DmsSenderLoop(); LOG("ERROR: DmsSenderLoop() ended unexpectedly!\n"); while(1){ sleep(0x00ffffff); } return NULL;}//return value:// 0: error// 1: successint startQMIDmsSender(void){ int ret; pthread_attr_t attr; qmi_client_error_type result; if(qmi_handle == QMI_INVALID_CLIENT_HANDLE){ LOG("ERROR: qmi_handle doesn't exist.\n"); return 0; } if(dms_client_handle_2 == NULL){ LOG("ERROR: dms_client_handle_2 doesn't exist.\n"); return 0; } dmssenderStarted = 0; pthread_mutex_lock(&dms_sender_mutex); pthread_attr_init (&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); #ifdef FEATURE_ENABLE_SYSTEM_RESTORATION pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);#endif__QMI_DMS_SENDER_PTHREAD_CREATE_AGAIN__: ret = pthread_create(&qmi_dms_sender_tid, &attr, initDmsSender, (void *)(&result)); if(ret != 0){ if(EAGAIN == errno){ sleep(1); goto __QMI_DMS_SENDER_PTHREAD_CREATE_AGAIN__; } LOG("ERROR: pthread_create() failed. errno=%d.\n", errno); return 0; } thread_id_array[THD_IDX_DMS_SENDER] = (unsigned long)qmi_dms_sender_tid; while(dmssenderStarted == 0){ pthread_cond_wait(&dms_sender_cond, &dms_sender_mutex); } pthread_mutex_unlock(&dms_sender_mutex); if(result < 0){ LOG("ERROR: initDmsSender() error.\n."); return 0; } return 1;}