espressif / esp-idf

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

Support for bigger ESP-NOW messages (IDFGH-7935) #9453

Closed AmirHmZz closed 1 month ago

AmirHmZz commented 2 years ago

I think it would be better to implement something like multipart message in esp-now. 250 bytes might be small for some purposes. Each message can be split into multiple ESPNow messages + one part number. These messages can be sent and received as byte streams.

MaxwellAlan commented 2 years ago

Hi @AmirHmZz

Thanks for your feature request.

Could you provide more detail for this feature that you may used in what kind of scenarios ? And how about the Throughput/Latency/Power/Security etc that required?

AmirHmZz commented 2 years ago

@MaxwellAlan Thanks for your quick replay! To be honest, I don't know where that 250 bytes message length limitation comes from exactly, but :

In my own company I had to implement these multipart messages in many projects, I think If this feature gets added to esp-idf developers can take advantage of it in many scenarios :

  1. Sending OTA updates over ESP-NOW
  2. Transferring configuration-like messages ( which is more than 250 bytes in my projects )
  3. Transferring bigger messages in lower rate

ESP-NOW is really a fantastic masterpiece but it's simplicity also make it difficult to use it in some scenarios. I should also mention that I know what policy is leading ESP-NOW to this simplicity, but I think it's not bad to also develop some features on top of ESP-NOW to facilitate non professional IOT developers work.

MaxwellAlan commented 2 years ago

Hi @AmirHmZz

Have recheck the code and 802.11 spec, the limitation is that we use Vendor Specific element field of Action frame to transmit data, which length field is only 1 byte(0xff = 255).

AmirHmZz commented 2 years ago

@MaxwellAlan Thanks a lot for your quick reply. Just for my curiosity, I've got four questions:

  1. Does ESP-NOW force messages to have a fixed size? I mean if it's possible, can ESP-NOW protocol let messgaes to have desired lengthes?

  2. Does message size effect on other parameters like latency, power consumption, etc?

  3. How large ESP-NOW messages can get?

  4. Can ESP-NOW gets data of big messages as streaming buffers? I mean for a message with length of 128KB ( like reading it from a file or another stream ) we cannot have all data in RAM. Also in the receiver side, message cannot be received in one piece and should be streamed or saved somewhere.

AmirHmZz commented 2 years ago

@MaxwellAlan based on your edit, we cannot increase size of ESP-NOW messages, What's your opinion about implementing multipart messages?

AmirHmZz commented 2 years ago

I mean esp-idf have developed lots of features like MESH networks on top of WiFi but when it comes to esp-now we have limited features...

MaxwellAlan commented 2 years ago

@AmirHmZz

Since there are some reserved field in 802.11 Managment Frame, maybe we can try with these fields, but there maybe some confilcts when the new 802.11 spec update. Or could you try with esp_wifi_80211_tx this API to send and sniffer mode to receive, both could work only base on WiFi stack and without TCP/IP stack.

ceribus commented 2 years ago

ESP-NOW uses vendor-specific action frames. These contain 1 byte Category, 3 bytes Organization Identifier and Vendor Specific Content.

According to the 802.11 standard the Vendor Specific Content could contain multiple Vendor-Specific Fields. 802.11-2020, 9.6.5 Vendor-specific action details: "...The Vendor Specific Content field contains vendor-specific field(s)." But right now ESP-NOW is only using one Vendor-Specific IE, which is limited to 255 bytes.

@MaxwellAlan Am I missing something or would it be possible to split the data into multiple IE?

AmirHmZz commented 2 years ago

@ceribu accroding to 802.11, how many Vendor Specific IE could be present in a vendor specific content?

ceribus commented 2 years ago

@AmirHmZz "The length of the vendor specific content in a Vendor Specific frame is limited by the maximum allowed MMPDU size." Seems to be limited by MMPDU size only, which is 2304 bytes max for b/g/n.

AmirHmZz commented 2 years ago

@ceribu So theoretically, the maximum length of ESP-NOW messages cannot get bigger than 2304 bytes, am I right ?

ceribus commented 2 years ago

@AmirHmZz Excluding headers, it could be about 2200 bytes.

AmirHmZz commented 1 year ago

Any updates on this?

