SYSTEM_EVENT_AP_STACONNECTED, /**< a station connected to ESP32 soft-AP */
SYSTEM_EVENT_AP_STADISCONNECTED, /**< a station disconnected from ESP32 soft-AP */
SYSTEM_EVENT_AP_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */
+ SYSTEM_EVENT_AP_STA_GOT_IP6, /**< ESP32 station or ap interface v6IP addr is preferred */
SYSTEM_EVENT_MAX
} system_event_id_t;
typedef struct {
uint8_t pin_code[8]; /**< PIN code of station in enrollee mode */
-}system_event_sta_wps_er_pin_t;
+} system_event_sta_wps_er_pin_t;
+
+typedef struct {
+ tcpip_adapter_ip6_info_t ip6_info;
+} system_event_ap_sta_got_ip6_t;
typedef struct {
uint8_t mac[6]; /**< MAC address of the station connected to ESP32 soft-AP */
system_event_ap_staconnected_t sta_connected; /**< a station connected to ESP32 soft-AP */
system_event_ap_stadisconnected_t sta_disconnected; /**< a station disconnected to ESP32 soft-AP */
system_event_ap_probe_req_rx_t ap_probereqrecved; /**< ESP32 soft-AP receive probe request packet */
+ system_event_ap_sta_got_ip6_t got_ip6; /**< ESP32 station or ap ipv6 addr state change to preferred */
} system_event_info_t;
typedef struct {
case IPPROTO_IPV6:
switch (optname) {
case IPV6_V6ONLY:
- /* @todo: this does not work for datagram sockets, yet */
+ /* @todo: this does not work for datagram sockets, yet */
+#if CONFIG_MDNS
+ //LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_TCP);
+#else
LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_TCP);
+#endif
if (*(const int*)optval) {
netconn_set_ipv6only(sock->conn, 1);
} else {
#include "lwip/netif.h"
#include "lwip/autoip.h"
#include "netif/etharp.h"
+#include "lwip/dhcp.h"
#include <stdlib.h>
#include <string.h>
netif_set_addr(netif, &autoip->llipaddr, &sn_mask, &gw_addr);
/* interface is used by routing now that an address is set */
+#if ESP_LWIP
+ struct dhcp *dhcp = netif->dhcp;
+ if (dhcp->cb != NULL) {
+ dhcp->cb();
+ }
+#endif
return ERR_OK;
}
pbuf_free(p);
}
+#ifdef ESP_LWIP
+
+/** Set callback for ipv6 addr status changed .
+ *
+ * @param netif the netif from which to remove the struct dhcp
+ * @param cb callback for dhcp
+ */
+void nd6_set_cb(struct netif *netif, void (*cb)(struct netif *netif, u8_t ip_index))
+{
+ LWIP_ASSERT("netif != NULL", netif != NULL);
+
+ if (netif != NULL && netif_is_up(netif)) {
+ netif->ipv6_addr_cb = cb;
+ }
+}
+#endif
/**
* Periodic timer for Neighbor discovery functions:
if ((netif->ip6_addr_state[i] & 0x07) >= LWIP_IPV6_DUP_DETECT_ATTEMPTS) {
/* No NA received in response. Mark address as valid. */
netif->ip6_addr_state[i] = IP6_ADDR_PREFERRED;
+#ifdef ESP_LWIP
+ if (netif->ipv6_addr_cb != NULL) {
+ netif->ipv6_addr_cb(netif, i);
+ }
+#endif
+
/* TODO implement preferred and valid lifetimes. */
} else if (netif->flags & NETIF_FLAG_UP) {
#if LWIP_IPV6_MLD
}
}
-#if ESP_LWIP
- ip6_addr_set( ip_2_ip6(&netif->link_local_addr), ip_2_ip6(&netif->ip6_addr[0]) );
-#endif
/* Set address state. */
#if LWIP_IPV6_DUP_DETECT_ATTEMPTS
return ERR_VAL;
}
-
-#if ESP_LWIP
-void
-netif_create_ip4_linklocal_address(struct netif * netif)
-{
-#if 1
- ip_addr_t linklocal;
- ip_addr_t linklocal_mask;
- ip4_addr_t addr = {0};
- /* Link-local prefix and mask. */
- IP4_ADDR(ip_2_ip4(&linklocal), 169, 254, 0, 0);
- IP4_ADDR(ip_2_ip4(&linklocal_mask), 255, 255, 0, 0);
-
- if (!ip4_addr_netcmp( ip_2_ip4(&linklocal), ip_2_ip4(&netif->link_local_addr), ip_2_ip4(&linklocal_mask) ) &&
- !ip4_addr_isany(ip_2_ip4(&netif->ip_addr)) ) {
- IP4_ADDR( ip_2_ip4(&netif->link_local_addr), 169, 254, ip4_addr3( ip_2_ip4(&netif->ip_addr) )
- , ip4_addr4( ip_2_ip4(&netif->ip_addr) ) );
- return;
- }
-
- while ( !(addr.addr) || !ip4_addr4(&addr) )
- //os_get_random((unsigned char *)&addr, sizeof(addr));
- addr.addr = LWIP_RAND();
-
-
- if ( ip_2_ip4(&netif->netmask)->addr > IP_CLASSB_NET &&
- !ip4_addr_isany( ip_2_ip4(&netif->ip_addr) )) { // random host address
- IP4_ADDR( ip_2_ip4(&netif->link_local_addr), 169, 254, ip4_addr3( ip_2_ip4(&netif->ip_addr))
- , ip4_addr4(&addr));
- } else {
- IP4_ADDR( ip_2_ip4(&netif->link_local_addr), 169, 254, ip4_addr3(&addr), ip4_addr4(&addr) );
- }
-#endif
-}
-
-#endif
-
-
/** Dummy IPv6 output function for netifs not supporting IPv6
*/
static err_t
#define ANNOUNCE_NUM 2 /* (number of announcement packets) */
#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */
#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */
+#if CONFIG_MDNS
+#define MAX_CONFLICTS 9 /* (max conflicts before rate limiting) */
+#define RATE_LIMIT_INTERVAL 20 /* seconds (delay between successive attempts) */
+#else
#define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */
#define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */
+#endif
#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */
/* AutoIP client states */
void nd6_reachability_hint(const ip6_addr_t * ip6addr);
#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */
+#if ESP_LWIP
+/** set nd6 callback when ipv6 addr state pref*/
+void nd6_set_cb(struct netif *netif, void (*cb)(struct netif *netif, u8_t ip_index));
+#endif
#ifdef __cplusplus
}
#endif
/** pointer to next in linked list */
struct netif *next;
-#if ESP_LWIP
-//ip_addr_t is changed by marco IPV4, IPV6
- ip_addr_t link_local_addr;
-#endif
-
#if LWIP_IPV4
/** IP address configuration in network byte order */
ip_addr_t ip_addr;
/** The state of each IPv6 address (Tentative, Preferred, etc).
* @see ip6_addr.h */
u8_t ip6_addr_state[LWIP_IPV6_NUM_ADDRESSES];
+#if ESP_LWIP
+ void (*ipv6_addr_cb)(struct netif* netif, u8_t ip_idex); /* callback for ipv6 addr states changed */
+#endif
+
#endif /* LWIP_IPV6 */
/** This function is called by the network device driver
* to pass a packet up the TCP/IP stack. */
*/
#define SMEMCPY(dst,src,len) memcpy(dst,src,len)
-extern unsigned long os_random(void);
-#define LWIP_RAND rand
+#define LWIP_RAND rand
+
/*
------------------------------------
---------- Memory options ----------
*/
#define LWIP_DHCP 1
+#define DHCP_MAXRTX 0
-#define DHCP_MAXRTX 0 //(*(volatile uint32*)0x600011E0)
/*
------------------------------------
---------- AUTOIP options ----------
------------------------------------
*/
+#if CONFIG_MDNS
+ /**
+ * LWIP_AUTOIP==1: Enable AUTOIP module.
+ */
+#define LWIP_AUTOIP 1
+
+/**
+* LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on
+* the same interface at the same time.
+*/
+#define LWIP_DHCP_AUTOIP_COOP 1
+
+/**
+* LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes
+* that should be sent before falling back on AUTOIP. This can be set
+* as low as 1 to get an AutoIP address very quickly, but you should
+* be prepared to handle a changing IP address when DHCP overrides
+* AutoIP.
+*/
+#define LWIP_DHCP_AUTOIP_COOP_TRIES 2
+#endif
+
/*
----------------------------------
---------- SNMP options ----------
---------- LOOPIF options ----------
------------------------------------
*/
+#if CONFIG_MDNS
+/**
+ * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP
+ * address equal to the netif IP address, looping them back up the stack.
+ */
+#define LWIP_NETIF_LOOPBACK 1
+
+/**
+ * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback
+ * sending for each netif (0 = disabled)
+ */
+#define LWIP_LOOPBACK_MAX_PBUFS 8
+#endif
/*
------------------------------------
*/
#define SO_REUSE CONFIG_LWIP_SO_REUSE
+#if CONFIG_MDNS
+/**
+ * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets
+ * to all local matches if SO_REUSEADDR is turned on.
+ * WARNING: Adds a memcpy for every packet if passing to more than one pcb!
+ */
+#define SO_REUSE_RXTOALL 1
+#endif
+
/*
----------------------------------------
---------- Statistics options ----------
ip4_addr_t gw;
} tcpip_adapter_ip_info_t;
+typedef struct {
+ ip6_addr_t ip;
+} tcpip_adapter_ip6_info_t;
+
typedef dhcps_lease_t tcpip_adapter_dhcps_lease_t;
#if CONFIG_DHCP_STA_LIST
typedef struct {
uint8_t mac[6];
ip4_addr_t ip;
-}tcpip_adapter_sta_info_t;
+} tcpip_adapter_sta_info_t;
typedef struct {
tcpip_adapter_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM];
int num;
-}tcpip_adapter_sta_list_t;
+} tcpip_adapter_sta_list_t;
#endif
#endif
*/
esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info);
+/**
+ * @brief create interface's linklocal IPv6 information
+ *
+ * @note this function will create a linklocal IPv6 address about input interface,
+ * if this address status changed to preferred, will call event call back ,
+ * notify user linklocal IPv6 address has been verified
+ *
+ * @param[in] tcpip_if: the interface which we want to set IP information
+ *
+ *
+ * @return ESP_OK
+ * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
+ */
+esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if);
+
+/**
+ * @brief get interface's linkloacl IPv6 information
+ *
+ * There has an IPv6 information copy in adapter library, if interface is up,and IPv6 info
+ * is preferred,it will get IPv6 linklocal IP successfully
+ *
+ * @param[in] tcpip_if: the interface which we want to set IP information
+ * @param[in] if_ip6: If successful, IPv6 information will be returned in this argument.
+ *
+ * @return ESP_OK
+ * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
+ */
+esp_err_t tcpip_adapter_get_ip6_linklocal(tcpip_adapter_if_t tcpip_if, ip6_addr_t *if_ip6);
+
#if 0
esp_err_t tcpip_adapter_get_mac(tcpip_adapter_if_t tcpip_if, uint8_t *mac);
#include "lwip/tcpip.h"
#include "lwip/dhcp.h"
#include "lwip/ip_addr.h"
-
+#include "lwip/ip6_addr.h"
+#include "lwip/nd6.h"
#include "netif/wlanif.h"
#include "apps/dhcpserver.h"
static struct netif *esp_netif[TCPIP_ADAPTER_IF_MAX];
static tcpip_adapter_ip_info_t esp_ip[TCPIP_ADAPTER_IF_MAX];
+static tcpip_adapter_ip6_info_t esp_ip6[TCPIP_ADAPTER_IF_MAX];
static tcpip_adapter_dhcp_status_t dhcps_status = TCPIP_ADAPTER_DHCP_INIT;
static tcpip_adapter_dhcp_status_t dhcpc_status = TCPIP_ADAPTER_DHCP_INIT;
return ESP_OK;
}
+static void tcpip_adapter_nd6_cb(struct netif *p_netif, uint8_t ip_idex)
+{
+ tcpip_adapter_ip6_info_t *ip6_info;
+
+ if (!p_netif) {
+ TCPIP_ADAPTER_DEBUG("null p_netif=%p\n", p_netif);
+ return;
+ }
+
+ if (p_netif == esp_netif[TCPIP_ADAPTER_IF_STA]) {
+ ip6_info = &esp_ip6[TCPIP_ADAPTER_IF_STA];
+ } else if(p_netif == esp_netif[TCPIP_ADAPTER_IF_AP]) {
+ ip6_info = &esp_ip6[TCPIP_ADAPTER_IF_AP];
+ } else {
+ return;
+ }
+
+ system_event_t evt;
+
+ ip6_addr_set(&ip6_info->ip, ip_2_ip6(&p_netif->ip6_addr[ip_idex]));
+
+ //notify event
+ evt.event_id = SYSTEM_EVENT_AP_STA_GOT_IP6;
+ memcpy(&evt.event_info.got_ip6.ip6_info, ip6_info, sizeof(tcpip_adapter_ip6_info_t));
+ esp_event_send(&evt);
+}
+
+esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if)
+{
+ struct netif *p_netif;
+
+ if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
+ return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
+ }
+
+ p_netif = esp_netif[tcpip_if];
+ if(p_netif != NULL && netif_is_up(p_netif)) {
+ netif_create_ip6_linklocal_address(p_netif, 1);
+ nd6_set_cb(p_netif, tcpip_adapter_nd6_cb);
+
+ return ESP_OK;
+ } else {
+ return ESP_FAIL;
+ }
+}
+
+esp_err_t tcpip_adapter_get_ip6_linklocal(tcpip_adapter_if_t tcpip_if, ip6_addr_t *if_ip6)
+{
+ struct netif *p_netif;
+
+ if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || if_ip6 == NULL) {
+ return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
+ }
+
+ p_netif = esp_netif[tcpip_if];
+ if (p_netif != NULL && netif_is_up(p_netif) && ip6_addr_ispreferred(netif_ip6_addr_state(p_netif, 0))) {
+ memcpy(if_ip6, &p_netif->ip6_addr[0], sizeof(ip6_addr_t));
+ } else {
+ return ESP_FAIL;
+ }
+ return ESP_OK;
+}
+
#if 0
esp_err_t tcpip_adapter_get_mac(tcpip_adapter_if_t tcpip_if, uint8_t mac[6])
{