-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqmi_uim_sender_qlinkdatanode.c
372 lines (295 loc) · 9.47 KB
/
qmi_uim_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 <user_identity_module_v01.h>#include "common_qlinkdatanode.h"#include "feature_macro_qlinkdatanode.h"#include "queue_qlinkdatanode.h"#include "socket_qlinkdatanode.h"/******************************External Functions*******************************/extern void queue_clr_apdu_node(void);extern void upload_status_info_and_power_up_virt_USIM_later(void);/******************************External Variables*******************************/extern int qmi_handle;extern qmi_client_type uim_client_handle;extern bool isUimPwrDwn;extern bool isQueued;//extern bool isOnlineMode;extern bool isUimRstOperCplt;extern pthread_mutex_t rst_uim_mtx;extern pthread_cond_t rst_uim_cond;#ifdef FEATURE_ENABLE_RWLOCK_CHAN_LCKextern pthread_rwlock_t ChannelLock;#elseextern pthread_mutex_t ChannelLock;#endifextern unsigned long thread_id_array[THD_IDX_MAX];extern char URC_special_mark_array[MAX_SPEC_URC_ARR_LEN];extern bool isUimPwrDwnMssage;extern bool isAutoReprotPowerDown;#ifdef FEATURE_ENABLE_OUT_OF_TRAFFIC_AND_DATE_0206 extern bool isCancelRecoveryNet;#endif/******************************Local Variables*******************************/static pthread_t qmi_uim_sender_tid;static pthread_mutex_t uim_sender_mutex = PTHREAD_MUTEX_INITIALIZER;static pthread_cond_t uim_sender_cond = PTHREAD_COND_INITIALIZER;static int uimsenderStarted = 0;static int uim_sender_pipe_rd_fd = -1;/******************************Global Variables*******************************/int uim_sender_pipe_wr_fd = -1;bool PowerUpUsimAfterPowerDown = false;bool PowerUpUsimAfterRecvingUrcRpt = false;#ifdef FEATURE_QMI_ASYNC_REQ_UIM_PDstatic void uim_pwr_dwn_cb(qmi_client_type user_handle, unsigned long msg_id, void *resp_struct, int resp_struct_len, void *resp_cb_data, qmi_client_error_type transp_err){ if(transp_err != QMI_NO_ERR){ LOG("ERROR: Transmission error. transp_err=%d.\n", transp_err); } /* //Move the setting of isOnlineMode into the handler of recving "+SIMCARD: NOT AVAILABLE" else{ isOnlineMode = false; LOG("Setting uim power down completes.\n"); } */ return;}#endif /*FEATURE_QMI_ASYNC_REQ_UIM_PD*/static void sender_set_uim_power_down(void){ qmi_client_error_type rc; uim_power_down_req_msg_v01 req_msg; uim_power_down_resp_msg_v01 resp_msg; #ifdef FEATURE_QMI_ASYNC_REQ_UIM_PD qmi_txn_handle txn_handle; #endif if(uim_client_handle == NULL){ LOG("ERROR: uim_client_handle is unavailable!\n"); return; } req_msg.slot = UIM_SLOT_1_V01; print_cur_gm_time(" QMIUIMSENDER (Set uim power down) ");#ifdef FEATURE_ENABLE_REBOOT_DEBUG isAutoReprotPowerDown = true; LOG("OK: isAutoReprotPowerDown = %d \n",isAutoReprotPowerDown ); #endif #ifndef FEATURE_QMI_ASYNC_REQ_UIM_PD rc = qmi_client_send_msg_sync(uim_client_handle, QMI_UIM_POWER_DOWN_REQ_V01, &req_msg, sizeof(req_msg), &resp_msg, sizeof(resp_msg), 50000); 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{ //Changed by rjf at 20151026 (isOnlineMode is for indicating operation mode only.)// isOnlineMode = false; LOG("Setting uim power down completes.\n"); } #else rc = qmi_client_send_msg_async(uim_client_handle, QMI_UIM_POWER_DOWN_REQ_V01, &req_msg, sizeof(req_msg), &resp_msg, sizeof(resp_msg), &uim_pwr_dwn_cb, NULL, &txn_handle); 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{ LOG("qmi_client_send_msg_async() returns.\n"); } */ #endif#ifdef FEATURE_ENABLE_SYSTEM_RESTORATION isUimPwrDwnMssage = false;#ifdef FEATURE_ENABLE_OUT_OF_TRAFFIC_AND_DATE_0206 LOG("Debug: isCancelRecoveryNet = %d \n",isCancelRecoveryNet); if (isCancelRecoveryNet == true){ LOG("Don't send reboot message to monitor thread.\n"); return; } #endif notify_RstMonitor(0x00); // by jack li 20160224 LOG("~~~~ start monitor 01 isUimPwrDwnMssage :=%d\n",isUimPwrDwnMssage);#endif return;}//Param:// opt:// 0x00: Power down virt USIM. (Of mdm9215.)// 0x01: Reserved! Power up virt USIM. (Of mdm9215.)void notify_UimSender(char opt){ int n = -1; LOG6("~~~~ notify_UimSender start (%02x) ~~~~\n", opt); if(opt != 0x00){ LOG("ERROR: Wrong param input. opt=%02x.\n", opt); goto __EXIT_OF_NOTIFY_UIMSENDER__; } do{ if(n == 0) LOG("write() failed. n=%d.\n", n); n = write(uim_sender_pipe_wr_fd, (void *)&opt, 1); }while ((n<0 && errno==EINTR) || n==0); if(n<0){ LOG("ERROR: write() failed. n=%d, errno=%s(%d).\n", n, strerror(errno), errno); } __EXIT_OF_NOTIFY_UIMSENDER__: LOG6("~~~~ notify_UimSender end ~~~~\n"); return;}void UimSenderLoop(void){ int n; int fdp1; fd_set rfd; char buf = 0xff; FD_ZERO(&rfd); FD_SET(uim_sender_pipe_rd_fd, &rfd); fdp1 = uim_sender_pipe_rd_fd+1;// LOG6("~~~~ UimSenderLoop ~~~~\n"); for(;;){ n = select(fdp1, &rfd, NULL, NULL, NULL); if (n < 0){ if (errno == EINTR) continue; LOG("select() error. errno=%s(%d).\n", strerror(errno), errno); continue; }else if(n == 0) continue; do{ n = read(uim_sender_pipe_rd_fd, (void *)(&buf), sizeof(buf)); }while ((n<0 && (errno==EINTR || errno == EAGAIN)) || (n == 0)); if(n > 0){ switch(buf){ case 0x00:{ sender_set_uim_power_down(); if(isQueued){ queue_clr_apdu_node(); // Fixed by rjf at 20150803 } #ifndef FEATURE_QMI_ASYNC_REQ_UIM_PD #error set isUimPwrDwn true when "+SIMCARD: NOT AVAILABLE" is recved// isUimPwrDwn = true; #endif pthread_mutex_lock(&rst_uim_mtx); isUimRstOperCplt = true; pthread_cond_broadcast(&rst_uim_cond); pthread_mutex_unlock(&rst_uim_mtx); //Fixed by rjf at 20150918 //Situation Presentation: // Not power up USIM directly but upload status info at first. if(PowerUpUsimAfterPowerDown){ LOG("PowerUpUsimAfterPowerDown = 1.\n"); PowerUpUsimAfterPowerDown = false; // ACQ_CHANNEL_LOCK_RD; upload_status_info_and_power_up_virt_USIM_later();// RLS_CHANNEL_LOCK; //After handling this URC rpt, the corresponding elem in URC_special_mark_array should be cleared. URC_special_mark_array[SPEC_URC_ARR_IDX_VIRT_USIM_PWR_DWN] = 0x00; } break; } // case 0x00 default:{ LOG("ERROR: Wrong buf (%02x) found!\n", buf); break; // Not possible to reach here. } // default } // switch end }else{ LOG("ERROR: Nothing found in uim_sender_pipe!\n"); } LOG("QMI uim sender completes.\n"); } LOG("ERROR: Unexpected error. UimSenderLoop() ended.\n"); return;}static void *initUimSender(void *user_data){ int ret; int uim_sender_pipe[2];// LOG6("~~~~ initUimSender ~~~~\n"); ret = pipe(uim_sender_pipe); *((int *)user_data) = ret; pthread_mutex_lock(&uim_sender_mutex); uimsenderStarted = 1; pthread_cond_broadcast(&uim_sender_cond); pthread_mutex_unlock(&uim_sender_mutex); if (ret < 0) { LOG("pipe() error. errno=%d.\n", errno); return NULL; } uim_sender_pipe_wr_fd = uim_sender_pipe[1]; uim_sender_pipe_rd_fd = uim_sender_pipe[0]; fcntl(uim_sender_pipe_rd_fd, F_SETFL, O_NONBLOCK);// fcntl(uim_sender_pipe_rd_fd, F_SETFL, O_NOATIME); //Add by rjf at 20151102 UimSenderLoop(); LOG("ERROR: UimSenderLoop() ended unexpectedly!\n"); while(1){ sleep(0x00ffffff); } return NULL;}//return value:// 0: error// 1: successint startQMIUimSender(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(uim_client_handle == NULL){ LOG("ERROR: uim_client_handle doesn't exist.\n"); return 0; } uimsenderStarted = 0; pthread_mutex_lock(&uim_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_UIM_SENDER_PTHREAD_CREATE_AGAIN__: ret = pthread_create(&qmi_uim_sender_tid, &attr, initUimSender, (void *)(&result)); if(ret != 0){ if(EAGAIN == errno){ sleep(1); goto __QMI_UIM_SENDER_PTHREAD_CREATE_AGAIN__; } LOG("ERROR: pthread_create() failed. errno=%d.\n", errno); return 0; } #ifdef FEATURE_ENABLE_PRINT_TID LOG("NOTICE: qmi_uim_sender_tid = %lu.\n", (unsigned long)qmi_uim_sender_tid); #endif thread_id_array[THD_IDX_UIM_SENDER] = (unsigned long)qmi_uim_sender_tid; while(uimsenderStarted == 0){ pthread_cond_wait(&uim_sender_cond, &uim_sender_mutex); } pthread_mutex_unlock(&uim_sender_mutex); if(result < 0){ LOG("ERROR: initUimSender() error.\n."); return 0; } return 1;}