blob: 56e4a6d0861f2b929b73c2e287ce862213dab35a [file] [log] [blame]
/*******************************************************************************
* Ö÷Òª¹¦ÄÜÊÇÉèÖÃ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