TCP-trans demo
```language
#define USER_TASK_STACK_SIZE (2048*2)
#define USER_TASK_PRIORITY (COS_USER_TASKS_PRIORITY_BASE)
static UINT8 tcp_status=0;
static UINT8 errorCnt=0;
typedef struct
{
UINT8 type;
char ip[100];
UINT32 port;
UINT8 gpsflag;
UINT16 gpstime;
char gpsnmea[10];
UINT8 heartflag;
UINT16 hearttime;
char heart[52];
UINT8 linkflag;
char link[52];
}trans_conf;
static trans_conf transconf;//weihu yi ge
static uint16_t cipCCFG_SendSz = 1000;
static uint8_t cipCCFG_esc = 0;
static uint8_t cipCCFG_WaitTm = 5;
static uint8_t Send_Heart_Flag=0;
static uint8_t Send_Gps_Flag=0;
typedef struct
{
uint8_t *buff; // buffer, shared by all mode
UINT32 buffLen; // existed buffer data byte count
UINT32 buffSize; // buffer size
HANDLE mutex;
} TR_BYPASS_BUFFER_T;
TR_BYPASS_BUFFER_T *g_tr_bypass_buf = NULL;
TR_BYPASS_BUFFER_T *at_TR_TCPIPBufCreate();
VOID at_TR_TCPIPBufDestroy(TR_BYPASS_BUFFER_T *bypass_buff);
VOID at_TR_delayAsync(void *param);
VOID bypassTRDataSend(void *param);
int bypassTRDataRecv(void *param, const uint8_t *data, unsigned length);
static void start_transparent_mode(UINT8 nDlc);
static void stop_transparent_mode(UINT8 nDlc);
static trans_conf init_trans_conf(trans_conf transconf);
static void trans_conf_file_init(void);
void Send_Heart_Timer();
void Send_Gps_Timer();
void UserTask(void *p_arg);
/********************
*********************
*********************
*********************
*********************
*********************
*********************
*********************
add user task here
*********************
*********************
*********************
*********************
*********************
*********************
*********************
**********************/
VOID UserCreateTask(void)
{
trans_conf_file_init();
COS_CreateTask(UserTask,
NULL, NULL,
USER_TASK_STACK_SIZE,
USER_TASK_PRIORITY,
COS_CREATE_DEFAULT, 0, "UserTask");
}
void Send_Heart_Timer()
{
AT_TC(10,"DMH_HEART_TEST");
if(tcp_status && transconf.heartflag){
//send heart data Flag
Send_Heart_Flag = 1;
}
sxr_StartFunctionTimer(transconf.hearttime SECOND,Send_Heart_Timer,(VOID*)NULL,0x10);
}
void Send_Gps_Timer()
{
AT_TC(10,"DMH_GPS_TEST");
if(tcp_status && transconf.gpsflag){
//send gps data Flag
Send_Gps_Flag = 1;
}
sxr_StartFunctionTimer(transconf.gpstime SECOND,Send_Gps_Timer,(VOID*)NULL,0x10);
}
void UserTask(void *p_arg)
{
AT_WriteUart("AP2000MT_GV1.0\r\n", strlen("AP2000MT_GV1.0\r\n"));
//wait reg net
wait_dev_reg_net();
//cgatt
wait_dev_active_net();
//open GPS
if(transconf.gpsflag == 1)
wait_dev_open_gps();
PRO_START:
//close tcp
wait_at_cipclose();
//connect
wait_at_cipstart(transconf.type,transconf.ip,transconf.port);
//heart timer
if(transconf.gpsflag == 1)
sxr_StartFunctionTimer(transconf.hearttime SECOND,Send_Heart_Timer,(VOID*)NULL,0x10);
//gps timer
if(transconf.heartflag == 1)
sxr_StartFunctionTimer(transconf.gpstime SECOND,Send_Gps_Timer,(VOID*)NULL,0x10);
//link data
if(transconf.linkflag == 1 || transconf.linkflag == 3){
if(SOCKET_ERROR == at_tcp_send(transconf.link,strlen(transconf.link)) )
goto PRO_START;
}
//set falg
tcp_status = 1;
//in trans
start_transparent_mode(0);
while (1)
{
{
if(get_tcp_socket()>0 && tcp_status==1){
if(Send_Heart_Flag){//send heart
Send_Heart_Flag = 0;
at_tcp_send(transconf.heart,strlen(transconf.heart));
}
if(Send_Gps_Flag){//send gps
Send_Gps_Flag = 0;
UINT8 arrStr[1024] = {0x00};
UINT32 arrLen = 0;
if(0 == strncmp(transconf.gpsnmea, "ALL", 3))
AT_GPS_NMEA_All(arrStr, &arrLen);
else
AT_GPS_Keyword_Filter(arrStr, &arrLen, transconf.gpsnmea, 3, strlen(transconf.gpsnmea));
at_tcp_send(arrStr,arrLen);
}
COS_Sleep(1000);
}
else{
tcp_status = 0;
stop_transparent_mode(0); //out trans
goto PRO_START;
}
}
}
}
/*function for transport*/
TR_BYPASS_BUFFER_T *at_TR_TCPIPBufCreate()
{
TR_BYPASS_BUFFER_T *bypass_buff = (TR_BYPASS_BUFFER_T *)AT_MALLOC(sizeof(*bypass_buff));
bypass_buff->buff = (uint8_t *)AT_MALLOC(AT_CMD_LINE_BUFF_LEN);
bypass_buff->buffLen = 0;
bypass_buff->buffSize = AT_CMD_LINE_BUFF_LEN;
bypass_buff->mutex = COS_CreateMutex();
return bypass_buff;
}
VOID at_TR_TCPIPBufDestroy(TR_BYPASS_BUFFER_T *bypass_buff)
{
if (bypass_buff == NULL)
return;
COS_DeleteMutex(bypass_buff->mutex);
AT_FREE(bypass_buff->buff);
AT_FREE(bypass_buff);
}
VOID at_TR_delayAsync(void *param)
{
AT_CMD_ENGINE_T *engine = (AT_CMD_ENGINE_T *)param;
if (g_tr_bypass_buf == NULL)
{
AT_TC(g_sw_TCPIP, "at_TR_delayAsync error,param == null");
at_StartCallbackTimer(5 * 1000, at_TR_delayAsync, param);
return;
}
AT_TC(g_sw_TCPIP, "at_TR_delayAsync,engine=%x,th->len=%d", engine, g_tr_bypass_buf->buffLen);
at_ModuleRunCommandExtra(engine, g_tr_bypass_buf->buff, g_tr_bypass_buf->buffLen);
}
VOID bypassTRDataSend(void *param)
{
AT_DISPATCH_T *dispatch = (AT_DISPATCH_T *)param;
if (!at_DispatchIsDataMode(dispatch))
{
AT_TC(g_sw_TCPIP, "bypassTRDataSend error,not data mode");
goto restart;
}
if (g_tr_bypass_buf == NULL)
{
AT_TC(g_sw_TCPIP, "bypassTRDataSend error,g_tr_bypass_buf == null");
goto restart;
}
if(g_tr_bypass_buf->buffLen == 0){
goto restart;
}
if (g_tr_bypass_buf->buffLen < cipCCFG_SendSz)
{
hal_HstSendEvent(0x10000000);
AT_TC(g_sw_TCPIP, "bypassTRDataSend do nothing buffLen=%d", g_tr_bypass_buf->buffLen);
//goto restart;
///////////////////////////////////////test by dmh///////////////////////////////////////
///////////////////////////////////////test by dmh///////////////////////////////////////
///////////////////////////////////////test by dmh///////////////////////////////////////
uint16_t send_all_size = g_tr_bypass_buf->buffLen;
uint16_t send_size = g_tr_bypass_buf->buffLen;
//add link len
if((transconf.linkflag == 2) || (transconf.linkflag==3)){
send_all_size += strlen(transconf.link);
}
UINT8 *data = AT_MALLOC(send_all_size+1);
if (data == NULL)
{
AT_TC(g_sw_TCPIP, "bypassTRDataSend MALLOC FAILS cipCCFG_SendSz=%d", send_all_size);
return;
}
memset(data, 0, send_all_size+1);
//add link data
if(send_all_size>send_size){
memcpy(data, transconf.link, strlen(transconf.link));
memcpy(data+strlen(transconf.link), g_tr_bypass_buf->buff, send_size);
}else
memcpy(data, g_tr_bypass_buf->buff, send_size);
COS_LockMutex(g_tr_bypass_buf->mutex);
memmove(g_tr_bypass_buf->buff, g_tr_bypass_buf->buff + send_size, g_tr_bypass_buf->buffLen - send_size);
g_tr_bypass_buf->buffLen -= send_size;
COS_UnlockMutex(g_tr_bypass_buf->mutex);
//SEND tcp data
if(SOCKET_ERROR ==at_tcp_send(data,strlen(data)))
{
errorCnt++;
if(errorCnt>10){
errorCnt = 0;
tcp_status = 0;
}
}else
errorCnt = 0;
AT_FREE(data);
///////////////////////////////////////test by dmh///////////////////////////////////////
///////////////////////////////////////test by dmh///////////////////////////////////////
///////////////////////////////////////test by dmh///////////////////////////////////////
}
else
{
uint16_t send_all_size = cipCCFG_SendSz;
//add link len
if((transconf.linkflag == 2) || (transconf.linkflag==3)){
send_all_size += strlen(transconf.link);
}
UINT8 *data = AT_MALLOC(send_all_size+1);//+1防止乱码//dmh
if (data == NULL)
{
AT_TC(g_sw_TCPIP, "bypassTRDataSend MALLOC FAILS cipCCFG_SendSz=%d", cipCCFG_SendSz);
return;
}
memset(data, 0, send_all_size+1);
//add link data
if(send_all_size>cipCCFG_SendSz){
memcpy(data, transconf.link, strlen(transconf.link));
memcpy(data+strlen(transconf.link), g_tr_bypass_buf->buff, cipCCFG_SendSz);
}else
memcpy(data, g_tr_bypass_buf->buff, cipCCFG_SendSz);
COS_LockMutex(g_tr_bypass_buf->mutex);
memmove(g_tr_bypass_buf->buff, g_tr_bypass_buf->buff + cipCCFG_SendSz, g_tr_bypass_buf->buffLen - cipCCFG_SendSz);
g_tr_bypass_buf->buffLen -= cipCCFG_SendSz;
COS_UnlockMutex(g_tr_bypass_buf->mutex);
//SEND tcp data
if(SOCKET_ERROR ==at_tcp_send(data,strlen(data)))
{
errorCnt++;
if(errorCnt>10){
errorCnt = 0;
tcp_status = 0;
}
}else
errorCnt = 0;
AT_FREE(data);
}
restart:
at_StartCallbackTimer(5 * 100, bypassTRDataSend, dispatch);
}
int bypassTRDataRecv(void *param, const uint8_t *data, unsigned length)
{
AT_TC(g_sw_TCPIP, "bypassTRDataRecv,length=%d ", length);
if (g_tr_bypass_buf == NULL)
g_tr_bypass_buf = at_TR_TCPIPBufCreate();
UINT8 escapeMode = TRUE;
AT_CMD_ENGINE_T *engine = NULL;
if (param != NULL)
{
if ((UINT32)param > 0x80000000)
engine = (AT_CMD_ENGINE_T *)param;
else
escapeMode = (UINT8)param;
}
if (escapeMode)
{
//TODO: implement escape mode
}
unsigned total = length;
COS_LockMutex(g_tr_bypass_buf->mutex);
while (length > 0)
{
uint8_t c = *data++;
length--;
// Remove previous byte for BACKSPACE
if (engine != NULL && c == CHAR_BACKSPACE && CHAR_BACKSPACE != CHAR_CTRL_Z && CHAR_BACKSPACE != CHAR_ESC)
{
if (g_tr_bypass_buf->buffLen > 0)
--g_tr_bypass_buf->buffLen;
continue;
}
// Drop whole buffer at overflow, maybe caused by data error
// or buffer too small
if (g_tr_bypass_buf->buffLen >= g_tr_bypass_buf->buffSize)
{
AT_TC(g_sw_TCPIP, "bypassTRDataRecv bypass mode overflow, drop all");
g_tr_bypass_buf->buffLen = 0;
}
g_tr_bypass_buf->buff[g_tr_bypass_buf->buffLen++] = c;
if (engine != NULL && (c == CHAR_CTRL_Z || c == CHAR_ESC))
{
COS_UnlockMutex(g_tr_bypass_buf->mutex);
at_StopCallbackTimer(at_TR_delayAsync, at_CmdGetChannel(engine));
at_ModuleRunCommandExtra(engine, g_tr_bypass_buf->buff, g_tr_bypass_buf->buffLen);
AT_TC(g_sw_TCPIP, "bypassTRDataRecv,return %d", total - length);
return total - length;
}
}
COS_UnlockMutex(g_tr_bypass_buf->mutex);
return total;
}
static void start_transparent_mode(UINT8 nDlc)
{
AT_DISPATCH_T *dispatch = at_DispatchGetByChannel(nDlc);
at_ModuleModeSwitch(AT_MODE_SWITCH_DATA_START, nDlc);
at_StartCallbackTimer(cipCCFG_WaitTm * 100, bypassTRDataSend, dispatch);
at_DataSetBypassMode(at_DispatchGetDataEngine(dispatch), bypassTRDataRecv, (void *)cipCCFG_esc);
}
static void stop_transparent_mode(UINT8 nDlc)
{
AT_DISPATCH_T *dispatch = at_DispatchGetByChannel(nDlc);
at_ModuleModeSwitch(AT_MODE_SWITCH_DATA_END, nDlc);
at_StopCallbackTimer(bypassTRDataSend, dispatch);
at_TCPIPBufDestroy(g_tr_bypass_buf);
g_tr_bypass_buf = NULL;
}
//begin add by dmh
static trans_conf init_trans_conf(trans_conf transconf)
{
/*
AT+CIPSTART=<mode>,<IPaddress>,<port>或AT+CIPSTART=<mode>,<domain name>,<port>
*/
transconf.type = 1;
sprintf(transconf.ip,"183.230.40.40");
transconf.port = 1811;
transconf.gpsflag = 0;
transconf.gpstime = 100;
sprintf(transconf.gpsnmea,"ALL");
transconf.heartflag=1;
sprintf(transconf.heart,"hearttest");
transconf.hearttime=30;
transconf.linkflag=1;
sprintf(transconf.link,"*275619#amaziot2000mt#AP2000MT*");
return transconf;
}
static void trans_conf_file_init(void)
{
//init write tans_file
transconf = init_trans_conf(transconf);
}
```