blob: daee1d39664370b37671bc31406c06fb82b3cfb8 [file] [log] [blame]
#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!!!");
}