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); }
// 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
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_WAITING_FOR_COMMAND; SYS_CONSOLE_MESSAGE("Waiting for command type: sendudppacket\r\n"); } } } break; case APP_TCPIP_WAITING_FOR_COMMAND: { if (APP_Send_Packet) { APP_Send_Packet = false; DNS_RESULT result = TCPIP_DNS_UsageBegin(0); if (result != DNS_RES_OK) { SYS_CONSOLE_MESSAGE("Error in DNS aborting 1\r\n"); break; } result = TCPIP_DNS_Resolve(APP_Hostname_Buffer, DNS_TYPE_A); if (result != DNS_RES_OK) { SYS_CONSOLE_MESSAGE("Error in DNS aborting 2\r\n"); TCPIP_DNS_UsageEnd(0); break; } appData.state = APP_TCPIP_WAIT_ON_DNS; } } break; case APP_TCPIP_WAIT_ON_DNS: { IPV4_ADDR addr; switch (_APP_PumpDNS(APP_Hostname_Buffer, &addr)) { case -1: { // Some sort of error, already reported appData.state = APP_TCPIP_WAITING_FOR_COMMAND; } break; case 0: { // Still waiting } break; case 1: { uint16_t port = atoi(APP_Port_Buffer); appData.socket = TCPIP_UDP_ClientOpen(IP_ADDRESS_TYPE_IPV4, port, (IP_MULTI_ADDRESS*) &addr); if (appData.socket == INVALID_SOCKET) { SYS_CONSOLE_MESSAGE("Could not start connection\r\n"); appData.state = APP_TCPIP_WAITING_FOR_COMMAND; } SYS_CONSOLE_MESSAGE("Starting connection\r\n"); appData.state = APP_TCPIP_WAIT_FOR_CONNECTION; } break; } } break; case APP_TCPIP_WAIT_FOR_CONNECTION: { if (!TCPIP_UDP_IsConnected(appData.socket)) { break; } if(UDPIsPutReady(appData.socket) == 0) { break; } TCPIP_UDP_ArrayPut(appData.socket, (uint8_t*)APP_Message_Buffer, strlen(APP_Message_Buffer)); TCPIP_UDP_Flush(appData.socket); appData.state = APP_TCPIP_WAIT_FOR_RESPONSE; } break; case APP_TCPIP_WAIT_FOR_RESPONSE: { char buffer[180]; memset(buffer, 0, sizeof(buffer)); if (!TCPIP_UDP_IsConnected(appData.socket)) { SYS_CONSOLE_MESSAGE("\r\nConnection Closed\r\n"); appData.state = APP_TCPIP_WAITING_FOR_COMMAND; break; } if (TCPIP_UDP_GetIsReady(appData.socket)) { TCPIP_UDP_ArrayGet(appData.socket, (uint8_t*)buffer, sizeof(buffer) - 1); SYS_CONSOLE_MESSAGE(buffer); appData.state = APP_TCPIP_WAITING_FOR_COMMAND; } } break; default: break; } }