espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.44k stars 7.25k forks source link

How do I add non mesh connections to esp_mesh (IDFGH-5823) #7528

Closed clementfumey closed 3 months ago

clementfumey commented 3 years ago

Environment

Problem Description

Based on recently merged commit from @shenjun7 to add non mesh connections access to esp_mesh I am trying to give internet access to an external (non-mesh) device through an ESP-MESH network.

I am using ip_internal_network examples from mesh folder, where I deleted all mqtt stuff to have only a bare esp-mesh network. I am only using two nodes in my mesh network, 1 that become root node and 1 I will use the AP to connect with my external device. I set the configuration to CONFIG_MESH_NON_MESH_AP_CONNECTIONS=2 to enable non-mesh connection. I found that mesh ap hidden ssid was ESPM_XXXXXX, with XXXXXX the last mac address bytes, so I used it to connect from my external device.

Expected Behavior

I expect a root node to be chosen, and successful connection to router, and IPv4 addressed to be assigned to both root (10.0.0.1) and child node (10.0.0.2). When external device connect, I expect an IPv4 address to be assigned and IP packet forwarded to router.

Actual Behavior

Root node is chosen, successful connection to router, IPv4 assigned to both root and child node. But no IPv4 assigned to non-mesh device. Very few logs about external devices trying to connect.

Debug Logs

Logs from the child node when the external device connect and leave somes seconds later :

I (329574) wifi:new:<13,2>, old:<13,2>, ap:<13,2>, sta:<13,2>, prof:13
I (329574) wifi:station: 38:78:62:5a:81:ed join, AID=1, bgn, 20
W (329654) wifi:<ba-add>idx:4 (ifx:1, 38:78:62:5a:81:ed), tid:0, ssn:0, winSize:64
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()
I (346004) wifi:station: 38:78:62:5a:81:ed leave, AID = 1, bss_flags is 134259, bss:0x3ffd2324
I (346004) wifi:new:<13,2>, old:<13,2>, ap:<13,2>, sta:<13,2>, prof:13
W (346004) wifi:<ba-del>idx
dhcp_coarse_tmr()
dhcp_coarse_tmr()
dhcp_coarse_tmr()

Wireshark capture from the external device where we can see that dhcp discover get no answer : non-mesh-connection.pcapng.zip

I am probably missing something. Is it the way of doing it ? Is it the purpose of the commit from @shenjun7 to give internet access to an external device through esp-mesh ? If so how am i supposed to do it ?

Jiangyafeng commented 3 years ago

@clementfumey Thank you very much for your feedback. It is true that there is still a problem that there is no way to obtain an ip address through DHCP. This will be fixed internally.

As for what you said, the link is disconnected after a few seconds because the assoc_expire time is set too short. You can set it to esp_mesh_set_ap_assoc_expire(60), and both mesh and non_mesh nodes need to turn off the ps function.

The hidden ssid of mesh ap is ESPM_XXXXXX, and XXXXXX is indeed the last 3 bytes of the mac address of the mesh node.

clementfumey commented 3 years ago

Thank you for your answer. I think it's more than an DHCP issue as even if I use a fix IPv4 adress on my external device, it's ARP request that are not transmit through the meshAP node.

Should I call ip_napt_enable somewhere in the meshNode to enable napt in the AP ?

Jiangyafeng commented 3 years ago

@clementfumey This problem is being repaired internally, and it seems that ip cannot be obtained on the surface. If there is any progress, I will let you know as soon as possible.

shenjun7 commented 3 years ago

Please update this function to solve the problem temporarily. We will merge into idf in the future.

esp_err_t esp_netif_create_default_wifi_mesh_netifs(esp_netif_t p_netif_sta, esp_netif_t p_netif_ap) { esp_netif_config_t cfg_ap = ESP_NETIF_DEFAULT_WIFI_AP(); esp_netif_t *netif_ap = esp_netif_new(&cfg_ap); assert(netif_ap); ESP_ERROR_CHECK(esp_netif_attach_wifi_ap(netif_ap)); ESP_ERROR_CHECK(esp_wifi_set_default_wifi_ap_handlers());

// ...and stop DHCP server to be compatible with former tcpip_adapter (to keep the ESP_NETIF_DHCP_STOPPED state)
// ESP_ERROR_CHECK(esp_netif_dhcps_stop(netif_ap));
// Create "almost" default station, but with un-flagged DHCP client
esp_netif_inherent_config_t netif_cfg;
memcpy(&netif_cfg, ESP_NETIF_BASE_DEFAULT_WIFI_STA, sizeof(netif_cfg));
netif_cfg.flags &= ~ESP_NETIF_DHCP_CLIENT;
esp_netif_config_t cfg_sta = {
        .base = &netif_cfg,
        .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA,
};
esp_netif_t *netif_sta = esp_netif_new(&cfg_sta);
assert(netif_sta);
ESP_ERROR_CHECK(esp_netif_attach_wifi_station(netif_sta));
ESP_ERROR_CHECK(esp_wifi_set_default_wifi_sta_handlers());

// ...and stop DHCP client (to be started separately if the station were promoted to root)
ESP_ERROR_CHECK(esp_netif_dhcpc_stop(netif_sta));

if (p_netif_sta) {
    *p_netif_sta = netif_sta;
}
if (p_netif_ap) {
    *p_netif_ap = netif_ap;
}
return ESP_OK;

}

