Compare commits

..

2 Commits

Author SHA1 Message Date
3d5c99570f mdns: Allow TXT entries larger than 63 bytes; add configurable maximum TXT RDATA size
This can be used to fix device adoption in ESPHome, which uses a long
"package_import_url" string to advertise the location of the sourcecode
for the device's configuration.
2026-01-02 00:44:16 -07:00
c01c655c5f mdns: add some txtdata unit tests 2026-01-02 00:09:35 -07:00
17 changed files with 197 additions and 2319 deletions

View File

@@ -92,9 +92,9 @@ If this call returns successfully, the following queries will be answered:
LWIP_ERROR("mdns add service txt failed\n", (res == ERR_OK), return);
}
Since a hostname struct is used for TXT storage each single item can be max
63 bytes long, and the total max length (including length bytes for each
item) is 255 bytes.
Each item is encoded as a length byte followed by the data, so each single
item can be max 255 bytes long, and the total max length (including length
bytes for each item) is defined by MDNS_TXT_RDATA_SIZE (default 255).
If your device runs a webserver on port 80, an example call might be:

View File

@@ -1,5 +0,0 @@
{
"name": "library-lwip",
"version": "2.2.0-bdk",
"description": "lwIP - A Lightweight TCPIP stack"
}

View File

@@ -1,110 +0,0 @@
/*
* cc.h - Architecture environment, some compiler specific, some
* environment specific (probably should move env stuff
* to sys_arch.h.)
*
* Typedefs for the types used by lwip -
* u8_t, s8_t, u16_t, s16_t, u32_t, s32_t, mem_ptr_t
*
* Compiler hints for packing lwip's structures -
* PACK_STRUCT_FIELD(x)
* PACK_STRUCT_STRUCT
* PACK_STRUCT_BEGIN
* PACK_STRUCT_END
*
* Platform specific diagnostic output -
* LWIP_PLATFORM_DIAG(x) - non-fatal, print a message.
* LWIP_PLATFORM_ASSERT(x) - fatal, print message and abandon execution.
* Portability defines for printf formatters:
* U16_F, S16_F, X16_F, U32_F, S32_F, X32_F, SZT_F
*
* "lightweight" synchronization mechanisms -
* SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable.
* SYS_ARCH_PROTECT(x) - enter protection mode.
* SYS_ARCH_UNPROTECT(x) - leave protection mode.
*
* If the compiler does not provide memset() this file must include a
* definition of it, or include a file which defines it.
*
* This file must either include a system-local <errno.h> which defines
* the standard *nix error codes, or it should #define LWIP_PROVIDE_ERRNO
* to make lwip/arch.h define the codes which are used throughout.
*/
#ifndef __CC_H__
#define __CC_H__
#include <stdint.h>
#include <stdio.h>
/*
* Typedefs for the types used by lwip -
* u8_t, s8_t, u16_t, s16_t, u32_t, s32_t, mem_ptr_t
*/
typedef unsigned char u8_t; /* Unsigned 8 bit quantity */
typedef signed char s8_t; /* Signed 8 bit quantity */
typedef unsigned short u16_t; /* Unsigned 16 bit quantity */
typedef signed short s16_t; /* Signed 16 bit quantity */
typedef unsigned long u32_t; /* Unsigned 32 bit quantity */
typedef signed long s32_t; /* Signed 32 bit quantity */
//typedef unsigned long mem_ptr_t; /* Unsigned 32 bit quantity */
typedef int intptr_t;
typedef unsigned int uintptr_t;
typedef int sys_prot_t;
#if defined(__GNUC__)
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT __attribute__((packed))
#define PACK_STRUCT_FIELD(x) x
#elif defined(__ICCARM__)
#define PACK_STRUCT_BEGIN __packed
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_FIELD(x) x
#else
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_FIELD(x) x
#endif
/*
* Platform specific diagnostic output -
* LWIP_PLATFORM_DIAG(x) - non-fatal, print a message.
* LWIP_PLATFORM_ASSERT(x) - fatal, print message and abandon execution.
* Portability defines for printf formatters:
* U16_F, S16_F, X16_F, U32_F, S32_F, X32_F, SZT_F
*/
#ifndef LWIP_PLATFORM_ASSERT
#define LWIP_PLATFORM_ASSERT(x) \
do \
{ printf("Assertion \"%s\" failed at line %d in %s\n", x, __LINE__, __FILE__); \
} while(0)
#endif
#ifndef LWIP_PLATFORM_DIAG
#define LWIP_PLATFORM_DIAG(x) do {printf x ;} while(0)
#endif
#define U16_F "4d"
#define S16_F "4d"
#define X16_F "4x"
#define U32_F "8ld"
#define S32_F "8ld"
#define X32_F "8lx"
/*
* unknow defination
*/
// cup byte order
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif
extern int bk_rand(); /* FIXME: move to right place */
#define LWIP_RAND() ((uint32_t)bk_rand())
#endif
// eof

View File

@@ -1,60 +0,0 @@
/*
* Copyright (c) 2001-2003 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 <adam@sics.se>
*
*/
#ifndef __SYS_RTXC_H__
#define __SYS_RTXC_H__
#include <FreeRTOS.h>
#include <queue.h>
#include <semphr.h>
#include <task.h>
#define SYS_MBOX_NULL (xQueueHandle)0
#define SYS_SEM_NULL (xSemaphoreHandle)0
#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE
typedef xSemaphoreHandle sys_sem_t;
typedef xQueueHandle sys_mbox_t;
typedef xTaskHandle sys_thread_t;
typedef void * sys_mutex_t;
typedef struct _sys_arch_state_t
{
// Task creation data.
char cTaskName[configMAX_TASK_NAME_LEN];
unsigned short nStackDepth;
unsigned short nTaskCount;
} sys_arch_state_t;
/* Message queue constants. */
#define archMESG_QUEUE_LENGTH ( 32 )
#endif /* __SYS_RTXC_H__ */

View File

