diff --git a/.gitmodules b/.gitmodules index 19b3794..17f8003 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "lwip/lwip"] path = lwip/lwip - url = https://github.com/SuperHouse/esp-lwip.git + url = https://github.com/ourairquality/lwip.git [submodule "extras/mbedtls/mbedtls"] path = extras/mbedtls/mbedtls url = https://github.com/ARMmbed/mbedtls.git diff --git a/README.md b/README.md index 6f1a381..5617771 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ Current status is alpha quality, actively developed. AP STATION mode (ie wifi cl ## Open Source Components * [FreeRTOS](http://www.freertos.org/) V9.0.0 -* [lwIP](http://lwip.wikia.com/wiki/LwIP_Wiki) v1.4.1, modified via the [esp-lwip project](https://github.com/kadamski/esp-lwip) by @kadamski. +* [lwIP](http://lwip.wikia.com/wiki/LwIP_Wiki) v2.0.3, with [some modifications](https://github.com/ourairquality/lwip/). * [newlib](https://github.com/projectgus/newlib-xtensa) v2.2.0, with patches for xtensa support and locking stubs for thread-safe operation on FreeRTOS. For details of how third party libraries are integrated, [see the wiki page](https://github.com/SuperHouse/esp-open-rtos/wiki/Third-Party-Libraries). diff --git a/core/app_main.c b/core/app_main.c index e56b0ab..5ea0851 100644 --- a/core/app_main.c +++ b/core/app_main.c @@ -311,8 +311,8 @@ static void init_g_ic(void) { if (sdk_g_ic.s._unknown310 > 4) { sdk_g_ic.s._unknown310 = 4; } - if (sdk_g_ic.s._unknown1e4._unknown1e4 == 0xffffffff) { - bzero(&sdk_g_ic.s._unknown1e4, sizeof(sdk_g_ic.s._unknown1e4)); + if (sdk_g_ic.s.sta_ssid.ssid_length == 0xffffffff) { + bzero(&sdk_g_ic.s.sta_ssid, sizeof(sdk_g_ic.s.sta_ssid)); bzero(&sdk_g_ic.s.sta_password, sizeof(sdk_g_ic.s.sta_password)); } sdk_g_ic.s.wifi_led_enable = 0; diff --git a/core/include/sdk_internal.h b/core/include/sdk_internal.h index 1847eef..3dfa8df 100644 --- a/core/include/sdk_internal.h +++ b/core/include/sdk_internal.h @@ -14,12 +14,12 @@ // 'info' is declared in app_main.o at .bss+0x4 struct sdk_info_st { - ip_addr_t softap_ipaddr; // 0x00 - ip_addr_t softap_netmask; // 0x04 - ip_addr_t softap_gw; // 0x08 - ip_addr_t sta_ipaddr; // 0x0c - ip_addr_t sta_netmask; // 0x10 - ip_addr_t sta_gw; // 0x14 + ip4_addr_t softap_ipaddr; // 0x00 + ip4_addr_t softap_netmask; // 0x04 + ip4_addr_t softap_gw; // 0x08 + ip4_addr_t sta_ipaddr; // 0x0c + ip4_addr_t sta_netmask; // 0x10 + ip4_addr_t sta_gw; // 0x14 uint8_t softap_mac_addr[6]; // 0x18 uint8_t sta_mac_addr[6]; // 0x1e }; @@ -83,7 +83,7 @@ struct _unknown_wpa1 { }; -struct sdk_netif_conninfo { +struct sdk_cnx_node { uint8_t mac_addr[6]; uint8_t _unknown07[2]; @@ -105,10 +105,12 @@ struct sdk_netif_conninfo { uint16_t _unknown9c; // ieee80211_hostap. increases by one one each timer func called. uint16_t _unknown9e; - uint32_t _unknowna0[18]; + uint32_t _unknowna0[17]; - int8_t _unknowne8; // - int8_t _unknowne9; // ppInstallKey + void *_unknowne4; + + uint8_t _unknowne8; // + uint8_t _unknowne9; // ppInstallKey int8_t _unknownea; int8_t _unknowneb; @@ -128,9 +130,9 @@ struct sdk_g_ic_netif_info { uint32_t _unknown48; // 0x48 uint8_t _unknown4c; // 0x4c uint8_t _unknown4d[59]; // 0x4d - 0x88 - struct sdk_netif_conninfo *_unknown88; // 0x88 + struct sdk_cnx_node *_unknown88; // 0x88 uint32_t _unknown8c; // 0x8c - struct sdk_netif_conninfo *conninfo[6]; // 0x90 - 0xa8 + struct sdk_cnx_node *cnx_nodes[6]; // 0x90 - 0xa8 uint8_t _unknowna8[12]; // 0xa8 - 0xb4 struct _unknown_softap1 *_unknownb4; uint8_t statusb8; // 0xb8 (arg of sta_status_set) @@ -206,10 +208,9 @@ struct sdk_g_ic_volatile_st { }; -struct sdk_g_ic_unk0_st { - uint16_t _unknown1e4; // sdk_wpa_config_profile - uint16_t _unknown1e6; // sdk_wpa_config_profile - uint8_t sta_ssid[32]; // 0x1e8 Station ssid. Null terminated string. +struct sdk_g_ic_ssid_with_length { + uint32_t ssid_length; // 0x1e4 sdk_wpa_config_profile + uint8_t ssid[32]; // 0x1e8 Station ssid. Null terminated string. }; // This is the portion of g_ic which is loaded/saved to the flash ROM, and thus @@ -224,7 +225,8 @@ struct sdk_g_ic_saved_st { uint8_t wifi_led_gpio; uint8_t wifi_led_state; // 0 or 1. - struct sdk_g_ic_unk0_st _unknown1e4; + // Current station ap config ssid and length. + struct sdk_g_ic_ssid_with_length sta_ssid; // 0x1e4 uint8_t _unknown208; uint8_t _unknown209; // sdk_wpa_config_profile @@ -260,7 +262,7 @@ struct sdk_g_ic_saved_st { uint8_t _unknown30d; // result of ieee80211_chan2ieee uint8_t _unknown30e; uint8_t _unknown30f; - uint8_t _unknown310; // count of entries in the softap conninfo array, less two. + uint8_t _unknown310; // count of entries in the softap cnx_node array, less two. uint8_t _unknown311[3]; @@ -331,8 +333,8 @@ _Static_assert(offsetof(struct _unknown_softap1, _unknown18) == 0x18, "bad struc _Static_assert(sizeof(struct _unknown_wpa1) == 0x4c, "_unknown_wpa1 is the wrong size!"); _Static_assert(offsetof(struct _unknown_wpa1, _unknown48) == 0x48, "bad struct"); -_Static_assert(offsetof(struct sdk_netif_conninfo, _unknown78) == 0x78, "bad struct"); -_Static_assert(offsetof(struct sdk_netif_conninfo, _unknown108) == 0x108, "bad struct"); +_Static_assert(offsetof(struct sdk_cnx_node, _unknown78) == 0x78, "bad struct"); +_Static_assert(offsetof(struct sdk_cnx_node, _unknown108) == 0x108, "bad struct"); _Static_assert(offsetof(struct sdk_g_ic_netif_info, started) == 0xbb, "bad struct"); @@ -340,7 +342,7 @@ _Static_assert(sizeof(struct sdk_g_ic_volatile_st) == 0x1d8, "sdk_g_ic_volatile_ _Static_assert(offsetof(struct sdk_g_ic_volatile_st, _unknown1d5) == 0x1d5, "bad struct"); _Static_assert(sizeof(struct sdk_g_ic_saved_st) == 0x370, "sdk_g_ic_saved_st is the wrong size!"); -_Static_assert(offsetof(struct sdk_g_ic_saved_st, _unknown1e4) == 0x1e4 - 0x1d8, "bad struct"); +_Static_assert(offsetof(struct sdk_g_ic_saved_st, sta_ssid) == 0x1e4 - 0x1d8, "bad struct"); _Static_assert(offsetof(struct sdk_g_ic_saved_st, _unknown546) == 0x546 - 0x1d8, "bad struct"); _Static_assert(sizeof(struct sdk_g_ic_st) == 0x548, "sdk_g_ic_st is the wrong size!"); @@ -357,21 +359,16 @@ _Static_assert(offsetof(struct esf_buf, length) == 0x16, "bad struct"); // ieee80211_output_pbuf and perhaps elsewhere. The value is just passed through // lwip and and not used by lwip so just ensure this slot is at the expected // offset. -_Static_assert(offsetof(struct netif, state) == 28, "netif->state offset wrong!"); +_Static_assert(offsetof(struct netif, state) == 4, "netif->state offset wrong!"); // Some sdk uses of netif->hwaddr have been converted to source code, but many // remain, but the content of this slot should not change in future versions of -// lwip, so just ensure it is at the expected offset. -_Static_assert(offsetof(struct netif, hwaddr) == 41, "netif->hwaddr offset wrong!"); +// lwip, so just ensure it is at the expected offset. Note the sdk binary +// libraries have been patched to move this offset from 41 to 42 to keep it +// 16-bit aligned to keep lwip v2 happy. +_Static_assert(offsetof(struct netif, hwaddr) == 8, "netif->hwaddr offset wrong!"); -// Most sdk uses of the netif->flags have been converted to source code. One -// known sdk binary read of the flags remains in wl_cnx.o:sdk_cnx_sta_leave -// which checks the NETIF_FLAG_DHCP flag. The NETIF_FLAG_DHCP has been removed -// in lwip v2, so some lwip hacks are needed to handle this for now until -// wl_cnx.o is converted so source code too. -_Static_assert(offsetof(struct netif, flags) == 47, "netif->flags offset wrong!"); - -_Static_assert(offsetof(struct pbuf, eb) == 16, "pbuf->eb offset wrong!"); +_Static_assert(offsetof(struct pbuf, esf_buf) == 16, "pbuf->esf_buf offset wrong!"); /// Misc. diff --git a/examples/access_point/access_point.c b/examples/access_point/access_point.c index f8fcd50..52c622f 100644 --- a/examples/access_point/access_point.c +++ b/examples/access_point/access_point.c @@ -48,7 +48,7 @@ void user_init(void) }; sdk_wifi_softap_set_config(&ap_config); - ip_addr_t first_client_ip; + ip4_addr_t first_client_ip; IP4_ADDR(&first_client_ip, 172, 16, 0, 2); dhcpserver_start(&first_client_ip, 4); @@ -65,14 +65,14 @@ static void telnetTask(void *pvParameters) printf("Status monitor: Failed to allocate socket.\r\n"); return; } - netconn_bind(nc, IP_ADDR_ANY, TELNET_PORT); + netconn_bind(nc, IP_ANY_TYPE, TELNET_PORT); netconn_listen(nc); while(1) { struct netconn *client = NULL; err_t err = netconn_accept(nc, &client); - if ( err != ERR_OK ) { + if (err != ERR_OK) { if(client) netconn_delete(client); continue; @@ -88,9 +88,8 @@ static void telnetTask(void *pvParameters) netconn_write(client, buf, strlen(buf), NETCONN_COPY); snprintf(buf, sizeof(buf), "Free heap %d bytes\r\n", (int)xPortGetFreeHeapSize()); netconn_write(client, buf, strlen(buf), NETCONN_COPY); - snprintf(buf, sizeof(buf), "Your address is %d.%d.%d.%d\r\n\r\n", - ip4_addr1(&client_addr), ip4_addr2(&client_addr), - ip4_addr3(&client_addr), ip4_addr4(&client_addr)); + char abuf[40]; + snprintf(buf, sizeof(buf), "Your address is %s\r\n\r\n", ipaddr_ntoa_r(&client_addr, abuf, sizeof(abuf))); netconn_write(client, buf, strlen(buf), NETCONN_COPY); netconn_delete(client); } diff --git a/examples/http_get/http_get.c b/examples/http_get/http_get.c index 0fe0ae1..f59aa8e 100644 --- a/examples/http_get/http_get.c +++ b/examples/http_get/http_get.c @@ -20,9 +20,9 @@ #include "ssid_config.h" -#define WEB_SERVER "chainxor.org" +#define WEB_SERVER "ipv6.google.com" #define WEB_PORT 80 -#define WEB_URL "http://chainxor.org/" +#define WEB_PATH "/" void http_get_task(void *pvParameters) { @@ -31,7 +31,7 @@ void http_get_task(void *pvParameters) while(1) { const struct addrinfo hints = { - .ai_family = AF_INET, + .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM, }; struct addrinfo *res; @@ -39,7 +39,7 @@ void http_get_task(void *pvParameters) printf("Running DNS lookup for %s...\r\n", WEB_SERVER); int err = getaddrinfo(WEB_SERVER, "80", &hints, &res); - if(err != 0 || res == NULL) { + if (err != 0 || res == NULL) { printf("DNS lookup failed err=%d res=%p\r\n", err, res); if(res) freeaddrinfo(res); @@ -47,9 +47,24 @@ void http_get_task(void *pvParameters) failures++; continue; } - /* Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */ - struct in_addr *addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr; - printf("DNS lookup succeeded. IP=%s\r\n", inet_ntoa(*addr)); + + { + struct netif *netif = sdk_system_get_netif(0); + int i; + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + printf(" ip6 %d state %x\n", i, netif_ip6_addr_state(netif, i)); + if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i))) + printf(" ip6 addr %d = %s\n", i, ip6addr_ntoa(netif_ip6_addr(netif, i))); + } + } + + struct sockaddr *sa = res->ai_addr; + if (sa->sa_family == AF_INET) { + printf("DNS lookup succeeded. IP=%s\r\n", inet_ntoa(((struct sockaddr_in *)sa)->sin_addr)); + } + if (sa->sa_family == AF_INET6) { + printf("DNS lookup succeeded. IP=%s\r\n", inet6_ntoa(((struct sockaddr_in6 *)sa)->sin6_addr)); + } int s = socket(res->ai_family, res->ai_socktype, 0); if(s < 0) { @@ -75,8 +90,10 @@ void http_get_task(void *pvParameters) freeaddrinfo(res); const char *req = - "GET "WEB_URL"\r\n" + "GET "WEB_PATH" HTTP/1.1\r\n" + "Host: "WEB_SERVER"\r\n" "User-Agent: esp-open-rtos/0.1 esp8266\r\n" + "Connection: close\r\n" "\r\n"; if (write(s, req, strlen(req)) < 0) { printf("... socket send failed\r\n"); @@ -126,6 +143,6 @@ void user_init(void) sdk_wifi_set_opmode(STATION_MODE); sdk_wifi_station_set_config(&config); - xTaskCreate(&http_get_task, "get_task", 256, NULL, 2, NULL); + xTaskCreate(&http_get_task, "get_task", 384, NULL, 2, NULL); } diff --git a/examples/tls_server/tls_server.c b/examples/tls_server/tls_server.c index 1317785..8ecfa56 100644 --- a/examples/tls_server/tls_server.c +++ b/examples/tls_server/tls_server.c @@ -202,9 +202,8 @@ void tls_server_task(void *pvParameters) socklen_t peer_addr_len = sizeof(struct sockaddr_in); getpeername(client_ctx.fd, (struct sockaddr *)&peer_addr, &peer_addr_len); unsigned char buf[256]; - int len = sprintf((char *) buf, "O hai, client %d.%d.%d.%d:%d\nFree heap size is %d bytes\n", - ip4_addr1(&peer_addr.sin_addr), ip4_addr2(&peer_addr.sin_addr), - ip4_addr3(&peer_addr.sin_addr), ip4_addr4(&peer_addr.sin_addr), + int len = sprintf((char *) buf, "O hai, client " IPSTR ":%d\nFree heap size is %d bytes\n", + IP2STR((ip4_addr_t *)&peer_addr.sin_addr.s_addr), peer_addr.sin_port, xPortGetFreeHeapSize()); while((ret = mbedtls_ssl_write(&ssl, buf, len)) <= 0) { diff --git a/examples/tls_server_bearssl/tls_server_bearssl.c b/examples/tls_server_bearssl/tls_server_bearssl.c index 09632ae..b1e48dc 100644 --- a/examples/tls_server_bearssl/tls_server_bearssl.c +++ b/examples/tls_server_bearssl/tls_server_bearssl.c @@ -146,9 +146,8 @@ void tls_server_task(void *pvParameters) /* Prepare a message to the client */ unsigned char buf[100]; - int len = sprintf((char *) buf, "O hai, client %d.%d.%d.%d:%d\r\nFree heap size is %d bytes\r\n", - ip4_addr1(&sa.sin_addr), ip4_addr2(&sa.sin_addr), - ip4_addr3(&sa.sin_addr), ip4_addr4(&sa.sin_addr), + int len = sprintf((char *) buf, "O hai, client " IPSTR ":%d\r\nFree heap size is %d bytes\r\n", + IP2STR((ip4_addr_t *)&sa.sin_addr.s_addr), ntohs(sa.sin_port), xPortGetFreeHeapSize()); /* Send the message and close the connection */ diff --git a/examples/upnp/lwipopts.h b/examples/upnp/lwipopts.h index 80c105b..56f45f2 100644 --- a/examples/upnp/lwipopts.h +++ b/examples/upnp/lwipopts.h @@ -1,7 +1,5 @@ #define LWIP_IGMP 1 -#define LWIP_POSIX_SOCKETS_IO_NAMES 0 - /* Use the defaults for everything else */ #include_next diff --git a/examples/upnp/upnp.c b/examples/upnp/upnp.c index a223d27..bb34cae 100644 --- a/examples/upnp/upnp.c +++ b/examples/upnp/upnp.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "upnp.h" @@ -18,13 +19,13 @@ static const char* get_my_ip(void) } /** - * @brief This function joins a multicast group witht he specified ip/port + * @brief This function joins a multicast group with the specified ip/port * @param group_ip the specified multicast group ip * @param group_port the specified multicast port number * @param recv the lwip UDP callback * @retval udp_pcb* or NULL if joining failed */ -static struct udp_pcb* mcast_join_group(char *group_ip, uint16_t group_port, void (* recv)(void * arg, struct udp_pcb * upcb, struct pbuf * p, struct ip_addr * addr, u16_t port)) +static struct udp_pcb* mcast_join_group(char *group_ip, uint16_t group_port, void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)) { bool status = false; struct udp_pcb *upcb; @@ -36,7 +37,7 @@ static struct udp_pcb* mcast_join_group(char *group_ip, uint16_t group_port, voi printf("Error, udp_new failed"); break; } - udp_bind(upcb, IP_ADDR_ANY, group_port); + udp_bind(upcb, IP4_ADDR_ANY, group_port); struct netif* netif = sdk_system_get_netif(STATION_IF); if (!netif) { printf("Error, netif is null"); @@ -46,10 +47,10 @@ static struct udp_pcb* mcast_join_group(char *group_ip, uint16_t group_port, voi netif->flags |= NETIF_FLAG_IGMP; igmp_start(netif); } - ip_addr_t ipgroup; - ipaddr_aton(group_ip, &ipgroup); - err_t err = igmp_joingroup(&netif->ip_addr, &ipgroup); - if(ERR_OK != err) { + ip4_addr_t ipgroup; + ip4addr_aton(group_ip, &ipgroup); + err_t err = igmp_joingroup_netif(netif, &ipgroup); + if (ERR_OK != err) { printf("Failed to join multicast group: %d", err); break; } @@ -68,7 +69,7 @@ static struct udp_pcb* mcast_join_group(char *group_ip, uint16_t group_port, voi return upcb; } -static void send(struct udp_pcb *upcb, struct ip_addr *addr, u16_t port) +static void send_udp(struct udp_pcb *upcb, const ip_addr_t *addr, u16_t port) { struct pbuf *p; char msg[500]; @@ -110,14 +111,14 @@ static void send(struct udp_pcb *upcb, struct ip_addr *addr, u16_t port) * @param port the remote port from which the packet was received * @retval None */ -static void receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port) +static void receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { if (p) { printf("Msg received port:%d len:%d\n", port, p->len); uint8_t *buf = (uint8_t*) p->payload; printf("Msg received port:%d len:%d\nbuf: %s\n", port, p->len, buf); - send(upcb, addr, port); + send_udp(upcb, addr, port); pbuf_free(p); } diff --git a/extras/dhcpserver/dhcpserver.c b/extras/dhcpserver/dhcpserver.c index d87daab..934beb2 100644 --- a/extras/dhcpserver/dhcpserver.c +++ b/extras/dhcpserver/dhcpserver.c @@ -14,18 +14,22 @@ * BSD Licensed as described in the file LICENSE */ #include +#include #include #include #include #include +#include "esplibs/libmain.h" /* Grow the size of the lwip dhcp_msg struct's options field, as LWIP defaults to a 68 octet options field for its DHCP client, and most full-sized clients send us more than this. */ #define DHCP_OPTIONS_LEN 312 -#include +#include +#include +#include _Static_assert(sizeof(struct dhcp_msg) == offsetof(struct dhcp_msg, options) + 312, "dhcp_msg_t should have extended options size"); @@ -35,15 +39,20 @@ _Static_assert(sizeof(struct dhcp_msg) == offsetof(struct dhcp_msg, options) + 3 typedef struct { uint8_t hwaddr[NETIF_MAX_HWADDR_LEN]; + uint8_t active; uint32_t expires; } dhcp_lease_t; typedef struct { struct netconn *nc; uint8_t max_leases; - ip_addr_t first_client_addr; + ip4_addr_t first_client_addr; struct netif *server_if; dhcp_lease_t *leases; /* length max_leases */ + /* Optional router */ + ip4_addr_t router; + /* Optional DNS server */ + ip4_addr_t dns; } server_state_t; /* Only one DHCP server task can run at once, so we have global state @@ -68,51 +77,67 @@ static uint8_t *add_dhcp_option_bytes(uint8_t *opt, uint8_t type, void *value, u static dhcp_lease_t *find_lease_slot(uint8_t *hwaddr); /* Copy IP address as dotted decimal to 'dest', must be at least 16 bytes long */ -inline static void sprintf_ipaddr(const ip_addr_t *addr, char *dest) +inline static void sprintf_ipaddr(const ip4_addr_t *addr, char *dest) { - if(addr == NULL) + if (addr == NULL) sprintf(dest, "NULL"); else sprintf(dest, "%d.%d.%d.%d", ip4_addr1(addr), ip4_addr2(addr), ip4_addr3(addr), ip4_addr4(addr)); } -void dhcpserver_start(const ip_addr_t *first_client_addr, uint8_t max_leases) +void dhcpserver_start(const ip4_addr_t *first_client_addr, uint8_t max_leases) { /* Stop any existing running dhcpserver */ - if(dhcpserver_task_handle) + if (dhcpserver_task_handle) dhcpserver_stop(); state = malloc(sizeof(server_state_t)); state->max_leases = max_leases; state->leases = calloc(max_leases, sizeof(dhcp_lease_t)); + bzero(state->leases, max_leases * sizeof(dhcp_lease_t)); // state->server_if is assigned once the task is running - see comment in dhcpserver_task() - ip_addr_copy(state->first_client_addr, *first_client_addr); + ip4_addr_copy(state->first_client_addr, *first_client_addr); - xTaskCreate(dhcpserver_task, "DHCPServer", 768, NULL, 8, &dhcpserver_task_handle); + /* Clear options */ + ip4_addr_set_zero(&state->router); + ip4_addr_set_zero(&state->dns); + + xTaskCreate(dhcpserver_task, "DHCP Server", 448, NULL, 2, &dhcpserver_task_handle); } void dhcpserver_stop(void) { - if(dhcpserver_task_handle) { + if (dhcpserver_task_handle) { vTaskDelete(dhcpserver_task_handle); free(state); dhcpserver_task_handle = NULL; } } +void dhcpserver_set_router(const ip4_addr_t *router) +{ + ip4_addr_copy(state->router, *router); +} + +void dhcpserver_set_dns(const ip4_addr_t *dns) +{ + ip4_addr_copy(state->dns, *dns); +} + static void dhcpserver_task(void *pxParameter) { /* netif_list isn't assigned until after user_init completes, which is why we do it inside the task */ state->server_if = netif_list; /* TODO: Make this configurable */ state->nc = netconn_new (NETCONN_UDP); - if(!state->nc) { + if (!state->nc) { printf("DHCP Server Error: Failed to allocate socket.\r\n"); return; } - netconn_bind(state->nc, IP_ADDR_ANY, DHCP_SERVER_PORT); + netconn_bind(state->nc, IP4_ADDR_ANY, LWIP_IANA_PORT_DHCP_SERVER); + netconn_bind_if (state->nc, netif_get_index(state->server_if)); while(1) { @@ -121,29 +146,32 @@ static void dhcpserver_task(void *pxParameter) /* Receive a DHCP packet */ err_t err = netconn_recv(state->nc, &netbuf); - if(err != ERR_OK) { + if (err != ERR_OK) { printf("DHCP Server Error: Failed to receive DHCP packet. err=%d\r\n", err); continue; } /* expire any leases that have passed */ uint32_t now = xTaskGetTickCount(); - for(int i = 0; i < state->max_leases; i++) { - uint32_t expires = state->leases[i].expires; - if(expires && expires < now) - state->leases[i].expires = 0; + for (int i = 0; i < state->max_leases; i++) { + if (state->leases[i].active) { + uint32_t expires = state->leases[i].expires - now; + if (expires >= 0x80000000) { + state->leases[i].active = 0; + } + } } ip_addr_t received_ip; u16_t port; netconn_addr(state->nc, &received_ip, &port); - if(netbuf_len(netbuf) < offsetof(struct dhcp_msg, options)) { + if (netbuf_len(netbuf) < offsetof(struct dhcp_msg, options)) { /* too short to be a valid DHCP client message */ netbuf_delete(netbuf); continue; } - if(netbuf_len(netbuf) >= sizeof(struct dhcp_msg)) { + if (netbuf_len(netbuf) >= sizeof(struct dhcp_msg)) { printf("DHCP Server Warning: Client sent more options than we know how to parse. len=%d\r\n", netbuf_len(netbuf)); } @@ -152,18 +180,18 @@ static void dhcpserver_task(void *pxParameter) uint8_t *message_type = find_dhcp_option(&received, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN, NULL); - if(!message_type) { + if (!message_type) { printf("DHCP Server Error: No message type field found"); continue; } - printf("State dump. Message type %d\n", *message_type); - for(int i = 0; i < state->max_leases; i++) { + for (int i = 0; i < state->max_leases; i++) { dhcp_lease_t *lease = &state->leases[i]; - printf("lease slot %d expiry %d hwaddr %02x:%02x:%02x:%02x:%02x:%02x\r\n", i, lease->expires, lease->hwaddr[0], - lease->hwaddr[1], lease->hwaddr[2], lease->hwaddr[3], lease->hwaddr[4], - lease->hwaddr[5]); + printf("lease slot %d active %d expiry %d hwaddr %02x:%02x:%02x:%02x:%02x:%02x\r\n", i, + lease->active, lease->expires - now, + lease->hwaddr[0], lease->hwaddr[1], lease->hwaddr[2], + lease->hwaddr[3], lease->hwaddr[4], lease->hwaddr[5]); } switch(*message_type) { @@ -184,13 +212,13 @@ static void dhcpserver_task(void *pxParameter) static void handle_dhcp_discover(struct dhcp_msg *dhcpmsg) { - if(dhcpmsg->htype != DHCP_HTYPE_ETH) + if (dhcpmsg->htype != LWIP_IANA_HWTYPE_ETHERNET) return; - if(dhcpmsg->hlen > NETIF_MAX_HWADDR_LEN) + if (dhcpmsg->hlen > NETIF_MAX_HWADDR_LEN) return; dhcp_lease_t *freelease = find_lease_slot(dhcpmsg->chaddr); - if(!freelease) { + if (!freelease) { printf("DHCP Server: All leases taken.\r\n"); return; /* Nothing available, so do nothing */ } @@ -199,13 +227,19 @@ static void handle_dhcp_discover(struct dhcp_msg *dhcpmsg) dhcpmsg->op = DHCP_BOOTREPLY; bzero(dhcpmsg->options, DHCP_OPTIONS_LEN); - ip_addr_copy(dhcpmsg->yiaddr, state->first_client_addr); - ip4_addr4(&(dhcpmsg->yiaddr)) += (freelease - state->leases); + dhcpmsg->yiaddr.addr = lwip_htonl(lwip_ntohl(state->first_client_addr.addr) + (freelease - state->leases)); uint8_t *opt = (uint8_t *)&dhcpmsg->options; opt = add_dhcp_option_byte(opt, DHCP_OPTION_MESSAGE_TYPE, DHCP_OFFER); opt = add_dhcp_option_bytes(opt, DHCP_OPTION_SERVER_ID, &state->server_if->ip_addr, 4); opt = add_dhcp_option_bytes(opt, DHCP_OPTION_SUBNET_MASK, &state->server_if->netmask, 4); + if (!ip4_addr_isany_val(state->router)) { + opt = add_dhcp_option_bytes(opt, DHCP_OPTION_ROUTER, &state->router, 4); + } + if (!ip4_addr_isany_val(state->dns)) { + opt = add_dhcp_option_bytes(opt, DHCP_OPTION_DNS_SERVER, &state->dns, 4); + } + opt = add_dhcp_option_bytes(opt, DHCP_OPTION_END, NULL, 0); struct netbuf *netbuf = netbuf_new(); @@ -218,17 +252,17 @@ static void handle_dhcp_discover(struct dhcp_msg *dhcpmsg) static void handle_dhcp_request(struct dhcp_msg *dhcpmsg) { static char ipbuf[16]; - if(dhcpmsg->htype != DHCP_HTYPE_ETH) + if (dhcpmsg->htype != LWIP_IANA_HWTYPE_ETHERNET) return; - if(dhcpmsg->hlen > NETIF_MAX_HWADDR_LEN) + if (dhcpmsg->hlen > NETIF_MAX_HWADDR_LEN) return; - ip_addr_t requested_ip; + ip4_addr_t requested_ip; uint8_t *requested_ip_opt = find_dhcp_option(dhcpmsg, DHCP_OPTION_REQUESTED_IP, 4, NULL); - if(requested_ip_opt) { - memcpy(&requested_ip.addr, requested_ip_opt, 4); - } else if(ip_addr_cmp(&requested_ip, IP_ADDR_ANY)) { - ip_addr_copy(requested_ip, dhcpmsg->ciaddr); + if (requested_ip_opt) { + memcpy(&requested_ip.addr, requested_ip_opt, 4); + } else if (ip4_addr_cmp(&requested_ip, IP4_ADDR_ANY4)) { + ip4_addr_copy(requested_ip, dhcpmsg->ciaddr); } else { printf("DHCP Server Error: No requested IP\r\n"); send_dhcp_nak(dhcpmsg); @@ -236,7 +270,7 @@ static void handle_dhcp_request(struct dhcp_msg *dhcpmsg) } /* Test the first 4 octets match */ - if(ip4_addr1(&requested_ip) != ip4_addr1(&state->first_client_addr) + if (ip4_addr1(&requested_ip) != ip4_addr1(&state->first_client_addr) || ip4_addr2(&requested_ip) != ip4_addr2(&state->first_client_addr) || ip4_addr3(&requested_ip) != ip4_addr3(&state->first_client_addr)) { sprintf_ipaddr(&requested_ip, ipbuf); @@ -246,14 +280,14 @@ static void handle_dhcp_request(struct dhcp_msg *dhcpmsg) } /* Test the last octet is in the MAXCLIENTS range */ int16_t octet_offs = ip4_addr4(&requested_ip) - ip4_addr4(&state->first_client_addr); - if(octet_offs < 0 || octet_offs >= state->max_leases) { + if (octet_offs < 0 || octet_offs >= state->max_leases) { printf("DHCP Server Error: Address out of range\r\n"); send_dhcp_nak(dhcpmsg); return; } dhcp_lease_t *requested_lease = state->leases + octet_offs; - if(requested_lease->expires != 0 && memcmp(requested_lease->hwaddr, dhcpmsg->chaddr,dhcpmsg->hlen)) + if (requested_lease->active && memcmp(requested_lease->hwaddr, dhcpmsg->chaddr,dhcpmsg->hlen)) { printf("DHCP Server Error: Lease for address already taken\r\n"); send_dhcp_nak(dhcpmsg); @@ -265,13 +299,17 @@ static void handle_dhcp_request(struct dhcp_msg *dhcpmsg) printf("DHCP lease addr %s assigned to MAC %02x:%02x:%02x:%02x:%02x:%02x\r\n", ipbuf, requested_lease->hwaddr[0], requested_lease->hwaddr[1], requested_lease->hwaddr[2], requested_lease->hwaddr[3], requested_lease->hwaddr[4], requested_lease->hwaddr[5]); - requested_lease->expires = DHCPSERVER_LEASE_TIME * configTICK_RATE_HZ; + uint32_t now = xTaskGetTickCount(); + requested_lease->expires = now + DHCPSERVER_LEASE_TIME * configTICK_RATE_HZ; + requested_lease->active = 1; + + sdk_wifi_softap_set_station_info(requested_lease->hwaddr, &requested_ip); /* Reuse the REQUEST message as the ACK message */ dhcpmsg->op = DHCP_BOOTREPLY; bzero(dhcpmsg->options, DHCP_OPTIONS_LEN); - ip_addr_copy(dhcpmsg->yiaddr, requested_ip); + ip4_addr_copy(dhcpmsg->yiaddr, requested_ip); uint8_t *opt = (uint8_t *)&dhcpmsg->options; opt = add_dhcp_option_byte(opt, DHCP_OPTION_MESSAGE_TYPE, DHCP_ACK); @@ -279,6 +317,13 @@ static void handle_dhcp_request(struct dhcp_msg *dhcpmsg) opt = add_dhcp_option_bytes(opt, DHCP_OPTION_LEASE_TIME, &expiry, 4); opt = add_dhcp_option_bytes(opt, DHCP_OPTION_SERVER_ID, &state->server_if->ip_addr, 4); opt = add_dhcp_option_bytes(opt, DHCP_OPTION_SUBNET_MASK, &state->server_if->netmask, 4); + if (!ip4_addr_isany_val(state->router)) { + opt = add_dhcp_option_bytes(opt, DHCP_OPTION_ROUTER, &state->router, 4); + } + if (!ip4_addr_isany_val(state->dns)) { + opt = add_dhcp_option_bytes(opt, DHCP_OPTION_DNS_SERVER, &state->dns, 4); + } + opt = add_dhcp_option_bytes(opt, DHCP_OPTION_END, NULL, 0); struct netbuf *netbuf = netbuf_new(); @@ -291,7 +336,8 @@ static void handle_dhcp_request(struct dhcp_msg *dhcpmsg) static void handle_dhcp_release(struct dhcp_msg *dhcpmsg) { dhcp_lease_t *lease = find_lease_slot(dhcpmsg->chaddr); - if(lease) { + if (lease) { + lease->active = 0; lease->expires = 0; } } @@ -319,17 +365,17 @@ static uint8_t *find_dhcp_option(struct dhcp_msg *msg, uint8_t option_num, uint8 uint8_t *start = (uint8_t *)&msg->options; uint8_t *msg_end = (uint8_t *)msg + sizeof(struct dhcp_msg); - for(uint8_t *p = start; p < msg_end-2;) { + for (uint8_t *p = start; p < msg_end-2;) { uint8_t type = *p++; uint8_t len = *p++; - if(type == DHCP_OPTION_END) + if (type == DHCP_OPTION_END) return NULL; - if(p+len >= msg_end) + if (p+len >= msg_end) break; /* We've overrun our valid DHCP message size, or this isn't a valid option */ - if(type == option_num) { - if(len < min_length) + if (type == option_num) { + if (len < min_length) break; - if(length) + if (length) *length = len; return p; /* start of actual option data */ } @@ -349,7 +395,7 @@ static uint8_t *add_dhcp_option_byte(uint8_t *opt, uint8_t type, uint8_t value) static uint8_t *add_dhcp_option_bytes(uint8_t *opt, uint8_t type, void *value, uint8_t len) { *opt++ = type; - if(len) { + if (len) { *opt++ = len; memcpy(opt, value, len); } @@ -360,8 +406,8 @@ static uint8_t *add_dhcp_option_bytes(uint8_t *opt, uint8_t type, void *value, u static dhcp_lease_t *find_lease_slot(uint8_t *hwaddr) { dhcp_lease_t *empty_lease = NULL; - for(int i = 0; i < state->max_leases; i++) { - if(state->leases[i].expires == 0 && !empty_lease) + for (int i = 0; i < state->max_leases; i++) { + if (!state->leases[i].active && !empty_lease) empty_lease = &state->leases[i]; else if (memcmp(hwaddr, state->leases[i].hwaddr, 6) == 0) return &state->leases[i]; diff --git a/extras/dhcpserver/include/dhcpserver.h b/extras/dhcpserver/include/dhcpserver.h index 95a59b8..62fa0ac 100644 --- a/extras/dhcpserver/include/dhcpserver.h +++ b/extras/dhcpserver/include/dhcpserver.h @@ -26,14 +26,20 @@ extern "C" { to a client. Subsequent lease addresses are calculated by incrementing the final octet of the IPv4 address, up to max_leases. */ -void dhcpserver_start(const ip_addr_t *first_client_addr, uint8_t max_leases); +void dhcpserver_start(const ip4_addr_t *first_client_addr, uint8_t max_leases); -void dhcpserver_get_lease(const ip_addr_t *first_client_addr, uint8_t max_leases); +void dhcpserver_get_lease(const ip4_addr_t *first_client_addr, uint8_t max_leases); /* Stop DHCP server. */ void dhcpserver_stop(void); +/* Set a router address to send as an option. */ +void dhcpserver_set_router(const ip4_addr_t *router); + +/* Set a DNS address to send as an option. */ +void dhcpserver_set_dns(const ip4_addr_t *dns); + #ifdef __cplusplus } #endif diff --git a/extras/httpd/httpd.c b/extras/httpd/httpd.c index f647ca6..253bc13 100644 --- a/extras/httpd/httpd.c +++ b/extras/httpd/httpd.c @@ -2675,7 +2675,7 @@ http_accept(void *arg, struct tcp_pcb *pcb, err_t err) * Initialize the httpd with the specified local address. */ static void -httpd_init_addr(ip_addr_t *local_addr) +httpd_init_addr(const ip_addr_t *local_addr) { struct tcp_pcb *pcb; err_t err; diff --git a/extras/sntp/sntp.c b/extras/sntp/sntp.c index d69b60e..c034df2 100644 --- a/extras/sntp/sntp.c +++ b/extras/sntp/sntp.c @@ -38,7 +38,7 @@ #include "sntp.h" -#include "lwip/timers.h" +#include "lwip/timeouts.h" #include "lwip/udp.h" #include "lwip/dns.h" #include "lwip/ip_addr.h" @@ -136,12 +136,12 @@ #define SNTP_STARTUP_DELAY 0 #endif -/** SNTP receive timeout - in milliseconds +/** SNTP receive timeout - in seconds * Also used as retry timeout - this shouldn't be too low. * Default is 3 seconds. */ #ifndef SNTP_RECV_TIMEOUT -#define SNTP_RECV_TIMEOUT 3000 +#define SNTP_RECV_TIMEOUT 3 #endif /** SNTP update delay - in milliseconds @@ -384,8 +384,8 @@ sntp_request(void *arg) /* bind to local address */ if (lwip_bind(sock, (struct sockaddr *)&local, sizeof(local)) == 0) { /* set recv timeout */ - timeout = SNTP_RECV_TIMEOUT; - lwip_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)); + const struct timeval timeout = { SNTP_RECV_TIMEOUT, 0 }; + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); /* prepare SNTP request */ sntp_initialize_request(&sntpmsg); @@ -511,7 +511,7 @@ sntp_try_next_server(void* arg) /** UDP recv callback for the sntp pcb */ static void -sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) +sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { u8_t mode; u8_t stratum; @@ -597,7 +597,7 @@ sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, ip_addr_t *addr, u16_t * @param server_addr resolved IP address of the SNTP server */ static void -sntp_send_request(ip_addr_t *server_addr) +sntp_send_request(const ip_addr_t *server_addr) { struct pbuf* p; p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM); @@ -611,7 +611,7 @@ sntp_send_request(ip_addr_t *server_addr) pbuf_free(p); /* set up receive timeout: try next server or retry on timeout */ - sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL); + sys_timeout((u32_t)SNTP_RECV_TIMEOUT * 1000, sntp_try_next_server, NULL); #if SNTP_CHECK_RESPONSE >= 1 /* save server address to verify it in sntp_recv */ ip_addr_set(&sntp_last_server_address, server_addr); @@ -629,7 +629,7 @@ sntp_send_request(ip_addr_t *server_addr) * DNS found callback when using DNS names as server address. */ static void -sntp_dns_found(const char* hostname, ip_addr_t *ipaddr, void *arg) +sntp_dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg) { LWIP_UNUSED_ARG(hostname); LWIP_UNUSED_ARG(arg); diff --git a/include/espressif/esp_wifi.h b/include/espressif/esp_wifi.h index 5d9ba19..8932974 100644 --- a/include/espressif/esp_wifi.h +++ b/include/espressif/esp_wifi.h @@ -44,9 +44,9 @@ enum { }; struct ip_info { - struct ip_addr ip; - struct ip_addr netmask; - struct ip_addr gw; + struct ip4_addr ip; + struct ip4_addr netmask; + struct ip4_addr gw; }; bool sdk_wifi_get_ip_info(uint8_t if_index, struct ip_info *info); diff --git a/include/espressif/sdk_private.h b/include/espressif/sdk_private.h index fa643a7..7ae4336 100644 --- a/include/espressif/sdk_private.h +++ b/include/espressif/sdk_private.h @@ -20,7 +20,7 @@ extern "C" { #endif -struct ip_addr; +struct ip4_addr; /********************************************* * Defined in libmain.a @@ -43,17 +43,6 @@ int sdk_uart_rx_one_char(char *buf); */ void sdk_os_putc(char c); -/* Called when an IP gets set on the "station" (client) interface. - */ -void sdk_system_station_got_ip_set(struct ip_addr *ip_addr, struct ip_addr *sn_mask, struct ip_addr *gw_addr); - -/* This is a no-op wrapper around ppRecycleRxPkt, which is defined in libpp.a - - It's called when a pbuf is freed, and allows pp to reuse the 'eb' pointer to ESP-specific - pbuf data. (See esp-lwip pbuf.h) - */ -void sdk_system_pp_recycle_rx_pkt(void *eb); - #ifdef __cplusplus } #endif diff --git a/lib/allsymbols.rename b/lib/allsymbols.rename index 5425845..cf30bc9 100644 --- a/lib/allsymbols.rename +++ b/lib/allsymbols.rename @@ -289,6 +289,7 @@ os_timer_disarm sdk_os_timer_disarm os_timer_setfn sdk_os_timer_setfn os_update_cpu_frequency sdk_os_update_cpu_frequency pbkdf2_sha1 sdk_pbkdf2_sha1 +pbuf_alloc sdk_pbuf_alloc pbus_set_rxbbgain sdk_pbus_set_rxbbgain pend_flag_noise_check sdk_pend_flag_noise_check pend_flag_periodic_cal sdk_pend_flag_periodic_cal diff --git a/lib/libmain.a b/lib/libmain.a index 60657ec..cd6f83a 100644 Binary files a/lib/libmain.a and b/lib/libmain.a differ diff --git a/lib/libnet80211.a b/lib/libnet80211.a index 4a36331..1146020 100644 Binary files a/lib/libnet80211.a and b/lib/libnet80211.a differ diff --git a/lib/libpp.a b/lib/libpp.a index 2747863..39631a2 100644 Binary files a/lib/libpp.a and b/lib/libpp.a differ diff --git a/lib/libwpa.a b/lib/libwpa.a index a8fa39a..1c99007 100644 Binary files a/lib/libwpa.a and b/lib/libwpa.a differ diff --git a/lwip/component.mk b/lwip/component.mk index 1bbe21c..ea35d05 100644 --- a/lwip/component.mk +++ b/lwip/component.mk @@ -1,14 +1,12 @@ # Component makefile for LWIP LWIP_DIR = $(lwip_ROOT)lwip/src/ -INC_DIRS += $(LWIP_DIR)include $(ROOT)lwip/include $(lwip_ROOT)include $(LWIP_DIR)include/posix $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip $(LWIP_DIR)include/lwip +INC_DIRS += $(LWIP_DIR)include $(ROOT)lwip/include $(lwip_ROOT)include $(LWIP_DIR)include/compat/posix $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip $(LWIP_DIR)include/lwip # args for passing into compile rule generation lwip_INC_DIR = # all in INC_DIRS, needed for normal operation -lwip_SRC_DIR = $(lwip_ROOT) $(LWIP_DIR)api $(LWIP_DIR)core $(LWIP_DIR)core/ipv4 $(LWIP_DIR)netif - -# LWIP 1.4.1 generates a single warning so we need to disable -Werror when building it -lwip_CFLAGS = $(CFLAGS) -Wno-address +lwip_SRC_DIR = $(lwip_ROOT) $(LWIP_DIR)api $(LWIP_DIR)core $(LWIP_DIR)core/ipv4 $(LWIP_DIR)core/ipv6 $(LWIP_DIR)netif +lwip_SRC_DIR += $(LWIP_DIR)apps/* $(eval $(call component_compile_rules,lwip)) diff --git a/lwip/esp_interface.c b/lwip/esp_interface.c index 6f37b5a..1edb508 100644 --- a/lwip/esp_interface.c +++ b/lwip/esp_interface.c @@ -37,6 +37,7 @@ * Original Author: Simon Goldschmidt * Modified by Angus Gratton based on work by @kadamski/Espressif via esp-lwip project. */ +#include #include "lwip/opt.h" #include "lwip/def.h" @@ -44,71 +45,138 @@ #include "lwip/pbuf.h" #include #include +#include "lwip/ip.h" +#include "lwip/ethip6.h" #include "netif/etharp.h" +#include "sysparam.h" +#include "netif/ppp/pppoe.h" /* declared in libnet80211.a */ int8_t sdk_ieee80211_output_pbuf(struct netif *ifp, struct pbuf* pb); +/* Define those to better describe your network interface. */ +#define IFNAME0 'e' +#define IFNAME1 'n' + +/** + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ +static void +low_level_init(struct netif *netif) +{ + /* set MAC hardware address length */ + netif->hwaddr_len = 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 | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6; + + /* Do whatever else is needed to initialize interface. */ +} + +/** + * 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 available since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ +#define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf)) static err_t low_level_output(struct netif *netif, struct pbuf *p) { - struct pbuf *q; + /* + * Note the pbuf reference count is generally one here, but not always. For + * example a buffer that had been queued by etharp_query() would have had + * its reference count increased to two, and the caller will free it on that + * return path. + */ - for(q = p; q != NULL; q = q->next) { - sdk_ieee80211_output_pbuf(netif, q); - } + /* If the pbuf does not have contiguous data, or there is not enough room + * for the link layer header, or there are multiple pbufs in the chain then + * clone a pbuf to output. */ + if ((p->type_internal & PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS) == 0 || + (u8_t *)p->payload < (u8_t *)p + SIZEOF_STRUCT_PBUF + PBUF_LINK_ENCAPSULATION_HLEN || + p->next) { + struct pbuf *q = pbuf_clone(PBUF_RAW_TX, PBUF_RAM, p); + if (q == NULL) { + return ERR_MEM; + } + sdk_ieee80211_output_pbuf(netif, q); + /* The sdk will pbuf_ref the pbuf before returning and free it later + * when it has been sent so free the link to it here. */ + pbuf_free(q); + } else { + /* The SDK modifies the eth_hdr, well the first 12 bytes of it at least, + * but otherwise leaves the payload unmodified so it can be reused by + * the caller. The only paths that appear to reuse the pbuf are in + * tcp_out for re-transmission of TCP segments, and these paths check + * that the number of references has returned to one before reusing the + * pbuf. + */ + sdk_ieee80211_output_pbuf(netif, p); + } - LINK_STATS_INC(link.xmit); - - return ERR_OK; + LINK_STATS_INC(link.xmit); + return ERR_OK; } -err_t ethernetif_init(struct netif *netif) -{ - LWIP_ASSERT("netif != NULL", (netif != NULL)); - -#if LWIP_NETIF_HOSTNAME - /* Initialize interface hostname */ - netif->hostname = "lwip"; -#endif /* LWIP_NETIF_HOSTNAME */ - - /* - * 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, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); - - // don't touch netif->state here, the field is used internally in the ESP SDK layers - netif->name[0] = 'e'; - netif->name[1] = 'n'; - netif->output = etharp_output; - netif->linkoutput = low_level_output; - - /* low_level_init components */ - netif->hwaddr_len = 6; - /* hwaddr seems to be set elsewhere, or (more likely) is set on tx by MAC layer */ - netif->mtu = 1500; - netif->flags = NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; - - return ERR_OK; -} - +/** + * 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 + */ /* called from ieee80211_deliver_data with new IP frames */ void ethernetif_input(struct netif *netif, struct pbuf *p) { - struct eth_hdr *ethhdr = p->payload; - /* examine packet payloads ethernet header */ + struct eth_hdr *ethhdr; + if (p == NULL) { + return; + } + + if (p->payload == NULL) { + return; + } + + if (netif == NULL) { + return; + } + + ethhdr = p->payload; switch(htons(ethhdr->type)) { /* IP or ARP packet? */ case ETHTYPE_IP: + case ETHTYPE_IPV6: 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) + if (netif->input(p, netif) != ERR_OK) { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); pbuf_free(p); @@ -122,3 +190,98 @@ void ethernetif_input(struct netif *netif, struct pbuf *p) break; } } + +/* Since the pbuf_type definition has changed in lwip v2 and it is used by the + * sdk when calling pbuf_alloc, the SDK libraries have been modified to rename + * their references to pbuf_alloc to _pbufalloc allowing the pbuf_type to be + * rewritten here. Doing this here keeps this hack out of the lwip code, and + * ensures that this re-writing is only applied to the sdk calls to pbuf_alloc. + * + * The only pbuf types used by the SDK are type 0 for PBUF_RAM when writing + * data, and type 2 for the received data. The receive data path references + * internal buffer objects that need to be freed with custom code so a custom + * pbuf allocation type is used for these. + * + * The pbuf_layer is now also the header offset, but the sdk calls only call + * with a value of 3 which was PBUF_RAW and is now translated to a header + * offset of zero. + */ +struct pbuf *sdk_pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) { + if (type == 0) { + LWIP_ASSERT("Unexpected sdk_pbuf_alloc layer", layer == 3 || layer == 4); + return pbuf_alloc(PBUF_RAW_TX, length, PBUF_RAM); + } else if (type == 2) { + LWIP_ASSERT("Unexpected sdk_pbuf_alloc layer", layer == 3); + return pbuf_alloc_reference(NULL, length, PBUF_ALLOC_FLAG_RX | PBUF_TYPE_ALLOC_SRC_MASK_ESP_RX); + } else { + LWIP_ASSERT("Unexpected pbuf_alloc type", 0); + for (;;); + } +} + +/** + * 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)); + + /* The hwaddr is currently set by sdk_wifi_station_start or + * sdk_wifi_softap_start. */ + +#if LWIP_IPV6 + // Where to do this??? + netif_create_ip6_linklocal_address(netif, 1); + netif->ip6_autoconfig_enabled = 1; + printf("ip6 link local address %s\n", ip6addr_ntoa(netif_ip6_addr(netif, 0))); +#endif + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + char *hostname = NULL; + /* Disabled for now as there were reports of crashes here, sysparam issues */ + /* sysparam_get_string("hostname", &hostname); */ + if (hostname && strlen(hostname) == 0) { + free(hostname); + hostname = NULL; + } + netif->hostname = hostname; +#endif /* LWIP_NETIF_HOSTNAME */ + + /* + * 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, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); + + // don't touch netif->state here, the field is used internally in the ESP SDK layers + 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...) */ +#if LWIP_IPV4 + netif->output = etharp_output; +#endif /* LWIP_IPV4 */ +#if LWIP_IPV6 + netif->output_ip6 = ethip6_output; +#endif /* LWIP_IPV6 */ + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + return ERR_OK; +} diff --git a/lwip/include/arch/cc.h b/lwip/include/arch/cc.h index 2922a54..5bf9d80 100644 --- a/lwip/include/arch/cc.h +++ b/lwip/include/arch/cc.h @@ -32,36 +32,18 @@ #ifndef __ARCH_CC_H__ #define __ARCH_CC_H__ -/* include ESP SDK prototypes as they're used in some LWIP routines */ -#include "espressif/sdk_private.h" - -/* ESP8266 SDK Interface - - The lwip-esp stack is designed to be also compatible with other ESP8266 SDKs, - so we can't use our 'sdk_' prefixes there -*/ -#define system_station_got_ip_set sdk_system_station_got_ip_set -#define system_pp_recycle_rx_pkt sdk_system_pp_recycle_rx_pkt - /* Include some files for defining library routines */ #include /* printf, fflush, FILE */ #include /* abort */ #include #include #include +#include -#define ERRNO - -#define BYTE_ORDER LITTLE_ENDIAN - -/** @todo fix some warnings: don't use #pragma if compiling with cygwin gcc */ -#ifndef __GNUC__ - #include - #pragma warning (disable: 4244) /* disable conversion warning (implicit integer promotion!) */ - #pragma warning (disable: 4127) /* conditional expression is constant */ - #pragma warning (disable: 4996) /* 'strncpy' was declared deprecated */ - #pragma warning (disable: 4103) /* structure packing changed by including file */ -#endif +struct ip4_addr; +struct esf_buf; +void sdk_system_station_got_ip_set(struct ip4_addr *, struct ip4_addr *, struct ip4_addr *); +void sdk_system_pp_recycle_rx_pkt(struct esf_buf *); /* Define generic types used in lwIP */ typedef uint8_t u8_t; @@ -112,4 +94,6 @@ typedef int sys_prot_t; #define LWIP_PLATFORM_HTONS(_n) ((u16_t)((((_n) & 0xff) << 8) | (((_n) >> 8) & 0xff))) #define LWIP_PLATFORM_HTONL(_n) ((u32_t)( (((_n) & 0xff) << 24) | (((_n) & 0xff00) << 8) | (((_n) >> 8) & 0xff00) | (((_n) >> 24) & 0xff) )) +#define LWIP_RAND() hwrand() + #endif /* __ARCH_CC_H__ */ diff --git a/lwip/include/lwipopts.h b/lwip/include/lwipopts.h index 8f46c7d..567c856 100644 --- a/lwip/include/lwipopts.h +++ b/lwip/include/lwipopts.h @@ -32,11 +32,15 @@ #ifndef __LWIPOPTS_H__ #define __LWIPOPTS_H__ -#define LWIP_ESP 1 -#define ESP_RTOS 1 -#define PBUF_RSV_FOR_WLAN 1 -#define EBUF_LWIP 1 +#define ESP_OPEN_RTOS 1 + +/* See tcp.c tcp_alloc(). */ +#ifndef ESP_TIMEWAIT_THRESHOLD #define ESP_TIMEWAIT_THRESHOLD 10000 +#endif + +/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided + * by your system, set this to 0 and include in cc.h */ #define LWIP_TIMEVAL_PRIVATE 0 /* @@ -63,6 +67,32 @@ */ #define SMEMCPY(dst,src,len) memcpy(dst,src,len) +/* + ------------------------------------ + ----------- Core locking ----------- + ------------------------------------ +*/ + +/** + * LWIP_TCPIP_CORE_LOCKING + * Creates a global mutex that is held during TCPIP thread operations. + * Can be locked by client code to perform lwIP operations without changing + * into TCPIP thread using callbacks. See LOCK_TCPIP_CORE() and + * UNLOCK_TCPIP_CORE(). + * Your system should provide mutexes supporting priority inversion to use this. + */ +#define LWIP_TCPIP_CORE_LOCKING 1 + +/** + * LWIP_TCPIP_CORE_LOCKING_INPUT: when LWIP_TCPIP_CORE_LOCKING is enabled, + * this lets tcpip_input() grab the mutex for input packets as well, + * instead of allocating a message and passing it to tcpip_thread. + * + * ATTENTION: this does not work when tcpip_input() is called from + * interrupt context! + */ +#define LWIP_TCPIP_CORE_LOCKING_INPUT 1 + /* ------------------------------------ ---------- Memory options ---------- @@ -76,16 +106,20 @@ #define MEM_LIBC_MALLOC 1 /** -* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. -* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution -* speed and usage from interrupts! -*/ + * MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. + * Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution + * speed (heap alloc can be much slower than pool alloc) and usage from interrupts + * (especially if your netif driver allocates PBUF_POOL pbufs for received frames + * from interrupt)! + * ATTENTION: Currently, this uses the heap for ALL pools (also for private pools, + * not only for internal pools defined in memp_std.h)! + */ #define MEMP_MEM_MALLOC 1 /** * 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 + * 4 byte alignment -> \#define MEM_ALIGNMENT 4 + * 2 byte alignment -> \#define MEM_ALIGNMENT 2 */ #define MEM_ALIGNMENT 4 @@ -100,6 +134,14 @@ ---------- ARP options ------- -------------------------------- */ + +/** + * LWIP_ARP==1: Enable ARP functionality. + */ +#ifndef LWIP_ARP +#define LWIP_ARP 1 +#endif + /** * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address * resolution. By default, only the most recent packet is queued per IP address. @@ -107,7 +149,9 @@ * startup time. Set this to 1 if you know your application sends more than one * packet in a row to an IP address that is not in the ARP cache. */ +#ifndef ARP_QUEUEING #define ARP_QUEUEING 1 +#endif /* -------------------------------- @@ -119,21 +163,27 @@ * this option does not affect outgoing packet sizes, which can be controlled * via IP_FRAG. */ -#define IP_REASSEMBLY 0 +#ifndef IP_REASSEMBLY +#define IP_REASSEMBLY 1 +#endif /** * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note * that this option does not affect incoming packet sizes, which can be * controlled via IP_REASSEMBLY. */ +#ifndef IP_FRAG #define IP_FRAG 1 +#endif /** * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived * in this time, the whole packet is discarded. */ +#ifndef IP_REASS_MAXAGE #define IP_REASS_MAXAGE 3 +#endif /** * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. @@ -141,7 +191,9 @@ * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive * packets even if the maximum amount of fragments is enqueued for reassembly! */ -#define IP_REASS_MAX_PBUFS 10 +#ifndef IP_REASS_MAX_PBUFS +#define IP_REASS_MAX_PBUFS 2 +#endif /* ---------------------------------- @@ -163,7 +215,16 @@ /** * LWIP_DHCP==1: Enable DHCP module. */ +#ifndef LWIP_DHCP #define LWIP_DHCP 1 +#endif + +/** + * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. + */ +#ifndef DHCP_DOES_ARP_CHECK +#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP)) +#endif #define LWIP_DHCP_BOOTP_FILE 0 @@ -174,14 +235,21 @@ */ /* ---------------------------------- - ---------- SNMP options ---------- + ----- SNMP MIB2 support ----- ---------------------------------- */ /* ---------------------------------- - ---------- IGMP options ---------- + ----- Multicast/IGMP options ----- ---------------------------------- */ +/** + * LWIP_IGMP==1: Turn on IGMP module. + */ +#ifndef LWIP_IGMP +#define LWIP_IGMP 1 +#endif + /* ---------------------------------- ---------- DNS options ----------- @@ -191,10 +259,19 @@ * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS * transport. */ +#ifndef LWIP_DNS #define LWIP_DNS 1 +#endif +/** DNS maximum number of entries to maintain locally. */ +#ifndef DNS_TABLE_SIZE #define DNS_TABLE_SIZE 1 +#endif + +/** DNS maximum host name length supported in the name table. */ +#ifndef DNS_MAX_NAME_LENGTH #define DNS_MAX_NAME_LENGTH 128 +#endif /* --------------------------------- @@ -206,30 +283,74 @@ ---------- TCP options ---------- --------------------------------- */ -/** - * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. - * Define to 0 if your device is low on memory. - */ -#define TCP_QUEUE_OOSEQ 0 - -/* - * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all - * events (accept, sent, etc) that happen in the system. - * LWIP_CALLBACK_API==1: The PCB callback function is called directly - * for the event. This is the default. -*/ -#define TCP_MSS 1460 - /** * TCP_MAXRTX: Maximum number of retransmissions of data segments. */ +#ifndef TCP_MAXRTX #define TCP_MAXRTX 6 - +#endif /** * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. */ +#ifndef TCP_SYNMAXRTX #define TCP_SYNMAXRTX 3 +#endif + +/** + * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. + * Define to 0 if your device is low on memory. + */ +#ifndef TCP_QUEUE_OOSEQ +#define TCP_QUEUE_OOSEQ 1 +#endif + +/** + * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default, + * you might want to increase this.) + * For the receive side, this MSS is advertised to the remote side + * when opening a connection. For the transmit size, this MSS sets + * an upper limit on the MSS advertised by the remote host. + */ +#ifndef TCP_MSS +#define TCP_MSS 1460 +#endif + +/** + * TCP_OOSEQ_MAX_BYTES: The maximum number of bytes queued on ooseq per pcb. + * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==1. + */ +#ifndef TCP_OOSEQ_MAX_BYTES +#if TCP_OOSEQ_MAX_BYTES +#define TCP_OOSEQ_MAX_BYTES (2 * TCP_MSS) +#endif +#endif + +/** + * TCP_OOSEQ_MAX_PBUFS: The maximum number of pbufs queued on ooseq per pcb. + * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==1. + */ +#ifndef TCP_OOSEQ_MAX_PBUFS +#if TCP_OOSEQ_MAX_PBUFS +#define TCP_OOSEQ_MAX_PBUFS 2 +#endif +#endif + +/** + * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. + */ +#ifndef TCP_LISTEN_BACKLOG +#define TCP_LISTEN_BACKLOG 1 +#endif + +/** + * The maximum allowed backlog for TCP listen netconns. + * This backlog is used unless another is explicitly specified. + * 0xff is the maximum (u8_t). + */ +#ifndef TCP_DEFAULT_LISTEN_BACKLOG +#define TCP_DEFAULT_LISTEN_BACKLOG 2 +#endif /* ---------------------------------- @@ -237,19 +358,50 @@ ---------------------------------- */ +/** + * PBUF_LINK_ENCAPSULATION_HLEN: the number of bytes that should be allocated + * for an additional encapsulation header before ethernet headers (e.g. 802.11) + * + * 1. LINK_HLEN 14Byte will be remove in WLAN layer + * 2. IEEE80211_HDR_MAX_LEN needs 40 bytes. + * 3. encryption needs exra 4 bytes ahead of actual data payload, and require + * DAddr and SAddr to be 4-byte aligned. + * 4. TRANSPORT and IP are all 20, 4 bytes aligned, nice... + * 5. LCC add 6 bytes more, We don't consider WAPI yet... + * 6. define LWIP_MEM_ALIGN to be 4 Byte aligned, pbuf struct is 16B, Only thing may be + * matter is ether_hdr is not 4B aligned. + * + * So, we need extra (40 + 4 - 14) = 30 and it's happen to be 4-Byte aligned + * + * 1. lwip + * | empty 30B | eth_hdr (14B) | payload ...| + * total: 44B ahead payload + * 2. net80211 + * | max 80211 hdr, 32B | ccmp/tkip iv (8B) | sec rsv(4B) | payload ...| + * total: 40B ahead sec_rsv and 44B ahead payload + * + */ +#define PBUF_LINK_ENCAPSULATION_HLEN 36 + /* ------------------------------------------------ ---------- Network Interfaces options ---------- ------------------------------------------------ */ /** - * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data + * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname + * field. + */ +#ifndef LWIP_NETIF_HOSTNAME +#define LWIP_NETIF_HOSTNAME 1 +#endif + +/** + * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP *tries* to put all data * to be sent into one single pbuf. This is for compatibility with DMA-enabled * MACs that do not support scatter-gather. * Beware that this might involve CPU-memcpy before transmitting that would not * be needed without this flag! Use this only if you need to! - * - * @todo: TCP and IP-frag do not work with this, yet: */ #define LWIP_NETIF_TX_SINGLE_PBUF 1 @@ -275,7 +427,9 @@ * The stack size value itself is platform-dependent, but is passed to * sys_thread_new() when the thread is created. */ -#define TCPIP_THREAD_STACKSIZE 512 //not ok:384 +#ifndef TCPIP_THREAD_STACKSIZE +#define TCPIP_THREAD_STACKSIZE 768 +#endif /** * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. @@ -327,30 +481,40 @@ * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and * SO_SNDTIMEO processing. */ +#ifndef LWIP_SO_SNDTIMEO #define LWIP_SO_SNDTIMEO 1 +#endif /** * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and * SO_RCVTIMEO processing. */ +#ifndef LWIP_SO_RCVTIMEO #define LWIP_SO_RCVTIMEO 1 +#endif /** * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set * in seconds. (does not require sockets.c, and will affect tcp.c) */ +#ifndef LWIP_TCP_KEEPALIVE #define LWIP_TCP_KEEPALIVE 1 +#endif /** * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. */ +#ifndef LWIP_SO_RCVBUF #define LWIP_SO_RCVBUF 0 +#endif /** * SO_REUSE==1: Enable SO_REUSEADDR option. */ +#ifndef SO_REUSE #define SO_REUSE 1 +#endif /* ---------------------------------------- @@ -358,6 +522,20 @@ ---------------------------------------- */ +/** + * LWIP_STATS==1: Enable statistics collection in lwip_stats. + */ +#ifndef LWIP_STATS +#define LWIP_STATS 0 +#endif + +/** + * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions. + */ +#ifndef LWIP_STATS_DISPLAY +#define LWIP_STATS_DISPLAY 0 +#endif + /* --------------------------------- ---------- PPP options ---------- @@ -375,6 +553,12 @@ ---------- IPv6 options --------------- --------------------------------------- */ +/** + * LWIP_IPV6==1: Enable IPv6 + */ +#ifndef LWIP_IPV6 +#define LWIP_IPV6 0 +#endif /* --------------------------------------- @@ -391,11 +575,29 @@ // Uncomment this line, and set the individual debug options you want, for IP stack debug output //#define LWIP_DEBUG +/** + * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is + * compared against this value. If it is smaller, then debugging + * messages are written. + */ +//#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_WARNING + +/** + * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable + * debug messages of certain types. + */ +#define LWIP_DBG_TYPES_ON LWIP_DBG_ON + /** * ETHARP_DEBUG: Enable debugging in etharp.c. */ #define ETHARP_DEBUG LWIP_DBG_OFF +/** + * NETIF_DEBUG: Enable debugging in netif.c. + */ +#define NETIF_DEBUG LWIP_DBG_OFF + /** * PBUF_DEBUG: Enable debugging in pbuf.c. */ @@ -406,50 +608,151 @@ */ #define API_LIB_DEBUG LWIP_DBG_OFF +/** + * API_MSG_DEBUG: Enable debugging in api_msg.c. + */ +#define API_MSG_DEBUG LWIP_DBG_OFF + /** * SOCKETS_DEBUG: Enable debugging in sockets.c. */ #define SOCKETS_DEBUG LWIP_DBG_OFF +/** + * ICMP_DEBUG: Enable debugging in icmp.c. + */ +#define ICMP_DEBUG LWIP_DBG_OFF + +/** + * IGMP_DEBUG: Enable debugging in igmp.c. + */ +#define IGMP_DEBUG LWIP_DBG_OFF + +/** + * INET_DEBUG: Enable debugging in inet.c. + */ +#define INET_DEBUG LWIP_DBG_OFF + /** * IP_DEBUG: Enable debugging for IP. */ #define IP_DEBUG LWIP_DBG_OFF +/** + * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass. + */ +#define IP_REASS_DEBUG LWIP_DBG_OFF + +/** + * RAW_DEBUG: Enable debugging in raw.c. + */ +#define RAW_DEBUG LWIP_DBG_OFF + +/** + * MEM_DEBUG: Enable debugging in mem.c. + */ +#define MEM_DEBUG LWIP_DBG_OFF + /** * MEMP_DEBUG: Enable debugging in memp.c. */ #define MEMP_DEBUG LWIP_DBG_OFF +/** + * SYS_DEBUG: Enable debugging in sys.c. + */ +#define SYS_DEBUG LWIP_DBG_OFF + +/** + * TIMERS_DEBUG: Enable debugging in timers.c. + */ +#define TIMERS_DEBUG LWIP_DBG_OFF + +/** + * TCP_DEBUG: Enable debugging for TCP. + */ +#define TCP_DEBUG LWIP_DBG_OFF + /** * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. */ #define TCP_INPUT_DEBUG LWIP_DBG_OFF +/** + * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit. + */ +#define TCP_FR_DEBUG LWIP_DBG_OFF + +/** + * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit + * timeout. + */ +#define TCP_RTO_DEBUG LWIP_DBG_OFF + +/** + * TCP_CWND_DEBUG: Enable debugging for TCP congestion window. + */ +#define TCP_CWND_DEBUG LWIP_DBG_OFF + +/** + * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating. + */ +#define TCP_WND_DEBUG LWIP_DBG_OFF + /** * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. */ #define TCP_OUTPUT_DEBUG LWIP_DBG_OFF /** - * UDP_DEBUG: Enable debugging in udp.c. + * TCP_RST_DEBUG: Enable debugging for TCP with the RST message. */ -#define UDP_DEBUG LWIP_DBG_OFF +#define TCP_RST_DEBUG LWIP_DBG_OFF /** - * ICMP_DEBUG: Enable debugging in udp.c. + * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths. */ -#define ICMP_DEBUG LWIP_DBG_OFF +#define TCP_QLEN_DEBUG LWIP_DBG_OFF + +/** + * UDP_DEBUG: Enable debugging in UDP. + */ +#define UDP_DEBUG LWIP_DBG_OFF /** * TCPIP_DEBUG: Enable debugging in tcpip.c. */ #define TCPIP_DEBUG LWIP_DBG_OFF +/** + * SLIP_DEBUG: Enable debugging in slipif.c. + */ +#define SLIP_DEBUG LWIP_DBG_OFF /** * DHCP_DEBUG: Enable debugging in dhcp.c. */ #define DHCP_DEBUG LWIP_DBG_OFF +/** + * AUTOIP_DEBUG: Enable debugging in autoip.c. + */ +#define AUTOIP_DEBUG LWIP_DBG_OFF + +/** + * DNS_DEBUG: Enable debugging for DNS. + */ +#define DNS_DEBUG LWIP_DBG_OFF + +/** + * IP6_DEBUG: Enable debugging for IPv6. + */ +#define IP6_DEBUG LWIP_DBG_OFF + +/* + -------------------------------------------------- + ---------- Performance tracking options ---------- + -------------------------------------------------- +*/ + #endif /* __LWIPOPTS_H__ */ diff --git a/lwip/lwip b/lwip/lwip index 3cf8d51..ae317fe 160000 --- a/lwip/lwip +++ b/lwip/lwip @@ -1 +1 @@ -Subproject commit 3cf8d514bd76e6ef77e6fa514d0ec6d96da7fd9a +Subproject commit ae317fe74dd61ab5eacf5c83dfe8f2af4795421e diff --git a/lwip/sys_arch.c b/lwip/sys_arch.c index 87d8450..1a9c5f9 100644 --- a/lwip/sys_arch.c +++ b/lwip/sys_arch.c @@ -49,17 +49,147 @@ #include "lwip/mem.h" #include "lwip/stats.h" -extern bool esp_in_isr; - -/* Based on the default xInsideISR mechanism to determine - if an ISR is running. - - Doesn't support the possibility that LWIP functions are called from the NMI - handler (none are called from NMI when using current/SDK implementation.) -*/ -static inline bool is_inside_isr() +/*---------------------------------------------------------------------------* + * Routine: sys_sem_new + *---------------------------------------------------------------------------* + * Description: + * Creates and returns a new semaphore. The "ucCount" argument specifies + * the initial state of the semaphore. + * NOTE: Currently this routine only creates counts of 1 or 0 + * Inputs: + * sys_mbox_t mbox -- Handle of mailbox + * u8_t ucCount -- Initial ucCount of semaphore (1 or 0) + * Outputs: + * sys_sem_t -- Created semaphore or 0 if could not create. + *---------------------------------------------------------------------------*/ +err_t sys_sem_new(sys_sem_t *pxSemaphore, u8_t ucCount) { - return esp_in_isr; + err_t xReturn = ERR_MEM; + + vSemaphoreCreateBinary(*pxSemaphore); + + if (*pxSemaphore != NULL) { + if (ucCount == 0U) { + xSemaphoreTake(*pxSemaphore, 1UL); + } + + xReturn = ERR_OK; + SYS_STATS_INC_USED(sem); + } else { + SYS_STATS_INC(sem.err); + } + + return xReturn; +} + +/*---------------------------------------------------------------------------* + * Routine: sys_sem_free + *---------------------------------------------------------------------------* + * Description: + * Deallocates a semaphore + * Inputs: + * sys_sem_t sem -- Semaphore to free + *---------------------------------------------------------------------------*/ +void sys_sem_free(sys_sem_t *pxSemaphore) +{ + SYS_STATS_DEC(sem.used); + vQueueDelete(*pxSemaphore); +} + +/*---------------------------------------------------------------------------* + * Routine: sys_sem_signal + *---------------------------------------------------------------------------* + * Description: + * Signals (releases) a semaphore + * Inputs: + * sys_sem_t sem -- Semaphore to signal + *---------------------------------------------------------------------------*/ +void sys_sem_signal(sys_sem_t *pxSemaphore) +{ + xSemaphoreGive(*pxSemaphore); +} + +/*---------------------------------------------------------------------------* + * Routine: sys_arch_sem_wait + *---------------------------------------------------------------------------* + * Description: + + * 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 zero, the thread should be blocked until the semaphore is signalled. + * + * The return value is SYS_ARCH_TIMEOUT if the semaphore wasn't signaled + * within the specified time or any other value if it was signaled (with or + * without waiting). + * + * Notice that lwIP implements a function with a similar name, + * sys_sem_wait(), that uses the sys_arch_sem_wait() function. + * Inputs: + * sys_sem_t sem -- Semaphore to wait on + * u32_t timeout -- Number of milliseconds until timeout + * Outputs: + * u32_t -- SYS_ARCH_TIMEOUT on timeout, any other value on success + *---------------------------------------------------------------------------*/ +u32_t sys_arch_sem_wait(sys_sem_t *pxSemaphore, u32_t ulTimeout) +{ + u32_t ulReturn; + + if (ulTimeout != 0UL) { + if (xSemaphoreTake(*pxSemaphore, ulTimeout / portTICK_PERIOD_MS) == pdTRUE) { + ulReturn = 0; + } else { + ulReturn = SYS_ARCH_TIMEOUT; + } + } else { + while (xSemaphoreTake(*pxSemaphore, portMAX_DELAY) != pdTRUE); + ulReturn = 0; + } + + return ulReturn; +} + +/** Create a new mutex + * @param mutex pointer to the mutex to create + * @return a new mutex */ +err_t sys_mutex_new(sys_mutex_t *pxMutex) +{ + err_t xReturn; + + *pxMutex = xSemaphoreCreateMutex(); + + if (*pxMutex != NULL) { + xReturn = ERR_OK; + SYS_STATS_INC_USED(mutex); + } else { + xReturn = ERR_MEM; + SYS_STATS_INC(mutex.err); + } + + return xReturn; +} + +/** Lock a mutex + * @param mutex the mutex to lock */ +void sys_mutex_lock(sys_mutex_t *pxMutex) +{ + while (xSemaphoreTake(*pxMutex, portMAX_DELAY) != pdPASS); +} + +/** Unlock a mutex + * @param mutex the mutex to unlock */ +void sys_mutex_unlock(sys_mutex_t *pxMutex) +{ + xSemaphoreGive(*pxMutex); +} + + +/** Delete a semaphore + * @param mutex the mutex to delete */ +void sys_mutex_free(sys_mutex_t *pxMutex) +{ + SYS_STATS_DEC(mutex.used); + vQueueDelete(*pxMutex); } /*---------------------------------------------------------------------------* @@ -72,16 +202,15 @@ static inline bool is_inside_isr() * Outputs: * sys_mbox_t -- Handle to new mailbox *---------------------------------------------------------------------------*/ -err_t sys_mbox_new( sys_mbox_t *pxMailBox, int iSize ) +err_t sys_mbox_new(sys_mbox_t *pxMailBox, int iSize) { err_t xReturn = ERR_MEM; - *pxMailBox = xQueueCreate( iSize, sizeof( void * ) ); + *pxMailBox = xQueueCreate(iSize, sizeof(void *)); - if( *pxMailBox != NULL ) - { + if (*pxMailBox != NULL) { xReturn = ERR_OK; - SYS_STATS_INC_USED( mbox ); + SYS_STATS_INC_USED(mbox); } return xReturn; @@ -100,25 +229,24 @@ err_t sys_mbox_new( sys_mbox_t *pxMailBox, int iSize ) * Outputs: * sys_mbox_t -- Handle to new mailbox *---------------------------------------------------------------------------*/ -void sys_mbox_free( sys_mbox_t *pxMailBox ) +void sys_mbox_free(sys_mbox_t *pxMailBox) { -unsigned long ulMessagesWaiting; + unsigned long ulMessagesWaiting; - ulMessagesWaiting = uxQueueMessagesWaiting( *pxMailBox ); - configASSERT( ( ulMessagesWaiting == 0 ) ); + ulMessagesWaiting = uxQueueMessagesWaiting(*pxMailBox); + configASSERT(ulMessagesWaiting == 0); #if SYS_STATS { - if( ulMessagesWaiting != 0UL ) - { - SYS_STATS_INC( mbox.err ); + if (ulMessagesWaiting != 0UL) { + SYS_STATS_INC(mbox.err); } - SYS_STATS_DEC( mbox.used ); + SYS_STATS_DEC(mbox.used); } #endif /* SYS_STATS */ - vQueueDelete( *pxMailBox ); + vQueueDelete(*pxMailBox); } /*---------------------------------------------------------------------------* @@ -130,9 +258,9 @@ unsigned long ulMessagesWaiting; * sys_mbox_t mbox -- Handle of mailbox * void *data -- Pointer to data to post *---------------------------------------------------------------------------*/ -void sys_mbox_post( sys_mbox_t *pxMailBox, void *pxMessageToPost ) +void sys_mbox_post(sys_mbox_t *pxMailBox, void *pxMessageToPost) { - while( xQueueSendToBack( *pxMailBox, &pxMessageToPost, portMAX_DELAY ) != pdTRUE ); + while (xQueueSendToBack(*pxMailBox, &pxMessageToPost, portMAX_DELAY) != pdTRUE); } /*---------------------------------------------------------------------------* @@ -148,26 +276,13 @@ void sys_mbox_post( sys_mbox_t *pxMailBox, void *pxMessageToPost ) * err_t -- ERR_OK if message posted, else ERR_MEM * if not. *---------------------------------------------------------------------------*/ -err_t sys_mbox_trypost( sys_mbox_t *pxMailBox, void *pxMessageToPost ) +err_t sys_mbox_trypost(sys_mbox_t *pxMailBox, void *pxMessageToPost) { -err_t xReturn; -portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + err_t xReturn; - if( is_inside_isr() != pdFALSE ) - { - xReturn = xQueueSendFromISR( *pxMailBox, &pxMessageToPost, &xHigherPriorityTaskWoken ); - } - else - { - xReturn = xQueueSend( *pxMailBox, &pxMessageToPost, ( TickType_t ) 0 ); - } - - if( xReturn == pdPASS ) - { + if (xQueueSend(*pxMailBox, &pxMessageToPost, 0)) { xReturn = ERR_OK; - } - else - { + } else { /* The queue was already full. */ xReturn = ERR_MEM; SYS_STATS_INC( mbox.err ); @@ -188,8 +303,8 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; * 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. + * SYS_ARCH_TIMEOUT if there was a timeout, any other value if a messages + * is received. * * Note that a function with a similar name, sys_mbox_fetch(), is * implemented by lwIP. @@ -198,52 +313,28 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; * void **msg -- Pointer to pointer to msg received * u32_t timeout -- Number of milliseconds until timeout * Outputs: - * u32_t -- SYS_ARCH_TIMEOUT if timeout, else number - * of milliseconds until received. + * u32_t -- SYS_ARCH_TIMEOUT on timeout, any other value if a message has been received *---------------------------------------------------------------------------*/ -u32_t sys_arch_mbox_fetch( sys_mbox_t *pxMailBox, void **ppvBuffer, u32_t ulTimeOut ) +u32_t sys_arch_mbox_fetch(sys_mbox_t *pxMailBox, void **ppvBuffer, u32_t ulTimeOut) { -void *pvDummy; -TickType_t xStartTime, xEndTime, xElapsed; -unsigned long ulReturn; + void *pvDummy; + unsigned long ulReturn; - xStartTime = xTaskGetTickCount(); - - if( NULL == ppvBuffer ) - { + if (ppvBuffer == NULL) { ppvBuffer = &pvDummy; } - if( ulTimeOut != 0UL ) - { - configASSERT( is_inside_isr() == ( portBASE_TYPE ) 0 ); - - if( pdTRUE == xQueueReceive( *pxMailBox, &( *ppvBuffer ), ulTimeOut/ portTICK_PERIOD_MS ) ) - { - xEndTime = xTaskGetTickCount(); - xElapsed = ( xEndTime - xStartTime ) * portTICK_PERIOD_MS; - - ulReturn = xElapsed; - } - else - { + if (ulTimeOut != 0UL) { + if (xQueueReceive(*pxMailBox, &(*ppvBuffer), ulTimeOut / portTICK_PERIOD_MS) == pdTRUE) { + ulReturn = 0; + } else { /* Timed out. */ *ppvBuffer = NULL; ulReturn = SYS_ARCH_TIMEOUT; } - } - else - { - while( pdTRUE != xQueueReceive( *pxMailBox, &( *ppvBuffer ), portMAX_DELAY ) ); - xEndTime = xTaskGetTickCount(); - xElapsed = ( xEndTime - xStartTime ) * portTICK_PERIOD_MS; - - if( xElapsed == 0UL ) - { - xElapsed = 1UL; - } - - ulReturn = xElapsed; + } else { + while (xQueueReceive(*pxMailBox, &(*ppvBuffer), portMAX_DELAY) != pdTRUE); + ulReturn = 0; } return ulReturn; @@ -263,218 +354,24 @@ unsigned long ulReturn; * u32_t -- SYS_MBOX_EMPTY if no messages. Otherwise, * return ERR_OK. *---------------------------------------------------------------------------*/ -u32_t sys_arch_mbox_tryfetch( sys_mbox_t *pxMailBox, void **ppvBuffer ) +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *pxMailBox, void **ppvBuffer) { -void *pvDummy; -unsigned long ulReturn; -long lResult; -portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + void *pvDummy; + unsigned long ulReturn; - if( ppvBuffer== NULL ) - { + if (ppvBuffer== NULL) { ppvBuffer = &pvDummy; } - if( is_inside_isr() != pdFALSE ) - { - lResult = xQueueReceiveFromISR( *pxMailBox, &( *ppvBuffer ), &xHigherPriorityTaskWoken ); - } - else - { - lResult = xQueueReceive( *pxMailBox, &( *ppvBuffer ), 0UL ); - } - - if( lResult == pdPASS ) - { + if (xQueueReceive(*pxMailBox, &(*ppvBuffer), 0UL) == pdPASS) { ulReturn = ERR_OK; - } - else - { + } else { ulReturn = SYS_MBOX_EMPTY; } return ulReturn; } -/*---------------------------------------------------------------------------* - * Routine: sys_sem_new - *---------------------------------------------------------------------------* - * Description: - * Creates and returns a new semaphore. The "ucCount" argument specifies - * the initial state of the semaphore. - * NOTE: Currently this routine only creates counts of 1 or 0 - * Inputs: - * sys_mbox_t mbox -- Handle of mailbox - * u8_t ucCount -- Initial ucCount of semaphore (1 or 0) - * Outputs: - * sys_sem_t -- Created semaphore or 0 if could not create. - *---------------------------------------------------------------------------*/ -err_t sys_sem_new( sys_sem_t *pxSemaphore, u8_t ucCount ) -{ -err_t xReturn = ERR_MEM; - - vSemaphoreCreateBinary( ( *pxSemaphore ) ); - - if( *pxSemaphore != NULL ) - { - if( ucCount == 0U ) - { - xSemaphoreTake( *pxSemaphore, 1UL ); - } - - xReturn = ERR_OK; - SYS_STATS_INC_USED( sem ); - } - else - { - SYS_STATS_INC( sem.err ); - } - - return xReturn; -} - -/*---------------------------------------------------------------------------* - * Routine: sys_arch_sem_wait - *---------------------------------------------------------------------------* - * Description: - * 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. - * Inputs: - * sys_sem_t sem -- Semaphore to wait on - * u32_t timeout -- Number of milliseconds until timeout - * Outputs: - * u32_t -- Time elapsed or SYS_ARCH_TIMEOUT. - *---------------------------------------------------------------------------*/ -u32_t sys_arch_sem_wait( sys_sem_t *pxSemaphore, u32_t ulTimeout ) -{ -TickType_t xStartTime, xEndTime, xElapsed; -unsigned long ulReturn; - - xStartTime = xTaskGetTickCount(); - - if( ulTimeout != 0UL ) - { - if( xSemaphoreTake( *pxSemaphore, ulTimeout / portTICK_PERIOD_MS ) == pdTRUE ) - { - xEndTime = xTaskGetTickCount(); - xElapsed = (xEndTime - xStartTime) * portTICK_PERIOD_MS; - ulReturn = xElapsed; - } - else - { - ulReturn = SYS_ARCH_TIMEOUT; - } - } - else - { - while( xSemaphoreTake( *pxSemaphore, portMAX_DELAY ) != pdTRUE ); - xEndTime = xTaskGetTickCount(); - xElapsed = ( xEndTime - xStartTime ) * portTICK_PERIOD_MS; - - if( xElapsed == 0UL ) - { - xElapsed = 1UL; - } - - ulReturn = xElapsed; - } - - return ulReturn; -} - -/** Create a new mutex - * @param mutex pointer to the mutex to create - * @return a new mutex */ -err_t sys_mutex_new( sys_mutex_t *pxMutex ) -{ -err_t xReturn = ERR_MEM; - - *pxMutex = xSemaphoreCreateMutex(); - - if( *pxMutex != NULL ) - { - xReturn = ERR_OK; - SYS_STATS_INC_USED( mutex ); - } - else - { - SYS_STATS_INC( mutex.err ); - } - - return xReturn; -} - -/** Lock a mutex - * @param mutex the mutex to lock */ -void sys_mutex_lock( sys_mutex_t *pxMutex ) -{ - while( xSemaphoreTake( *pxMutex, portMAX_DELAY ) != pdPASS ); -} - -/** Unlock a mutex - * @param mutex the mutex to unlock */ -void sys_mutex_unlock(sys_mutex_t *pxMutex ) -{ - xSemaphoreGive( *pxMutex ); -} - - -/** Delete a semaphore - * @param mutex the mutex to delete */ -void sys_mutex_free( sys_mutex_t *pxMutex ) -{ - SYS_STATS_DEC( mutex.used ); - vQueueDelete( *pxMutex ); -} - - -/*---------------------------------------------------------------------------* - * Routine: sys_sem_signal - *---------------------------------------------------------------------------* - * Description: - * Signals (releases) a semaphore - * Inputs: - * sys_sem_t sem -- Semaphore to signal - *---------------------------------------------------------------------------*/ -void sys_sem_signal( sys_sem_t *pxSemaphore ) -{ -portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - - if( is_inside_isr() != pdFALSE ) - { - xSemaphoreGiveFromISR( *pxSemaphore, &xHigherPriorityTaskWoken ); - } - else - { - xSemaphoreGive( *pxSemaphore ); - } -} - -/*---------------------------------------------------------------------------* - * Routine: sys_sem_free - *---------------------------------------------------------------------------* - * Description: - * Deallocates a semaphore - * Inputs: - * sys_sem_t sem -- Semaphore to free - *---------------------------------------------------------------------------*/ -void sys_sem_free( sys_sem_t *pxSemaphore ) -{ - SYS_STATS_DEC(sem.used); - vQueueDelete( *pxSemaphore ); -} - /*---------------------------------------------------------------------------* * Routine: sys_init *---------------------------------------------------------------------------* @@ -508,20 +405,17 @@ u32_t sys_now(void) * Outputs: * sys_thread_t -- Pointer to per-thread timeouts. *---------------------------------------------------------------------------*/ -sys_thread_t sys_thread_new( const char *pcName, void( *pxThread )( void *pvParameters ), void *pvArg, int iStackSize, int iPriority ) +sys_thread_t sys_thread_new(const char *pcName, void(*pxThread)(void *pvParameters), void *pvArg, int iStackSize, int iPriority) { -TaskHandle_t xCreatedTask; -portBASE_TYPE xResult; -sys_thread_t xReturn; + TaskHandle_t xCreatedTask; + portBASE_TYPE xResult; + sys_thread_t xReturn; - xResult = xTaskCreate( pxThread, pcName, iStackSize, pvArg, iPriority, &xCreatedTask ); + xResult = xTaskCreate(pxThread, pcName, iStackSize, pvArg, iPriority, &xCreatedTask); - if( xResult == pdPASS ) - { + if (xResult == pdPASS) { xReturn = xCreatedTask; - } - else - { + } else { xReturn = NULL; } @@ -547,13 +441,14 @@ sys_thread_t xReturn; * Outputs: * sys_prot_t -- Previous protection level (not used here) *---------------------------------------------------------------------------*/ -sys_prot_t sys_arch_protect( void ) +static uint32_t my_nesting = 0; +sys_prot_t sys_arch_protect(void) { - if( is_inside_isr() == pdFALSE ) - { - taskENTER_CRITICAL(); - } - return ( sys_prot_t ) 1; + taskENTER_CRITICAL(); + uint32_t prev = my_nesting; + my_nesting++; + return prev; + //return (sys_prot_t)1; } /*---------------------------------------------------------------------------* @@ -567,26 +462,16 @@ sys_prot_t sys_arch_protect( void ) * Inputs: * sys_prot_t -- Previous protection level (not used here) *---------------------------------------------------------------------------*/ -void sys_arch_unprotect( sys_prot_t xValue ) +void sys_arch_unprotect(sys_prot_t xValue) { - (void) xValue; - if( is_inside_isr() == pdFALSE ) - { - taskEXIT_CRITICAL(); + //(void) xValue; + my_nesting--; + if (xValue != my_nesting) { + printf("lwip nesting %d\n", my_nesting); } + taskEXIT_CRITICAL(); } -/* - * Prints an assertion messages and aborts execution. - */ -void sys_assert( const char *pcMessage ) -{ - (void) pcMessage; - - for (;;) - { - } -} /*-------------------------------------------------------------------------* * End of File: sys_arch.c *-------------------------------------------------------------------------*/ diff --git a/open_esplibs/include/esplibs/libmain.h b/open_esplibs/include/esplibs/libmain.h index 9f4ad1a..593092c 100644 --- a/open_esplibs/include/esplibs/libmain.h +++ b/open_esplibs/include/esplibs/libmain.h @@ -56,6 +56,7 @@ uint32_t sdk_system_relative_time(uint32_t reltime); uint32_t sdk_system_get_checksum(uint8_t *, uint32_t); void sdk_wifi_softap_cacl_mac(uint8_t *, uint8_t *); void sdk_wifi_softap_set_default_ssid(void); +bool sdk_wifi_softap_set_station_info(const uint8_t *hwaddr, ip4_addr_t *); // xtensa_context.o diff --git a/open_esplibs/include/esplibs/libnet80211.h b/open_esplibs/include/esplibs/libnet80211.h index b7a2db6..d2c117b 100644 --- a/open_esplibs/include/esplibs/libnet80211.h +++ b/open_esplibs/include/esplibs/libnet80211.h @@ -32,7 +32,7 @@ struct esf_buf *sdk_ieee80211_getmgtframe(void **arg0, uint32_t arg1, uint32_t a extern uint8_t sdk_TmpSTAAPCloseAP; extern uint8_t sdk_PendFreeBcnEb; void sdk_ieee80211_hostap_attach(struct sdk_g_ic_st *); -void sdk_hostap_handle_timer(struct sdk_netif_conninfo *cnx_node); +void sdk_hostap_handle_timer(struct sdk_cnx_node *cnx_node); bool sdk_wifi_softap_start(); bool sdk_wifi_softap_stop(); @@ -85,10 +85,10 @@ int sdk_chm_check_same_channel(); extern ETSTimer sdk_sta_con_timer; extern void *sdk_g_cnx_probe_rc_list_cb; void sdk_cnx_sta_leave(struct sdk_g_ic_netif_info *netif_info, void *); -void *sdk_cnx_node_search(uint8_t mac[6]); -void sdk_cnx_node_leave(struct sdk_g_ic_netif_info *netif, struct sdk_netif_conninfo *conn); +struct sdk_cnx_node *sdk_cnx_node_search(uint8_t mac[6]); +void sdk_cnx_node_leave(struct sdk_g_ic_netif_info *netif, struct sdk_cnx_node *conn); void sdk_cnx_rc_update_state_metric(void *, int, int); -void sdk_cnx_remove_rc(void *); +void sdk_cnx_node_remove(struct sdk_cnx_node *cnx_node); void sdk_cnx_attach(struct sdk_g_ic_st *); #endif /* _ESPLIBS_LIBNET80211_H */ diff --git a/open_esplibs/include/esplibs/libpp.h b/open_esplibs/include/esplibs/libpp.h index c6185b6..836a689 100644 --- a/open_esplibs/include/esplibs/libpp.h +++ b/open_esplibs/include/esplibs/libpp.h @@ -23,6 +23,7 @@ extern uint8_t sdk_interface_mask; void sdk_ic_set_vif(int, int, uint8_t (*)[6], int, int); void sdk_ic_bss_info_update(int, uint8_t (*hwaddr)[], int, int); void sdk_ic_set_sta(int, int, void *, int, int, int, int, int); +void sdk_ic_remove_key(uint32_t); // lmac.o extern uint32_t sdk_lmacConfMib; diff --git a/open_esplibs/include/esplibs/libwpa.h b/open_esplibs/include/esplibs/libwpa.h index 36a2fc2..2839e56 100644 --- a/open_esplibs/include/esplibs/libwpa.h +++ b/open_esplibs/include/esplibs/libwpa.h @@ -53,6 +53,7 @@ int sdk_os_get_random(uint8_t *dst, uint32_t size); // wpa_auth.o uint32_t *sdk_wpa_init(uint8_t (*hwaddr)[], struct _unknown_wpa1 *, int); +void sdk_wpa_auth_sta_deinit(void *); // wpabuf.o diff --git a/open_esplibs/include/open_esplibs.h b/open_esplibs/include/open_esplibs.h index da59d3c..8db78c5 100644 --- a/open_esplibs/include/open_esplibs.h +++ b/open_esplibs/include/open_esplibs.h @@ -6,6 +6,10 @@ // useful for quickly troubleshooting whether a bug is due to the // reimplementation of Espressif libraries, or something else. +// Some source code is mandatory and these are not included as options here. +// For example code referencing lwip structures and flags etc that has changed +// since the initial binary code. + #ifndef OPEN_ESPLIBS #define OPEN_ESPLIBS 1 #endif @@ -32,8 +36,8 @@ #ifndef OPEN_LIBMAIN_XTENSA_CONTEXT #define OPEN_LIBMAIN_XTENSA_CONTEXT (OPEN_LIBMAIN) #endif -#ifndef OPEN_LIBMAIN_USER_INTERFACE -#define OPEN_LIBMAIN_USER_INTERFACE (OPEN_LIBMAIN) +#ifndef OPEN_LIBMAIN_ETS_TIMER +#define OPEN_LIBMAIN_ETS_TIMER (OPEN_LIBMAIN) #endif #ifndef OPEN_LIBNET80211 @@ -42,18 +46,6 @@ #ifndef OPEN_LIBNET80211_ETS #define OPEN_LIBNET80211_ETS (OPEN_LIBNET80211) #endif -#ifndef OPEN_LIBNET80211_HOSTAP -#define OPEN_LIBNET80211_HOSTAP (OPEN_LIBNET80211) -#endif -#ifndef OPEN_LIBNET80211_INPUT -#define OPEN_LIBNET80211_INPUT (OPEN_LIBNET80211) -#endif -#ifndef OPEN_LIBNET80211_STA -#define OPEN_LIBNET80211_STA (OPEN_LIBNET80211) -#endif -#ifndef OPEN_LIBNET80211_WL_CNX -#define OPEN_LIBNET80211_WL_CNX (OPEN_LIBNET80211) -#endif #ifndef OPEN_LIBPHY #define OPEN_LIBPHY (OPEN_ESPLIBS) @@ -115,8 +107,4 @@ #define OPEN_LIBWPA_OS_XTENSA (OPEN_LIBWPA) #endif -#ifndef OPEN_LIBWPA_WPA_MAIN -#define OPEN_LIBWPA_WPA_MAIN (OPEN_LIBWPA) -#endif - #endif /* _OPEN_ESPLIBS_H */ diff --git a/open_esplibs/libmain/user_interface.c b/open_esplibs/libmain/user_interface.c index eed34a1..a21530d 100644 --- a/open_esplibs/libmain/user_interface.c +++ b/open_esplibs/libmain/user_interface.c @@ -3,9 +3,6 @@ Copyright (C) 2015 Espressif Systems. Derived from MIT Licensed SDK libraries. BSD Licensed as described in the file LICENSE */ -#include "open_esplibs.h" -#if OPEN_LIBMAIN_USER_INTERFACE -// The contents of this file are only built if OPEN_LIBMAIN_USER_INTERFACE is set to true #include "FreeRTOS.h" #include "task.h" @@ -147,8 +144,8 @@ bool IRAM sdk_system_rtc_mem_read(uint32_t src_addr, void *des_addr, uint16_t sa return true; } -void sdk_system_pp_recycle_rx_pkt(void *eb) { - sdk_ppRecycleRxPkt(eb); +void sdk_system_pp_recycle_rx_pkt(struct esf_buf *esf_buf) { + sdk_ppRecycleRxPkt(esf_buf); } uint16_t sdk_system_adc_read(void) { @@ -471,8 +468,7 @@ uint32_t sdk_system_relative_time(uint32_t reltime) { return WDEV.SYS_TIME - reltime; } -// Change arg types to ip4_addr for lwip v2. -void sdk_system_station_got_ip_set(struct ip_addr *ip, struct ip_addr *mask, struct ip_addr *gw) { +void sdk_system_station_got_ip_set(struct ip4_addr *ip, struct ip4_addr *mask, struct ip4_addr *gw) { uint8_t *ip_bytes = (uint8_t *)&ip->addr; uint8_t *mask_bytes = (uint8_t *)&mask->addr; uint8_t *gw_bytes = (uint8_t *)&gw->addr; @@ -588,9 +584,9 @@ bool sdk_wifi_get_ip_info(uint8_t if_index, struct ip_info *info) { if (!info) return false; struct netif *netif = _get_netif(if_index); if (netif) { - info->ip = netif->ip_addr; - info->netmask = netif->netmask; - info->gw = netif->gw; + ip4_addr_set(&info->ip, ip_2_ip4(&netif->ip_addr)); + ip4_addr_set(&info->netmask, ip_2_ip4(&netif->netmask)); + ip4_addr_set(&info->gw, ip_2_ip4(&netif->gw)); return true; } @@ -719,5 +715,3 @@ bool sdk_wifi_set_sleep_type(enum sdk_sleep_type type) sdk_pm_set_sleep_type_from_upper(type); return true; } - -#endif /* OPEN_LIBMAIN_USER_INTERFACE */ diff --git a/open_esplibs/libnet80211/ieee80211_hostap.c b/open_esplibs/libnet80211/ieee80211_hostap.c index fbe7f49..74f9675 100644 --- a/open_esplibs/libnet80211/ieee80211_hostap.c +++ b/open_esplibs/libnet80211/ieee80211_hostap.c @@ -3,8 +3,306 @@ Copyright (C) 2015 Espressif Systems. Derived from MIT Licensed SDK libraries. BSD Licensed as described in the file LICENSE */ -#include "open_esplibs.h" -#if OPEN_LIBNET80211_HOSTAP -// The contents of this file are only built if OPEN_LIBNET80211_HOSTAP is set to true -#endif /* OPEN_LIBNET80211_HOSTAP */ +#include +#include "tcpip.h" +#include "espressif/esp_wifi.h" +#include "espressif/esp_misc.h" +#include "etstimer.h" +#include "esplibs/libmain.h" +#include "esplibs/libnet80211.h" +#include "esplibs/libpp.h" +#include "esplibs/libwpa.h" + +static uint8_t hostap_flags = 0; +static ETSTimer hostap_timer; +static struct esf_buf *hostap_timer_parg = NULL; + +void IRAM *zalloc(size_t nbytes); + +static void IRAM hostap_timer_func(struct esf_buf *esf_buf) { + struct sdk_cnx_node *cnx_node = sdk_g_ic.v.softap_netif_info->cnx_nodes[0]; + int32_t mode = sdk_wifi_get_phy_mode(); + uint8_t *frame = esf_buf->frame; + *(uint16_t *)(frame + 22) = (cnx_node->_unknown9c - 1) << 4; + + cnx_node->_unknown9c += 1; + + if (sdk_g_ic.s.wifi_led_enable) { + uint32_t gpio = sdk_g_ic.s.wifi_led_gpio; + uint32_t state = sdk_g_ic.s.wifi_led_state; + sdk_gpio_output_set(state << gpio, (((state & 1) == 0) ? 1 : 0) << gpio, + 1 << gpio, 0); + sdk_g_ic.s.wifi_led_state = (state & 1) ? 0 : 1; + } + + uint8_t *frame2 = frame + sdk_g_ic.s._unknown288 + (mode == 1 ? 23 : 27) ; + memcpy(frame2 + 29, &sdk_g_ic.v._unknown1d2, 1); + + uint32_t v1 = frame2[26]; + if (v1 == 0) { + v1 = frame2[27]; + } + frame2[26] = v1 - 1; + + uint32_t v2 = sdk_ieee80211_chan2ieee(sdk_g_ic.v._unknown14c); + frame2[23] = v2; + sdk_g_ic.s._unknown30d = v2; + + int32_t v3 = *((volatile int32_t *)0x3ff20c00); // mactime + *(uint32_t *)(esf_buf->extra + 16) = v3; + *(uint32_t *)(frame + 24) = v3; + *(uint32_t *)(frame + 28) = 0; + + if (sdk_chm_check_same_channel()) { + hostap_flags |= 1; + sdk_ppTxPkt(esf_buf); + return; + } + sdk_ets_timer_disarm(&hostap_timer); + sdk_ets_timer_arm(&hostap_timer, sdk_wDev_Get_Next_TBTT(), 0); +} + +static void IRAM hostap_tx_callback() { + uint32_t flags = hostap_flags & 0xfe; + + if (sdk_TmpSTAAPCloseAP == 0) { + hostap_flags = flags; + sdk_ets_timer_disarm(&hostap_timer); + sdk_ets_timer_arm(&hostap_timer, sdk_wDev_Get_Next_TBTT(), 0); + return; + } + + sdk_PendFreeBcnEb = 1; + + if (flags & 2) { + hostap_flags = flags & 0xfd; + sdk_wifi_softap_start(); + return; + } + + hostap_flags = flags; +} + +static void hostap_attach_misc() { + struct sdk_g_ic_netif_info *netif_info = sdk_g_ic.v.softap_netif_info; + + struct _unknown_softap1 *ptr1 = zalloc(28); // 0x1c + netif_info->_unknownb4 = ptr1; + + struct _unknown_softap2 *ptr2 = zalloc(204); // 0xcc + ptr1->_unknown04 = ptr2; + + struct _unknown_wpa1 *ptr3 = zalloc(76); // 0x4c + + uint32_t v1 = sdk_g_ic.s._unknown30e; + if (v1 == 2) { + ptr3->_unknown00 = 1; + } else if (v1 == 3) { + ptr3->_unknown00 = 2; + } else if (v1 == 4) { + ptr3->_unknown00 = 3; + } + + ptr3->_unknown28 = 2; + ptr3->_unknown04 = 2; + ptr3->_unknown0c = 2; + ptr3->_unknown08 = 10; + ptr3->_unknown20 = 10; + + int s1 = (sdk_g_ic.s._unknown28a << 16) | sdk_g_ic.s._unknown288; + memcpy(&ptr2->_unknown10, &sdk_g_ic.s._unknown28c, s1); + ptr2->_unknown30 = s1; + + uint8_t *ptr4 = zalloc(64); // 0x40 + ptr2->_unknown3c = ptr4; + + char *str1 = sdk_g_ic.s._unknown2ac; + memcpy(ptr4, str1, strlen(str1)); + + struct sdk_cnx_node *cnx_node = netif_info->cnx_nodes[0]; + + ptr2->_unknownb4 = 300; + + netif_info->_unknown4c = 3; + netif_info->_unknown48 |= 16; + + cnx_node->_unknown08 |= 1; + + sdk_hostapd_setup_wpa_psk(ptr2); + + struct netif *netif = netif_info->netif; + + ptr1->_unknown18 = sdk_wpa_init(&netif->hwaddr, ptr3, 0); + + free(ptr3); +} + +static void softap_stop_free() { + struct sdk_g_ic_netif_info *netif_info = sdk_g_ic.v.softap_netif_info; + netif_info->_unknown4c = 0; + netif_info->_unknown48 &= 0xffffffef; + netif_info->cnx_nodes[0]->_unknown08 = 0; + + struct _unknown_softap1 *unkb4 = netif_info->_unknownb4; + if (!unkb4) return; + + uint32_t *unk18 = unkb4->_unknown18; + if (unk18) { + uint32_t *ptr1 = ((uint32_t **)unk18)[20]; + if (ptr1) + free(ptr1); + + uint32_t *ptr2 = *(uint32_t **)unk18; + if (ptr2) + free(ptr2); + + free(unk18); + } + + struct _unknown_softap2 *unk04 = unkb4->_unknown04; + if (unk04) { + uint32_t *unk38 = unk04->_unknown38; + if (unk38) + free(unk38); + + uint8_t *unk3c = unk04->_unknown3c; + if (unk3c) + free(unk3c); + + free(unk04); + } + + free(unkb4); + netif_info->_unknownb4 = NULL; +} + +void sdk_ieee80211_hostap_attach(struct sdk_g_ic_st *ic) { + uint32_t scratch[12]; // ?? + struct sdk_g_ic_netif_info *netif_info = ic->v.softap_netif_info; + + uint32_t v1 = ic->s._unknown30e; + if (v1 >= 2 && v1 < 5) + hostap_attach_misc(); + + struct netif *netif = netif_info->netif; + sdk_ic_bss_info_update(1, &netif->hwaddr, 2, 100); + + ic->v._unknown1d0 = 0; + netif_info->_unknown3c = 5; + + sdk_ppRegisterTxCallback(hostap_tx_callback, 4); + + hostap_timer_parg = sdk_ieee80211_beacon_alloc(netif_info, scratch); + sdk_ets_timer_disarm(&hostap_timer); + sdk_ets_timer_setfn(&hostap_timer, (ETSTimerFunc *)hostap_timer_func, hostap_timer_parg); + sdk_wDev_Reset_TBTT(); + sdk_ets_timer_arm(&hostap_timer, sdk_wDev_Get_Next_TBTT(), 0); +} + +bool sdk_wifi_softap_start() { + struct sdk_g_ic_netif_info *netif_info = sdk_g_ic.v.softap_netif_info; + if (!netif_info) return 0; + if (netif_info->started) return 1; + + uint8_t flags = hostap_flags; + if (flags & 1) { + hostap_flags = flags | 2; + return 1; + } + + uint8_t (*mac_addr)[6] = &sdk_info.softap_mac_addr; + if (!netif_info->netif) { + struct netif *netif = (struct netif *)malloc(sizeof(struct netif)); + netif_info->netif = netif; + memcpy(&netif->hwaddr, mac_addr, 6); + netif_add(netif, &sdk_info.softap_ipaddr, &sdk_info.softap_netmask, + &sdk_info.softap_gw, netif_info, ethernetif_init, tcpip_input); + } + + sdk_ic_set_vif(1, 1, mac_addr, 1, 0); + + netif_set_up(netif_info->netif); + + if (sdk_wifi_get_opmode() != 3 || + !sdk_g_ic.v.station_netif_info || + sdk_g_ic.v.station_netif_info->_unknown3c < 2) { + + uint32_t i1 = (sdk_g_ic.s._unknown30d - 1) & 0xff; + + int nmi_on = sdk_NMIIrqIsOn; + if (!nmi_on) { + vPortEnterCritical(); + + do { + DPORT.DPORT0 = DPORT.DPORT0 & 0xffffffe0; + } while (DPORT.DPORT0 & 1); + } + + // current channel? + uint32_t *chan = &sdk_g_ic.v._unknown84[i1 * 3]; + sdk_g_ic.v._unknown14c = chan; + + if (!nmi_on) { + DPORT.DPORT0 = (DPORT.DPORT0 & 0xffffffe0) | 1; + vPortExitCritical(); + } + + sdk_chm_set_current_channel(chan); + } + + sdk_ieee80211_hostap_attach(&sdk_g_ic); + sdk_TmpSTAAPCloseAP = 0; + netif_info->started = 1; + return 1; +} + +bool sdk_wifi_softap_stop() { + struct sdk_g_ic_netif_info *netif_info = sdk_g_ic.v.softap_netif_info; + + if (!netif_info) + return 0; + + if (!netif_info->started) + return 1; + + uint32_t end = sdk_g_ic.s._unknown310 + 2; + uint32_t count = 1; + + // Note this defensive test seems dead code, the value is loaded + // as a uint8_t value so adding 2 ensures this test always passes. + if (end >= 2) { + do { + struct sdk_cnx_node *cnx_node = netif_info->cnx_nodes[count]; + if (cnx_node) { + struct sdk_cnx_node *cnx_node2 = netif_info->_unknown88; + netif_info->_unknown88 = cnx_node; + + sdk_ieee80211_send_mgmt(netif_info, 160, 4); + sdk_ieee80211_send_mgmt(netif_info, 192, 2); + + netif_info->_unknown88 = cnx_node2; + + sdk_cnx_node_leave(netif_info, netif_info->cnx_nodes[count]); + + // Number of entries might have changed, perhaps + // should have if one was removed above? + end = sdk_g_ic.s._unknown310 + 2; + } + count++; + } while (count < end); + } + + netif_set_down(netif_info->netif); + sdk_TmpSTAAPCloseAP = 1; + sdk_ets_timer_disarm(&hostap_timer); + sdk_ic_bss_info_update(1, &sdk_info.softap_mac_addr, 2, 0); + sdk_ic_set_vif(1, 0, NULL, 1, 0); + softap_stop_free(); + + if ((hostap_flags & 1) == 0) + sdk_esf_buf_recycle(hostap_timer_parg, 4); + + netif_info->started = 0; + return 1; +} diff --git a/open_esplibs/libnet80211/ieee80211_input.c b/open_esplibs/libnet80211/ieee80211_input.c index be07a51..583dba9 100644 --- a/open_esplibs/libnet80211/ieee80211_input.c +++ b/open_esplibs/libnet80211/ieee80211_input.c @@ -3,9 +3,6 @@ Copyright (C) 2015 Espressif Systems. Derived from MIT Licensed SDK libraries. BSD Licensed as described in the file LICENSE */ -#include "open_esplibs.h" -#if OPEN_LIBNET80211_INPUT -// The contents of this file are only built if OPEN_LIBNET80211_INPUT is set to true #include "esplibs/libpp.h" @@ -14,10 +11,9 @@ void IRAM sdk_ieee80211_deliver_data(struct sdk_g_ic_netif_info *netif_info, str if (netif->flags & NETIF_FLAG_LINK_UP) { uint16_t length = esf_buf->length; - struct pbuf *pbuf = pbuf_alloc(PBUF_RAW, length, PBUF_REF); - pbuf->payload = esf_buf->pbuf2->payload; + struct pbuf *pbuf = pbuf_alloc_reference(esf_buf->pbuf2->payload, length, PBUF_ALLOC_FLAG_RX | PBUF_TYPE_ALLOC_SRC_MASK_ESP_RX); esf_buf->pbuf1 = pbuf; - pbuf->eb = (void *)esf_buf; + pbuf->esf_buf = (void *)esf_buf; ethernetif_input(netif, pbuf); return; } @@ -27,5 +23,3 @@ void IRAM sdk_ieee80211_deliver_data(struct sdk_g_ic_netif_info *netif_info, str return; } - -#endif /* OPEN_LIBNET80211_INPUT */ diff --git a/open_esplibs/libnet80211/ieee80211_sta.c b/open_esplibs/libnet80211/ieee80211_sta.c index 5362dc3..3e7f695 100644 --- a/open_esplibs/libnet80211/ieee80211_sta.c +++ b/open_esplibs/libnet80211/ieee80211_sta.c @@ -3,9 +3,6 @@ Copyright (C) 2015 Espressif Systems. Derived from MIT Licensed SDK libraries. BSD Licensed as described in the file LICENSE */ -#include "open_esplibs.h" -#if OPEN_LIBNET80211_STA -// The contents of this file are only built if OPEN_LIBNET80211_STA is set to true #include #include "esplibs/libmain.h" @@ -72,5 +69,3 @@ bool sdk_wifi_station_stop() { return 1; } - -#endif /* OPEN_LIBNET80211_STA */ diff --git a/open_esplibs/libnet80211/wl_cnx.c b/open_esplibs/libnet80211/wl_cnx.c index 3b7d709..0d2459e 100644 --- a/open_esplibs/libnet80211/wl_cnx.c +++ b/open_esplibs/libnet80211/wl_cnx.c @@ -3,18 +3,29 @@ Copyright (C) 2015 Espressif Systems. Derived from MIT Licensed SDK libraries. BSD Licensed as described in the file LICENSE */ -#include "open_esplibs.h" -#if OPEN_LIBNET80211_WL_CNX -// The contents of this file are only built if OPEN_LIBNET80211_WL_CNX is set to true #include "espressif/esp_misc.h" #include "esplibs/libnet80211.h" +#include "esplibs/libpp.h" +#include "esplibs/libwpa.h" #include #include "lwip/dhcp.h" ETSTimer sdk_sta_con_timer; void *sdk_g_cnx_probe_rc_list_cb; +/* + * Called from the ESP sdk_cnx_sta_leave function. Split out via a hack to the + * binary library to allow modification to track changes to lwip, for example + * changes to the offset of the netif->flags removal of the NETIF_FLAG_DHCP flag + * lwip v2 etc. + */ +void dhcp_if_down(struct netif *netif) +{ + dhcp_release_and_stop(netif); + netif_set_down(netif); +} + #if 0 // Most of the code in this file assesses static data so it will be all or none. @@ -24,7 +35,6 @@ static uint8_t Ldata004; static uint32_t Ldata006; static void *Ldate007; -// Use of the netif->flags and the NETIF_FLAG_DHCP flag removed in lwip v2. void sdk_cnx_sta_leave(struct sdk_g_ic_netif_info *netif_info, void *arg1) { struct netif *netif = netif_info->netif; @@ -32,13 +42,9 @@ void sdk_cnx_sta_leave(struct sdk_g_ic_netif_info *netif_info, void *arg1) { uint16_t v1 = *(uint16_t *)(arg1 + 0x1a) & 0xfff; sdk_ic_set_sta(0, 0, arg1, 0, v1, phy_type, 0, 0); - netif_set_down(netif); - - // The NETIF_FLAG_DHCP flags is removed in lwip v2? - if (netif->flags & 0x8) { - dhcp_release(netif); - dhcp_stop(netif); - } + // Note the SDK binary was modified here as it made use of the + // netif flags which changed in lwip v2. + dhcp_if_down(netif); uint32_t v2 = *(uint8_t *)(arg1 + 0xe8); free(sdk_g_ic.v._unknown190[v2]); @@ -77,7 +83,30 @@ void sdk_cnx_sta_leave(struct sdk_g_ic_netif_info *netif_info, void *arg1) { } #endif -void IRAM *sdk_cnx_node_search(uint8_t mac[6]) +void sdk_cnx_node_remove(struct sdk_cnx_node *cnx_node) { + const uint32_t num = sdk_g_ic.s._unknown310 + 2; + if ((int32_t)num < (int32_t)2) { + return; + } + + struct sdk_g_ic_netif_info *netif_info = sdk_g_ic.v.softap_netif_info; + uint32_t i = 1; + do { + if (netif_info->cnx_nodes[i] == cnx_node) { + uint32_t v2 = cnx_node->_unknowne8; + sdk_ic_remove_key(v2 + 2); + sdk_wpa_auth_sta_deinit(cnx_node->_unknowne4); + free(sdk_g_ic.v._unknown190[v2]); + sdk_g_ic.v._unknown190[v2] = NULL; + free(cnx_node); + netif_info->cnx_nodes[i] = NULL; + return; + } + i += 1; + } while (i < num); +} + +struct sdk_cnx_node *sdk_cnx_node_search(uint8_t mac[6]) { int end = sdk_g_ic.s._unknown310 + 2; @@ -86,15 +115,15 @@ void IRAM *sdk_cnx_node_search(uint8_t mac[6]) if (end < 1) return NULL; - struct sdk_netif_conninfo **conninfo = sdk_g_ic.v.softap_netif_info->conninfo; + struct sdk_cnx_node **cnx_nodes = sdk_g_ic.v.softap_netif_info->cnx_nodes; int i = 0; do { - struct sdk_netif_conninfo *info = conninfo[i]; + struct sdk_cnx_node *cnx_node = cnx_nodes[i]; - if (info) { - if (memcmp(mac, info->mac_addr, 6) == 0) { - return info; + if (cnx_node) { + if (memcmp(mac, cnx_node->mac_addr, 6) == 0) { + return cnx_node; } } i++; @@ -102,5 +131,3 @@ void IRAM *sdk_cnx_node_search(uint8_t mac[6]) return NULL; } - -#endif /* OPEN_LIBNET80211_WL_CNX */ diff --git a/open_esplibs/libpp/wdev.c b/open_esplibs/libpp/wdev.c index 1564a59..902b3dc 100644 --- a/open_esplibs/libpp/wdev.c +++ b/open_esplibs/libpp/wdev.c @@ -5,7 +5,13 @@ */ #include "open_esplibs.h" #if OPEN_LIBPP_WDEV -// The contents of this file are only built if OPEN_LIBPHY_PHY_CHIP_SLEEP is set to true +// The contents of this file are only built if OPEN_LIBPP_WDEV is set to true +// Note the SDK allocated 8000 bytes for TX buffers that appears to be +// unused. Rather TX buffers appear to be allocated by upper layers. The +// location of this areas is at wDevCtrl + 0x2190. The SDK has been modified +// to allocate only one word (4 bytes) per buffer on initialization and even +// these seem unused but to be sure avoid the first 20 bytes. So there are +// 7980 bytes free starting at wDevCtrl + 0x21a4. #endif /* OPEN_LIBPP_WDEV */ diff --git a/open_esplibs/libwpa/wpa_main.c b/open_esplibs/libwpa/wpa_main.c index 1c70516..43f332c 100644 --- a/open_esplibs/libwpa/wpa_main.c +++ b/open_esplibs/libwpa/wpa_main.c @@ -3,13 +3,13 @@ Copyright (C) 2015 Espressif Systems. Derived from MIT Licensed SDK libraries. BSD Licensed as described in the file LICENSE */ -#include "open_esplibs.h" -#if OPEN_LIBWPA_WPA_MAIN -// The contents of this file are only built if OPEN_LIBWPA_WPA_MAIN is set to true +#include +#include #include "espressif/user_interface.h" #include "etstimer.h" #include "espressif/osapi.h" +#include "espressif/esp_sta.h" #include "esplibs/libnet80211.h" #include "esplibs/libmain.h" #include "esplibs/libwpa.h" @@ -44,8 +44,8 @@ void sdk_wpa_config_bss(struct sdk_g_ic_st *g_ic, uint8_t (* hwaddr2)[6]) { struct sdk_g_ic_netif_info *netif_info = g_ic->v.station_netif_info; struct netif *netif = netif_info->netif; sdk_wpa_set_bss(netif->hwaddr, hwaddr2, g_ic->s._unknown20a, g_ic->s._unknown20c, - g_ic->s.sta_password, g_ic->s._unknown1e4.sta_ssid, - (g_ic->s._unknown1e4._unknown1e6 << 16) | g_ic->s._unknown1e4._unknown1e4); + g_ic->s.sta_password, g_ic->s.sta_ssid.ssid, + g_ic->s.sta_ssid.ssid_length); } void sdk_wpa_config_assoc_ie(int arg0, int16_t *arg1, int32_t arg2) { @@ -57,14 +57,14 @@ void sdk_wpa_config_assoc_ie(int arg0, int16_t *arg1, int32_t arg2) { *arg1 = arg2; } -void sdk_dhcp_bind_check() { +void sdk_dhcp_bind_check(void *parg) { struct sdk_g_ic_netif_info *netif_info = sdk_g_ic.v.station_netif_info; uint8_t connect_status = netif_info->connect_status; uint8_t unknown20a = sdk_g_ic.s._unknown20a; - if (connect_status != 5) { + if (connect_status != STATION_GOT_IP) { if (unknown20a == 7 || unknown20a == 8) { - netif_info->connect_status = 2; + netif_info->connect_status = STATION_CONNECTING; } } } @@ -72,13 +72,13 @@ void sdk_dhcp_bind_check() { void sdk_eagle_auth_done() { struct sdk_g_ic_netif_info *netif_info = sdk_g_ic.v.station_netif_info; struct netif *netif = netif_info->netif; - struct sdk_netif_conninfo *conninfo = netif_info->_unknown88; + struct sdk_cnx_node *cnx_node = netif_info->_unknown88; - if (conninfo->_unknown08 & 1) + if (cnx_node->_unknown08 & 1) return; - uint32_t channel = conninfo->_unknown78->channel; - char *ssid = (char *)sdk_g_ic.s._unknown1e4.sta_ssid; + uint32_t channel = cnx_node->_unknown78->channel; + char *ssid = (char *)sdk_g_ic.s.sta_ssid.ssid; printf("\nconnected with %s, channel %d\n", ssid, channel); RTCMEM_SYSTEM[61] = 0x00010000 | channel; @@ -89,24 +89,29 @@ void sdk_eagle_auth_done() { sdk_os_timer_arm(timer, 15000, 0); netif_info->statusb9 = 0; - conninfo->_unknown18 = 0; - conninfo->_unknown08 |= 1; + cnx_node->_unknown18 = 0; + cnx_node->_unknown08 |= 1; - // TODO lwip v2 removed the NETIF_FLAG_DHCP flag. - if (netif->flags & 0x08) // NETIF_FLAG_DHCP + if (dhcp_supplied_address(netif)) return; - // lwip v2: if (ip4_addr_isany_val(netif->ip_addr)) { - if (netif->ip_addr.addr == 0) { - if (sdk_dhcpc_flag != DHCP_STOPPED) { - printf("dhcp client start...\n"); - dhcp_start(netif); - } + if (sdk_dhcpc_flag != DHCP_STOPPED) { + printf("dhcp client start...\n"); + netif_set_up(netif); + dhcp_start(netif); return; } - system_station_got_ip_set(&netif->ip_addr, &netif->netmask, &netif->gw); + if (ip4_addr_isany_val(sdk_info.sta_ipaddr)) { + printf("expected a static ip address?\n"); + return; + } + + netif_set_addr(netif, &sdk_info.sta_ipaddr, &sdk_info.sta_netmask, &sdk_info.sta_gw); netif_set_up(netif); + sdk_system_station_got_ip_set(ip_2_ip4(&netif->ip_addr), + ip_2_ip4(&netif->netmask), + ip_2_ip4(&netif->gw)); } void sdk_wpa_neg_complete() { @@ -120,5 +125,3 @@ void sdk_wpa_attach(struct sdk_g_ic_st *g_ic) { wpa_callback2, sdk_wpa_neg_complete); sdk_ppRegisterTxCallback(sdk_eapol_txcb, 3); } - -#endif /* OPEN_LIBWPA_WPA_MAIN */