static void TCPIP_ZCLL_Process(void) { int netIx; ZCLL_NET_HANDLE *hZcll; TCPIP_NET_IF* pNetIf; int zgzc_action; IPV4_ADDR zeroAdd = {0}; #if defined(TCPIP_ZC_INFO_ZCLL) || defined(TCPIP_ZC_DEBUG_ZCLL) char zeroconf_dbg_msg[256]; #endif for(netIx = 0; netIx < TCPIP_STACK_NumberOfNetworksGet(); netIx++) { hZcll = phZCLL + netIx; pNetIf = (TCPIP_NET_IF*)TCPIP_STACK_IndexToNet(netIx); if(hZcll->zcll_state == SM_INIT) { // nothing to do in this state continue; } if(!TCPIP_STACK_NetworkIsLinked(pNetIf)) { // lost connection; re-start hZcll->zcll_state = SM_ADDR_INIT; TCPIP_STACK_AddressServiceEvent(pNetIf, TCPIP_STACK_ADDRESS_SERVICE_ZCLL, TCPIP_STACK_ADDRESS_SERVICE_EVENT_CONN_LOST); } switch(hZcll->zcll_state) { case SM_ADDR_INIT: /* Not yet seeded in init routine */ /* setup random number generator * we key this off the MAC-48 HW identifier * the first 3 octets are the manufacturer * the next 3 the serial number * we'll use the last four for the largest variety */ hZcll->conflict_count = 0; _TCPIPStackSetConfigAddress(pNetIf, &zeroAdd, &zeroAdd, true); hZcll->probe_count = 0; hZcll->zcll_state = SM_ADDR_PROBE; INFO_ZCLL_PRINT("ADDR_INIT --> ADDR_PROBE \r\n"); // No break. Fall through case SM_ADDR_PROBE: zgzc_action = zgzc_wait_for(&hZcll->random_delay, &hZcll->event_time, &hZcll->time_recorded); if(zgzc_action == ZGZC_STARTED_WAITING) { if (hZcll->probe_count == 0) { // First probe. Wait for [0 ~ PROBE_WAIT] seconds before sending the probe. hZcll->random_delay = (_zcll_rand() % (PROBE_WAIT * SYS_TMR_TickCounterFrequencyGet())); DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"PROBE_WAIT Random Delay [%d]: %ld secs \r\n", hZcll->probe_count, hZcll->random_delay); } else if (hZcll->probe_count < PROBE_NUM) { // Subsequent probes. Wait for [PROBE_MIN ~ PROBE_MAX] seconds before sending the probe. hZcll->random_delay = ( (_zcll_rand() % ((PROBE_MAX-PROBE_MIN) * SYS_TMR_TickCounterFrequencyGet()) ) + (PROBE_MIN * SYS_TMR_TickCounterFrequencyGet()) ); DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"PROBE Random Delay [%d]: %ld ticks \r\n", hZcll->probe_count, hZcll->random_delay); } else { // Completed PROBE_NUM of probes. Now wait for ANNOUNCE_WAIT seconds to determine if // we can claim it. hZcll->random_delay = (ANNOUNCE_WAIT * SYS_TMR_TickCounterFrequencyGet()); DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"ANNOUNCE_WAIT delay [%d]: %ld ticks\r\n", hZcll->probe_count, hZcll->random_delay /*SYS_TMR_TickCounterFrequencyGet() */); } DEBUG0_ZCLL_PRINT((char*)zeroconf_dbg_msg); break; } else if(zgzc_action == ZGZC_STARTED_WAITING) { // Not Completed the delay proposed break; } // Completed the delay required DEBUG0_ZCLL_MESG(zeroconf_dbg_msg," delay: %ld ticks " \ "completed \r\n", hZcll->random_delay); DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg); if(hZcll->zcll_flags.probe_conflict) { /* Conflict with selected address */ INFO_ZCLL_PRINT("Probe Conflict-1 Detected. Need to select diff addr \r\n"); hZcll->temp_IP_addr.Val = 0x0; hZcll->conflict_count++; _TCPIPStackSetConfigAddress(pNetIf, &zeroAdd, &zeroAdd, true); } else if((hZcll->conflict_count == 0) && hZcll->temp_IP_addr.Val && pNetIf->netIPAddr.Val != 0x0 && (TCPIP_ARP_IsResolved(pNetIf,&hZcll->temp_IP_addr, &hZcll->temp_MAC_addr)) ) { if(!memcmp (&hZcll->temp_MAC_addr, &pNetIf->netMACAddr, 6) ) { DEBUG0_ZCLL_PRINT("SM_ADDR_PROBE: Resolved with our address only. " \ "Rare Case !!!! \r\n"); } else { /* Conflict with selected address */ INFO_ZCLL_PRINT("Probe Conflict-2 Detected. Need to select diff addr \r\n"); hZcll->temp_IP_addr.Val = 0x0; hZcll->conflict_count++; _TCPIPStackSetConfigAddress(pNetIf, &zeroAdd, &zeroAdd, true); } } if ((hZcll->zcll_flags.probe_conflict == 1) || (!hZcll->bDefaultIPTried)) { /* * Pick random IP address in IPv4 link-local range * 169.254.1.0/16 is the allowed address range however * 169.254.0.0/24 and 169.254.255.0/24 must be excluded, * which removes 512 address from our 65535 candidates. * That leaves us with 65023 (0xfdff). * The link-local address must start with 169.254.#.# * If it does not then assign it the default value of 169.254.1.2 and send out probe. */ hZcll->probe_count = 0; if(!hZcll->bDefaultIPTried) { // First probe, and the default IP is a valid IPV4_SOFTAP_LLBASE address. if (((!hZcll->bDefaultIPTried) && (pNetIf->DefaultIPAddr.v[0] != 169)) || ((pNetIf->DefaultIPAddr.v[1] != 254) && (pNetIf->DefaultIPAddr.v[2] != 0) && (pNetIf->DefaultIPAddr.v[3] != 255))) { WARN_ZCLL_MESG(zeroconf_dbg_msg,"\r\n%d.%d.%d.%d not a valid link local addess. " "Autogenerating address.\r\n" ,pNetIf->DefaultIPAddr.v[0],pNetIf->DefaultIPAddr.v[1] ,pNetIf->DefaultIPAddr.v[2],pNetIf->DefaultIPAddr.v[3]); WARN_ZCLL_PRINT((char *)zeroconf_dbg_msg); // First probe, if the default IP is a valid IPv4 LL then use it. hZcll->temp_IP_addr.Val = (IPV4_LLBASE | ((abs(_zcll_rand()) % 0xfdff) )); hZcll->bDefaultIPTried = 1; } else { hZcll->temp_IP_addr.Val = TCPIP_Helper_ntohl(pNetIf->DefaultIPAddr.Val); } hZcll->bDefaultIPTried = 1; } else { hZcll->temp_IP_addr.Val = (IPV4_LLBASE | ((abs(_zcll_rand()) % 0xfdff) )); } INFO_ZCLL_MESG(zeroconf_dbg_msg,"Picked IP-Addr [%d]: %d.%d.%d.%d \r\n", hZcll->probe_count, hZcll->temp_IP_addr.v[3],hZcll->temp_IP_addr.v[2], hZcll->temp_IP_addr.v[1],hZcll->temp_IP_addr.v[0]); INFO_ZCLL_PRINT((char *)zeroconf_dbg_msg); hZcll->temp_IP_addr.Val = TCPIP_Helper_ntohl((uint32_t) hZcll->temp_IP_addr.Val); } if((hZcll->zcll_flags.probe_conflict == 1) || (hZcll->probe_count < PROBE_NUM)) { hZcll->zcll_flags.probe_conflict = 0; TCPIP_ZCLL_ARPAction( pNetIf , &pNetIf->netIPAddr , &hZcll->temp_IP_addr , ARP_OPERATION_REQ | ARP_OPERATION_CONFIGURE , ZCLL_ARP_PROBE); hZcll->probe_count++; DEBUG0_ZCLL_MESG(zeroconf_dbg_msg, "Sending ARP [%d]\r\n", hZcll->probe_count); DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg); break; } // No conflict detected ... if(hZcll->probe_count >= PROBE_NUM) { hZcll->zcll_state = SM_ADDR_CLAIM; hZcll->bDefaultIPTried = 0; INFO_ZCLL_PRINT("ADDR_PROBE --> ADDR_CLAIM \r\n"); } break; case SM_ADDR_CLAIM: zgzc_action = zgzc_wait_for( &hZcll->random_delay, &hZcll->event_time, &hZcll->time_recorded); if(zgzc_action == ZGZC_STARTED_WAITING) { if (hZcll->bDefaultIPTried == 0) { // First announcement is immediate. We have passed the ANNOUNCE_WAIT in // PROBE state already. hZcll->random_delay = 0; } else { // Subsequent announcements need to wait ANNOUNCE_INTERVAL seconds // before sending the announcement. hZcll->random_delay = (ANNOUNCE_INTERVAL * SYS_TMR_TickCounterFrequencyGet()); } break; } else if(zgzc_action == ZGZC_KEEP_WAITING) { // Not Completed the delay proposed break; } // Completed the delay required DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"ANNOUNCE delay: %ld ticks completed \r\n", hZcll->random_delay); DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg); if ( hZcll->bDefaultIPTried < ANNOUNCE_NUM ) { TCPIP_ZCLL_ARPAction(pNetIf,&hZcll->temp_IP_addr,&hZcll->temp_IP_addr, ARP_OPERATION_REQ | ARP_OPERATION_CONFIGURE, ZCLL_ARP_CLAIM); (hZcll->bDefaultIPTried)++; DEBUG0_ZCLL_MESG(zeroconf_dbg_msg, "Sending ANNOUNCEMENT [%d]\r\n", hZcll->bDefaultIPTried); DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg); } else { // Claim it. Goto DEFEND state IPV4_ADDR zcllMask; zcllMask.Val = IPV4_LLBASE_MASK; _TCPIPStackSetConfigAddress(pNetIf, &hZcll->temp_IP_addr, &zcllMask, false); hZcll->zcll_state = SM_ADDR_DEFEND; INFO_ZCLL_MESG(zeroconf_dbg_msg,"\r\n******** Taken IP-Addr: " \ "%d.%d.%d.%d ******** \r\n", pNetIf->netIPAddr.v[0],pNetIf->netIPAddr.v[1], pNetIf->netIPAddr.v[2],pNetIf->netIPAddr.v[3]); INFO_ZCLL_PRINT((char *)zeroconf_dbg_msg); INFO_ZCLL_PRINT("ADDR_CLAIM --> ADDR_DEFEND \r\n"); } break; case SM_ADDR_DEFEND: if( hZcll->zcll_flags.late_conflict) { if (!hZcll->zcll_flags.defended) { hZcll->zcll_flags.late_conflict = 0; INFO_ZCLL_PRINT("CONFLICT DETECTED !!! \r\n"); INFO_ZCLL_PRINT("Defending the Self Address once \r\n"); TCPIP_ZCLL_ARPAction( pNetIf ,&pNetIf->netIPAddr ,&pNetIf->netIPAddr ,ARP_OPERATION_RESP | ARP_OPERATION_CONFIGURE ,ZCLL_ARP_DEFEND); hZcll->zcll_flags.defended = true; } else { // We are not allowed to defend another conflict during an active defended period INFO_ZCLL_PRINT("Releasing the IP-Address because of multiple Conflicts \r\n"); hZcll->zcll_state = SM_ADDR_RELEASE; hZcll->zcll_flags.defended = false; hZcll->event_time = false; hZcll->random_delay = false; INFO_ZCLL_PRINT("ADDR_DEFEND --> ADDR_RELEASE \r\n"); break; } } if (hZcll->zcll_flags.defended) { zgzc_action = zgzc_wait_for(&hZcll->random_delay, &hZcll->event_time, &hZcll->time_recorded); if(zgzc_action == ZGZC_STARTED_WAITING) { hZcll->random_delay = (DEFEND_INTERVAL * SYS_TMR_TickCounterFrequencyGet()); DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"DEFEND_INTERVAL Delay : %ld ticks\r\n", hZcll->random_delay/*SYS_TMR_TickCounterFrequencyGet() */); DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg); break; } else if(zgzc_action == ZGZC_KEEP_WAITING) { // Not Completed the delay proposed break; } // Completed the delay required DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"ANNOUNCE delay: %ld ticks " \ "completed \r\n", hZcll->random_delay); DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg); hZcll->zcll_flags.defended = false; } break; case SM_ADDR_RELEASE: INFO_ZCLL_PRINT("ADDR_RELEASE --> ADDR_INIT\r\n"); _TCPIPStackSetConfigAddress(pNetIf, &zeroAdd, &zeroAdd, true); // Need New Addr hZcll->temp_IP_addr.Val = (IPV4_LLBASE | ((abs(_zcll_rand()) % 0xfdff) )); hZcll->temp_IP_addr.Val = TCPIP_Helper_ntohl((uint32_t) hZcll->temp_IP_addr.Val); hZcll->zcll_state = SM_ADDR_INIT; hZcll->time_recorded = false; hZcll->zcll_flags.defended = false; hZcll->event_time = false; 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
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); }