| /******************************************************************************* | |
| * Ö÷Òª¹¦ÄÜÊÇÉèÖÃ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 |