@@ -1,353 +0,0 @@
/**
* @file
* Ethernet Interface Skeleton
*
*/
/*
* 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 <adam@sics.se>
*
*/
/*
* This file is a skeleton for developing Ethernet network interface
* drivers for lwIP. Add code to the low_level functions and do a
* search-and-replace for the word "ethernetif" to replace it with
* something that better describes your network interface.
*/
#include "include.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include <lwip/stats.h>
#include <lwip/snmp.h>
#include "lwip/ethip6.h"
#include "ethernetif.h"
#include <stdio.h>
#include <string.h>
#include "netif/etharp.h"
#include "lwip_netif_address.h"
#include "sa_station.h"
#include "drv_model_pub.h"
#include "mem_pub.h"
#include "common.h"
#include "hostapd_cfg.h"
#include "sk_intf.h"
#include "rw_pub.h"
#include "rtos_pub.h"
#include "param_config.h"
/* Define those to better describe your network interface. */
#define IFNAME0 'e'
#define IFNAME1 'n'
#include "uart_pub.h"
#define ETH_INTF_DEBUG
#ifdef ETH_INTF_DEBUG
#define ETH_INTF_PRT warning_prf
#define ETH_INTF_WARN warning_prf
#define ETH_INTF_FATAL fatal_prf
#else
#define ETH_INTF_PRT null_prf
#define ETH_INTF_WARN null_prf
#define ETH_INTF_FATAL null_prf
#endif
extern int bmsg_tx_sender(struct pbuf *p, uint32_t vif_idx);
/* Forward declarations. */
void ethernetif_input(int iface, struct pbuf *p);
/**
* In this function, the hardware should be initialized.
* Called from ethernetif_init().
*
* @param netif the already initialized lwip network interface structure
* for this ethernetif
*/
const char wlan_name[][6] =
{
"wlan0\0",
"wlan1\0",
"wlan2\0",
"wlan3\0",
};
static void low_level_init(struct netif *netif)
{
VIF_INF_PTR vif_entry = (VIF_INF_PTR)(netif->state);
u8 *macptr = (u8*)&vif_entry->mac_addr;
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
netif->hostname = (char*)&wlan_name[vif_entry->index];
#endif /* LWIP_NETIF_HOSTNAME */
//wifi_get_mac_address((char *)wireless_mac, type);
/* set MAC hardware address length */
ETH_INTF_PRT("enter low level!\r\n");
ETH_INTF_PRT("mac %2x:%2x:%2x:%2x:%2x:%2x\r\n", macptr[0], macptr[1], macptr[2],
macptr[3], macptr[4], macptr[5]);
netif->hwaddr_len = ETHARP_HWADDR_LEN;
os_memcpy(netif->hwaddr, macptr, ETHARP_HWADDR_LEN);
/* maximum transfer unit */
netif->mtu = 1500;
/* device capabilities */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
#ifdef CONFIG_IPV6
netif->flags |= NETIF_FLAG_MLD6;
#endif
ETH_INTF_PRT("leave low level!\r\n");
}
/**
* This function should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
* @param netif the lwip network interface structure for this ethernetif
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
* @return ERR_OK if the packet could be sent
* an err_t value if the packet couldn't be sent
*
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
* strange results. You might consider waiting for space in the DMA queue
* to become availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
int ret;
err_t err = ERR_OK;
uint8_t vif_idx = rwm_mgmt_get_netif2vif(netif);
//os_printf("output:%x\r\n", p);
ret = bmsg_tx_sender(p, (uint32_t)vif_idx);
if(0 != ret)
{
err = ERR_TIMEOUT;
}
return err;
}
/**
* This function should be called when a packet is ready to be read
* from the interface. It uses the function low_level_input() that
* should handle the actual reception of bytes from the network
* interface. Then the type of the received packet is determined and
* the appropriate input function is called.
*
* @param netif the lwip network interface structure for this ethernetif
*/
void
ethernetif_input(int iface, struct pbuf *p)
{
struct eth_hdr *ethhdr;
struct netif *netif;
if (p->len <= SIZEOF_ETH_HDR) {
pbuf_free(p);
return;
}
netif = rwm_mgmt_get_vif2netif((uint8_t)iface);
if(!netif) {
//ETH_INTF_PRT("ethernetif_input no netif found %d\r\n", iface);
pbuf_free(p);
p = NULL;
return;
}
/* points to packet payload, which starts with an Ethernet header */
ethhdr = p->payload;
/* Ignore our own multicast packets when they come back from the AP */
if ((ethhdr->dest.addr[0] & 0x01) /* multicast */ &&
!memcmp(ethhdr->src.addr, netif->hwaddr, ETH_HWADDR_LEN)) {
pbuf_free(p);
p = NULL;
return;
}
switch (htons(ethhdr->type))
{
/* IP or ARP packet? */
case ETHTYPE_IP:
case ETHTYPE_ARP:
case ETHTYPE_IPV6:
#if PPPOE_SUPPORT
/* PPPoE packet? */
case ETHTYPE_PPPOEDISC:
case ETHTYPE_PPPOE:
#endif /* PPPOE_SUPPORT */
/* full packet send to tcpip_thread to process */
if (netif->input(p, netif) != ERR_OK) // ethernet_input
{
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\r\n"));
pbuf_free(p);
p = NULL;
}
break;
case ETH_P_EAPOL:
ke_l2_packet_tx(p->payload, p->len, iface);
pbuf_free(p);
p = NULL;
break;
default:
pbuf_free(p);
p = NULL;
break;
}
}
/**
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
* This function should be passed as a parameter to netif_add().
*
* @param netif the lwip network interface structure for this ethernetif
* @return ERR_OK if the loopif is initialized
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t
ethernetif_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
/*
* Initialize the snmp variables and counters inside the struct netif.
* The last argument should be replaced with your link speed, in units
* of bits per second.
*/
NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
* is available...) */
netif->output = etharp_output;
netif->linkoutput = low_level_output;
#ifdef CONFIG_IPV6
netif->output_ip6 = ethip6_output;
#endif
/* initialize the hardware */
low_level_init(netif);
return ERR_OK;
}
/**
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
* This function should be passed as a parameter to netifapi_netif_add().
*
* @param netif the lwip network interface structure for this ethernetif
* @return ERR_OK if the loopif is initialized
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t lwip_netif_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
/*
* Initialize the snmp variables and counters inside the struct netif.
* The last argument should be replaced with your link speed, in units
* of bits per second.
*/
NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
* is available...) */
netif->output = etharp_output;
netif->linkoutput = low_level_output;
#ifdef CONFIG_IPV6
netif->output_ip6 = ethip6_output;
#endif
/* initialize the hardware */
low_level_init(netif);
return ERR_OK;
}
err_t lwip_netif_uap_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
//netif->state = NULL;
netif->name[0] = 'u';
netif->name[1] = 'a';
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
* is available...) */
netif->output = etharp_output;
netif->linkoutput = low_level_output;
#ifdef CONFIG_IPV6
netif->output_ip6 = ethip6_output;
#endif
/* initialize the hardware */
low_level_init(netif);
return ERR_OK;
}
// eof

View File

@@ -1,13 +0,0 @@
#ifndef __ETHERNETIF_H__
#define __ETHERNETIF_H__
#include "lwip/err.h"
#include "lwip/netif.h"
void ethernetif_recv(struct netif *netif, int total_len);
err_t ethernetif_init(struct netif *netif);
#endif

View File

@@ -1,17 +0,0 @@
#ifndef __LWIP_INTF_H__
#define __LWIP_INTF_H__
#define LWIP_INTF_DEBUG
#ifdef LWIP_INTF_DEBUG
#define LWIP_INTF_PRT warning_prf
#define LWIP_INTF_WARN warning_prf
#define LWIP_INTF_FATAL fatal_prf
#else
#define LWIP_INTF_PRT null_prf
#define LWIP_INTF_WARN null_prf
#define LWIP_INTF_FATAL null_prf
#endif
#endif
// eof

View File

@@ -1,59 +0,0 @@
#ifndef _MXCHIP_NETIF_ADDR_H_
#define _MXCHIP_NETIF_ADDR_H_
/** MLAN BSS type */
typedef enum _wifi_interface_type
{
WIFI_INTERFACE_TYPE_STA = 0,
WIFI_INTERFACE_TYPE_UAP = 1,
WIFI_INTERFACE_TYPE_ANY = 0xff,
} wifi_interface_type;
#define ADDR_TYPE_STATIC 1
#define ADDR_TYPE_DHCP 0
/** This data structure represents an IPv4 address */
struct ipv4_config {
/** DHCP_Disable DHCP_Client DHCP_Server */
unsigned addr_type;
/** The system's IP address in network order. */
unsigned address;
/** The system's default gateway in network order. */
unsigned gw;
/** The system's subnet mask in network order. */
unsigned netmask;
/** The system's primary dns server in network order. */
unsigned dns1;
/** The system's secondary dns server in network order. */
unsigned dns2;
};
#ifdef CONFIG_IPV6
struct ipv6_config
{
/** The system's IPv6 address in network order. */
uint32_t addr[4];
/** The address type: linklocal, site-local or global. */
unsigned char addr_type;
/** The state of IPv6 address (Tentative, Preferred, etc). */
unsigned char addr_state;
};
#endif
/** Network IP configuration.
*
* This data structure represents the network IP configuration
* for IPv4 as well as IPv6 addresses
*/
struct wlan_ip_config {
#ifdef CONFIG_IPV6
/** The network IPv6 address configuration that should be
* associated with this interface. */
struct ipv6_config ipv6[LWIP_IPV6_NUM_ADDRESSES];
#endif
/** The network IPv4 address configuration that should be
* associated with this interface. */
struct ipv4_config ipv4;
};
#endif

View File

