/******************************************************************************* | |
* Ö÷Òª¹¦ÄÜÊÇÉèÖÃCMUX¹¦ÄÜÇл» | |
* Ö§³ÖµÄ¹¦ÄÜÈçÏÂ: | |
* ²éѯ»òÉèÖÃCMUXģʽÇл» | |
* | |
* ºóÐøÈçÓÐCMUX¹¦ÄÜÏà¹ØµÄ״̬²éѯ»òÉèÖõÄÏà¹ØÐèÇ󣬿ÉÒÔÔÚ´ËÎļþÖÐÌí¼ÓATÃüÁî´¦Àí | |
**********************************************************************************/ | |
#if (APP_OS_TYPE == APP_OS_LINUX) | |
#include "ext_cmux_func.h" | |
#include "ext_dev_func.h" | |
/************************************************************************** | |
* È«¾Ö±äÁ¿¶¨ÒåÇø | |
**************************************************************************/ | |
int32_t g_cmux_flag = 0;//Åжϵ±Ç°ÊÇ·ñÊÇcmux״̬ | |
int32_t g_commonPortinCmux = -1; //Çл»³Écmux״̬ʱÆÕͨģʽÏÂÎļþÃèÊö·û | |
int32_t g_selfAdaptFlag = 0; //±ê¼ÇÊÇ·ñÐèÒªÅжϲ¨ÌØÂÊ×ÔÊÊÓ¦£¬0:²»ÐèÒª£¬1:ÐèÒª | |
int32_t g_iUartPort = -1; //µ±Ç°UartÉ豸¾ä±ú | |
static pthread_t s_uiMonitorHungupThread = -1; //´¦Àí¼à¿ØhungupµÄÏß³Ì | |
#define N_GSM0710 21 //cmuxÏà¹ØÅäÖà | |
#define cmuxChID 1 //µ±Ç°Ê¹ÓõÄcmuxͨµÀºÅ | |
//========================================================================================================// | |
//º¯ÊýʵÏÖÇø | |
//========================================================================================================// | |
static int zUP_SetPort(int32_t iFd) | |
{ | |
if(iFd < 0) | |
{ | |
at_print(AT_ERR,"Set usb port error. iFd == %d\n", iFd); | |
return 0; | |
} | |
at_print(AT_ERR,"Set usb port ok. iFd == %d\n", iFd); | |
//ioctl(iFd, (('R'<<8)|1|(0x4004<<16)), 0x400); | |
//ioctl(iFd, (('R'<<8)|4|(0x4004<<16)), 0); | |
vFnSetUsbInfo(iFd, &s_tUsbInfo, AUTO_MODE); | |
return 1; | |
} | |
static void zUP_MuxChannelConfig(int32_t iFd) | |
{ | |
static struct termios Muxtio; | |
tcgetattr(iFd, &Muxtio); // save current port settings | |
Muxtio.c_cflag = CS8 | CLOCAL | CREAD; | |
Muxtio.c_iflag = IGNPAR; | |
Muxtio.c_oflag = 0; | |
Muxtio.c_lflag = 0; //!ICANON; | |
Muxtio.c_cc[VMIN] = 1; | |
Muxtio.c_cc[VTIME] = 0; | |
//cfsetospeed(&Muxtio, B38400); | |
//cfsetispeed(&Muxtio, B38400); | |
tcsetattr(iFd, TCSANOW, &Muxtio); | |
} | |
int zUP_CreateCMUXATThread() | |
{ | |
char shellCmd[AT_CMD_MAX] = {0}; | |
char mainDevNum[AT_CMD_MAX] = {0}; | |
char cmuxDevice[AT_CMD_MAX] = {0}; | |
FILE *fp = NULL; | |
int32_t result = -1; | |
int32_t g_modeToCMUXAT = -1; //CMUX1µÄÎļþÃèÊö·û | |
system("rm -f /tmp/uartproxy_file"); | |
system("cat /proc/devices | grep gsmtty > /tmp/uartproxy_file"); | |
fp = fopen("/tmp/uartproxy_file", "r"); | |
if(NULL == fp) | |
{ | |
at_print(AT_ERR,"can not open file /tmp/uartproxy_file\n"); | |
return -1; | |
} | |
memset(shellCmd, 0, sizeof(shellCmd)); | |
fgets(shellCmd, sizeof(shellCmd), fp); | |
at_print(AT_ERR,"shellCmd= %s!!!\n", shellCmd); | |
memcpy(mainDevNum, shellCmd, (int32_t)(strchr(shellCmd,' ') - shellCmd)); | |
at_print(AT_ERR,"mainDevNum= %s!!!\n", mainDevNum); | |
fclose(fp); | |
memset(shellCmd, 0, sizeof(shellCmd)); | |
snprintf(shellCmd, sizeof(shellCmd), "/bin/mknod /dev/gsmtty0 c %s 0", mainDevNum);//cmuxͨµÀ0±ØÐë´´½¨ | |
result = zxic_system(shellCmd); | |
at_print(AT_ERR,"result1= %d!!!\n", result); | |
memset(shellCmd, 0, sizeof(shellCmd)); | |
snprintf(shellCmd, sizeof(shellCmd),"/bin/mknod /dev/gsmtty%d c %s %d", cmuxChID, mainDevNum, cmuxChID); | |
result = zxic_system(shellCmd); | |
at_print(AT_ERR,"result2= %d!!!\n", result); | |
sprintf(cmuxDevice, "/dev/gsmtty%d", cmuxChID);//»ñÈ¡cmuxÉ豸Ãû | |
g_modeToCMUXAT = open(cmuxDevice, O_RDWR); | |
if(g_modeToCMUXAT < 0) | |
{ | |
// UART_PROXY_LOG("Open port %d error.\n", g_modeToCMUXAT); | |
return 0; | |
} | |
g_commonPortinCmux = g_iUartPort; | |
g_iUartPort = g_modeToCMUXAT; | |
at_print(AT_ERR,"use gsmtty%d start!!!!\n", cmuxChID); | |
zUP_MuxChannelConfig(g_iUartPort); | |
return 1; | |
} | |
static int32_t zUP_GetUartEvents(int32_t fd) | |
{ | |
struct pollfd fds; | |
int32_t time_delay = 300; | |
fds.fd = fd; | |
fds.events = POLLHUP; | |
if(poll(&fds, 1, time_delay) <= 0) | |
{ | |
return 0; | |
} | |
if(fds.revents) | |
{ | |
return 1; | |
} | |
return 0; | |
} | |
static void *zUP_MonitorHungupHander() | |
{ | |
int32_t result = 0; | |
while(1) | |
{ | |
result = zUP_GetUartEvents(g_commonPortinCmux); | |
at_print(AT_DEBUG,"tty GetUartEvents ret is %d\n",result); | |
if(result > 0) | |
{ | |
at_print(AT_DEBUG,"GetUartEvents ret is %d\n",result); | |
//·¢ËÍÏûÏ¢¸øat_Ctl£¬½øÐÐmux2USBµÄ²Ù×÷£¬ÖØÐ»ñÈ¡µ½fd | |
//ipc_send_message(MODULE_ID_AT_CTL,MODULE_ID_AT_CTL, XXX, 0, NULL,0); | |
#if 0 | |
if(zUP_UartOpenConfig() == 0) | |
{ | |
at_print(AT_DEBUG,"zUP_UartOpenConfig 0 %d\n"); | |
return NULL; | |
} | |
g_cmux_flag = 0; | |
zUP_Mux2USB(g_iUartPort); | |
#endif | |
g_cmux_flag = 0; | |
pthread_cancel(s_uiMonitorHungupThread); | |
} | |
} | |
return NULL; | |
} | |
int zUP_CreateMonitorHungupThread() | |
{ | |
int32_t iResult = -1; | |
pthread_attr_t attr; | |
pthread_attr_init(&attr); | |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | |
iResult = pthread_create(&s_uiMonitorHungupThread, &attr, zUP_MonitorHungupHander, NULL); | |
pthread_attr_destroy(&attr); | |
if(0 != iResult) | |
{ | |
at_print(AT_ERR,"Call MonitorHungup pthread_create() error.\n"); | |
return 0; | |
} | |
return 1; | |
} | |
void OpenMultiCmuxChannel() | |
{ | |
// UART_PROXY_LOG("Enter %s, and will go open multi mux_fd\n", __FUNCTION__); | |
if(!zUP_CreateCMUXATThread()) | |
{ | |
at_print(AT_ERR,"Call zUP_CreateCMUXATThread() error.\n"); | |
return; | |
} | |
if(!zUP_CreateMonitorHungupThread()) | |
{ | |
at_print(AT_ERR,"Call zUP_CreateMonitorHungupThread() error.\n"); | |
return; | |
} | |
} | |
static void bFnCmuxProc() | |
{ | |
int ldisc = N_GSM0710; | |
int ret = 0; | |
struct gsm_config cmux_config; | |
g_cmux_flag = 1; | |
ret = ioctl(g_iUartPort, TIOCSETD, &ldisc);//Çл»Ïß·¹æ³Ì | |
at_print(AT_DEBUG,"tty goto mux ret is %d\n",ret); | |
ret = ioctl(g_iUartPort, GSMIOC_GETCONF, &cmux_config); | |
at_print(AT_DEBUG,"get mux ret is %d\n",ret); | |
cmux_config.initiator = 0; | |
cmux_config.encapsulation = 0; | |
cmux_config.mru = 512; | |
cmux_config.mtu = 512; | |
ret = ioctl(g_iUartPort, GSMIOC_SETCONF, &cmux_config); | |
at_print(AT_DEBUG,"set mux ret is %d\n",ret); | |
OpenMultiCmuxChannel(); | |
} | |
struct at_cmux_req | |
{ | |
char name[32]; | |
int cmux_mode; //»ù±¾/¸ß¼¶Ä£Ê½ | |
int subset; //Ö¡¸ñʽÀàÐÍ | |
int port_speed; //cmux²¨ÌØÂÊ | |
int frame_len; //×î´óÖ¡³¤(N1) | |
int ack_time; //½ÓÊÕÈ·ÈÏʱ¼ä(T1) | |
int recon_count; //×î´óÖØÁ¬´ÎÊý(N2) | |
int resp_time; //ÏìӦʱ¼ä(T2) | |
int awak_time; //»½ÐÑʱ¼ä(T3) | |
int win_size; //´°¿Ú´óС | |
}; | |
int zcmuxSet_req(int at_fd,char * at_paras,void * *res_msg,int * res_msglen) | |
{ | |
struct at_cmux_req *req = NULL; | |
req = malloc(sizeof(struct at_cmux_req)); | |
if(req == NULL){softap_assert("");return AT_END;} | |
memset(req,0,sizeof(struct at_cmux_req)); | |
void *p[9] = {&req->cmux_mode,&req->subset,&req->port_speed,&req->frame_len,&req->ack_time,&req->recon_count,&req->resp_time,&req->awak_time,&req->win_size}; | |
if(at_paras==NULL) | |
softap_assert("zcmuxSet_req:at_paras is null"); | |
parse_param2("%d,%d,%d,%d,%d,%d,%d,%d,%d",at_paras,p); | |
at_print(AT_DEBUG,"zcmuxSet_req: cmux_mode = %d, subset = %d, port_speed = %d, frame_len = %d, ack_time = %d, recon_count = %d, resp_time = %d, awak_time = %d, win_size = %d\n", | |
req->cmux_mode, req->subset, req->port_speed, req->frame_len, req->ack_time, req->recon_count, | |
req->resp_time, req->awak_time, req->win_size); | |
if(req->cmux_mode == 0 && req->subset >= 0 && req->subset <= 1 && req->port_speed >= 0 && req->port_speed <= 5 && | |
(req->frame_len >= 8||req->frame_len == 0) && req->frame_len <= 32768 && req->ack_time >= 0 && req->ack_time <= 255 && req->recon_count >= 0 && req->recon_count <= 100 | |
&& req->resp_time >= 0 && req->resp_time <= 255 && req->awak_time == 0 && req->win_size == 0) | |
{ | |
at_print(AT_ERR, "Enter zcmuxSet_req\n"); | |
//req->fd = at_fd; | |
char *name = at_portmng_get_name_by_fd(at_fd); | |
if(name) | |
memcpy(req->name, name, sizeof(req->name)); | |
*res_msg = req; | |
*res_msglen = sizeof(struct at_cmux_req); | |
return AT_CONTINUE; | |
} | |
free(req); | |
*res_msg = at_err_build(ATERR_PARAM_INVALID); | |
*res_msglen = strlen(*res_msg); | |
return AT_END; | |
} | |
int zcmuxSet_rsp(void *rsp_msg, void**ret, int *retlen) | |
{ | |
int rsp = *(int *)rsp_msg; | |
if(rsp) | |
{ | |
*ret = at_ok_build(); | |
} | |
else | |
{ | |
*ret = at_err_build(ATERR_PROC_FAILED); | |
} | |
*retlen = strlen(*ret); | |
return AT_END; | |
} | |
#endif |