343 lines
10 KiB
C
343 lines
10 KiB
C
//*****************************************************************************
|
|
//
|
|
// locator.c - A device locator server using UDP in lwIP.
|
|
//
|
|
// Copyright (c) 2009-2014 Texas Instruments Incorporated. All rights reserved.
|
|
// Software License Agreement
|
|
//
|
|
// Texas Instruments (TI) is supplying this software for use solely and
|
|
// exclusively on TI's microcontroller products. The software is owned by
|
|
// TI and/or its suppliers, and is protected under applicable copyright
|
|
// laws. You may not combine this software with "viral" open-source
|
|
// software in order to form a larger program.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
|
|
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
|
|
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
|
|
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
|
|
// DAMAGES, FOR ANY REASON WHATSOEVER.
|
|
//
|
|
// This is part of revision 2.1.0.12573 of the Tiva Utility Library.
|
|
//
|
|
//*****************************************************************************
|
|
|
|
#include <stdint.h>
|
|
#include "utils/locator.h"
|
|
#include "utils/lwiplib.h"
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! \addtogroup locator_api
|
|
//! @{
|
|
//
|
|
//*****************************************************************************
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// These defines are used to describe the device locator protocol.
|
|
//
|
|
//*****************************************************************************
|
|
#define TAG_CMD 0xff
|
|
#define TAG_STATUS 0xfe
|
|
#define CMD_DISCOVER_TARGET 0x02
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// 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 uint8_t g_pui8LocatorData[84];
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// 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,
|
|
const ip_addr_t *addr, u16_t port)
|
|
{
|
|
uint8_t *pui8Data;
|
|
uint32_t ui32Idx;
|
|
|
|
//
|
|
// Validate the contents of the datagram.
|
|
//
|
|
pui8Data = p->payload;
|
|
if((p->len != 4) || (pui8Data[0] != TAG_CMD) || (pui8Data[1] != 4) ||
|
|
(pui8Data[2] != CMD_DISCOVER_TARGET) ||
|
|
(pui8Data[3] != ((0 - TAG_CMD - 4 - CMD_DISCOVER_TARGET) & 0xff)))
|
|
{
|
|
pbuf_free(p);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// The incoming pbuf is no longer needed, so free it.
|
|
//
|
|
pbuf_free(p);
|
|
|
|
//
|
|
// Allocate a new pbuf for sending the response.
|
|
//
|
|
p = pbuf_alloc(PBUF_TRANSPORT, sizeof(g_pui8LocatorData), PBUF_RAM);
|
|
if(p == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Calculate and fill in the checksum on the response packet.
|
|
//
|
|
for(ui32Idx = 0, g_pui8LocatorData[sizeof(g_pui8LocatorData) - 1] = 0;
|
|
ui32Idx < (sizeof(g_pui8LocatorData) - 1); ui32Idx++)
|
|
{
|
|
g_pui8LocatorData[sizeof(g_pui8LocatorData) - 1] -=
|
|
g_pui8LocatorData[ui32Idx];
|
|
}
|
|
|
|
//
|
|
// Copy the response packet data into the pbuf.
|
|
//
|
|
pui8Data = p->payload;
|
|
for(ui32Idx = 0; ui32Idx < sizeof(g_pui8LocatorData); ui32Idx++)
|
|
{
|
|
pui8Data[ui32Idx] = g_pui8LocatorData[ui32Idx];
|
|
}
|
|
|
|
//
|
|
// Send the response.
|
|
//
|
|
udp_sendto(pcb, p, addr, port);
|
|
|
|
//
|
|
// Free the pbuf.
|
|
//
|
|
pbuf_free(p);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Initializes the locator service.
|
|
//!
|
|
//! This function prepares the locator service to handle device discovery
|
|
//! requests. A UDP server is created and the locator response data is
|
|
//! initialized to all empty.
|
|
//!
|
|
//! \return None.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
LocatorInit(void)
|
|
{
|
|
uint32_t ui32Idx;
|
|
void *pcb;
|
|
|
|
//
|
|
// Clear out the response data.
|
|
//
|
|
for(ui32Idx = 0; ui32Idx < 84; ui32Idx++)
|
|
{
|
|
g_pui8LocatorData[ui32Idx] = 0;
|
|
}
|
|
|
|
//
|
|
// Fill in the header for the response data.
|
|
//
|
|
g_pui8LocatorData[0] = TAG_STATUS;
|
|
g_pui8LocatorData[1] = sizeof(g_pui8LocatorData);
|
|
g_pui8LocatorData[2] = CMD_DISCOVER_TARGET;
|
|
|
|
//
|
|
// Fill in the MAC address for the response data.
|
|
//
|
|
g_pui8LocatorData[9] = 0;
|
|
g_pui8LocatorData[10] = 0;
|
|
g_pui8LocatorData[11] = 0;
|
|
g_pui8LocatorData[12] = 0;
|
|
g_pui8LocatorData[13] = 0;
|
|
g_pui8LocatorData[14] = 0;
|
|
|
|
//
|
|
// Create a new UDP port for listening to device locator requests.
|
|
//
|
|
pcb = udp_new();
|
|
udp_recv(pcb, LocatorReceive, NULL);
|
|
udp_bind(pcb, IP_ADDR_ANY, 23);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Sets the board type in the locator response packet.
|
|
//!
|
|
//! \param ui32Type is the type of the board.
|
|
//!
|
|
//! This function sets the board type field in the locator response packet.
|
|
//!
|
|
//! \return None.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
LocatorBoardTypeSet(uint32_t ui32Type)
|
|
{
|
|
//
|
|
// Save the board type in the response data.
|
|
//
|
|
g_pui8LocatorData[3] = ui32Type & 0xff;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Sets the board ID in the locator response packet.
|
|
//!
|
|
//! \param ui32ID is the ID of the board.
|
|
//!
|
|
//! This function sets the board ID field in the locator response packet.
|
|
//!
|
|
//! \return None.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
LocatorBoardIDSet(uint32_t ui32ID)
|
|
{
|
|
//
|
|
// Save the board ID in the response data.
|
|
//
|
|
g_pui8LocatorData[4] = ui32ID & 0xff;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Sets the client IP address in the locator response packet.
|
|
//!
|
|
//! \param ui32IP is the IP address of the currently connected client.
|
|
//!
|
|
//! This function sets the IP address of the currently connected client in the
|
|
//! locator response packet. The IP should be set to 0.0.0.0 if there is no
|
|
//! client connected. It should never be set for devices that do not have a
|
|
//! strict one-to-one mapping of client to server (for example, a web server).
|
|
//!
|
|
//! \return None.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
LocatorClientIPSet(uint32_t ui32IP)
|
|
{
|
|
//
|
|
// Save the client IP address in the response data.
|
|
//
|
|
g_pui8LocatorData[5] = ui32IP & 0xff;
|
|
g_pui8LocatorData[6] = (ui32IP >> 8) & 0xff;
|
|
g_pui8LocatorData[7] = (ui32IP >> 16) & 0xff;
|
|
g_pui8LocatorData[8] = (ui32IP >> 24) & 0xff;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Sets the MAC address in the locator response packet.
|
|
//!
|
|
//! \param pui8MACArray is the MAC address of the network interface.
|
|
//!
|
|
//! This function sets the MAC address of the network interface in the locator
|
|
//! response packet.
|
|
//!
|
|
//! \return None.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
LocatorMACAddrSet(uint8_t *pui8MACArray)
|
|
{
|
|
//
|
|
// Save the MAC address.
|
|
//
|
|
g_pui8LocatorData[9] = pui8MACArray[0];
|
|
g_pui8LocatorData[10] = pui8MACArray[1];
|
|
g_pui8LocatorData[11] = pui8MACArray[2];
|
|
g_pui8LocatorData[12] = pui8MACArray[3];
|
|
g_pui8LocatorData[13] = pui8MACArray[4];
|
|
g_pui8LocatorData[14] = pui8MACArray[5];
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Sets the firmware version in the locator response packet.
|
|
//!
|
|
//! \param ui32Version is the version number of the device firmware.
|
|
//!
|
|
//! This function sets the version number of the device firmware in the locator
|
|
//! response packet.
|
|
//!
|
|
//! \return None.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
LocatorVersionSet(uint32_t ui32Version)
|
|
{
|
|
//
|
|
// Save the firmware version number in the response data.
|
|
//
|
|
g_pui8LocatorData[15] = ui32Version & 0xff;
|
|
g_pui8LocatorData[16] = (ui32Version >> 8) & 0xff;
|
|
g_pui8LocatorData[17] = (ui32Version >> 16) & 0xff;
|
|
g_pui8LocatorData[18] = (ui32Version >> 24) & 0xff;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Sets the application title in the locator response packet.
|
|
//!
|
|
//! \param pcAppTitle is a pointer to the application title string.
|
|
//!
|
|
//! This function sets the application title in the locator response packet.
|
|
//! The string is truncated at 64 characters if it is longer (without a
|
|
//! terminating 0), and is zero-filled to 64 characters if it is shorter.
|
|
//!
|
|
//! \return None.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
LocatorAppTitleSet(const char *pcAppTitle)
|
|
{
|
|
uint32_t ui32Count;
|
|
|
|
//
|
|
// Copy the application title string into the response data.
|
|
//
|
|
for(ui32Count = 0; (ui32Count < 64) && *pcAppTitle; ui32Count++)
|
|
{
|
|
g_pui8LocatorData[ui32Count + 19] = *pcAppTitle++;
|
|
}
|
|
|
|
//
|
|
// Zero-fill the remainder of the space in the response data (if any).
|
|
//
|
|
for(; ui32Count < 64; ui32Count++)
|
|
{
|
|
g_pui8LocatorData[ui32Count + 19] = 0;
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Close the Doxygen group.
|
|
//! @}
|
|
//
|
|
//*****************************************************************************
|