| #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 <list> | 
 | #include <vendor-ril/telephony/ril.h> | 
 | #include <vendor-ril/telephony/mtk_ril_sp.h> | 
 | #include "liblog/lynq_deflog.h" | 
 | #include "lynq_sim_urc.h" | 
 |  | 
 | int module_len_urc_addr_serv; | 
 | struct sockaddr_in module_urc_addr_serv; | 
 | static int module_urc_sock_fd = -1; | 
 | int module_urc_status = 1; | 
 | pthread_t module_urc_tid = -1; | 
 |  | 
 | static pthread_mutex_t s_ProcessUrcMsgBlockMutex = PTHREAD_MUTEX_INITIALIZER; | 
 | #define BLOCK_PROCESS_URC_MSG_INIT() pthread_mutex_init(&s_ProcessUrcMsgBlockMutex,NULL) | 
 | #define BLOCK_PROCESS_URC_MSG_LOCK() pthread_mutex_lock(&s_ProcessUrcMsgBlockMutex) | 
 | #define BLOCK_PROCESS_URC_MSG_UNLOCK() pthread_mutex_unlock(&s_ProcessUrcMsgBlockMutex) | 
 |  | 
 | bool is_support_urc(int urc_id) | 
 | { | 
 |     switch(urc_id) | 
 |     { | 
 |         case LYNQ_URC_ALLOW_DATA: | 
 |             return true; | 
 |         default: | 
 |             return false; | 
 |     } | 
 | } | 
 |  | 
 | void *thread_urc_recv(void *p) | 
 | { | 
 |     Parcel *urc_p =NULL; | 
 |     char urc_data[LYNQ_REC_BUF]; | 
 |     int res = 0; | 
 |     lynq_head_t* phead; | 
 |     LYINFLOG("urc recv thread is running"); | 
 |     while(module_urc_status) | 
 |     { | 
 |         bzero(urc_data,LYNQ_REC_BUF); | 
 |         res = recvfrom(module_urc_sock_fd,urc_data,sizeof(urc_data),0,(struct sockaddr *)&module_urc_addr_serv,(socklen_t*)&module_len_urc_addr_serv); | 
 |         if(res<sizeof(int32_t)*2) | 
 |         { | 
 |             LYERRLOG("thread_urc_recv step2 fail: res is %d",res); | 
 |             continue; | 
 |         } | 
 |  | 
 |         phead=(lynq_head_t*) urc_data; | 
 |         if(is_support_urc(phead->urcid)==false) | 
 |         { | 
 |             continue; | 
 |         } | 
 |         urc_p = new Parcel(); | 
 |         if(urc_p == NULL) | 
 |         { | 
 |             LYERRLOG("new parcel failure!!!"); | 
 |             continue; | 
 |         } | 
 |         urc_p->setData((uint8_t *)urc_data,res); // p.setData((uint8_t *) buffer, buflen); | 
 |         urc_p->setDataPosition(0); | 
 |         if(urc_p->dataAvail()>0) | 
 |         { | 
 |             urc_msg_process(urc_p); | 
 |         } | 
 |         else  | 
 |         { | 
 |             delete urc_p; | 
 |             urc_p = NULL; | 
 |         }         | 
 |     } | 
 |     LYINFLOG("urc recv thread ended"); | 
 |     return NULL; | 
 | } | 
 |  | 
 | void lynq_close_urc_rev_thread() | 
 | { | 
 |     int ret; | 
 |  | 
 |     BLOCK_PROCESS_URC_MSG_LOCK();  //just cancel urc process tid when recv from | 
 |     module_urc_status = 0; | 
 |     if(module_urc_tid!=-1) | 
 |     { | 
 |         ret = pthread_cancel(module_urc_tid); | 
 |         LYINFLOG("pthread cancel urc rev ret = %d",ret); | 
 |     } | 
 |     BLOCK_PROCESS_URC_MSG_UNLOCK(); | 
 |     if(module_urc_tid != -1) | 
 |     { | 
 |         ret = pthread_join(module_urc_tid,NULL); | 
 |         LYINFLOG("pthread join urc tid ret = %d",ret); | 
 |         module_urc_tid =-1; | 
 |     } | 
 | } | 
 |  | 
 | void lynq_close_urc_socket() | 
 | { | 
 |     if (module_urc_sock_fd >= 0) | 
 |     { | 
 |         close(module_urc_sock_fd); | 
 |         module_urc_sock_fd =-1; | 
 |     } | 
 | } | 
 |  | 
 | int lynq_setup_urc_socket() | 
 | { | 
 |     int on = 1; | 
 |     int ret = 0; | 
 |     module_len_urc_addr_serv = sizeof(sockaddr_in); | 
 |     module_urc_sock_fd = socket(AF_INET, SOCK_DGRAM, 0); | 
 |     if (module_urc_sock_fd <0){ | 
 |         LYERRLOG("urc socket error"); | 
 |         return RESULT_ERROR;   | 
 |     } | 
 |     module_urc_addr_serv.sin_family = AF_INET; | 
 |     module_urc_addr_serv.sin_port = htons(LYNQ_URC_SERVICE_PORT); | 
 |     module_urc_addr_serv.sin_addr.s_addr = inet_addr(LYNQ_URC_ADDRESS); | 
 |     /* Set socket to allow reuse of address and port, SO_REUSEADDR value is 2*/ | 
 |     ret = setsockopt(module_urc_sock_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof on); | 
 |     if(ret <0) | 
 |     { | 
 |         LYERRLOG("urc socket set error"); | 
 |         close(module_urc_sock_fd); | 
 |         module_urc_sock_fd =-1; | 
 |         return RESULT_ERROR;   | 
 |     } | 
 |     ret = bind(module_urc_sock_fd ,(struct sockaddr*)&module_urc_addr_serv, sizeof(module_urc_addr_serv)); | 
 |     if(ret <0) | 
 |     { | 
 |         LYERRLOG("urc socket bind error"); | 
 |         close(module_urc_sock_fd); | 
 |         module_urc_sock_fd =-1; | 
 |         return RESULT_ERROR; | 
 |     } | 
 |     return RESULT_OK; | 
 | } | 
 |  | 
 | int lynq_start_all_urc_socket_thread() | 
 | { | 
 |     int ret= lynq_setup_urc_socket(); | 
 |     if(ret!=RESULT_OK) | 
 |     { | 
 |         LYERRLOG("call lynq_setup_urc_socket fail"); | 
 |         return RESULT_ERROR; | 
 |     } | 
 |  | 
 |     module_urc_status = 1; | 
 |     ret = pthread_create(&module_urc_tid,NULL,thread_urc_recv,NULL); | 
 |     if(ret <0) | 
 |     { | 
 |         LYERRLOG("urc recv pthread create error"); | 
 |         module_urc_status = 0; | 
 |         lynq_close_urc_socket(); | 
 |         return RESULT_ERROR; | 
 |     } | 
 |     LYINFLOG("urc start success"); | 
 |     return RESULT_OK;   | 
 | } | 
 |  | 
 | void lynq_close_all_urc_socket_thread() | 
 | { | 
 |     lynq_close_urc_rev_thread(); | 
 |     lynq_close_urc_socket(); | 
 |     LYERRLOG("close all urc socket thread!!!"); | 
 | } | 
 |  |