/********************************************************************* * 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; }
/********************************************************************* * Function: void 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 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. ********************************************************************/ void ANNOUNCE_Task(NET_CONFIG * pNetIf) { static enum { DISCOVERY_HOME = 0, DISCOVERY_LISTEN, DISCOVERY_REQUEST_RECEIVED, DISCOVERY_DISABLED } DiscoverySM[TCPIP_NETWORK_INTERFACES] = {DISCOVERY_HOME}; static UDP_SOCKET MySocket[TCPIP_NETWORK_INTERFACES]; uint8_t i; int netIx; UDP_SOCKET s; if(!pNetIf) { return; } else { netIx = _TCPIPStackNetIx(pNetIf); } s = MySocket[netIx]; switch(DiscoverySM[netIx]) { case DISCOVERY_HOME: // Open a UDP socket for inbound and outbound transmission // Since we expect to only receive broadcast packets and // only send unicast packets directly to the node we last // received from, the remote NodeInfo parameter can be anything MySocket[netIx] = UDPOpen(0,UDP_OPEN_SERVER,ANNOUNCE_PORT, ANNOUNCE_PORT); if(MySocket[netIx] == INVALID_UDP_SOCKET) { return; } else { DiscoverySM[netIx]++; UDPSocketSetNet(MySocket[netIx], pNetIf); } break; case DISCOVERY_LISTEN: // Do nothing if no data is waiting if(!UDPIsGetReady(s)) return; // See if this is a discovery query or reply UDPGet(s, &i); UDPDiscard(s); if(i != 'D') return; // We received a discovery request, reply when we can DiscoverySM[netIx]++; // Change the destination to the unicast address of the last received packet TCPIP_IPV4_SetDestAddress(UDPSocketDcpt[s].pTxPkt,remoteNode.IPAddr.Val); memcpy((void*)&UDPSocketDcpt[s].pTxPkt->remoteMACAddr, (const void*)&remoteNode.MACAddr, sizeof(MAC_ADDR)); // 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, 0, NULL); // Listen for other discovery requests DiscoverySM[netIx] = DISCOVERY_LISTEN; break; case DISCOVERY_DISABLED: break; } }