/******************************************************************************** * File Name: WiredLanTask * Function Describe:The Wired Lan Task * Relate Module: * Explain: * Writer: slw * Date: *******************************************************************************/ #define THIS_FILE_ID 11 //--------------------------------------------------------------------------------- #include "includes.h" #include "spi.h" #include "socket.h" #include "Internet/TcpEchoServer.h" #include "Internet/dhcp.h" #include "Internet/dns.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ //SOCKET 分配 #define SOCK_UDPS_DHCP 0 //DHCP 用于动态分配本地IP #define SOCK_UDPS_DNS 1 //DNS Clinet #define SOCK_TCPS_APP1 2 //Clinet #define SOCK_TCPS_LOOPBACK 7 //回环测试 //uint8_t DHCP_MSG_BUF[548]; #define DATA_BUF_SIZE 1050 uint8_t gDATABUF[DATA_BUF_SIZE]; SUT_WL_STATUS sutWLanStatus; /* Private macro -------------------------------------------------------------*/ OS_TID idWLanTask=0; U64 stkWLANTask[WIRE_LAN_TASK_STK_SIZE]; // Default Network Configuration wiz_NetInfo gWIZNETINFO = { .mac = {0x00, 0x08, 0xdc,0x00, 0xab, 0xcd}, .ip = {0, 0, 0, 0}, .sn = {255,255,255,0}, .gw = {0, 0, 0, 0}, .dns = {0,0,0,0}, .dhcp = NETINFO_DHCP };//dhcp:=NETINFO_STATIC or NETINFO_DHCP /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ void network_init(void); // Initialize Network information and display it void cb_ip_assign(void); //callback func when IP is assigned from DHCP server first void cb_ip_update(void); // callback func when IP is changed void cb_ip_conflict(void); // callback func when the assigned IP is conflict with others. uint8_t ClientInit(void); void ClientRun(void); int32_t WiredSendTcpData(uint8_t *data,uint16_t len); void SetIoMode(uint8_t iomode);//SOCK_IO_NONBLOCK;//SOCK_IO_BLOCK; int SendLogin2Server(void); int SendCurPosition2Server(void); /* ************************************************************************ W5500 PMODE配置 111: ALL CAPABLE,Auto-Negotiation enable * ************************************************************************/ void W5500_PMODE_CONFIG(void) { GPIO_InitTypeDef GPIO_InitStruct; //PB3->PMODE0,PB4->PMODE1,PB5->PMODE2 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4|GPIO_Pin_5; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_SetBits(GPIOB,(GPIO_Pin_3 | GPIO_Pin_4|GPIO_Pin_5)); } /* ************************************************************************ W5500 RESET 配置 (Active low) RESET should be held low at least 500 us for W550 * ************************************************************************/ void W5500_RESET_CONFIG(void) { GPIO_InitTypeDef GPIO_InitStruct; //PB2->RESET GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_ResetBits(GPIOB,GPIO_Pin_2); os_dly_wait(1); GPIO_SetBits(GPIOB,GPIO_Pin_2); } /* 链接服务器 type=0 app服务器 type=1 server服务器 成功 返回1 失败 返回0 */ int8_t Connect2Server(int type) { uint8_t mode; char tracebuf[22]; int8_t r; if(type){ SlwTrace(DEBUG,"[WL]Connect2FoTaServer\r\n"); if(sutServerIp.FotaServerIP[0]==0){ SlwTrace(DEBUG,"SOCKERR_IPINVALID\r\n"); os_dly_wait(500); return 0; } r=connect(SOCK_TCPS_APP1,sutServerIp.FotaServerIP,sutProductPara.FotaPort); }else{ SlwTrace(DEBUG,"[WL]Connect2AppServer\r\n"); if(sutServerIp.AppServerIP[0]==0){ SlwTrace(DEBUG,"SOCKERR_IPINVALID\r\n"); os_dly_wait(500); return 0; } r=connect(SOCK_TCPS_APP1,sutServerIp.AppServerIP,sutProductPara.AppPort); } if(r==SOCK_OK){ SlwTrace(DEBUG,"Connect OK!\r\n"); return 1; }else if(r==SOCKERR_SOCKINIT || r==SOCKERR_SOCKMODE){//socket未初始化,初始化之 SlwTrace(DEBUG,"socket init...\r\n"); mode=SOCK_IO_NONBLOCK; socket(SOCK_TCPS_APP1,Sn_MR_TCP,6000,SF_TCP_NODELAY); ctlsocket(SOCK_TCPS_APP1,CS_SET_IOMODE,&mode); }else if(r==SOCKERR_TIMEOUT){ SlwTrace(DEBUG,"Connect timeout!\r\n"); //os_dly_wait(1000); }else { sprintf(tracebuf,"connect err=%d\r\n",r); SlwTrace(DEBUG,tracebuf); } return 0; } /* */ void Disconnect2Server(void) { disconnect(SOCK_TCPS_APP1); SlwTrace(DEBUG,"[WL]CloseSocket!\r\n"); } //int32_t SendReg2Server(void) //{ // int r,len; // SlwTrace(DEBUG,">>SendReg>>\r\n"); // sutModemStatus.TcpSendTimeCt++; // sutTestData.NetMode=2;//LAN模式上传 // len=TcpPackingReg(g_ucTcpSendBuf); // if(len==0)return -1; // Debugsend(g_ucTcpSendBuf, len);//打印发送的数据 // r = WiredSendTcpData(g_ucTcpSendBuf,len); // return r; //} //int32_t SendGetFileInfo2Server(void) //{ // int r,len; // SlwTrace(DEBUG,">>SendGetFileInfo>>\r\n"); // len=PacketGetFileInfo(g_ucTcpSendBuf); // r = WiredSendTcpData(g_ucTcpSendBuf,len); // return r; //} //uint8_t TcpData[400]; //int32_t RecvDataFromServer() //{ // char tracebuf[20]; // int32_t r; // r=recv(SOCK_TCPS_APP1,gDATABUF, sizeof(gDATABUF)); // if(r>0){ // snprintf(tracebuf,sizeof(tracebuf),">SendUpload>>\r\n"); // sutTestData.CSQ=0; // sutTestData.NetMode=2; // len=TcpPackingSendTest(g_ucTcpSendBuf); // return WiredSendTcpData(g_ucTcpSendBuf,len); //} void WiredLanRecv(unsigned char *pData,unsigned short len) { unsigned short UploadInterval,SamplingInterval; unsigned short AckID,AckNum; unsigned char Result; unsigned short NewVer; int cmd; int i; char buf[30]; sutWLanStatus.ServerOfflineCt=0; sprintf(buf,"[WL]Recv<<%d\r\n",len); SlwTrace(DEBUG,buf); //FoTa升级接收数据处理 if(sutFotaPara.fotaStatus!=FOTA_END){ FoTaRecvData(pData,len); return; } //正常应用接收数据处理 cmd=CheckPacket(pData,len); if(cmd<0){ sprintf(buf,"[WL]CheckPacket Err=%d\r\n",cmd); SlwTrace(DEBUG,buf); return; } switch(cmd) { case 0x8200://上传应答 //pData=8001 0005 000000000000 0000 01 02 03 04 86 // ID 属性 设备编号 流水号 结果 红外使能 摄像头使能 复位使能 校验 SlwTrace(DEBUG,"[WL]<0 未成功需要继续等N分钟再重新登陆 sutWLanStatus.UnauthorizedCt=(unsigned short)pData[18]; if(sutWLanStatus.UnauthorizedCt>0){ sutWLanStatus.UnauthorizedCt*=60; SlwTrace(DEBUG,"Unauthorized!\r\n"); sprintf(buf,"UCt=%d\r\n",sutWLanStatus.UnauthorizedCt); SlwTrace(DEBUG,buf); } if(pData[19]==1){//使能升级 NewVer=((unsigned short)pData[20]<<8)|pData[21]; if(NewVer!=0 && NewVer!=sutProductPara.SoftwareVer && sutModemStatus.FoTaGetFileInfoCt<5){ sprintf(buf,"[WL]CurVer=%d NewVer=%d\r\n",sutProductPara.SoftwareVer,NewVer ); SlwTrace(DEBUG,buf); SlwTrace(DEBUG,"[WL]Upgrade now!\r\n"); sutFotaPara.targetVersion=NewVer; sutFotaPara.fotaStatus=FOTA_GET_FILEINFO; Disconnect2Server(); sutWLanStatus.Step=WL_STEP_CONNETING; return; }else{ sutWLanStatus.FoTaGetFileInfoCt=0; } }else sutWLanStatus.FoTaGetFileInfoCt=0; UploadInterval=((unsigned short)pData[22]<<8)|pData[23]; SamplingInterval=((unsigned short)pData[24]<<8)|pData[25]; if((sutDeviceConfig.UploadInterval!=UploadInterval&& UploadInterval>=5) || (sutDeviceConfig.SamplingInterval!=SamplingInterval && SamplingInterval>=5)){ sutDeviceConfig.UploadInterval=UploadInterval; sutDeviceConfig.SamplingInterval=SamplingInterval; SaveDeviceConfigToFlash(); } break; } } void WireLanInit(void) { uint8_t memsize[2][8] = {{2,2,2,2,2,2,2,2},{2,2,2,2,2,2,2,2}}; W5500_PMODE_CONFIG(); W5500_RESET_CONFIG(); SPI_Configuration();//Config SPI reg_wizchip_cris_cbfunc(SPI_CrisEnter, SPI_CrisExit); //注册临界区函数 #if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_ reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect);//注册SPI片选信号函数 #elif _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_ reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect); // CS must be tried with LOW. #else #if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SIP_) != _WIZCHIP_IO_MODE_SIP_ #error "Unknown _WIZCHIP_IO_MODE_" #else reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect); #endif #endif /* SPI Read & Write callback function */ reg_wizchip_spi_cbfunc(SPI_ReadByte, SPI_WriteByte); //注册读写函数 /* WIZCHIP SOCKET Buffer initialize */ if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memsize) == -1){ SlwTrace(DEBUG,"WIZCHIP Initialized fail.\r\n"); GPIO_ResetBits(GPIOB,GPIO_Pin_2);//set W5500 Reset os_dly_wait(6000); } } void WLNextStep(WLAN_STEP step) { sutWLanStatus.StepCt=0; sutWLanStatus.Step=step; } int WLanRecvProcess(void) { int8_t flag=1; int ret; ret=recv(SOCK_TCPS_APP1,gDATABUF, sizeof(gDATABUF)); if(ret>0)WiredLanRecv(gDATABUF,ret); return ret; } /******************************************************************* *WiredLanTask *有线网络任务 ********************************************************************/ __task void WiredLanTask(void) { static unsigned long lastTick=100; unsigned long curTick; static unsigned short susSendUploadCt=0; static unsigned char sucSendTickCt=0; static unsigned char sucSendWaitAckCt=0;//发送后等待ACK计数器 char tracebuf[50]; static uint8_t TraceCt=0; uint8_t tmp; int r; // int32_t ret = 0; // uint8_t flag=1; SlwTrace(DEBUG,"WiredLanTask Start...\r\n"); memset(&sutWLanStatus,0,sizeof(SUT_WL_STATUS)); while(1){ if(++TraceCt>2)TraceCt=0; switch(sutWLanStatus.Step) { case WL_STEP_INIT: if(TraceCt==1)SlwTrace(DEBUG,"[WL_INIT]\r\n"); WireLanInit(); WLNextStep(WL_STEP_GET_PHYLINK); break; case WL_STEP_GET_PHYLINK://检查IC是否工作(启动后需要插入网线才工作) if(TraceCt==1)SlwTrace(DEBUG,"[WL_PHYLINK]\r\n"); os_dly_wait(100); if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1){ SlwTrace(DEBUG,"Unknown PHY Link stauts.\r\n"); if(++sutWLanStatus.StepCt>6000)WLNextStep(WL_STEP_INIT); } if(PHY_LINK_ON==tmp){ network_init(); WLNextStep(WL_STEP_CK); }else if(++sutWLanStatus.StepCt>30000)WLNextStep(WL_STEP_INIT); break; case WL_STEP_CK://持续检查网线是否插入 if(TraceCt==1)SlwTrace(DEBUG,"[WL_CK]\r\n"); os_dly_wait(100); tmp=getPHYCFGR(); if((tmp&PHYCFGR_LNK_ON)==PHYCFGR_LNK_ON){ gWIZNETINFO.ip[0]=0;gWIZNETINFO.ip[1]=0;gWIZNETINFO.ip[2]=0;gWIZNETINFO.ip[3]=0; //DHCP client initialization DHCP_init(SOCK_UDPS_DHCP,gDATABUF);//DHCP_init(SOCK_UDPS_DHCP,DHCP_MSG_BUF); //Register DHCP call back function reg_dhcp_cbfunc(cb_ip_assign,cb_ip_update,cb_ip_conflict); WLNextStep(WL_STEP_DHCP); } else if(++sutWLanStatus.StepCt>30000)WLNextStep(WL_STEP_GET_PHYLINK); break; case WL_STEP_DHCP: os_dly_wait(1); DHCP_run(); //控制一秒执行一次 curTick=os_time_get(); if(curTick>lastTick){ lastTick=curTick+100; }else continue; if(TraceCt==1)SlwTrace(DEBUG,"[WL_DHCP]\r\n"); DHCP_time_handler(); if(gWIZNETINFO.ip[0]!=0)WLNextStep(WL_STEP_IDEL); else if(++sutWLanStatus.StepCt>3000)WLNextStep(WL_STEP_IDEL); break; case WL_STEP_IDEL: if(TraceCt==1)SlwTrace(DEBUG,"[WL_IDEL]\r\n"); os_dly_wait(100); //IP为0 不登陆,需要等4G获取域名解析到IP才连接服务器 if(sutServerIp.AppServerIP[0]==0){ continue; } //4G离线时间超过125秒才登陆服务器 if(sutModemStatus.ServerOfflineCt>WLAN_CONNECT_AFTER_4G_TIME){ WLNextStep(WL_STEP_CONNETING); } break; case WL_STEP_CONNETING: if(TraceCt==1)SlwTrace(DEBUG,"[WL_CONNETING]\r\n"); os_dly_wait(100); //连接服务器 if(sutFotaPara.fotaStatus!=FOTA_END){//远程升级 r=Connect2Server(1); }else{//正常 r=Connect2Server(0); } if(r){ sutWLanStatus.CmdNum=sutWLanStatus.RecvCmdNum+5;//保证不相等 sutModemStatus.CtrlReSendCt=5;//使进入WL_STEP_LOGIN后马上发送 WLNextStep(WL_STEP_LOGIN); }else{ //5秒一次,连接10次不成功, if(++sutWLanStatus.StepCt>10)WLNextStep(WL_STEP_CK); else os_dly_wait(500); } break; case WL_STEP_LOGIN: os_dly_wait(1); r=WLanRecvProcess(); if(r<0){ sprintf(tracebuf,"[WL]Recv Err=%d\r\n",r); SlwTrace(DEBUG,tracebuf); Disconnect2Server(); WLNextStep(WL_STEP_CONNETING); continue; }else if(r>0)continue; //控制一秒执行一次 curTick=os_time_get(); if(curTick>lastTick){ lastTick=curTick+100; }else continue; SlwTrace(DEBUG,"[WL_LOGIN]\r\n"); //远程升级 if(sutFotaPara.fotaStatus==FOTA_GET_FILEINFO){ if(FoTaGetFileInfo(1)<0){ Disconnect2Server(); WLNextStep(WL_STEP_CONNETING); continue; } if(++sutWLanStatus.CtrlReSendCt>5){//连续发几次都收不到服务器应答,退出升级 sutWLanStatus.CtrlReSendCt=0; sutFotaPara.fotaStatus=FOTA_END; Disconnect2Server(); WLNextStep(WL_STEP_CONNETING); continue; } }else if(sutFotaPara.fotaStatus==FOTA_GET_FILEDATA){ sutFotaPara.getFileInfoCt=0; if(++sutFotaPara.reSendCt>FOTA_RE_SEND_CT_MAX){ sutFotaPara.reSendCt=0; if(FoTaGetFileData(1)<0){ Disconnect2Server(); WLNextStep(WL_STEP_CONNETING); continue; } } }else{//sutFotaPara.fotaStatus==FOTA_END //----正常工作 if(sutWLanStatus.CmdNum!=sutWLanStatus.RecvCmdNum){ if(++sutWLanStatus.CtrlReSendCt>5){ sutWLanStatus.CtrlReSendCt=0; r=SendLogin2Server(); if(r<=0){ Disconnect2Server(); WLNextStep(WL_STEP_CONNETING); continue; } } }else{ if(sutWLanStatus.UnauthorizedCt>0){ sutWLanStatus.UnauthorizedCt--; if(sutWLanStatus.UnauthorizedCt==0){ sutWLanStatus.CmdNum=sutWLanStatus.RecvCmdNum+1; } }else{ sutWLanStatus.Step=WL_STEP_UPLOAD; sutWLanStatus.CtrlIntervalSendCt=sutDeviceConfig.UploadInterval; } } } break; case WL_STEP_UPLOAD: os_dly_wait(1); r=WLanRecvProcess(); if(r<0){ sprintf(tracebuf,"[WL]Recv Err=%d\r\n",r); SlwTrace(DEBUG,tracebuf); Disconnect2Server(); WLNextStep(WL_STEP_CONNETING); continue; }else if(r>0)continue; //控制一秒执行一次 curTick=os_time_get(); if(curTick>lastTick){ lastTick=curTick+100; }else continue; if(TraceCt==1)SlwTrace(DEBUG,"[WL_UPLOAD]\r\n"); if(++sutWLanStatus.CtrlIntervalSendCt>=sutDeviceConfig.UploadInterval || sutTestData.TcUpdated){ sutWLanStatus.CtrlIntervalSendCt=0; sutWLanStatus.CmdNum++; sutTestData.TcUpdated=0; sutWLanStatus.CtrlReSendCt=3; } if(sutWLanStatus.CmdNum!=sutWLanStatus.RecvCmdNum){ if(++sutWLanStatus.CtrlReSendCt>3){ sutWLanStatus.CtrlReSendCt=0; SendCurPosition2Server(); } } if(sutFotaPara.fotaStatus==FOTA_END && sutModemStatus.ServerOfflineCtWD Send %d>\r\n",len); SlwTrace(DEBUG,buf); //------------------------------- //sutModemStatus.TcpSendTimeCt++; r=send(SOCK_TCPS_APP1,data,len); switch(r){ case SOCKERR_TIMEOUT://- Timeout occurred \n SlwTrace(DEBUG,"err:SOCKERR_TIMEOUT\r\n"); break; case SOCKERR_SOCKMODE://Invalid operation in the socket \n SlwTrace(DEBUG,"err:SOCKERR_SOCKMODE\r\n"); break; case SOCKERR_SOCKNUM://Invalid socket number \n SlwTrace(DEBUG,"err:SOCKERR_SOCKNUM\r\n"); break; case SOCKERR_DATALEN://zero data length \n SlwTrace(DEBUG,"err:SOCKERR_DATALEN\r\n"); break; case SOCK_BUSY://Socket is busy. SlwTrace(DEBUG,"err:SOCK_BUSY\r\n"); break; } if(sutDeviceConfig.DebugPrintEn != 0 && r>0){ snprintf(buf,sizeof(buf),"Send[%d/%d] OK!\r\n",r,len); SlwTrace(DEBUG,buf); } return r; } /* 发登陆包 成功 >0 失败 <=0 */ int SendLogin2Server(void) { char buf[20]; unsigned short len; len=PacketLogin(sutWLanStatus.CmdNum); sprintf(buf,"[WL]SLogin>>%d\r\n",len); SlwTrace(DEBUG,buf); if(len==0)return -20; return WiredSendTcpData(g_ucPropacketBuf,len); } /* 发当前点位置包 成功 >0 失败 <=0 */ int SendCurPosition2Server(void) { char buf[20]; unsigned short i,len; SUT_POSITION sutPosition; memset(&sutPosition,0,sizeof(SUT_POSITION)); if(sutGpsInfo.isGpsValid)sutPosition.Status.GNSS=1; else sutPosition.Status.GNSS=0; sutPosition.Status.ACC=1; sutPosition.Status.BD=sutGpsInfo.isBDWork; sutPosition.Status.GPS=sutGpsInfo.isGpsWork; sutPosition.Status.West=sutGpsInfo.West; sutPosition.Status.South=sutGpsInfo.South; sutPosition.Latitude=sutGpsInfo.Latitude;//22620926;//114035268; //114.035268 sutPosition.Longitude=sutGpsInfo.Longitude; //114035268;//22620926; //22.620926 sutPosition.Speed=sutGpsInfo.Speed;//0; sutPosition.Aspect=sutGpsInfo.Aspect;//123; sutPosition.Altitude=sutGpsInfo.Altitude; RTC_Get(sutPosition.Time); sutPosition.ExtraMsgId=0x3A;//RT231固定3A sutPosition.NetMode=2;//WL sutPosition.CSQ =0; sutPosition.Infrared=sutTestData.Infrared; sutPosition.Camera=sutTestData.Camera; for(i=0;i>%d\r\n",len); SlwTrace(DEBUG,buf); return WiredSendTcpData(g_ucPropacketBuf,len); }