/* * locator.c * * Device Locator server using UDP * */ /* * Copyright (c) 2001-2004 Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * This file is part of the lwIP TCP/IP stack. * * Author: Adam Dunkels * */ /* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ * ALL RIGHTS RESERVED */ #include "locator.h" #include "lwiplib.h" /****************************************************************************** ** INTERNAL MACRO DEFINITIONS *******************************************************************************/ #define TAG_CMD (0xff) #define TAG_STATUS (0xfe) #define CMD_DISCOVER_TARGET (0x02) /****************************************************************************** ** INTERNAL VARIABLE DEFINITIONS *******************************************************************************/ /* ** An array that contains the device locator response data. The format of the ** data is as follows: ** ** Byte Description ** -------- ------------------------ ** 0 TAG_STATUS ** 1 packet length ** 2 CMD_DISCOVER_TARGET ** 3 board type ** 4 board ID ** 5..8 client IP address ** 9..14 MAC address ** 15..18 firmware version ** 19..82 application title ** 83 checksum */ static unsigned char locatorData[84]; /****************************************************************************** ** INTERNAL FUNCTION PROTOTYPES *******************************************************************************/ static void LocatorReceive(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port); /****************************************************************************** ** FUNCTION DEFINITIONS *******************************************************************************/ /* ** This function is called by the lwIP TCP/IP stack when it receives a UDP ** packet from the discovery port. It produces the response packet, which is ** sent back to the querying client. */ static void LocatorReceive(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) { unsigned char *pucData; unsigned long ulIdx; /* Validate the contents of the datagram.*/ pucData = p->payload; if((p->len != 4) || (pucData[0] != TAG_CMD) || (pucData[1] != 4) || (pucData[2] != CMD_DISCOVER_TARGET) || (pucData[3] != ((0 - TAG_CMD - 4 - CMD_DISCOVER_TARGET) & 0xff))) { pbuf_free(p); return; } pbuf_free(p); p = pbuf_alloc(PBUF_TRANSPORT, sizeof(locatorData), PBUF_RAM); if(p == NULL) { return; } /* Calcuate and fill in the checksum on the response packet.*/ for(ulIdx = 0, locatorData[sizeof(locatorData) - 1] = 0; ulIdx < (sizeof(locatorData) - 1); ulIdx++) { locatorData[sizeof(locatorData) - 1] -= locatorData[ulIdx]; } /* Copy the response packet data into the pbuf. */ pucData = p->payload; for(ulIdx = 0; ulIdx < sizeof(locatorData); ulIdx++) { pucData[ulIdx] = locatorData[ulIdx]; } /* Send the response.*/ udp_sendto(pcb, p, addr, port); pbuf_free(p); } /* ** Initializes the locator service. Prepares the locator service to ** handle device discovery requests. . */ void LocatorConfig(unsigned char *macArray, const char *appTitle) { unsigned int idx; void *pcb; /* Clear out the response data.*/ for(idx = 0; idx < 84; idx++) { locatorData[idx] = 0; } /* Fill in the header for the response data.*/ locatorData[0] = TAG_STATUS; locatorData[1] = sizeof(locatorData); locatorData[2] = CMD_DISCOVER_TARGET; /* Fill in the MAC address for the response data. */ locatorData[9] = macArray[0]; locatorData[10] = macArray[1]; locatorData[11] = macArray[2]; locatorData[12] = macArray[3]; locatorData[13] = macArray[4]; locatorData[14] = macArray[5]; /* Create a new UDP port for listening to device locator requests.*/ pcb = udp_new(); udp_recv(pcb, (udp_recv_fn) LocatorReceive, NULL); udp_bind(pcb, IP_ADDR_ANY, 23); udp_connect(pcb, IP_ADDR_ANY, 23); /* Copy the application title string into the response data. */ for(idx = 0; (idx < 64) && *appTitle; idx++) { locatorData[idx + 19] = *appTitle++; } /* Zero-fill the remainder of the space in the response data (if any).*/ for(; idx < 64; idx++) { locatorData[idx + 19] = 0; } } /***************************** End Of File ***********************************/