zhangyanjiaoesp commented 1 year ago

@AmirHmZz We will consider increasing the length of ESP-NOW by adding more Vendor-Specific IE. But currently we have higher priority work to do, so this feature is delayed. Have you tried to use the esp_wifi_80211_tx API ?

AmirHmZz commented 1 year ago

What is exactly esp_wifi_80211_tx API?

zhangyanjiaoesp commented 1 year ago

@AmirHmZz You can refer to the doc about esp_wifi_80211_tx: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html?highlight=80211_tx#_CPPv417esp_wifi_80211_tx16wifi_interface_tPKvib

ceribus commented 1 year ago

@zhangyanjiaoesp I was just wondering why Vendor Specific IEs are used for ESP-NOW? Since they are not explicitly required by the 802.11 standard, any custom type of content could be used for the Vendor Specific Content field of the Vendor Specific Action Frame.

derkalaender commented 1 year ago

I'm by no means an expert, but this is also how I understood the 802.11 standard. The action frame body requires the action field, which in turn for the vendor-specific action frame is defined as Category, Organization Identifier, and then Vendor Specific Content. "The Vendor Specific Content field contains vendor-specific field(s)". However, these vendor-specific fields are not defined anywhere, so I assume it can be any custom data.

I think the vendor-specific element is used by mistake. The action frame body, after the action field, also specifies that "one or more vendor-specific elements are optionally present", however, only if the category is not vendor-specific [...] which it is in this case!

And I think you are aware of this, because the "Random Values" field you use is not defined as part of the action frame. So I think that already constitutes "vendor specific fields", otherwise ESP-NOW would not be follow the standard.

zhangyanjiaoesp commented 1 year ago

@ceribus @derkalaender You are right, any custom type of content could be used for the Vendor Specific Content field of the Vendor Specific Action Frame. And the ESP-NOW was designed to using Vendor Specific IEs.

When changing code to support for bigger ESP-NOW messages, we should consider the compatibility with the original ESP-NOW product. Adding more Vendor Specific IEs is one way, and using a new type of content is another way, we will try to find a suitable way to ensure compatibility and the needs of customers.

nicklasb commented 1 year ago

Just found this thread, I have several use cases where I occasionally want to send a, say 30-100 kbytes low-res image without the overhead and power consumption of a full wifi session. There are lots of other cases. If the max length could be for example 1.5 Kb, (which seems possible according to the above api), that would probably make for a much more efficient transfer of data than 250 bytes. Also..I mean we are in the to 2.4 GHz band among the gamerz and netflixers, do we really need to be this shy? :-) I would still have to implement multi-part data transfers, but I feel it would be a little bit less problematic get it performant. Ideally, I would want ESP-NOW to handle that behind the scenes.

zhangyanjiaoesp commented 8 months ago

@nicklasb We will consider your scenario when modifying the code.

nicklasb commented 8 months ago

@nicklasb We will consider your scenario when modifying the code.

That's encouraging. :-)

AmirHmZz commented 6 months ago

Any updates or milestones about this feature request?

zhangyanjiaoesp commented 6 months ago

@AmirHmZz We will solve this problem in a high priority.

zhangyanjiaoesp commented 6 months ago

@AmirHmZz which IDF branch do you use? which chip do you use ? I have modify the code, and I can provide a wifi lib for you to test.

AmirHmZz commented 6 months ago

@zhangyanjiaoesp Hello again. I use esp-idf v5.1.2 on ESP32 chip. Thank you.

zhangyanjiaoesp commented 6 months ago

@AmirHmZz Here is the wifi lib: wifi_lib_esp32_v5.1.2.zip wifi firmware version: 6979f8f Currently, the max length is 1600, and the new ESP-NOW version which can support longer length is 2.0, the old ESP-NOW version is 1.0, when you are using ESP-NOW to send/receive, the devices should use the same version.

AmirHmZz commented 6 months ago

Thank you. Do I need to change ESP_NOW_MAX_DATA_LEN? https://github.com/espressif/esp-idf/blob/003f3bb5dc7c8af8b71926b7a0118cfc503cab11/components/esp_wifi/include/esp_now.h#L52

zhangyanjiaoesp commented 6 months ago