@@ -1,462 +0,0 @@
/*
* Copyright (c) 2001-2003 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 <adam@sics.se>
*
*/
#ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__
#include "sys_config.h"
/**
* Loopback demo related options.
*/
#define LWIP_NETIF_LOOPBACK 1
#define LWIP_HAVE_LOOPIF 1
#define LWIP_NETIF_LOOPBACK_MULTITHREADING 1
#define LWIP_LOOPBACK_MAX_PBUFS 8
#define TCPIP_THREAD_NAME "tcp/ip"
#define TCPIP_THREAD_STACKSIZE 512
#define TCPIP_THREAD_PRIO 7
#define DEFAULT_THREAD_STACKSIZE 200
#define DEFAULT_THREAD_PRIO 1
/* Disable lwIP asserts */
#define LWIP_NOASSERT 1
#define LWIP_DEBUG 0
#define LWIP_DEBUG_TRACE 0
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define IGMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define PPP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF
#define AUTOIP_DEBUG LWIP_DBG_OFF
#define SNMP_MSG_DEBUG LWIP_DBG_OFF
#define SNMP_MIB_DEBUG LWIP_DBG_OFF
#define DNS_DEBUG LWIP_DBG_OFF
//#define LWIP_COMPAT_MUTEX 1
/**
* SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
* critical regions during buffer allocation, deallocation and memory
* allocation and deallocation.
*/
#define SYS_LIGHTWEIGHT_PROT 1
/*
------------------------------------
---------- Memory options ----------
------------------------------------
*/
/**
* MEM_ALIGNMENT: should be set to the alignment of the CPU
* 4 byte alignment -> #define MEM_ALIGNMENT 4
* 2 byte alignment -> #define MEM_ALIGNMENT 2
*/
#define MEM_ALIGNMENT 4
#define MAX_SOCKETS_TCP 12
#define MAX_LISTENING_SOCKETS_TCP 4
#define MAX_SOCKETS_UDP 22
#define TCP_SND_BUF_COUNT 5
/* Value of TCP_SND_BUF_COUNT denotes the number of buffers and is set by
* CONFIG option available in the SDK
*/
/* Buffer size needed for TCP: Max. number of TCP sockets * Size of pbuf *
* Max. number of TCP sender buffers per socket
*
* Listening sockets for TCP servers do not require the same amount buffer
* space. Hence do not consider these sockets for memory computation
*/
#define TCP_MEM_SIZE (MAX_SOCKETS_TCP * \
PBUF_POOL_BUFSIZE * (TCP_SND_BUF/TCP_MSS))
/* Buffer size needed for UDP: Max. number of UDP sockets * Size of pbuf
*/
#define UDP_MEM_SIZE (MAX_SOCKETS_UDP * PBUF_POOL_BUFSIZE)
/**
* MEM_SIZE: the size of the heap memory. If the application will send
* a lot of data that needs to be copied, this should be set high.
*/
#if ((defined(CFG_LWIP_MEM_POLICY))&&(CFG_LWIP_MEM_POLICY == LWIP_REDUCE_THE_PLAN))
#define MEM_SIZE (16*1024)
#else
#define MEM_SIZE (32*1024)
#endif
/*
------------------------------------------------
---------- Internal Memory Pool Sizes ----------
------------------------------------------------
*/
/**
* MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF).
* If the application sends a lot of data out of ROM (or other static memory),
* this should be set high.
*/
#define MEMP_NUM_PBUF 10
/**
* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections.
* (requires the LWIP_TCP option)
*/
#define MEMP_NUM_TCP_PCB MAX_SOCKETS_TCP
#define MEMP_NUM_TCP_PCB_LISTEN MAX_LISTENING_SOCKETS_TCP
/**
* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments.
* (requires the LWIP_TCP option)
*/
//#define MEMP_NUM_TCP_SEG 12
/**
* MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used
* for incoming packets.
* (only needed if you use tcpip.c)
*/
#define MEMP_NUM_TCPIP_MSG_INPKT 16
/**
* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts.
* (requires NO_SYS==0)
*/
#define MEMP_NUM_SYS_TIMEOUT LWIP_NUM_SYS_TIMEOUT_INTERNAL + 10
/**
* MEMP_NUM_NETBUF: the number of struct netbufs.
* (only needed if you use the sequential API, like api_lib.c)
*/
#define MEMP_NUM_NETBUF 16
/**
* MEMP_NUM_NETCONN: the number of struct netconns.
* (only needed if you use the sequential API, like api_lib.c)
*
* This number corresponds to the maximum number of active sockets at any
* given point in time. This number must be sum of max. TCP sockets, max. TCP
* sockets used for listening, and max. number of UDP sockets
*/
#define MEMP_NUM_NETCONN (MAX_SOCKETS_TCP + \
MAX_LISTENING_SOCKETS_TCP + MAX_SOCKETS_UDP)
/**
* PBUF_POOL_SIZE: the number of buffers in the pbuf pool.
*/
#if ((defined(CFG_LWIP_MEM_POLICY))&&(CFG_LWIP_MEM_POLICY == LWIP_REDUCE_THE_PLAN))
#define PBUF_POOL_SIZE 3
#else
#define PBUF_POOL_SIZE 10
#endif
/*
----------------------------------
---------- Pbuf options ----------
----------------------------------
*/
/**
* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is
* designed to accomodate single full size TCP frame in one pbuf, including
* TCP_MSS, IP header, and link header.
*/
#define PBUF_POOL_BUFSIZE 1580
/*
---------------------------------
---------- RAW options ----------
---------------------------------
*/
/**
* LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
*/
#define LWIP_RAW 1
#define LWIP_IPV4 1
#ifdef CONFIG_IPV6
#define LWIP_IPV6 1
#endif
/* Enable IPv4 Auto IP */
#ifdef CONFIG_AUTOIP
#define LWIP_AUTOIP 1
#define LWIP_DHCP_AUTOIP_COOP 1
#define LWIP_DHCP_AUTOIP_COOP_TRIES 5
#endif
/*
------------------------------------
---------- Socket options ----------
------------------------------------
*/
/**
* LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
*/
#define LWIP_SOCKET 1
#define LWIP_NETIF_API 1
/**
* LWIP_RECV_CB==1: Enable callback when a socket receives data.
*/
#define LWIP_RECV_CB 1
/**
* SO_REUSE==1: Enable SO_REUSEADDR option.
*/
#define SO_REUSE 1
#define SO_REUSE_RXTOALL 1
/**
* Enable TCP_KEEPALIVE
*/
#define LWIP_TCP_KEEPALIVE 1
/*
----------------------------------------
---------- Statistics options ----------
----------------------------------------
*/
/**
* LWIP_STATS==1: Enable statistics collection in lwip_stats.
*/
#define LWIP_STATS 1
/**
* LWIP_STATS_DISPLAY==1: Compile in the statistics output functions.
*/
#define LWIP_STATS_DISPLAY 0
/*
----------------------------------
---------- DHCP options ----------
----------------------------------
*/
/**
* LWIP_DHCP==1: Enable DHCP module.
*/
#define LWIP_DHCP 1
#define LWIP_NETIF_STATUS_CALLBACK 1
/**
* DNS related options, revisit later to fine tune.
*/
#define LWIP_DNS 1
#define DNS_TABLE_SIZE 2 // number of table entries, default 4
//#define DNS_MAX_NAME_LENGTH 64 // max. name length, default 256
#define DNS_MAX_SERVERS 2 // number of DNS servers, default 2
#define DNS_DOES_NAME_CHECK 1 // compare received name with given,def 0
#define DNS_MSG_SIZE 512
#define MDNS_MSG_SIZE 512
#define MDNS_TABLE_SIZE 1 // number of mDNS table entries
#define MDNS_MAX_SERVERS 1 // number of mDNS multicast addresses
/* TODO: Number of active UDP PCBs is equal to number of active UDP sockets plus
* two. Need to find the users of these 2 PCBs
*/
#define MEMP_NUM_UDP_PCB (MAX_SOCKETS_UDP + 2)
/* NOTE: some times the socket() call for SOCK_DGRAM might fail if you dont
* have enough MEMP_NUM_UDP_PCB */
/*
----------------------------------
---------- IGMP options ----------
----------------------------------
*/
/**
* LWIP_IGMP==1: Turn on IGMP module.
*/
#define LWIP_IGMP 1
/**
* LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and
* SO_SNDTIMEO processing.
*/
#define LWIP_SO_SNDTIMEO 1
/**
* LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and
* SO_RCVTIMEO processing.
*/
#define LWIP_SO_RCVTIMEO 1
#define LWIP_SO_SNDTIMEO 1
/**
* TCP_LISTEN_BACKLOG==1: Handle backlog connections.
*/
#define TCP_LISTEN_BACKLOG 1
#define LWIP_PROVIDE_ERRNO 1
#include <errno.h>
#define ERRNO 1
//#define LWIP_SNMP 1
/*
------------------------------------------------
---------- Network Interfaces options ----------
------------------------------------------------
*/
/**
* LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname
* field.
*/
#define LWIP_NETIF_HOSTNAME 1
/*
The STM32F107 allows computing and verifying the IP, UDP, TCP and ICMP checksums by hardware:
- To use this feature let the following define uncommented.
- To disable it and process by CPU comment the the checksum.
*/
//#define CHECKSUM_BY_HARDWARE
#ifdef CHECKSUM_BY_HARDWARE
/* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/
#define CHECKSUM_GEN_IP 0
/* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/
#define CHECKSUM_GEN_UDP 0
/* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/
#define CHECKSUM_GEN_TCP 0
/* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/
#define CHECKSUM_CHECK_IP 0
/* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/
#define CHECKSUM_CHECK_UDP 0
/* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/
#define CHECKSUM_CHECK_TCP 0
#else
/* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/
#define CHECKSUM_GEN_IP 1
/* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/
#define CHECKSUM_GEN_UDP 1
/* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/
#define CHECKSUM_GEN_TCP 1
/* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/
#define CHECKSUM_CHECK_IP 1
/* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/
#define CHECKSUM_CHECK_UDP 1
/* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/
#define CHECKSUM_CHECK_TCP 1
#endif
/**
* TCP_RESOURCE_FAIL_RETRY_LIMIT: limit for retrying sending of tcp segment
* on resource failure error returned by driver.
*/
#define TCP_RESOURCE_FAIL_RETRY_LIMIT 50
//#ifdef CONFIG_ENABLE_MXCHIP
/* save memory */
#if ((defined(CFG_LWIP_MEM_POLICY))&&(CFG_LWIP_MEM_POLICY == LWIP_REDUCE_THE_PLAN))
#define TCP_MSS (1500 - 40)
/* TCP receive window. */
#define TCP_WND (3 * TCP_MSS)
/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF (10*TCP_MSS)
#define TCP_SND_QUEUELEN (20)
#else
#define TCP_MSS (1500 - 40)
/* TCP receive window. */
#define TCP_WND (10*TCP_MSS)
/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF (10*TCP_MSS)
#define TCP_SND_QUEUELEN (20)
#endif
/* ARP before DHCP causes multi-second delay - turn it off */
#define DHCP_DOES_ARP_CHECK (0)
#define TCP_MAX_ACCEPT_CONN 5
#define MEMP_NUM_TCP_SEG (TCP_SND_QUEUELEN*2)
#define IP_REASS_MAX_PBUFS 0
#define IP_REASSEMBLY 0
#define IP_REASS_MAX_PBUFS 0
#define IP_REASSEMBLY 0
#define MEMP_NUM_REASSDATA 0
#define IP_FRAG 0
#define MEM_LIBC_MALLOC (0)
#define DEFAULT_UDP_RECVMBOX_SIZE 3 //each udp socket max buffer 3 packets.
#define MEMP_MEM_MALLOC (0)
#define TCP_MSL (TCP_TMR_INTERVAL)
#define LWIP_COMPAT_MUTEX_ALLOWED (1)
#define MEMP_STATS 1
#define MEM_STATS 1
#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
#define ETHARP_SUPPORT_STATIC_ENTRIES 1
#define LWIP_RIPPLE20 1
/* Beken specific LWIP options */
#define BK_DHCP 1
#endif /* __LWIPOPTS_H__ */