clementfumey commented 3 years ago

thank you @shenjun7 . I was using ip_internal_network example which is not using esp_netif_create_default_wifi_mesh_netifs function but mesh_netif.c instead. I am struggling to figure out which code is doing what. I will try to use esp_netif_create_default_wifi_mesh_netifs instead of mesh_netif and see the differences.

clementfumey-inventhys commented 3 years ago

@shenjun7 Here is a schema of what happens either with ip_internal_network or whith internal_communication with your proposed modification examples :

esp_mesh

The functionality I'm trying to achieve is more based on ip_internal_network as I want to give a non-mesh device an internet connection through the mesh. In this example, the root node has a DHCP client on its station side and a DHCP server on its AP side. For others mesh nodes, they only have DHCP Client. Every Mesh nodes, regarding their layers effectively achieve DHCP Request and gets a IP address. However when an external device connects to a mesh node AP, dhcp request are not even display in the mesh node logs. We get the logs I (329574) wifi:station: 38:78:62:5a:81:ed join, AID=1, bgn, 20 but never get the ethernet_input and ip_input logs of the dhcp request like we have when a mesh node join :

I (345241) wifi:station: 84:cc:a8:5e:50:30 join, AID=1, bgn, 40U
I (345241) mesh_main: <MESH_EVENT_PS_CHILD_DUTY>cidx:0, 84:cc:a8:5e:50:30, duty:0
W (345241) mesh_main: <MESH_EVENT_ROUTING_TABLE_ADD>add 1, new:2, layer:1
I (345251) mesh: <nvs>write assoc:1
I (345261) mesh_main: <MESH_EVENT_CHILD_CONNECTED>aid:1, 84:cc:a8:5e:50:30
ethernet_input: dest:ff:ff:ff:ff:ff:ff, src:84:cc:a8:5e:50:30, type:800
ip_input: iphdr->dest 0xffffffff netif->ip_addr 0x104a8c0 (0xffffff, 0x4a8c0, 0xff000000)
ip4_input: packet accepted on interface ap
ip4_input: 
IP header:
+-------------------------------+
| 4 | 5 |  0x00 |       336     | (v, hl, tos, len)
+-------------------------------+
|        0      |000|       0   | (id, flags, offset)
+-------------------------------+
|  255  |   17  |    0xba9d     | (ttl, proto, chksum)
+-------------------------------+
|    0  |    0  |    0  |    0  | (src)
+-------------------------------+
|  255  |  255  |  255  |  255  | (dest)
+-------------------------------+
ip4_input: p->len 336 p->tot_len 336
xenpac commented 2 years ago

just curious, ..add non mesh connections access to esp_mesh... meaning:

@clementfumey , do you have source code for your mesh example without mqtt?

shenjun7 commented 2 years ago

Sorry for the late reply. According to the updated function(esp_netif_create_default_wifi_mesh_netifs(esp_netif_t p_netif_sta, esp_netif_t p_netif_ap)), each mesh AP can be used as a dhcp server to assign IP to non-mesh nodes. Root as the only dhcp server to allocate IP to non-mesh nodes requires a lot of changes, we will update in the future.

italocjs commented 2 years ago

Hi @clementfumey, have you managed to make this work? i have also been trying to do exactly the same without any luck. (provide a smartphone access to internet through a mesh network). If you managed it, could you please share the code?

wizche commented 2 years ago

Hey @shenjun7 and @clementfumey / @clementfumey-inventhys I was having a look at this too. Did you endup porting the ip_internal_network example to use the (fixed) esp_netif_create_default_wifi_mesh_netifs API? The main changes seems that @shenjun7 removed the code that disabled the DHCP server and client (respectively for AP and STA):

// AP config flags
netif_cfg.flags &= ~ESP_NETIF_DHCP_SERVER;
// STA config flags
netif_cfg.flags &= ~ESP_NETIF_DHCP_CLIENT;

Which is AFAIK not even being set in the corresponding mesh_netif.c code permalink.

EDIT: I added a (draft) PR with a "pseudo-working" example, please check #8158

lukecam95 commented 1 year ago

Hi, were there any updates on this issue? I would like to connect a mobile app to the mesh network.

zhangyanjiaoesp commented 7 months ago

@lukecam95 you can refer to https://github.com/espressif/esp-idf/pull/8158

Sherry616 commented 3 months ago

Thanks for reporting, we will close this issue. Feel free to reopen if have more updates. Thanks for using our Espressif product!