Thank you. Do I need to change ESP_NOW_MAX_DATA_LEN?

https://github.com/espressif/esp-idf/blob/003f3bb5dc7c8af8b71926b7a0118cfc503cab11/components/esp_wifi/include/esp_now.h#L52

Yes, change it to 1600.

AmirHmZz commented 4 months ago

@zhangyanjiaoesp Sorry for the delay, finally I could test it. I've tried it on two esp32 modules with idf v5.1.2 with the example provided by esp-idf and the result was:

Could you please try the example and reproduce it?

AmirHmZz commented 4 months ago

@zhangyanjiaoesp Any updates on this?

zhangyanjiaoesp commented 4 months ago

@AmirHmZz sorry, I will check it this week

zhangyanjiaoesp commented 3 months ago

@AmirHmZz I have tested the espnow example locally, I can set the buffer length up to 1485. Here are the logs, I set the CONFIG_ESPNOW_SEND_COUNT = 10, so there only 10 unicast data in the logs.

Because the static RX buffer size is 1600, excluding some headers, the actual data is less than 1600.

image

device1

I (659) wifi:wifi firmware version: 6979f8f
I (659) wifi:wifi certification version: v7.0
I (659) wifi:config NVS flash: enabled
I (659) wifi:config nano formating: disabled
I (669) wifi:Init data frame dynamic rx buffer num: 32
I (669) wifi:Init static rx mgmt buffer num: 5
I (669) wifi:Init management short buffer num: 32
I (679) wifi:Init dynamic tx buffer num: 32
I (679) wifi:Init static rx buffer size: 1600
I (689) wifi:Init static rx buffer num: 10
I (689) wifi:Init dynamic rx buffer num: 32
I (699) wifi_init: rx ba win: 6
I (699) wifi_init: tcpip mbox: 32
I (699) wifi_init: udp mbox: 6
I (709) wifi_init: tcp mbox: 6
I (709) wifi_init: tcp tx win: 5744
I (709) wifi_init: tcp rx win: 5744
I (719) wifi_init: tcp mss: 1440
I (719) wifi_init: WiFi IRAM OP enabled
I (729) wifi_init: WiFi RX IRAM OP enabled
I (729) phy_init: phy_version 4780,16b31a7,Sep 22 2023,20:42:16
I (819) wifi:mode : sta (64:b7:08:29:2b:a4)
I (819) wifi:enable tsf
I (819) ESPNOW: espnow [version: 2.0] init
I (829) main_task: Returned from app_main()
I (5829) espnow_example: Start sending broadcast data
I (5829) espnow_example: Receive 19th broadcast data from: 64:b7:08:29:31:f4, len: 1485
I (5829) espnow_example: Receive 20th broadcast data from: 64:b7:08:29:31:f4, len: 1485
I (5839) espnow_example: Receive 21th broadcast data from: 64:b7:08:29:31:f4, len: 1485
I (5849) espnow_example: Receive 22th broadcast data from: 64:b7:08:29:31:f4, len: 1485
I (5849) espnow_example: Receive 23th broadcast data from: 64:b7:08:29:31:f4, len: 1485
I (6859) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (6859) espnow_example: Receive 24th broadcast data from: 64:b7:08:29:31:f4, len: 1485
I (7869) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (7869) espnow_example: Receive 25th broadcast data from: 64:b7:08:29:31:f4, len: 1485
I (7869) espnow_example: Receive 0th unicast data from: 64:b7:08:29:31:f4, len: 1485
I (8469) espnow_example: Receive 1th unicast data from: 64:b7:08:29:31:f4, len: 1485
I (9479) espnow_example: Receive 2th unicast data from: 64:b7:08:29:31:f4, len: 1485
I (10489) espnow_example: Receive 3th unicast data from: 64:b7:08:29:31:f4, len: 1485
I (11519) espnow_example: Receive 4th unicast data from: 64:b7:08:29:31:f4, len: 1485
I (12529) espnow_example: Receive 5th unicast data from: 64:b7:08:29:31:f4, len: 1485
I (13539) espnow_example: Receive 6th unicast data from: 64:b7:08:29:31:f4, len: 1485
I (14549) espnow_example: Receive 7th unicast data from: 64:b7:08:29:31:f4, len: 1485
I (15569) espnow_example: Receive 8th unicast data from: 64:b7:08:29:31:f4, len: 1485
I (16579) espnow_example: Receive 9th unicast data from: 64:b7:08:29:31:f4, len: 1485