View File

@@ -1,702 +0,0 @@
#include "include.h"
#include <stdio.h>
#include <string.h>
#include <lwip/inet.h>
#include "netif/etharp.h"
#include "lwip/netif.h"
#include <lwip/netifapi.h>
#include <lwip/tcpip.h>
#include <lwip/dns.h>
#include <lwip/dhcp.h>
#include "lwip/prot/dhcp.h"
#include <lwip/sockets.h>
#include "ethernetif.h"
#include "sa_station.h"
#include "drv_model_pub.h"
#include "mem_pub.h"
#include "common.h"
#include "rw_pub.h"
#include "lwip_netif_address.h"
#include "rtos_pub.h"
#include "net.h"
#if CFG_ROLE_LAUNCH
#include "role_launch.h"
#endif
/* forward declaration */
FUNC_1PARAM_PTR bk_wlan_get_status_cb(void);
struct ipv4_config sta_ip_settings;
struct ipv4_config uap_ip_settings;
static int up_iface;
uint32_t sta_ip_start_flag = 0;
uint32_t uap_ip_start_flag = 0;
#ifdef CONFIG_IPV6
#define IPV6_ADDR_STATE_TENTATIVE "Tentative"
#define IPV6_ADDR_STATE_PREFERRED "Preferred"
#define IPV6_ADDR_STATE_INVALID "Invalid"
#define IPV6_ADDR_STATE_VALID "Valid"
#define IPV6_ADDR_STATE_DEPRECATED "Deprecated"
#define IPV6_ADDR_TYPE_LINKLOCAL "Link-Local"
#define IPV6_ADDR_TYPE_GLOBAL "Global"
#define IPV6_ADDR_TYPE_UNIQUELOCAL "Unique-Local"
#define IPV6_ADDR_TYPE_SITELOCAL "Site-Local"
#define IPV6_ADDR_UNKNOWN "Unknown"
#endif
#define net_e warning_prf
#define net_d warning_prf
typedef void (*net_sta_ipup_cb_fn)(void* data);
struct interface {
struct netif netif;
ip4_addr_t ipaddr;
ip4_addr_t nmask;
ip4_addr_t gw;
};
FUNCPTR sta_connected_func;
static struct interface g_mlan = {{0}};
static struct interface g_uap = {{0}};
net_sta_ipup_cb_fn sta_ipup_cb = NULL;
extern void *net_get_sta_handle(void);
extern void *net_get_uap_handle(void);
extern err_t lwip_netif_init(struct netif *netif);
extern err_t lwip_netif_uap_init(struct netif *netif);
extern int net_get_if_ip_addr(uint32_t *ip, void *intrfc_handle);
extern int net_get_if_ip_mask(uint32_t *nm, void *intrfc_handle);
extern int net_configure_address(struct ipv4_config *addr, void *intrfc_handle);
extern int dhcp_server_start(void *intrfc_handle);
extern void dhcp_server_stop(void);
extern void net_configure_dns(struct wlan_ip_config *ip);
int net_dhcp_hostname_set(char *hostname)
{
netif_set_hostname(&g_mlan.netif, hostname);
return 0;
}
void net_ipv4stack_init(void)
{
static bool tcpip_init_done = 0;
if (tcpip_init_done)
return;
net_d("Initializing TCP/IP stack\r\n");
tcpip_init(NULL, NULL);
tcpip_init_done = true;
}
void net_wlan_init(void)
{
static int wlan_init_done = 0;
int ret;
if (!wlan_init_done) {
net_ipv4stack_init();
g_mlan.ipaddr.addr = INADDR_ANY;
ret = netifapi_netif_add(&g_mlan.netif, &g_mlan.ipaddr,
&g_mlan.ipaddr, &g_mlan.ipaddr, NULL,
lwip_netif_init, tcpip_input);
if (ret) {
/*FIXME: Handle the error case cleanly */
net_e("MLAN interface add failed");
}
ret = netifapi_netif_add(&g_uap.netif, &g_uap.ipaddr,
&g_uap.ipaddr, &g_uap.ipaddr, NULL,
lwip_netif_uap_init, tcpip_input);
if (ret) {
/*FIXME: Handle the error case cleanly */
net_e("UAP interface add failed");
}
wlan_init_done = 1;
}
return;
}
void net_set_sta_ipup_callback(void *fn)
{
sta_ipup_cb = (net_sta_ipup_cb_fn)fn;
}
void user_connected_callback(FUNCPTR fn)
{
sta_connected_func = fn;
}
static void wm_netif_status_static_callback(struct netif *n)
{
if (n->flags & NETIF_FLAG_UP)
{
// static IP success;
os_printf("using static ip...\n");
mhdr_set_station_status(RW_EVT_STA_GOT_IP);/* dhcp success*/
if(sta_ipup_cb != NULL)
sta_ipup_cb(NULL);
if(sta_connected_func != NULL)
(*sta_connected_func)();
}
else
{
// static IP fail;
}
}
static void wm_netif_status_callback(struct netif *n)
{
FUNC_1PARAM_PTR fn;
struct dhcp *dhcp;
u32 val;
if (n->flags & NETIF_FLAG_UP)
{
dhcp = netif_dhcp_data(n);
if(dhcp != NULL)
{
if (dhcp->state == DHCP_STATE_BOUND)
{
os_printf("ip_addr: %x\r\n", ip_addr_get_ip4_u32(&n->ip_addr));
#if CFG_ROLE_LAUNCH
rl_pre_sta_set_status(RL_STATUS_STA_LAUNCHED);
#endif
fn = (FUNC_1PARAM_PTR)bk_wlan_get_status_cb();
if(fn)
{
val = RW_EVT_STA_GOT_IP;
(*fn)(&val);
}
mhdr_set_station_status(RW_EVT_STA_GOT_IP);
/* dhcp success*/
if(sta_ipup_cb != NULL)
sta_ipup_cb(NULL);
if(sta_connected_func != NULL)
(*sta_connected_func)();
}
else
{
// dhcp fail
}
}
else
{
// static IP success;
}
}
else
{
// dhcp fail;
}
}
static int check_iface_mask(void *handle, uint32_t ipaddr)
{
uint32_t interface_ip, interface_mask;
net_get_if_ip_addr(&interface_ip, handle);
net_get_if_ip_mask(&interface_mask, handle);
if (interface_ip > 0)
if ((interface_ip & interface_mask) ==
(ipaddr & interface_mask))
return 0;
return -1;
}
void *net_ip_to_interface(uint32_t ipaddr)
{
int ret;
void *handle;
/* Check mlan handle */
handle = net_get_sta_handle();
ret = check_iface_mask(handle, ipaddr);
if (ret == 0)
return handle;
/* Check uap handle */
handle = net_get_uap_handle();
ret = check_iface_mask(handle, ipaddr);
if (ret == 0)
return handle;
/* If more interfaces are added then above check needs to done for
* those newly added interfaces
*/
return NULL;
}
void *net_sock_to_interface(int sock)
{
struct sockaddr_in peer;
unsigned long peerlen = sizeof(struct sockaddr_in);
void *req_iface = NULL;
getpeername(sock, (struct sockaddr *)&peer, &peerlen);
req_iface = net_ip_to_interface(peer.sin_addr.s_addr);
return req_iface;
}
void *net_get_sta_handle(void)
{
return &g_mlan.netif;
}
void *net_get_uap_handle(void)
{
return &g_uap.netif;
}
void *net_get_netif_handle(uint8_t iface)
{
return NULL;
}
void net_interface_up(void *intrfc_handle)
{
struct interface *if_handle = (struct interface *)intrfc_handle;
netifapi_netif_set_up(&if_handle->netif);
}
void net_interface_down(void *intrfc_handle)
{
struct interface *if_handle = (struct interface *)intrfc_handle;
netifapi_netif_set_down(&if_handle->netif);
}
void net_interface_dhcp_stop(void *intrfc_handle)
{
struct interface *if_handle = (struct interface *)intrfc_handle;
netifapi_dhcp_stop(&if_handle->netif);
netif_set_status_callback(&if_handle->netif, NULL);
}
void sta_ip_down(void)
{
if(sta_ip_start_flag)
{
os_printf("sta_ip_down\r\n");
sta_ip_start_flag = 0;
netifapi_netif_set_down(&g_mlan.netif);
netif_set_status_callback(&g_mlan.netif, NULL);
netifapi_dhcp_stop(&g_mlan.netif);
}
}
void sta_ip_start(void)
{
struct wlan_ip_config address = {0};
if(!sta_ip_start_flag)
{
os_printf("sta_ip_start\r\n");
sta_ip_start_flag = 1;
net_configure_address(&sta_ip_settings, net_get_sta_handle());
return;
}
os_printf("sta_ip_start2:0x%x\r\n", address.ipv4.address);
net_get_if_addr(&address, net_get_sta_handle());
if((mhdr_get_station_status() == RW_EVT_STA_CONNECTED)
&& (0 != address.ipv4.address))
{
mhdr_set_station_status(RW_EVT_STA_GOT_IP);
}
}
void sta_set_vif_netif(void)
{
rwm_mgmt_set_vif_netif(&g_mlan.netif);
}
void ap_set_vif_netif(void)
{
rwm_mgmt_set_vif_netif(&g_uap.netif);
}
void sta_set_default_netif(void)
{
netifapi_netif_set_default(net_get_sta_handle());
}
void ap_set_default_netif(void)
{
// as the default netif is sta's netif, so ap need to send
// boardcast or not sub net packets, need set ap netif before
// send those packets, after finish sending, reset default netif
// to sat's netif.
netifapi_netif_set_default(net_get_uap_handle());
}
void reset_default_netif(void)
{
if (sta_ip_is_start()) {
netifapi_netif_set_default(net_get_sta_handle());
} else {
netifapi_netif_set_default(NULL);
}
}
uint32_t sta_ip_is_start(void)
{
return sta_ip_start_flag;
}
void uap_ip_down(void)
{
if (uap_ip_start_flag )
{
os_printf("uap_ip_down\r\n");
uap_ip_start_flag = 0;
netifapi_netif_set_down(&g_uap.netif);
netif_set_status_callback(&g_uap.netif, NULL);
dhcp_server_stop();
}
}
void uap_ip_start(void)
{
if ( !uap_ip_start_flag )
{
os_printf("uap_ip_start\r\n");
uap_ip_start_flag = 1;
net_configure_address(&uap_ip_settings, net_get_uap_handle());
}
}
uint32_t uap_ip_is_start(void)
{
return uap_ip_start_flag;
}
#define DEF_UAP_IP 0xc0a80a01UL /* 192.168.10.1 */
void ip_address_set(int iface, int dhcp, char *ip, char *mask, char*gw, char*dns)
{
uint32_t tmp;
struct ipv4_config addr;
memset(&addr, 0, sizeof(struct ipv4_config));
if (dhcp == 1) {
addr.addr_type = ADDR_TYPE_DHCP;
} else {
addr.addr_type = ADDR_TYPE_STATIC;
tmp = inet_addr((char*)ip);
addr.address = (tmp);
tmp = inet_addr((char*)mask);
if (tmp == 0xFFFFFFFF)
tmp = 0x00FFFFFF;// if not set valid netmask, set as 255.255.255.0
addr.netmask= (tmp);
tmp = inet_addr((char*)gw);
addr.gw = (tmp);
tmp = inet_addr((char*)dns);
addr.dns1 = (tmp);
}
if (iface == 1) // Station
memcpy(&sta_ip_settings, &addr, sizeof(addr));
else
memcpy(&uap_ip_settings, &addr, sizeof(addr));
}
int net_configure_address(struct ipv4_config *addr, void *intrfc_handle)
{
if (!intrfc_handle)
return -1;
struct interface *if_handle = (struct interface *)intrfc_handle;
net_d("\r\nconfiguring interface %s (with %s)",
(if_handle == &g_mlan) ? "mlan" :"uap",
(addr->addr_type == ADDR_TYPE_DHCP)
? "DHCP client" : "Static IP");
netifapi_netif_set_down(&if_handle->netif);
/* De-register previously registered DHCP Callback for correct
* address configuration.
*/
netif_set_status_callback(&if_handle->netif, NULL);
switch (addr->addr_type) {
case ADDR_TYPE_STATIC:
if_handle->ipaddr.addr = addr->address;
if_handle->nmask.addr = addr->netmask;
if_handle->gw.addr = addr->gw;
netifapi_netif_set_addr(&if_handle->netif, &if_handle->ipaddr,
&if_handle->nmask, &if_handle->gw);
netifapi_netif_set_up(&if_handle->netif);
net_configure_dns((struct wlan_ip_config *)addr);
if(if_handle == &g_mlan)
{
netif_set_status_callback(&if_handle->netif,
wm_netif_status_static_callback);
}
break;
case ADDR_TYPE_DHCP:
/* Reset the address since we might be transitioning from static to DHCP */
memset(&if_handle->ipaddr, 0, sizeof(ip_addr_t));
memset(&if_handle->nmask, 0, sizeof(ip_addr_t));
memset(&if_handle->gw, 0, sizeof(ip_addr_t));
netifapi_netif_set_addr(&if_handle->netif, &if_handle->ipaddr,
&if_handle->nmask, &if_handle->gw);
netif_set_status_callback(&if_handle->netif,
wm_netif_status_callback);
netifapi_netif_set_up(&if_handle->netif);
netifapi_dhcp_start(&if_handle->netif);
break;
default:
break;
}
#ifdef CONFIG_IPV6
netif_create_ip6_linklocal_address(&if_handle->netif, 1);
#endif
/* Finally this should send the following event. */
if (if_handle == &g_mlan) {
// static IP up;
/* XXX For DHCP, the above event will only indicate that the
* DHCP address obtaining process has started. Once the DHCP
* address has been obtained, another event,
* WD_EVENT_NET_DHCP_CONFIG, should be sent to the wlcmgr.
*/
up_iface = 1;
// we always set sta netif as the default.
sta_set_default_netif();
} else {
// softap IP up, start dhcp server;
dhcp_server_start(net_get_uap_handle());
up_iface = 0;
// as the default netif is sta's netif, so ap need to send
// boardcast or not sub net packets, need set ap netif before
// send those packets, after finish sending, reset default netif
// to sta's netif.
os_printf("def netif is no ap's netif, sending boardcast or no-subnet ip packets may failed\r\n");
}
return 0;
}
int net_get_if_addr(struct wlan_ip_config *addr, void *intrfc_handle)
{
const ip_addr_t *tmp;
struct interface *if_handle = (struct interface *)intrfc_handle;
if(netif_is_up(&if_handle->netif)) {
addr->ipv4.address = ip_addr_get_ip4_u32(&if_handle->netif.ip_addr);
addr->ipv4.netmask = ip_addr_get_ip4_u32(&if_handle->netif.netmask);
addr->ipv4.gw = ip_addr_get_ip4_u32(&if_handle->netif.gw);
tmp = dns_getserver(0);
addr->ipv4.dns1 = ip_addr_get_ip4_u32(tmp);
tmp = dns_getserver(1);
addr->ipv4.dns2 = ip_addr_get_ip4_u32(tmp);
}
return 0;
}
int net_get_if_macaddr(void *macaddr, void *intrfc_handle)
{
struct interface *if_handle = (struct interface *)intrfc_handle;
os_memcpy(macaddr, &if_handle->netif.hwaddr[0], if_handle->netif.hwaddr_len);
return 0;
}
#ifdef CONFIG_IPV6
int net_get_if_ipv6_addr(struct wlan_ip_config *addr, void *intrfc_handle)
{
struct interface *if_handle = (struct interface *)intrfc_handle;
int i;
for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
ip6_addr_copy_to_packed(addr->ipv6[i],
*ip_2_ip6(&if_handle->netif.ip6_addr[i]));
addr->ipv6[i].addr_state = if_handle->netif.ip6_addr_state[i];
}
/* TODO carry out more processing based on IPv6 fields in netif */
return 0;
}
int net_get_if_ipv6_pref_addr(struct wlan_ip_config *addr, void *intrfc_handle)
{
int i, ret = 0;
struct interface *if_handle = (struct interface *)intrfc_handle;
for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (if_handle->netif.ip6_addr_state[i] == IP6_ADDR_PREFERRED) {
ip6_addr_copy_to_packed(addr->ipv6[ret],
*ip_2_ip6(&if_handle->netif.ip6_addr[i]));
ret++;
}
}
return ret;
}
#endif /* CONFIG_IPV6 */
int net_get_if_ip_addr(uint32_t *ip, void *intrfc_handle)
{
struct interface *if_handle = (struct interface *)intrfc_handle;
*ip = ip_addr_get_ip4_u32(&if_handle->netif.ip_addr);
return 0;
}
int net_get_if_gw_addr(uint32_t *ip, void *intrfc_handle)
{
struct interface *if_handle = (struct interface *)intrfc_handle;
*ip = ip_addr_get_ip4_u32(&if_handle->netif.gw);
return 0;
}
int net_get_if_ip_mask(uint32_t *nm, void *intrfc_handle)
{
struct interface *if_handle = (struct interface *)intrfc_handle;
*nm = ip_addr_get_ip4_u32(&if_handle->netif.netmask);
return 0;
}
void net_configure_dns(struct wlan_ip_config *ip)
{
ip_addr_t tmp;
if (ip->ipv4.addr_type == ADDR_TYPE_STATIC) {
if (ip->ipv4.dns1 == 0)
ip->ipv4.dns1 = ip->ipv4.gw;
if (ip->ipv4.dns2 == 0)
ip->ipv4.dns2 = ip->ipv4.dns1;
ip_addr_set_ip4_u32(&tmp, ip->ipv4.dns1);
dns_setserver(0, &tmp);
ip_addr_set_ip4_u32(&tmp, ip->ipv4.dns2);
dns_setserver(1, &tmp);
}
/* DNS MAX Retries should be configured in lwip/dns.c to 3/4 */
/* DNS Cache size of about 4 is sufficient */
}
void net_wlan_initial(void)
{
net_ipv4stack_init();
}
void net_wlan_add_netif(void *mac)
{
VIF_INF_PTR vif_entry = NULL;
struct interface *wlan_if = NULL;
err_t err;
u8 vif_idx;
u8 *b = (u8*)mac;
if(!b || (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])))
return;
vif_idx = rwm_mgmt_vif_mac2idx(mac);
if(vif_idx == 0xff) {
os_printf("net_add_netif-not-found\r\n");
return ;
}
vif_entry = rwm_mgmt_vif_idx2ptr(vif_idx);
if(!vif_entry) {
os_printf("net_wlan_add_netif not vif found, %d\r\n", vif_idx);
return ;
}
if(vif_entry->type == VIF_AP) {
wlan_if = &g_uap;
} else if(vif_entry->type == VIF_STA) {
wlan_if = &g_mlan;
} else {
os_printf("net_wlan_add_netif with other role\r\n");
return ;
}
wlan_if->ipaddr.addr = INADDR_ANY;
err = netifapi_netif_add(&wlan_if->netif,
&wlan_if->ipaddr,
&wlan_if->ipaddr,
&wlan_if->ipaddr,
(void*)vif_entry,
ethernetif_init,
tcpip_input);
if (err)
{
os_printf("net_wlan_add_netif failed\r\n");
}
else
{
vif_entry->priv = &wlan_if->netif;
}
os_printf("[net]addvif_idx:%d\r\n", vif_idx);
}
void net_wlan_remove_netif(void *mac)
{
err_t err;
u8 vif_idx;
VIF_INF_PTR vif_entry = NULL;
struct netif *netif = NULL;
u8 *b = (u8*)mac;
if(!b || (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])))
return;
vif_idx = rwm_mgmt_vif_mac2idx(mac);
if(vif_idx == 0xff) {
os_printf("net_wlan_add_netif not vif idx found\r\n");
return ;
}
vif_entry = rwm_mgmt_vif_idx2ptr(vif_idx);
if(!vif_entry) {
os_printf("net_wlan_add_netif not vif found, %d\r\n", vif_idx);
return ;
}
netif = (struct netif *)vif_entry->priv;
if(!netif) {
os_printf("net_wlan_remove_netif netif is null\r\n");
return;
}
err = netifapi_netif_remove(netif);
if(err != ERR_OK) {
os_printf("net_wlan_remove_netif failed\r\n");
} else {
netif->state = NULL;
}
os_printf("[net]remoVif_idx:%d\r\n", vif_idx);
}
//eof

