// //--tested, working--// //bit of a misnomer. This waits to receive a packet and then stores it in a buffer //it is important that this is called before any of the read or available commands //are called. This does the actual work. Read, peek, etc. are just organizational. // int WiFiUDP::parsePacket() { // //make sure we actually have a socket // if (_socketIndex == NO_SOCKET_AVAIL) { return 0; } // //the sl_select command blocks until something interesting happens or //it times out (current timeout set for 10 ms, the minimum) // SlTimeval_t timeout; timeout.tv_sec = 0; timeout.tv_usec = 10000; int socketHandle = WiFiClass::_handleArray[_socketIndex]; SlFdSet_t readSocketHandles, errorSocketHandles; SL_FD_ZERO(&readSocketHandles); SL_FD_ZERO(&errorSocketHandles); SL_FD_SET(socketHandle, &readSocketHandles); SL_FD_SET(socketHandle, &errorSocketHandles); int iRet = sl_Select(socketHandle+1, &readSocketHandles, NULL, &errorSocketHandles, &timeout); if (iRet <= 0) { return 0; } // //Since we've reached this point, the sl_select command has indicated //that either we're going to get an error, or an immediate read // SlSockAddrIn_t address = {0}; int AddrSize = sizeof(address); int bytes = sl_RecvFrom(socketHandle, rx_buf, UDP_RX_PACKET_MAX_SIZE, NULL, (SlSockAddr_t*)&address, (SlSocklen_t*)&AddrSize); // //store the sender's address (sl_HtonX reorders bits to processor order) //!! Although this follows some examples (upd_socket), it goes against the //!! API documentation. The API maintains that the 5th arg to RecvFrom is not in/out // _remoteIP = address.sin_addr.s_addr; _remotePort = sl_Htons(address.sin_port); // //If an error occured, return 0, otherwise return the byte length of the packet //and reset the buffer index counter and fill level variables // if (bytes < 0) { rx_fillLevel = 0; return 0; } else { rx_currentIndex = 0; rx_fillLevel = bytes; return bytes; } }
/* * ::sendto() */ int recvfrom(int s, void *buffer, size_t length, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { SlSockAddr_t sl_sockaddr; SlSocklen_t sl_addrlen = sizeof(SlSockAddr_t); int result = sl_RecvFrom(s, buffer, length, flags, &sl_sockaddr, &sl_addrlen); if (src_addr != NULL) { switch (sl_sockaddr.sa_family) { default: errno = EAFNOSUPPORT; return -1; case SL_AF_INET: { if (sizeof(struct sockaddr_in) < *addrlen) { break; } struct sockaddr_in *addr_in = (struct sockaddr_in *)src_addr; SlSockAddrIn_t *sl_addr_in = (SlSockAddrIn_t*)&sl_sockaddr; addr_in->sin_family = AF_INET; addr_in->sin_port = sl_addr_in->sin_port; addr_in->sin_addr.s_addr = sl_addr_in->sin_addr.s_addr; break; } } } if (result < 0) { switch (result) { default: errno = EINVAL; break; case SL_POOL_IS_EMPTY: usleep(10000); /* fall through */ case SL_EAGAIN: errno = EAGAIN; break; } return -1; } return result; }
// "Embedded Systems: Real Time Interfacing to ARM Cortex M Microcontrollers", // ISBN: 978-1463590154, Jonathan Valvano, copyright (c) 2014, Volume 2, Program 11.3 int main3(void){ UINT8 IsDHCP = 0; _NetCfgIpV4Args_t ipV4; SlSockAddrIn_t Addr, LocalAddr; UINT16 AddrSize = 0; INT16 SockID = 0; INT16 Status = 1; // ok UINT32 data; unsigned char len = sizeof(_NetCfgIpV4Args_t); initClk(); // PLL 50 MHz, ADC needs PPL active 16 ST7735_InitR(INITR_REDTAB); // Initialize 17 ST7735_OutString("Internet of Things\n"); // 18 ST7735_OutString("Embedded Systems\n"); // 19 ST7735_OutString("Vol. 2, Valvano"); // 20 ST7735_PlotClear(0,4095); // range from 0 to 4095 21 sl_Start(0, 0, 0); // Initializing the CC3100 device 22 WlanConnect(); // connect to AP 23 sl_NetCfgGet(SL_IPV4_STA_P2P_CL_GET_INFO,&IsDHCP,&len, // 24 (unsigned char *)&ipV4); // 25 LocalAddr.sin_family = SL_AF_INET; // 26 LocalAddr.sin_port = sl_Htons((UINT16)PORT_NUM); // 27 LocalAddr.sin_addr.s_addr = 0; // 28 AddrSize = sizeof(SlSockAddrIn_t); // 29 while(1){ SockID = sl_Socket(SL_AF_INET,SL_SOCK_DGRAM, 0); // 31 Status = sl_Bind(SockID, (SlSockAddr_t *)&LocalAddr, // 32 AddrSize); // 33 Status = sl_RecvFrom(SockID, uBuf, BUF_SIZE, 0, // 34 (SlSockAddr_t *)&Addr, (SlSocklen_t*)&AddrSize );// 35 if((uBuf[0]==ATYPE)&&(uBuf[1]== '=')){ // 36 int i,bOk; uint32_t place; // 37 data = 0; bOk = 1; // 38 i=4; // ignore possible negative sign 39 for(place = 1000; place; place = place/10){ // 40 if((uBuf[i]&0xF0)==0x30){ // ignore spaces 41 data += place*(uBuf[i]-0x30); // 42 }else{ // 43 if((uBuf[i]&0xF0)!= ' '){ // 44 bOk = 0; // 45 } // 46 } // 47 i++; // 48 } // 49 if(bOk){ // 50 ST7735_PlotLine(data); // 51 ST7735_PlotNextErase(); // 51 } } } }
//***************************************************************************** // //! \brief Task Created by main fucntion. This task creates a udp server and //! wait for packets. Upon receiving the packet, signals the other task. //! //! \param pvParameters is a general void pointer (not used here). //! //! \return none // //***************************************************************************** void UDPServerTask(void *pvParameters) { unsigned char ucSyncMsg; unsigned char ucQueueMsg = 3; int iSockDesc = 0; int iRetVal = 0; sockaddr_in sLocalAddr; sockaddr_in sClientAddr; unsigned int iAddrSize = 0; // // waiting for the other task to start simplelink and connection to the AP // osi_MsgQRead(&g_tConnectionFlag, &ucSyncMsg, OSI_WAIT_FOREVER); osi_MsgQDelete(&g_tConnectionFlag); // // configure the Server // sLocalAddr.sin_family = SL_AF_INET; sLocalAddr.sin_port = sl_Htons((unsigned short)APP_UDP_PORT); sLocalAddr.sin_addr.s_addr = 0; iAddrSize = sizeof(sockaddr_in); // // creating a UDP socket // iSockDesc = sl_Socket(SL_AF_INET,SL_SOCK_DGRAM, 0); if(iSockDesc < 0) { UART_PRINT("sock error\n\r"); LOOP_FOREVER(); } // // binding the socket // iRetVal = sl_Bind(iSockDesc, (SlSockAddr_t *)&sLocalAddr, iAddrSize); if(iRetVal < 0) { UART_PRINT("bind error\n\r"); LOOP_FOREVER(); } while(FOREVER) { // // waiting on a UDP packet // iRetVal = sl_RecvFrom(iSockDesc, g_cBuffer, BUFF_SIZE, 0, ( SlSockAddr_t *)&sClientAddr, (SlSocklen_t*)&iAddrSize ); if(iRetVal > 0) { // // signal the other task about receiving the UDP packet // osi_MsgQWrite(&g_tWkupSignalQueue, &ucQueueMsg, OSI_WAIT_FOREVER); } else { UART_PRINT("recv error\n\r"); LOOP_FOREVER(); } } }
int main(void){ UINT8 IsDHCP = 0; _NetCfgIpV4Args_t ipV4; SlSockAddrIn_t Addr; SlSockAddrIn_t LocalAddr; UINT16 AddrSize = 0; INT16 SockID = 0; INT16 Status = 1; // ok UINT32 data; unsigned char len = sizeof(_NetCfgIpV4Args_t); stopWDT(); // Stop WDT initClk(); // PLL 50 MHz, ADC needs PPL active Board_Init(); // initialize LaunchPad I/O ConfigureUART(); // Initialize the UART. UARTprintf("Section 11.4 IoT example, Volume 2 Real-time interfacing\n"); UARTprintf("This node is configured to receive UDP packets\n"); UARTprintf("This node should be at IP: %d.%d.%d.%d Port: %d\n\n", SL_IPV4_BYTE(IP_ADDR,3), SL_IPV4_BYTE(IP_ADDR,2), SL_IPV4_BYTE(IP_ADDR,1), SL_IPV4_BYTE(IP_ADDR,0),PORT_NUM); ST7735_InitR(INITR_REDTAB); ST7735_OutString("Internet of Things\n"); ST7735_OutString("Embedded Systems\n"); ST7735_OutString("Vol. 2, Valvano"); ST7735_PlotClear(0,4095); // range from 0 to 4095 while(1){ sl_Start(0, 0, 0); /* Initializing the CC3100 device */ /* Connecting to WLAN AP - Set with static parameters defined at the top After this call we will be connected and have IP address */ WlanConnect(); // connect to AP /* Read the IP parameter */ sl_NetCfgGet(SL_IPV4_STA_P2P_CL_GET_INFO,&IsDHCP,&len,(unsigned char *)&ipV4); UARTprintf("This node is at IP: %d.%d.%d.%d\n", SL_IPV4_BYTE(ipV4.ipV4,3), SL_IPV4_BYTE(ipV4.ipV4,2), SL_IPV4_BYTE(ipV4.ipV4,1), SL_IPV4_BYTE(ipV4.ipV4,0)); while(Status > 0){ UARTprintf("\nReceiving a UDP packet ..."); LocalAddr.sin_family = SL_AF_INET; LocalAddr.sin_port = sl_Htons((UINT16)PORT_NUM); LocalAddr.sin_addr.s_addr = 0; AddrSize = sizeof(SlSockAddrIn_t); SockID = sl_Socket(SL_AF_INET,SL_SOCK_DGRAM, 0); if( SockID < 0 ){ UARTprintf("SockIDerror\n"); Status = -1; // error }else{ Status = sl_Bind(SockID, (SlSockAddr_t *)&LocalAddr, AddrSize); if( Status < 0 ){ sl_Close(SockID); UARTprintf("Sock Bind error\n"); }else{ Status = sl_RecvFrom(SockID, uBuf, BUF_SIZE, 0, (SlSockAddr_t *)&Addr, (SlSocklen_t*)&AddrSize ); if( Status <= 0 ){ sl_Close(SockID); UARTprintf("Receive error %d ",Status); }else{ LED_Toggle(); sl_Close(SockID); UARTprintf("ok %s ",uBuf); if((uBuf[0]==ATYPE)&&(uBuf[1]== '=')){ int i,bOk; uint32_t place; data = 0; bOk = 1; i=4; // ignore possible negative sign for(place = 1000; place; place = place/10){ if((uBuf[i]&0xF0)==0x30){ // ignore spaces data += place*(uBuf[i]-0x30); }else{ if((uBuf[i]&0xF0)!= ' '){ bOk = 0; } } i++; } if(bOk){ ST7735_PlotLine(data); ST7735_PlotNextErase(); } } } } } ROM_SysCtlDelay(ROM_SysCtlClockGet() / 25); // 120ms } } }
//**************************************************************************** // //! \brief Opening a UDP server side socket and receiving data //! //! This function opens a UDP socket in Listen mode and waits for an incoming //! UDP connection. //! If a socket connection is established then the function will try to //! read 1000 UDP packets from the connected client. //! //! \param[in] port number on which the server will be listening on //! //! \return 0 on success, Negative value on Error. // //**************************************************************************** int BsdUdpServer(unsigned short usPort) { SlSockAddrIn_t sAddr; SlSockAddrIn_t sLocalAddr; int iCounter; int iAddrSize; int iSockID; int iStatus; long lLoopCount = 0; short sTestBufLen; // filling the buffer for (iCounter=0 ; iCounter<BUF_SIZE ; iCounter++) { g_cBsdBuf[iCounter] = (char)(iCounter % 10); } sTestBufLen = BUF_SIZE; //filling the UDP server socket address sLocalAddr.sin_family = SL_AF_INET; sLocalAddr.sin_port = sl_Htons((unsigned short)usPort); sLocalAddr.sin_addr.s_addr = 0; iAddrSize = sizeof(SlSockAddrIn_t); // creating a UDP socket iSockID = sl_Socket(SL_AF_INET,SL_SOCK_DGRAM, 0); if( iSockID < 0 ) { // error ASSERT_ON_ERROR(UCP_SERVER_FAILED); } // binding the UDP socket to the UDP server address iStatus = sl_Bind(iSockID, (SlSockAddr_t *)&sLocalAddr, iAddrSize); if( iStatus < 0 ) { // error sl_Close(iSockID); ASSERT_ON_ERROR(UCP_SERVER_FAILED); } // no listen or accept is required as UDP is connectionless protocol /// waits for 1000 packets from a UDP client while (lLoopCount < g_ulPacketCount) { iStatus = sl_RecvFrom(iSockID, g_cBsdBuf, sTestBufLen, 0, ( SlSockAddr_t *)&sAddr, (SlSocklen_t*)&iAddrSize ); if( iStatus < 0 ) { // error sl_Close(iSockID); ASSERT_ON_ERROR(UCP_SERVER_FAILED); } lLoopCount++; } UART_PRINT("Recieved %u packets successfully\n\r",g_ulPacketCount); //closing the socket after receiving 1000 packets sl_Close(iSockID); return SUCCESS; }
//***************************************************************************** // //! \brief Get the NTP time //! //! \param none //! //! \return void //! \note //! \warning // //***************************************************************************** uint8_t GetTime(struct tm * decodedTime) { const char * g_acSNTPserver = "wwv.nist.gov"; //Add any one of the above servers unsigned long ulDestinationIP; int iSocketDesc; long lRetVal; char cDataBuf[48]; int iAddrSize; SlSockAddr_t sAddr; SlSockAddrIn_t sLocalAddr; // // Create UDP socket // iSocketDesc = sl_Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(iSocketDesc < 0) { ERR_PRINT(iSocketDesc); return 0; } //g_sAppData.iSockID = iSocketDesc; UART_PRINT("Socket created\n\r"); // // Get the NTP server host IP address using the DNS lookup // lRetVal = Network_IF_GetHostIP((char*)g_acSNTPserver, &ulDestinationIP); if( lRetVal >= 0) { struct SlTimeval_t timeVal; timeVal.tv_sec = SERVER_RESPONSE_TIMEOUT; // Seconds timeVal.tv_usec = 0; // Microseconds. 10000 microseconds resolution lRetVal = sl_SetSockOpt(iSocketDesc,SL_SOL_SOCKET,SL_SO_RCVTIMEO,\ (unsigned char*)&timeVal, sizeof(timeVal)); if(lRetVal < 0) { ERR_PRINT(lRetVal); // // Close the socket // close(iSocketDesc); UART_PRINT("Socket closed\n\r"); return 0; } // // Send a query ? to the NTP server to get the NTP time // memset(cDataBuf, 0, sizeof(cDataBuf)); cDataBuf[0] = '\x1b'; sAddr.sa_family = AF_INET; // the source port sAddr.sa_data[0] = 0x00; sAddr.sa_data[1] = 0x7B; // UDP port number for NTP is 123 sAddr.sa_data[2] = (char)((ulDestinationIP>>24)&0xff); sAddr.sa_data[3] = (char)((ulDestinationIP>>16)&0xff); sAddr.sa_data[4] = (char)((ulDestinationIP>>8)&0xff); sAddr.sa_data[5] = (char)(ulDestinationIP&0xff); lRetVal = sl_SendTo(iSocketDesc, cDataBuf, sizeof(cDataBuf), 0, &sAddr, sizeof(sAddr)); if (lRetVal != sizeof(cDataBuf)) { // could not send SNTP request //ASSERT_ON_ERROR(SERVER_GET_TIME_FAILED); return 0; } // // Wait to receive the NTP time from the server // sLocalAddr.sin_family = SL_AF_INET; sLocalAddr.sin_port = 0; sLocalAddr.sin_addr.s_addr = 0; lRetVal = sl_Bind(iSocketDesc, (SlSockAddr_t *)&sLocalAddr, sizeof(SlSockAddrIn_t)); iAddrSize = sizeof(SlSockAddrIn_t); lRetVal = sl_RecvFrom(iSocketDesc, cDataBuf, sizeof(cDataBuf), 0, (SlSockAddr_t *)&sLocalAddr, (SlSocklen_t*)&iAddrSize); //ASSERT_ON_ERROR(lRetVal); if(lRetVal < 0) { UART_PRINT("Server Get Time failed\n\r"); // // Close the socket // close(iSocketDesc); UART_PRINT("Socket closed\n\r"); return 0; } // We received the time DecodeSNTPTime(cDataBuf, decodedTime); } else {
//**************************************************************************** // MAIN FUNCTION //**************************************************************************** int main(void) { long lRetVal; char cCmdBuff[20]; signed char cCmd = APP_SLEEP; SlSockAddrIn_t sAddr; SlSockAddrIn_t sLocalAddr; SlSockAddrIn_t sBrdAddr; int iCounter; int iAddrSize; int iSockID; int iStatus; long lLoopCount = 0; short sTestBufLen; struct SlTimeval_t timeVal; // // Board Initialization // BoardInit(); // // uDMA Initialization // UDMAInit(); // // Configure the pinmux settings for the peripherals exercised // Note: pinmux has been modified after the output from pin mux tools // to enable sleep clk for the peripherals exercised // PinMuxConfig(); // // Initialize the platform // platform_init(); // // Initialise the UART terminal // InitTerm(); // // Display banner // DisplayBanner(); // // starting the simplelink // lRetVal = sl_Start(NULL, NULL, NULL); if (lRetVal < 0) { UART_PRINT("Failed to start the device \n\r"); LOOP_FOREVER(); } // // Swtich to STA mode if device is not // SwitchToStaMode(lRetVal); // // set connection policy // sl_WlanPolicySet(SL_POLICY_CONNECTION, SL_CONNECTION_POLICY(0, 0, 0, 0, 0), NULL, 0); // // Set the power management policy of NWP // lRetVal = sl_WlanPolicySet(SL_POLICY_PM, SL_NORMAL_POLICY, NULL, 0); UART_PRINT("Trying to Connect to AP: %s ...\r\n",SSID_NAME); // //Connecting to WLAN AP // lRetVal = WlanConnect(); if(lRetVal < 0) { UART_PRINT("Failed to establish connection w/ an AP \n\r"); LOOP_FOREVER(); } // filling the buffer for (iCounter=0 ; iCounter<BUF_SIZE ; iCounter++) { g_cBsdBuf[iCounter] = (char)(iCounter % 10); } sTestBufLen = BUF_SIZE; //filling the UDP server socket address sLocalAddr.sin_family = SL_AF_INET; sLocalAddr.sin_port = sl_Htons((unsigned short)PORT_NUM); sLocalAddr.sin_addr.s_addr = 0; //filling the UDP server socket address sBrdAddr.sin_family = SL_AF_INET; sBrdAddr.sin_port = sl_Htons((unsigned short)PORT_NUM); sBrdAddr.sin_addr.s_addr = sl_Htonl((unsigned int)g_ulDestinationIp); iAddrSize = sizeof(SlSockAddrIn_t); // creating a UDP socket iSockID = sl_Socket(SL_AF_INET,SL_SOCK_DGRAM, 0); /* setting time out for socket recv */ timeVal.tv_sec = 5; // Seconds timeVal.tv_usec = 0; // Microseconds. 10000 microseconds resolution sl_SetSockOpt(iSockID,SL_SOL_SOCKET,SL_SO_RCVTIMEO, (_u8 *)&timeVal, sizeof(timeVal)); // binding the UDP socket to the UDP server address iStatus = sl_Bind(iSockID, (SlSockAddr_t *)&sLocalAddr, iAddrSize); if( iStatus < 0 ) { // error sl_Close(iSockID); ASSERT_ON_ERROR(iStatus); } // // setting Apps power policy // lp3p0_setup_power_policy(POWER_POLICY_STANDBY); UART_PRINT("enter one of the following command:\n\r"); UART_PRINT("sleep - for putting the system into LPDS mode\n\r"); UART_PRINT(" GPIO 13 and timer(5 sec) are the wk source configured\n\r"); UART_PRINT("recv - for receiving 1000 UDP packets\n\r"); UART_PRINT("send - for broadcasting 1000 UDP packets\n\r"); do{ UART_PRINT("cmd#"); // // get cmd over UART // GetCmd(cCmdBuff, 20); // // parse the command // ParseCmd(cCmdBuff, &cCmd); if(cCmd == APP_SLEEP) { // // set timer and gpio as wake src // set_rtc_as_wk_src(WK_LPDS, LPDS_DUR_SEC, false); set_gpio_as_wk_src(WK_LPDS, GPIO_SRC_WKUP, PRCM_LPDS_FALL_EDGE); cc_idle_task_pm(); } else if(cCmd == APP_RECV) { lLoopCount = 0; /// waits for 1000 packets from a UDP client while (lLoopCount < g_ulPacketCount) { iStatus = sl_RecvFrom(iSockID, g_cBsdBuf, sTestBufLen, 0, ( SlSockAddr_t *)&sAddr, (SlSocklen_t*)&iAddrSize ); if( iStatus < 0 ) { //error break; } lLoopCount++; } UART_PRINT("Recieved %u packets successfully \n\r",lLoopCount); if(lLoopCount != g_ulPacketCount) { if(iStatus == SL_EAGAIN) { UART_PRINT("timed out\n\r"); } else { UART_PRINT("recv error: %d\n\r", iStatus); } } } else if(cCmd == APP_SEND) { lLoopCount = 0; // sending 1000 packets to the UDP server while (lLoopCount < g_ulPacketCount) { // sending packet iStatus = sl_SendTo(iSockID, g_cBsdBuf, sTestBufLen, 0, (SlSockAddr_t *)&sBrdAddr, iAddrSize); if( iStatus <= 0 ) { // error UART_PRINT("send error\n\r"); break; } lLoopCount++; } UART_PRINT("Sent %u packets successfully\n\r",lLoopCount); } }while(FOREVER); }
//***************************************************************************** // //! Gets the current time from the selected SNTP server //! //! \brief This function obtains the NTP time from the server. //! //! \param GmtDiffHr is the GMT Time Zone difference in hours //! \param GmtDiffMins is the GMT Time Zone difference in minutes //! //! \return 0 : success, -ve : failure //! //***************************************************************************** long GetSNTPTime(unsigned char ucGmtDiffHr, unsigned char ucGmtDiffMins) { /* NTP Packet Header: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |LI | VN |Mode | Stratum | Poll | Precision | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Root Delay | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Root Dispersion | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Reference Identifier | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | Reference Timestamp (64) | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | Originate Timestamp (64) | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | Receive Timestamp (64) | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | Transmit Timestamp (64) | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Key Identifier (optional) (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | | Message Digest (optional) (128) | | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ char cDataBuf[48]; long lRetVal = 0; int iAddrSize; // // Send a query to the NTP server to get the NTP time // memset(cDataBuf, 0, sizeof(cDataBuf)); cDataBuf[0] = '\x1b'; sAddr.sa_family = AF_INET; // the source port sAddr.sa_data[0] = 0x00; sAddr.sa_data[1] = 0x7B; // UDP port number for NTP is 123 sAddr.sa_data[2] = (char)((g_sAppData.ulDestinationIP>>24)&0xff); sAddr.sa_data[3] = (char)((g_sAppData.ulDestinationIP>>16)&0xff); sAddr.sa_data[4] = (char)((g_sAppData.ulDestinationIP>>8)&0xff); sAddr.sa_data[5] = (char)(g_sAppData.ulDestinationIP&0xff); lRetVal = sl_SendTo(g_sAppData.iSockID, cDataBuf, sizeof(cDataBuf), 0, &sAddr, sizeof(sAddr)); if (lRetVal != sizeof(cDataBuf)) { // could not send SNTP request hourSet = 25; // This will ensure we try to fetch time again //ASSERT_ON_ERROR(SERVER_GET_TIME_FAILED); } // // Wait to receive the NTP time from the server // sLocalAddr.sin_family = SL_AF_INET; sLocalAddr.sin_port = 0; sLocalAddr.sin_addr.s_addr = 0; if(g_sAppData.ulElapsedSec == 0) { lRetVal = sl_Bind(g_sAppData.iSockID, (SlSockAddr_t *)&sLocalAddr, sizeof(SlSockAddrIn_t)); } iAddrSize = sizeof(SlSockAddrIn_t); lRetVal = sl_RecvFrom(g_sAppData.iSockID, cDataBuf, sizeof(cDataBuf), 0, (SlSockAddr_t *)&sLocalAddr, (SlSocklen_t*)&iAddrSize); ASSERT_ON_ERROR(lRetVal); // // Confirm that the MODE is 4 --> server // if ((cDataBuf[0] & 0x7) != 4) // expect only server response { hourSet = 25; // This will ensure we try to fetch time again //ASSERT_ON_ERROR(SERVER_GET_TIME_FAILED); // MODE is not server, abort } else { unsigned char iIndex; // // Getting the data from the Transmit Timestamp (seconds) field // This is the time at which the reply departed the // server for the client // g_sAppData.ulElapsedSec = cDataBuf[40]; g_sAppData.ulElapsedSec <<= 8; g_sAppData.ulElapsedSec += cDataBuf[41]; g_sAppData.ulElapsedSec <<= 8; g_sAppData.ulElapsedSec += cDataBuf[42]; g_sAppData.ulElapsedSec <<= 8; g_sAppData.ulElapsedSec += cDataBuf[43]; // // seconds are relative to 0h on 1 January 1900 // g_sAppData.ulElapsedSec -= TIME2013; // // in order to correct the timezone // g_sAppData.ulElapsedSec += (ucGmtDiffHr * SEC_IN_HOUR); g_sAppData.ulElapsedSec += (ucGmtDiffMins * SEC_IN_MIN); g_sAppData.pcCCPtr = &g_sAppData.acTimeStore[0]; // // day, number of days since beginning of 2013 // g_sAppData.isGeneralVar = g_sAppData.ulElapsedSec/SEC_IN_DAY; memcpy(g_sAppData.pcCCPtr, g_acDaysOfWeek2013[g_sAppData.isGeneralVar%7], 3); g_sAppData.pcCCPtr += 3; *g_sAppData.pcCCPtr++ = '\x20'; // // month // g_sAppData.isGeneralVar %= 365; for (iIndex = 0; iIndex < 12; iIndex++) { g_sAppData.isGeneralVar -= g_acNumOfDaysPerMonth[iIndex]; if (g_sAppData.isGeneralVar < 0) break; } if(iIndex == 12) { iIndex = 0; } memcpy(g_sAppData.pcCCPtr, g_acMonthOfYear[iIndex], 3); g_sAppData.pcCCPtr += 3; *g_sAppData.pcCCPtr++ = '\x20'; // Set the Month Value dateTime.sl_tm_mon = iIndex + 1; // // date // restore the day in current month // g_sAppData.isGeneralVar += g_acNumOfDaysPerMonth[iIndex]; g_sAppData.uisCCLen = itoa(g_sAppData.isGeneralVar + 1, g_sAppData.pcCCPtr); g_sAppData.pcCCPtr += g_sAppData.uisCCLen; *g_sAppData.pcCCPtr++ = '\x20'; // Set the Date dateTime.sl_tm_day = g_sAppData.isGeneralVar + 1; // // time // g_sAppData.ulGeneralVar = g_sAppData.ulElapsedSec%SEC_IN_DAY; // number of seconds per hour g_sAppData.ulGeneralVar1 = g_sAppData.ulGeneralVar%SEC_IN_HOUR; // number of hours g_sAppData.ulGeneralVar /= SEC_IN_HOUR; g_sAppData.uisCCLen = itoa(g_sAppData.ulGeneralVar, g_sAppData.pcCCPtr); g_sAppData.pcCCPtr += g_sAppData.uisCCLen; *g_sAppData.pcCCPtr++ = ':'; // Set the hour dateTime.sl_tm_hour = g_sAppData.ulGeneralVar; // number of minutes per hour g_sAppData.ulGeneralVar = g_sAppData.ulGeneralVar1/SEC_IN_MIN; // Set the minutes dateTime.sl_tm_min = g_sAppData.ulGeneralVar; // number of seconds per minute g_sAppData.ulGeneralVar1 %= SEC_IN_MIN; g_sAppData.uisCCLen = itoa(g_sAppData.ulGeneralVar, g_sAppData.pcCCPtr); g_sAppData.pcCCPtr += g_sAppData.uisCCLen; *g_sAppData.pcCCPtr++ = ':'; g_sAppData.uisCCLen = itoa(g_sAppData.ulGeneralVar1, g_sAppData.pcCCPtr); g_sAppData.pcCCPtr += g_sAppData.uisCCLen; *g_sAppData.pcCCPtr++ = '\x20'; //Set the seconds dateTime.sl_tm_sec = g_sAppData.ulGeneralVar1; // // year // number of days since beginning of 2013 // g_sAppData.ulGeneralVar = g_sAppData.ulElapsedSec/SEC_IN_DAY; g_sAppData.ulGeneralVar /= 365; g_sAppData.uisCCLen = itoa(YEAR2013 + g_sAppData.ulGeneralVar, g_sAppData.pcCCPtr); g_sAppData.pcCCPtr += g_sAppData.uisCCLen; *g_sAppData.pcCCPtr++ = '\0'; //Set the year dateTime.sl_tm_year = 2013 + g_sAppData.ulGeneralVar; CLI_Write("Response from server: "); CLI_Write((unsigned char *)g_acSNTPserver); CLI_Write("\n\r"); CLI_Write((unsigned char *)g_sAppData.acTimeStore); CLI_Write("\n\r\n\r"); //Set time of the device for certificate verification. lRetVal = setDeviceTimeDate(); if(lRetVal < 0) { CLI_Write("Unable to set time in the device.\n\r"); return lRetVal; } } return SUCCESS; }