device2

I (659) wifi:wifi firmware version: 6979f8f
I (659) wifi:wifi certification version: v7.0
I (659) wifi:config NVS flash: enabled
I (659) wifi:config nano formating: disabled
I (669) wifi:Init data frame dynamic rx buffer num: 32
I (669) wifi:Init static rx mgmt buffer num: 5
I (669) wifi:Init management short buffer num: 32
I (679) wifi:Init dynamic tx buffer num: 32
I (679) wifi:Init static rx buffer size: 1600
I (689) wifi:Init static rx buffer num: 10
I (689) wifi:Init dynamic rx buffer num: 32
I (699) wifi_init: rx ba win: 6
I (699) wifi_init: tcpip mbox: 32
I (699) wifi_init: udp mbox: 6
I (709) wifi_init: tcp mbox: 6
I (709) wifi_init: tcp tx win: 5744
I (709) wifi_init: tcp rx win: 5744
I (719) wifi_init: tcp mss: 1440
I (719) wifi_init: WiFi IRAM OP enabled
I (729) wifi_init: WiFi RX IRAM OP enabled
I (729) phy_init: phy_version 4780,16b31a7,Sep 22 2023,20:42:16
I (819) wifi:mode : sta (64:b7:08:29:31:f4)
I (819) wifi:enable tsf
I (829) ESPNOW: espnow [version: 2.0] init
I (829) main_task: Returned from app_main()
I (5829) espnow_example: Start sending broadcast data
I (6839) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (7859) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (8869) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (9899) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (10909) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (11929) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (12959) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (13969) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (14979) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (15989) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (16999) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (18019) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (19059) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (20069) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (21089) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (22109) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (23119) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (24129) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (25149) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (26159) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (27169) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (28179) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (29189) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (30219) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (30219) espnow_example: Receive 0th broadcast data from: 64:b7:08:29:2b:a4, len: 1485
I (31239) espnow_example: send data to ff:ff:ff:ff:ff:ff
I (31239) espnow_example: Receive 1th broadcast data from: 64:b7:08:29:2b:a4, len: 1485
I (31239) espnow_example: Start sending unicast data
I (31239) espnow_example: send data to 64:b7:08:29:2b:a4
I (32309) espnow_example: send data to 64:b7:08:29:2b:a4
I (32309) espnow_example: Receive 2th broadcast data from: 64:b7:08:29:2b:a4, len: 1485
I (33319) espnow_example: send data to 64:b7:08:29:2b:a4
I (34329) espnow_example: send data to 64:b7:08:29:2b:a4
I (35339) espnow_example: send data to 64:b7:08:29:2b:a4
I (36369) espnow_example: send data to 64:b7:08:29:2b:a4
I (37379) espnow_example: send data to 64:b7:08:29:2b:a4
I (38389) espnow_example: send data to 64:b7:08:29:2b:a4
I (39399) espnow_example: send data to 64:b7:08:29:2b:a4
I (40419) espnow_example: send data to 64:b7:08:29:2b:a4
I (40429) espnow_example: Send done
I (40439) ESPNOW: espnow [version: 2.0] deinit
AmirHmZz commented 3 months ago

@zhangyanjiaoesp I've tested with two other boards and everything seems to work fine! Thanks. Two questions:

  1. When this change gets merged into the master?
  2. Will this change be backported for idf 5.1 or 5.2?
zhangyanjiaoesp commented 3 months ago

@zhangyanjiaoesp I've tested with two other boards and everything seems to work fine! Thanks. Two questions:

  1. When this change gets merged into the master?
  2. Will this change be backported for idf 5.1 or 5.2?

@AmirHmZz In general, new features will only be available on the master and will not backport to older versions. We will merged it into the master ASAP.

AmirHmZz commented 3 months ago

@zhangyanjiaoesp So, it will be available on esp-idf 5.3 or 5.4?

zhangyanjiaoesp commented 3 months ago

It will be available on esp-idf 5.4.