View File

@@ -1,25 +0,0 @@
#ifndef _NET_H_
#define _NET_H_
#include "lwip_netif_address.h"
extern void uap_ip_down(void);
extern void uap_ip_start(void);
extern void sta_ip_down(void);
extern void sta_ip_start(void);
extern uint32_t uap_ip_is_start(void);
extern uint32_t sta_ip_is_start(void);
extern void *net_get_sta_handle(void);
extern void *net_get_uap_handle(void);
extern void net_wlan_remove_netif(void *mac);
extern int net_get_if_macaddr(void *macaddr, void *intrfc_handle);
extern int net_get_if_addr(struct wlan_ip_config *addr, void *intrfc_handle);
extern void ip_address_set(int iface, int dhcp, char *ip, char *mask, char*gw, char*dns);
#ifdef CONFIG_IPV6
int net_get_if_ipv6_addr(struct wlan_ip_config *addr, void *intrfc_handle);
int net_get_if_ipv6_pref_addr(struct wlan_ip_config *addr, void *intrfc_handle);
#endif
#endif // _NET_H_
// eof

View File

@@ -1,501 +0,0 @@
/*
* Copyright (c) 2001-2003 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 <adam@sics.se>
*
*/
#include "typedef.h"
#include "sys_rtos.h"
#include "rtos_pub.h"
/* lwIP includes. */
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "lwip/stats.h"
#include "lwip/timeouts.h"
#include "portmacro.h"
#define CFG_ENABLE_LWIP_MUTEX 1
#if CFG_ENABLE_LWIP_MUTEX
static sys_mutex_t sys_arch_mutex;
#endif
/*-----------------------------------------------------------------------------------*/
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
{
(void ) size;
if (size > 0)
*mbox = xQueueCreate( size, sizeof( void * ) );
else
*mbox = xQueueCreate( archMESG_QUEUE_LENGTH, sizeof( void * ) );
#if SYS_STATS
++lwip_stats.sys.mbox.used;
if (lwip_stats.sys.mbox.max < lwip_stats.sys.mbox.used) {
lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used;
}
#endif /* SYS_STATS */
if (*mbox == NULL)
return ERR_MEM;
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
Deallocates a mailbox. If there are messages still present in the
mailbox when the mailbox is deallocated, it is an indication of a
programming error in lwIP and the developer should be notified.
*/
void sys_mbox_free(sys_mbox_t *mbox)
{
if( uxQueueMessagesWaiting( *mbox ) )
{
/* Line for breakpoint. Should never break here! */
portNOP();
#if SYS_STATS
lwip_stats.sys.mbox.err++;
#endif /* SYS_STATS */
// TODO notify the user of failure.
}
vQueueDelete( *mbox );
#if SYS_STATS
--lwip_stats.sys.mbox.used;
#endif /* SYS_STATS */
}
/*-----------------------------------------------------------------------------------*/
// Posts the "msg" to the mailbox.
void sys_mbox_post(sys_mbox_t *mbox, void *data)
{
while ( xQueueSendToBack(*mbox, &data, portMAX_DELAY ) != pdTRUE ){}
}
/*-----------------------------------------------------------------------------------*/
// Try to post the "msg" to the mailbox.
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
{
err_t result;
if ( xQueueSend( *mbox, &msg, 0 ) == pdPASS )
{
result = ERR_OK;
}
else {
// could not post, queue must be full
result = ERR_MEM;
#if SYS_STATS
lwip_stats.sys.mbox.err++;
#endif /* SYS_STATS */
}
return result;
}
/*-----------------------------------------------------------------------------------*/
/*
Blocks the thread until a message arrives in the mailbox, but does
not block the thread longer than "timeout" milliseconds (similar to
the sys_arch_sem_wait() function). The "msg" argument is a result
parameter that is set by the function (i.e., by doing "*msg =
ptr"). The "msg" parameter maybe NULL to indicate that the message
should be dropped.
The return values are the same as for the sys_arch_sem_wait() function:
Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
timeout.
Note that a function with a similar name, sys_mbox_fetch(), is
implemented by lwIP.
*/
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
{
void *dummyptr;
portTickType StartTime, EndTime, Elapsed;
StartTime = xTaskGetTickCount();
if ( msg == NULL )
{
msg = &dummyptr;
}
if ( timeout != 0 )
{
if ( pdTRUE == xQueueReceive( *mbox, &(*msg), timeout / portTICK_RATE_MS ) )
{
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_RATE_MS;
return ( Elapsed );
}
else // timed out blocking for message
{
*msg = NULL;
return SYS_ARCH_TIMEOUT;
}
}
else // block forever for a message.
{
while( pdTRUE != xQueueReceive( *mbox, &(*msg), portMAX_DELAY ) ){} // time is arbitrary
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_RATE_MS;
return ( Elapsed ); // return time blocked TODO test
}
}
/*-----------------------------------------------------------------------------------*/
/*
Similar to sys_arch_mbox_fetch, but if message is not ready immediately, we'll
return with SYS_MBOX_EMPTY. On success, 0 is returned.
*/
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
{
void *dummyptr;
if ( msg == NULL )
{
msg = &dummyptr;
}
if ( pdTRUE == xQueueReceive( *mbox, &(*msg), 0 ) )
{
return ERR_OK;
}
else
{
return SYS_MBOX_EMPTY;
}
}
/*----------------------------------------------------------------------------------*/
int sys_mbox_valid(sys_mbox_t *mbox)
{
if (*mbox == SYS_MBOX_NULL)
return 0;
else
return 1;
}
/*-----------------------------------------------------------------------------------*/
void sys_mbox_set_invalid(sys_mbox_t *mbox)
{
*mbox = SYS_MBOX_NULL;
}
/*-----------------------------------------------------------------------------------*/
// Creates a new semaphore. The "count" argument specifies
// the initial state of the semaphore.
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
{
vSemaphoreCreateBinary(*sem );
if(*sem == NULL)
{
#if SYS_STATS
++lwip_stats.sys.sem.err;
#endif /* SYS_STATS */
return ERR_MEM;
}
if(count == 0) // Means it can't be taken
{
xSemaphoreTake(*sem,1);
}
#if SYS_STATS
++lwip_stats.sys.sem.used;
if (lwip_stats.sys.sem.max < lwip_stats.sys.sem.used) {
lwip_stats.sys.sem.max = lwip_stats.sys.sem.used;
}
#endif /* SYS_STATS */
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
Blocks the thread while waiting for the semaphore to be
signaled. If the "timeout" argument is non-zero, the thread should
only be blocked for the specified time (measured in
milliseconds).
If the timeout argument is non-zero, the return value is the number of
milliseconds spent waiting for the semaphore to be signaled. If the
semaphore wasn't signaled within the specified time, the return value is
SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
(i.e., it was already signaled), the function may return zero.
Notice that lwIP implements a function with a similar name,
sys_sem_wait(), that uses the sys_arch_sem_wait() function.
*/
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
{
portTickType StartTime, EndTime, Elapsed;
StartTime = xTaskGetTickCount();
if( timeout != 0)
{
if( xSemaphoreTake( *sem, timeout / portTICK_RATE_MS ) == pdTRUE )
{
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_RATE_MS;
return (Elapsed); // return time blocked TODO test
}
else
{
return SYS_ARCH_TIMEOUT;
}
}
else // must block without a timeout
{
while( xSemaphoreTake( *sem, portMAX_DELAY) != pdTRUE)
{
;
}
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_RATE_MS;
return ( Elapsed ); // return time blocked
}
}
/*-----------------------------------------------------------------------------------*/
// Signals a semaphore
void sys_sem_signal(sys_sem_t *sem)
{
xSemaphoreGive(*sem);
}
/*-----------------------------------------------------------------------------------*/
// Deallocates a semaphore
void sys_sem_free(sys_sem_t *sem)
{
#if SYS_STATS
--lwip_stats.sys.sem.used;
#endif /* SYS_STATS */
vQueueDelete(*sem);
}
/*-----------------------------------------------------------------------------------*/
int sys_sem_valid(sys_sem_t *sem)
{
if (*sem == SYS_SEM_NULL)
return 0;
else
return 1;
}
/*-----------------------------------------------------------------------------------*/
void sys_sem_set_invalid(sys_sem_t *sem)
{
*sem = SYS_SEM_NULL;
}
/*-----------------------------------------------------------------------------------*/
err_t sys_mutex_trylock(sys_mutex_t *pxMutex)
{
if (xSemaphoreTake(*pxMutex, 0) == pdPASS)
return 0;
else
return -1;
}
/*-----------------------------------------------------------------------------------*/
// Initialize sys arch
void sys_init(void)
{
#if CFG_ENABLE_LWIP_MUTEX
sys_mutex_new(&sys_arch_mutex);
#endif
}
/*-----------------------------------------------------------------------------------*/
/* Mutexes*/
/*-----------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------*/
/* Create a new mutex*/
err_t sys_mutex_new(sys_mutex_t *mutex) {
*mutex = xSemaphoreCreateMutex();
if(*mutex == NULL)
{
#if SYS_STATS
++lwip_stats.sys.mutex.err;
#endif /* SYS_STATS */
return ERR_MEM;
}
#if SYS_STATS
++lwip_stats.sys.mutex.used;
if (lwip_stats.sys.mutex.max < lwip_stats.sys.mutex.used) {
lwip_stats.sys.mutex.max = lwip_stats.sys.mutex.used;
}
#endif /* SYS_STATS */
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/* Deallocate a mutex*/
void sys_mutex_free(sys_mutex_t *mutex)
{
#if SYS_STATS
--lwip_stats.sys.mutex.used;
#endif /* SYS_STATS */
vQueueDelete(*mutex);
}
/*-----------------------------------------------------------------------------------*/
/* Lock a mutex*/
void sys_mutex_lock(sys_mutex_t *mutex)
{
sys_arch_sem_wait(mutex, BEKEN_WAIT_FOREVER);
}
/*-----------------------------------------------------------------------------------*/
/* Unlock a mutex*/
void sys_mutex_unlock(sys_mutex_t *mutex)
{
xSemaphoreGive(*mutex);
}
/*-----------------------------------------------------------------------------------*/
// TODO
/*-----------------------------------------------------------------------------------*/
/*
Starts a new thread with priority "prio" that will begin its execution in the
function "thread()". The "arg" argument will be passed as an argument to the
thread() function. The id of the new thread is returned. Both the id and
the priority are system dependent.
*/
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio)
{
xTaskHandle CreatedTask;
int result;
result = xTaskCreate( thread, ( portCHAR * ) name, stacksize, arg, prio, &CreatedTask );
if(result == pdPASS)
{
return CreatedTask;
}
else
{
return NULL;
}
}
int sys_thread_delete(xTaskHandle pid)
{
return pdPASS;
}
/*
This optional function does a "fast" critical region protection and returns
the previous protection level. This function is only called during very short
critical regions. An embedded system which supports ISR-based drivers might
want to implement this function by disabling interrupts. Task-based systems
might want to implement this by using a mutex or disabling tasking. This
function should support recursive calls from the same task or interrupt. In
other words, sys_arch_protect() could be called while already protected. In
that case the return value indicates that it is already protected.
sys_arch_protect() is only required if your port is supporting an operating
system.
*/
sys_prot_t sys_arch_protect(void)
{
#if CFG_ENABLE_LWIP_MUTEX
sys_mutex_lock(&sys_arch_mutex);
return 0;
#else
return port_disable_interrupts_flag();
#endif
}
/*
This optional function does a "fast" set of critical region protection to the
value specified by pval. See the documentation for sys_arch_protect() for
more information. This function is only required if your port is supporting
an operating system.
*/
void sys_arch_unprotect(sys_prot_t pval)
{
#if CFG_ENABLE_LWIP_MUTEX
(void)pval;
sys_mutex_unlock(&sys_arch_mutex);
#else
port_enable_interrupts_flag(pval);
#endif
}
/*
* Prints an assertion messages and aborts execution.
*/
void sys_assert( const char *msg )
{
(void) msg;
/*FSL:only needed for debugging*/
printf(msg);
printf("\n\r");
vPortEnterCritical();
for(;;)
;
}
u32_t sys_now(void)
{
return xTaskGetTickCount() * portTICK_RATE_MS;
}
u32_t sys_jiffies(void)
{
return xTaskGetTickCount() * portTICK_RATE_MS;
}
void sys_arch_msleep(int ms)
{
vTaskDelay(ms / portTICK_RATE_MS);
}
// eof

View File

@@ -1272,7 +1272,7 @@ mdns_parse_pkt_known_answers(struct netif *netif, struct mdns_packet *pkt,
} else if (match & REPLY_SERVICE_TXT) {
mdns_prepare_txtdata(service);
if (service->txtdata.length == ans.rd_length &&
pbuf_memcmp(pkt->pbuf, ans.rd_offset, service->txtdata.name, ans.rd_length) == 0) {
pbuf_memcmp(pkt->pbuf, ans.rd_offset, service->txtdata.rdata, ans.rd_length) == 0) {
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: TXT\n"));
reply->serv_replies[i] &= ~REPLY_SERVICE_TXT;
}
@@ -2050,7 +2050,7 @@ mdns_handle_response(struct mdns_packet *pkt, struct netif *netif)
} else if (ans.info.type == DNS_RRTYPE_TXT) {
mdns_prepare_txtdata(service);
if (service->txtdata.length == ans.rd_length &&
pbuf_memcmp(pkt->pbuf, ans.rd_offset, service->txtdata.name, ans.rd_length) == 0) {
pbuf_memcmp(pkt->pbuf, ans.rd_offset, service->txtdata.rdata, ans.rd_length) == 0) {
LWIP_DEBUGF(MDNS_DEBUG, ("mDNS: response equals our own TXT record -> no conflict\n"));
conflict = 0;
}
@@ -2613,10 +2613,29 @@ mdns_resp_rename_service(struct netif *netif, u8_t slot, const char *name)
return ERR_OK;
}
/* Adds an RFC 1035 character-string to TXT RDATA. */
static err_t
mdns_txt_add_charstr(struct mdns_txtdata *txtdata, const char *value, u8_t len)
{
if (1 + len + txtdata->length > MDNS_TXT_RDATA_SIZE) {
LWIP_DEBUGF(MDNS_DEBUG, ("mdns_txt_add_charstr: adding string would exceed buffer (1+%d+%d > %d). Consider increasing MDNS_TXT_RDATA_SIZE.\n",
len, txtdata->length, MDNS_TXT_RDATA_SIZE));
return ERR_MEM;
}
txtdata->rdata[txtdata->length] = len;
txtdata->length++;
if (len) {
MEMCPY(&txtdata->rdata[txtdata->length], value, len);
txtdata->length += len;
}
return ERR_OK;
}
/**
* @ingroup mdns
* Call this function from inside the service_get_txt_fn_t callback to add text data.
* Buffer for TXT data is 256 bytes, and each field is prefixed with a length byte.
* Buffer for TXT data is MDNS_TXT_RDATA_SIZE (default 256) bytes, and each
* field is prefixed with a length byte.
* @param service The service provided to the get_txt callback
* @param txt String to add to the TXT field.
* @param txt_len Length of string
@@ -2628,10 +2647,8 @@ mdns_resp_add_service_txtitem(struct mdns_service *service, const char *txt, u8_
LWIP_ASSERT_CORE_LOCKED();
LWIP_ASSERT("mdns_resp_add_service_txtitem: service != NULL", service);
LWIP_DEBUGF(MDNS_DEBUG, ("mDNS: adding txtitem: txt_len=%d, %02x %02x %02x %02x", txt_len, (int)txt[0], (int)txt[1], (int)txt[2], (int)txt[3])); /* DEBUG FIXME(dlitz) */
/* Use a mdns_domain struct to store txt chunks since it is the same encoding */
return mdns_domain_add_label(&service->txtdata, txt, txt_len);
return mdns_txt_add_charstr(&service->txtdata, txt, txt_len);
}
#if LWIP_MDNS_SEARCH

View File

@@ -62,7 +62,7 @@ static void mdns_clear_outmsg(struct mdns_outmsg *outmsg);
void
mdns_prepare_txtdata(struct mdns_service *service)
{
memset(&service->txtdata, 0, sizeof(struct mdns_domain));
memset(&service->txtdata, 0, sizeof(struct mdns_txtdata));
if (service->txt_fn) {
service->txt_fn(service, service->txt_userdata);
}
@@ -508,7 +508,7 @@ mdns_add_txt_answer(struct mdns_outpacket *reply, struct mdns_outmsg *msg,
}
LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with TXT record\n"));
return mdns_add_answer(reply, &service_instance, DNS_RRTYPE_TXT, DNS_RRCLASS_IN,
msg->cache_flush, ttl, (u8_t *) &service->txtdata.name,
msg->cache_flush, ttl, service->txtdata.rdata,
service->txtdata.length, NULL);
}

View File

@@ -88,6 +88,12 @@
#define MDNS_OUTPUT_PACKET_SIZE ((MDNS_MAX_SERVICES == 1) ? 512 : 1450)
#endif
/** The maximum size of TXT RDATA allocated for each service.
*/
#ifndef MDNS_TXT_RDATA_SIZE
# define MDNS_TXT_RDATA_SIZE 256
#endif
/** MDNS_RESP_USENETIF_EXTCALLBACK==1: register an ext_callback on the netif
* to automatically restart probing/announcing on status or address change.
*/

View File

@@ -90,10 +90,16 @@ struct mdns_request {
};
#endif
/** TXT record data */
struct mdns_txtdata {
u8_t rdata[MDNS_TXT_RDATA_SIZE];
u16_t length;
};
/** Description of a service */
struct mdns_service {
/** TXT record to answer with */
struct mdns_domain txtdata;
struct mdns_txtdata txtdata;
/** Name of service, like 'myweb' */
char name[MDNS_LABEL_MAXLEN + 1];
/** Type of service, like '_http' */

View File

@@ -35,6 +35,7 @@
#include "lwip/pbuf.h"
#include "lwip/apps/mdns.h"
#include "lwip/apps/mdns_domain.h"
#include "lwip/apps/mdns_out.h"
#include "lwip/apps/mdns_priv.h"
START_TEST(readname_basic)
@@ -876,6 +877,155 @@ START_TEST(compress_long_match)
}
END_TEST
#define TXT_STRING_1 "path=/"
#define TXT_LENGTH_1 6
#define TXT_LENSTR_1 "\006"
#define TXT_STRING_2 ""
#define TXT_LENGTH_2 0
#define TXT_LENSTR_2 "\000"
#define TXT_STRING_3 "This sentence is sixty-three bytes long, including punctuation."
#define TXT_LENGTH_3 63
#define TXT_LENSTR_3 "\077"
#define TXT_STRING_4 "This tests whether mdns_resp_add_service_txtitem can properly handle strings longer than 63 characters."
#define TXT_LENGTH_4 103
#define TXT_LENSTR_4 "\147"
START_TEST(txt_short_item)
{
const char *expected_txtdata = TXT_LENSTR_1 TXT_STRING_1;
const size_t expected_txtdata_length = 1 + TXT_LENGTH_1;
struct mdns_service service;
err_t res;
memset(&service, 0, sizeof(struct mdns_service));
mdns_prepare_txtdata(&service);
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_1, TXT_LENGTH_1);
fail_unless(res == ERR_OK);
fail_unless(service.txtdata.length == expected_txtdata_length);
fail_if(memcmp(service.txtdata.rdata, expected_txtdata, expected_txtdata_length));
}
END_TEST
START_TEST(txt_empty_item)
{
const char *expected_txtdata = TXT_LENSTR_2 TXT_STRING_2;
const size_t expected_txtdata_length = 1 + TXT_LENGTH_2;
struct mdns_service service;
err_t res;
memset(&service, 0, sizeof(struct mdns_service));
mdns_prepare_txtdata(&service);
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_2, TXT_LENGTH_2);
fail_unless(res == ERR_OK);
fail_unless(service.txtdata.length == expected_txtdata_length);
fail_if(memcmp(service.txtdata.rdata, expected_txtdata, expected_txtdata_length));
}
END_TEST
START_TEST(txt_long_item)
{
const char *expected_txtdata = TXT_LENSTR_4 TXT_STRING_4;
const size_t expected_txtdata_length = 1 + TXT_LENGTH_4;
struct mdns_service service;
err_t res;
memset(&service, 0, sizeof(struct mdns_service));
mdns_prepare_txtdata(&service);
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_4, TXT_LENGTH_4);
fail_unless(res == ERR_OK);
fail_unless(service.txtdata.length == expected_txtdata_length);
fail_if(memcmp(service.txtdata.rdata, expected_txtdata, expected_txtdata_length));
}
END_TEST
START_TEST(txt_multiple_items)
{
const char *expected_txtdata = (
TXT_LENSTR_1
TXT_STRING_1
TXT_LENSTR_2
TXT_STRING_2
TXT_LENSTR_3
TXT_STRING_3
TXT_LENSTR_4
TXT_STRING_4
);
const size_t expected_txtdata_length = (
1 + TXT_LENGTH_1
+ 1 + TXT_LENGTH_2
+ 1 + TXT_LENGTH_3
+ 1 + TXT_LENGTH_4
);
struct mdns_service service;
err_t res;
memset(&service, 0, sizeof(struct mdns_service));
mdns_prepare_txtdata(&service);
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_1, TXT_LENGTH_1);
fail_unless(res == ERR_OK); /* TXT_STRING_1 */
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_2, TXT_LENGTH_2);
fail_unless(res == ERR_OK); /* TXT_STRING_1 */
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_3, TXT_LENGTH_3);
fail_unless(res == ERR_OK); /* TXT_STRING_3 */
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_4, TXT_LENGTH_4);
fail_unless(res == ERR_OK); /* TXT_STRING_4 */
fail_unless(service.txtdata.length == expected_txtdata_length);
fail_if(memcmp(service.txtdata.rdata, expected_txtdata, expected_txtdata_length));
}
END_TEST
START_TEST(txt_buffer_full)
{
const char *expected_txtdata = (
TXT_LENSTR_3 TXT_STRING_3
TXT_LENSTR_3 TXT_STRING_3
TXT_LENSTR_3 TXT_STRING_3
TXT_LENSTR_3 TXT_STRING_3
);
const size_t expected_txtdata_length = 256;
struct mdns_service service;
err_t res;
int i;
memset(&service, 0, sizeof(struct mdns_service));
mdns_prepare_txtdata(&service);
/* add a 64-byte string 4 times = 256 bytes */
for (i = 0; i < 4; i++) {
res = mdns_resp_add_service_txtitem(&service, TXT_STRING_3, TXT_LENGTH_3);
ck_assert_msg(res == ERR_OK,
"adding text item failed with error %d (i=%d, txtdata.length=%d)",
res, i, service.txtdata.length);
}
/* Try to add a few more strings while the buffer is full. This should fail. */
res = mdns_resp_add_service_txtitem(&service, "", 0);
fail_unless(res != ERR_OK); /* empty string */
res = mdns_resp_add_service_txtitem(&service, "path=/", 6);
fail_unless(res != ERR_OK); /* short string */
fail_unless(service.txtdata.length == expected_txtdata_length);
fail_if(memcmp(service.txtdata.rdata, expected_txtdata, expected_txtdata_length));
}
END_TEST
Suite* mdns_suite(void)
{
testfunc tests[] = {
@@ -911,6 +1061,12 @@ Suite* mdns_suite(void)
TESTFUNC(compress_2nd_label_short),
TESTFUNC(compress_jump_to_jump),
TESTFUNC(compress_long_match),
TESTFUNC(txt_short_item),
TESTFUNC(txt_empty_item),
TESTFUNC(txt_long_item),
TESTFUNC(txt_multiple_items),
TESTFUNC(txt_buffer_full),
};
return create_suite("MDNS", tests, sizeof(tests)/sizeof(testfunc), NULL, NULL);
}