static void _SntpInit(TCPIP_NET_IF* pNewIf) { if(pSntpIf != 0) { if(pNewIf == pSntpIf) { // this interface is going away/re-initialized, etc if(sntpSocket != INVALID_UDP_SOCKET) { TCPIP_UDP_Close(sntpSocket); sntpSocket = INVALID_UDP_SOCKET; } pSntpIf = 0; sntpState = SM_HOME; ntpTimeStamp.llStamp = 0; ntpLastStampTick = 0; } } }//_SntpInit
void APP_Tasks( void ) { static IPV4_ADDR dwLastIP[2] = { {-1}, {-1} }; IPV4_ADDR ipAddr; int i; switch(appData.state) { case APP_TCPIP_WAIT_FOR_IP: // if the IP address of an interface has changed // display the new value on the system console nNets = TCPIP_STACK_NumberOfNetworksGet(); for (i = 0; i < nNets; i++) { netH = TCPIP_STACK_IndexToNet(i); ipAddr.Val = TCPIP_STACK_NetAddress(netH); if(dwLastIP[i].Val != ipAddr.Val) { dwLastIP[i].Val = ipAddr.Val; SYS_CONSOLE_MESSAGE(TCPIP_STACK_NetNameGet(netH)); SYS_CONSOLE_MESSAGE(" IP Address: "); SYS_CONSOLE_PRINT("%d.%d.%d.%d \r\n", ipAddr.v[0], ipAddr.v[1], ipAddr.v[2], ipAddr.v[3]); if (ipAddr.v[0] != 0 && ipAddr.v[0] != 169) // Wait for a Valid IP { appData.state = APP_TCPIP_OPENING_SERVER; } } } break; case APP_TCPIP_OPENING_SERVER: { SYS_CONSOLE_PRINT("Waiting for Client Connection on port: %d\r\n", SERVER_PORT); appData.socket = TCPIP_UDP_ServerOpen(IP_ADDRESS_TYPE_IPV4, SERVER_PORT, 0); if (appData.socket == INVALID_SOCKET) { SYS_CONSOLE_MESSAGE("Couldn't open server socket\r\n"); break; } appData.state = APP_TCPIP_WAIT_FOR_CONNECTION; } break; case APP_TCPIP_WAIT_FOR_CONNECTION: { if (!TCPIP_UDP_IsConnected(appData.socket)) { return; } else { // We got a connection appData.state = APP_TCPIP_SERVING_CONNECTION; SYS_CONSOLE_MESSAGE("Received a connection\r\n"); } } break; case APP_TCPIP_SERVING_CONNECTION: { if (!TCPIP_UDP_IsConnected(appData.socket)) { appData.state = APP_TCPIP_CLOSING_CONNECTION; SYS_CONSOLE_MESSAGE("Connection was closed\r\n"); break; } int16_t wMaxGet, wMaxPut, wCurrentChunk; uint16_t w, w2; uint8_t AppBuffer[32]; // Figure out how many bytes have been received and how many we can transmit. wMaxGet = TCPIP_UDP_GetIsReady(appData.socket); // Get UDP RX FIFO byte count wMaxPut = UDPIsPutReady(appData.socket); //SYS_CONSOLE_PRINT("\t%d bytes are available.\r\n", wMaxGet); if (wMaxGet == 0) { break; } if (wMaxPut < wMaxGet) { wMaxGet = wMaxPut; } // Process all bytes that we can // This is implemented as a loop, processing up to sizeof(AppBuffer) bytes at a time. // This limits memory usage while maximizing performance. Single byte Gets and Puts are a lot slower than multibyte GetArrays and PutArrays. wCurrentChunk = sizeof(AppBuffer); for(w = 0; w < wMaxGet; w += sizeof(AppBuffer)) { // Make sure the last chunk, which will likely be smaller than sizeof(AppBuffer), is treated correctly. if(w + sizeof(AppBuffer) > wMaxGet) wCurrentChunk = wMaxGet - w; // Transfer the data out of the TCP RX FIFO and into our local processing buffer. TCPIP_UDP_ArrayGet(appData.socket, AppBuffer, wCurrentChunk); SYS_CONSOLE_PRINT("\tReceived a message of '%s'\r\n", AppBuffer); // Perform the "ToUpper" operation on each data byte for(w2 = 0; w2 < wCurrentChunk; w2++) { i = AppBuffer[w2]; if(i >= 'a' && i <= 'z') { i -= ('a' - 'A'); AppBuffer[w2] = i; } else if(i == '\e') //escape { SYS_CONSOLE_MESSAGE("Connection was closed\r\n"); } } SYS_CONSOLE_PRINT("\tSending a messages '%s'\r\n", AppBuffer); // Transfer the data out of our local processing buffer and into the TCP TX FIFO. TCPIP_UDP_ArrayPut(appData.socket, AppBuffer, wCurrentChunk); TCPIP_UDP_Flush(appData.socket); appData.state = APP_TCPIP_CLOSING_CONNECTION; } } break; case APP_TCPIP_CLOSING_CONNECTION: { // Close the socket connection. TCPIP_UDP_Close(appData.socket); appData.state = APP_TCPIP_OPENING_SERVER; } break; default: break; } }
// sntp_manager.h bool TCPIP_SNTP_Client(TCPIP_NET_IF* pNetIf) { NTP_PACKET pkt; uint16_t w; DNS_RESULT dnsRes; static SYS_TICK SNTPTimer; if(pSntpIf != 0 && pNetIf != pSntpIf) { // not our job return false; } switch(sntpState) { case SM_HOME: sntpSocket = INVALID_UDP_SOCKET; pSntpIf = pSntpDefIf; if(!TCPIP_STACK_NetworkIsLinked(pSntpIf)) { pSntpIf = _TCPIPStackAnyNetLinked(true); } if(TCPIP_DNS_UsageBegin(pSntpIf) != DNS_RES_OK) { ntpLastError = SNTP_RES_NTP_DNS_ERR; break; } TCPIP_DNS_Resolve(NTP_SERVER, ntpConnection ==IP_ADDRESS_TYPE_IPV6 ? DNS_TYPE_AAAA : DNS_TYPE_A); sntpState++; break; case SM_WAIT_DNS: dnsRes = TCPIP_DNS_IsResolved(NTP_SERVER, &serverIP); if(dnsRes == DNS_RES_PENDING) { // ongoing operation; break; } else if(dnsRes < 0) { // some DNS error occurred; retry after waiting a while SNTPTimer = SYS_TICK_Get(); sntpState = SM_SHORT_WAIT; ntpLastError = SNTP_RES_NTP_DNS_ERR; } else { sntpState++; } TCPIP_DNS_UsageEnd(pSntpIf); break; case SM_DNS_RESOLVED: sntpSocket = TCPIP_UDP_ClientOpen(ntpConnection, NTP_SERVER_PORT, &serverIP); if(sntpSocket != INVALID_UDP_SOCKET) { TCPIP_UDP_SocketNetSet(sntpSocket, pSntpIf); sntpState++; SNTPTimer = SYS_TICK_Get(); } else { ntpLastError = SNTP_RES_SKT_ERR; } break; case SM_UDP_IS_OPENED: if(TCPIP_UDP_IsOpened(sntpSocket) == true) { SNTPTimer = SYS_TICK_Get(); sntpState = SM_UDP_SEND; } else if((SYS_TICK_Get() - SNTPTimer > 1*SYS_TICK_TicksPerSecondGet())) { // failed to open TCPIP_UDP_Close(sntpSocket); sntpState = SM_DNS_RESOLVED; sntpSocket = INVALID_UDP_SOCKET; ntpLastError = SNTP_RES_SKT_ERR; } break; case SM_UDP_SEND: // Open up the sending UDP socket // Make certain the socket can be written to if(!TCPIP_UDP_TxPutIsReady(sntpSocket, sizeof(pkt))) { // Wait no more than 1 sec if((SYS_TICK_Get() - SNTPTimer > 1*SYS_TICK_TicksPerSecondGet())) { TCPIP_UDP_Close(sntpSocket); sntpState = SM_DNS_RESOLVED; sntpSocket = INVALID_UDP_SOCKET; ntpLastError = SNTP_RES_SKT_ERR; break; } } // Success // Transmit a time request packet memset(&pkt, 0, sizeof(pkt)); pkt.flags.versionNumber = NTP_VERSION; pkt.flags.mode = 3; // NTP Client pkt.orig_ts_secs = TCPIP_Helper_htonl(NTP_EPOCH); TCPIP_UDP_ArrayPut(sntpSocket, (uint8_t*) &pkt, sizeof(pkt)); TCPIP_UDP_Flush(sntpSocket); SNTPTimer = SYS_TICK_Get(); sntpState = SM_UDP_RECV; break; case SM_UDP_RECV: // Look for a response time packet if(!TCPIP_UDP_GetIsReady(sntpSocket)) { if((SYS_TICK_Get()) - SNTPTimer > NTP_REPLY_TIMEOUT * SYS_TICK_TicksPerSecondGet()) { // Abort the request and resume TCPIP_UDP_Close(sntpSocket); //SNTPTimer = SYS_TICK_Get(); //sntpState = SM_SHORT_WAIT; sntpState = SM_HOME; sntpSocket = INVALID_UDP_SOCKET; ntpLastError = SNTP_RES_NTP_SERVER_TMO; } break; } // Get the response time packet w = TCPIP_UDP_ArrayGet(sntpSocket, (uint8_t*) &pkt, sizeof(pkt)); TCPIP_UDP_Close(sntpSocket); SNTPTimer = SYS_TICK_Get(); sntpState = SM_WAIT; sntpSocket = INVALID_UDP_SOCKET; // sanity packet check if(w != sizeof(pkt) || pkt.flags.versionNumber != NTP_VERSION ) { ntpLastError = SNTP_RES_NTP_VERSION_ERR; break; } if((pkt.tx_ts_secs == 0 && pkt.tx_ts_fraq == 0)) { ntpLastError = SNTP_RES_NTP_TSTAMP_ERR; break; } if(pkt.stratum == 0 ) { ntpLastError = SNTP_RES_NTP_KOD_ERR; break; } if(pkt.stratum >= NTP_MAX_STRATUM || pkt.flags.leapIndicator == 3 ) { ntpLastError = SNTP_RES_NTP_SYNC_ERR; break; } // get the last timestamp ntpTimeStamp.tStampSeconds = pkt.tx_ts_secs; ntpTimeStamp.tStampFraction = pkt.tx_ts_fraq; ntpLastStampTick = SYS_TICK_Get(); // Set out local time to match the returned time dwLastUpdateTick = ntpLastStampTick; dwSNTPSeconds = TCPIP_Helper_ntohl(pkt.tx_ts_secs) - NTP_EPOCH; // Do rounding. If the partial seconds is > 0.5 then add 1 to the seconds count. if(((uint8_t*)&pkt.tx_ts_fraq)[0] & 0x80) dwSNTPSeconds++; break; case SM_SHORT_WAIT: // Attempt to requery the NTP server after a specified NTP_FAST_QUERY_INTERVAL time (ex: 8 seconds) has elapsed. if(SYS_TICK_Get() - SNTPTimer > (NTP_FAST_QUERY_INTERVAL * SYS_TICK_TicksPerSecondGet())) { sntpState = SM_HOME; sntpSocket = INVALID_UDP_SOCKET; } break; case SM_WAIT: // Requery the NTP server after a specified NTP_QUERY_INTERVAL time (ex: 10 minutes) has elapsed. if(SYS_TICK_Get() - SNTPTimer > (NTP_QUERY_INTERVAL * SYS_TICK_TicksPerSecondGet())) { sntpState = SM_HOME; sntpSocket = INVALID_UDP_SOCKET; } break; } return true; }//TCPIP_SNTP_Client
/********************************************************************* * Function: bool TCPIP_ANNOUNCE_Task(void) * * Summary: Announce callback task. * * PreCondition: Stack is initialized() * * Input: None * * Output: None * * Side Effects: None * * Overview: Recurring task used to listen for Discovery * messages on the specified TCPIP_ANNOUNCE_PORT. These * messages can be sent using the TCP/IP * Discoverer tool. If one is received, this * function will transmit a reply. * * Note: A UDP socket must be available before this * function is called. It is freed at the end of * the function. UDP_MAX_SOCKETS may need to be * increased if other modules use UDP sockets. ********************************************************************/ bool TCPIP_ANNOUNCE_Task(TCPIP_NET_IF * pNetIf) { uint8_t i; int netIx; UDP_SOCKET s; if(!pNetIf) { return false; } else { netIx = TCPIP_STACK_NetIxGet(pNetIf); } s = announceDcpt.skt; switch(announceDcpt.sm) { case DISCOVERY_HOME: // Open a UDP socket for inbound and outbound transmission // Allow receive on any interface s = TCPIP_UDP_ServerOpen(IP_ADDRESS_TYPE_IPV4, TCPIP_ANNOUNCE_PORT, 0); if(s == INVALID_UDP_SOCKET) { return false; } if(!TCPIP_UDP_RemoteBind(s, IP_ADDRESS_TYPE_IPV4, TCPIP_ANNOUNCE_PORT, 0)) { TCPIP_UDP_Close(s); break; } if(!TCPIP_UDP_OptionsSet(s, UDP_OPTION_STRICT_PORT, (void*)true)) { TCPIP_UDP_Close(s); break; } announceDcpt.skt = s; announceDcpt.sm++; break; case DISCOVERY_LISTEN: // Do nothing if no data is waiting if(!TCPIP_UDP_GetIsReady(s)) return false; // See if this is a discovery query or reply TCPIP_UDP_Get(s, &i); TCPIP_UDP_Discard(s); if(i != 'D') return false; // We received a discovery request, reply when we can announceDcpt.sm++; // No break needed. If we get down here, we are now ready for the DISCOVERY_REQUEST_RECEIVED state case DISCOVERY_REQUEST_RECEIVED: ANNOUNCE_Notify (pNetIf, DHCP_EVENT_BOUND, NULL); // fake a legitimate DHCP event // Listen for other discovery requests announceDcpt.sm = DISCOVERY_LISTEN; break; case DISCOVERY_DISABLED: break; } return true; }
void TCPIP_ANNOUNCE_Send(void) { UDP_SOCKET announceSocket; uint16_t dataLen; uint16_t minimumDataLen; uint16_t txLen; bool truncated; TCPIP_NET_IF *pNetIf; const char* interfaceName; ANNOUNCE_FIELD_PAYLOAD payloadType; int netIx; uint16_t terminatorLen = strlen ((const char *)announceFieldTerminator); #if defined (TCPIP_STACK_USE_IPV6) IPV6_INTERFACE_CONFIG* pIpv6Config; IPV6_ADDR_STRUCT * addressPointer; IPV6_HEAP_NDP_DR_ENTRY *defaultRouter; IPV6_ADDR *pGatewayAddr; #endif // create the socket announceSocket = TCPIP_UDP_ClientOpen(IP_ADDRESS_TYPE_IPV4, TCPIP_ANNOUNCE_PORT, 0); if (announceSocket == INVALID_UDP_SOCKET) { // keep the request pending, we'll try next time return; } for(netIx = 0; netIx < announceIfs; netIx++) { // reply to the request on the interface it arrived on if((announceRequestMask & (1 << netIx)) != 0) { pNetIf = (TCPIP_NET_IF*)TCPIP_STACK_IndexToNet(netIx); if(TCPIP_STACK_NetworkIsLinked(pNetIf)) { // reply only if this interface is up and running TCPIP_UDP_SocketNetSet (announceSocket, pNetIf); TCPIP_UDP_BcastIPV4AddressSet(announceSocket, UDP_BCAST_NETWORK_DIRECTED, pNetIf); #if defined (TCPIP_STACK_USE_IPV6) pIpv6Config = TCPIP_IPV6_InterfaceConfigGet(pNetIf); #endif interfaceName = TCPIP_STACK_MACIdToString(pNetIf->macId); truncated = false; dataLen = ((terminatorLen + 1) * 4) + sizeof (IPV4_ADDR) + sizeof (TCPIP_MAC_ADDR); dataLen += strlen(interfaceName); dataLen += strlen((char *)pNetIf->NetBIOSName); minimumDataLen = dataLen + 1 + terminatorLen; #if defined (TCPIP_STACK_USE_IPV6) addressPointer = (IPV6_ADDR_STRUCT *)pIpv6Config->listIpv6UnicastAddresses.head; while(addressPointer != NULL) { dataLen += sizeof (IPV6_ADDR) + 1 + terminatorLen; addressPointer = addressPointer->next; } addressPointer = (IPV6_ADDR_STRUCT *)pIpv6Config->listIpv6MulticastAddresses.head; while(addressPointer != NULL) { dataLen += sizeof (IPV6_ADDR) + 1 + terminatorLen; addressPointer = addressPointer->next; } defaultRouter = pIpv6Config->currentDefaultRouter; while(defaultRouter != NULL) { dataLen += sizeof (IPV6_ADDR) + 1 + terminatorLen; defaultRouter = defaultRouter->next; } // For IPV6 gateway address dataLen += sizeof (IPV6_ADDR) + 1 + terminatorLen; #endif if (dataLen > ANNOUNCE_MAX_PAYLOAD) { dataLen = ANNOUNCE_MAX_PAYLOAD; } if ((txLen = TCPIP_UDP_TxPutIsReady(announceSocket, dataLen)) < dataLen) { truncated = true; if ((txLen = TCPIP_UDP_TxPutIsReady(announceSocket, minimumDataLen)) < minimumDataLen) { TCPIP_UDP_Close (announceSocket); return; } } // Put Mac Address payloadType = ANNOUNCE_FIELD_MAC_ADDR; TCPIP_UDP_Put (announceSocket, payloadType); TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)&pNetIf->netMACAddr, sizeof (TCPIP_MAC_ADDR)); TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen); if (truncated) { payloadType = ANNOUNCE_FIELD_TRUNCATED; TCPIP_UDP_Put (announceSocket, payloadType); TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen); } // Put Mac Type payloadType = ANNOUNCE_FIELD_MAC_TYPE; TCPIP_UDP_Put (announceSocket, payloadType); TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)interfaceName, strlen (interfaceName)); TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen); // Put Host Name payloadType = ANNOUNCE_FIELD_HOST_NAME; TCPIP_UDP_Put (announceSocket, payloadType); TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)&pNetIf->NetBIOSName, strlen((char*)pNetIf->NetBIOSName)); TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen); // Put IPv4 Address payloadType = ANNOUNCE_FIELD_IPV4_ADDRESS; TCPIP_UDP_Put (announceSocket, payloadType); TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)&pNetIf->netIPAddr, sizeof (IPV4_ADDR)); TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen); #if defined (TCPIP_STACK_USE_IPV6) // Put IPv6 unicast addresses minimumDataLen = sizeof (IPV6_ADDR) + 1 + terminatorLen; addressPointer = (IPV6_ADDR_STRUCT *)pIpv6Config->listIpv6UnicastAddresses.head; payloadType = ANNOUNCE_FIELD_IPV6_UNICAST; while(addressPointer != NULL && (TCPIP_UDP_TxPutIsReady(announceSocket, minimumDataLen) >= minimumDataLen)) { TCPIP_UDP_Put (announceSocket, payloadType); TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)&addressPointer->address, sizeof (IPV6_ADDR)); TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen); addressPointer = addressPointer->next; } // Put IPv6 multicast listeners addressPointer = (IPV6_ADDR_STRUCT *)pIpv6Config->listIpv6MulticastAddresses.head; payloadType = ANNOUNCE_FIELD_IPV6_MULTICAST; while(addressPointer != NULL && (TCPIP_UDP_TxPutIsReady(announceSocket, minimumDataLen) >= minimumDataLen)) { TCPIP_UDP_Put (announceSocket, payloadType); TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)&addressPointer->address, sizeof (IPV6_ADDR)); TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen); addressPointer = addressPointer->next; } defaultRouter = pIpv6Config->currentDefaultRouter; payloadType = ANNOUNCE_FIELD_IPV6_DEFAULT_ROUTER; while(defaultRouter != NULL && (TCPIP_UDP_TxPutIsReady(announceSocket, minimumDataLen) >= minimumDataLen)) { TCPIP_UDP_Put (announceSocket, payloadType); TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)&defaultRouter->neighborInfo->remoteIPAddress, sizeof (IPV6_ADDR)); TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen); defaultRouter = defaultRouter->next; } pGatewayAddr = (IPV6_ADDR*)TCPIP_STACK_NetDefaultIPv6GatewayGet(pNetIf); if(pGatewayAddr) { payloadType = ANNOUNCE_FIELD_IPV6_DEFAULT_GATEWAY; TCPIP_UDP_Put (announceSocket, payloadType); TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)pGatewayAddr, sizeof (IPV6_ADDR)); TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen); } #endif TCPIP_UDP_Flush (announceSocket); } announceRequestMask &= ~(1 << netIx); // clear requests on this interface } } TCPIP_UDP_Close (announceSocket); }