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

[TW#13173] Usage of esp_wifi_internal_tx function #677

Closed digitalentity closed 7 years ago

digitalentity commented 7 years ago

WiFi API has the declaration of esp_wifi_internal_tx which is used by lwip implementation. Is it safe to use esp_wifi_internal_tx in own application? What are the limitations of the function? Can it be used to broadcast custom data packets? Will it send packets from a device in client mode if it is not associated with an AP?

igrr commented 7 years ago

We don't treat this function as part of public API, so you're on your own if you decide to use it. There will be a new function to send 802.11 frames, similar to the one provided in the ESP8266 SDKs, which will be part of public API.

digitalentity commented 7 years ago

@igrr thanks for fast response. When this new function for sending 802.11 frames will be available? Should I tinker with esp_wifi_internal_tx or better wait for that function?

digitalentity commented 7 years ago

@igrr Btw, is wifi_send_pkt_freedom still functional and supported on ESP8266?

igrr commented 7 years ago

Could be a couple of weeks, depending on how QA for the current version goes. W.r.t. wifi_send_pkt_freedom, it is listed in the latest non-OS SDK API reference, so should be supported. It prevents you from sending certain kinds of frames (just like the ESP32 counterpart will) but otherwise should work fine for sending data frames.

digitalentity commented 7 years ago

Ok, thanks. And final question - is it possible to disable 802.11 retransmission of non-acked data frames?

liuzfesp commented 7 years ago

@digitalentity as @igrr said, esp_wifi_internal_tx is not a public API, it's internal only. Moreover, esp_wifi_internal_tx is only used to send ethernet packet from lwip to wifi driver after the connection is setup and the IP address got. If you want to send raw 802.11 packets, we have another API esp_wifi_80211_tx, however, this API is not ready yet, I think it will be ready in next release. Finally, when you talk about non-acked frames, do you means multicast packets? For multicast, WIFI will not retransmit the packet. BTW, what kind of 802.11 packets you want to send with esp_wifi_80211_tx? Including all packets? or just some specified packets, such as beacon, probe request etc....

digitalentity commented 7 years ago

Thanks for the answer @liuzfesp. I'm thinking about sending raw data frames to avoid IPv4 overhead. Ability to send beacon frames would also be good. Also, thanks for the hint about multicast packets.

I'm closing this since my question was answered. Thanks for help @igrr and @liuzfesp

hoonkai commented 7 years ago

Is esp_wifi_internal_tx() already pre-built into the components/esp32/lib/libnet80211.a library?

serverwentdown commented 7 years ago

@liuzfesp Any updates on the esp_wifi_80211_tx() API?

liuzfesp commented 7 years ago

Hi @serverwentdown , esp_wifi_80211_tx is already implemented in idf 2.1, but we still haven't declared it in esp_wifi.h officially because not all of it's function are full tested, we need more test about it before we publish it. This API is actually a complicated API, especially if you want to send the packet when the station or soft-AP has WiFi connections. Anyway, you can use this API if you want, the declaration: esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void *buffer, int len); BTW, some ESP32 customer (such as Ali etc) already use this API for their application and it works well. Recently we will test it and publish it, but I still can't promise the exact publish date.

liuzfesp commented 7 years ago

@serverwentdown please be kindly reminder that the interface of this API may changed to:

/**

  • @brief Send raw ieee80211 package API
  • @attention 1. Only WiFi non-QoS data, beacon, probe request, probe response
  • and action frames are allowed to be sent by this API
  • @attention 2. This API can be used in station mode, or soft-AP mode or
  • station + softAP mode, or when sniffer is enabled
  • @attention 3. It's not recommended to call this API once the WiFi connection
  • is setup
  • @param ifx interface
  • @param buffer raw ieee80211 buffer
  • @param len length of buffer
  • @param en_sys_seq enable the system sequence
  • @return
    • ERR_OK: succeed
    • ESP_ERR_WIFI_NO_MEM: out of memory
    • ESP_ERR_WIFI_ARG: invalid argument
    • ESP_ERR_WIFI_IF: invalid interface
    • ESP_ERR_WIFI_FAIL: internal fail / esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void buffer, int len, bool en_sys_seq);
liuzfesp commented 7 years ago

But in IDF 2.1, the interface is still:

esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void *buffer, int len) please let me know if you find something wrong with this API.

seppestas commented 6 years ago

We are experimenting with this functionality to send custom WiFi beacon frames in a project that might be released as a product. Official support would be really helpfull and is one of the discussion points in deciding whether to stick to the ESP32.

I understand and appreciate the concerns about security though. Maybe an interesting approach to protect the functionality would be some kind setting in flash only accessible using JTAG / SWD?

projectgus commented 6 years ago

Hi @seppestas ,

For this requirement, there's a couple of supported features that may give you what you need:

ESPNOW allows you to send & receive custom connectionless 802.11 data frames.

802.11 vendor Information Element support allows you to attach arbitrary data to different 802.11 frame types in a standards compliant way.

seppestas commented 6 years ago

Hey @projectgus

After some investigation, both ESPNOW and the vendor Information Element feature seem to be too restrictive for our use-case.

ESPNOW sets the first 4 bytes of the MAC frame data to a combination of a "Category Code" (with a value of 127) and a Organization Identifier defined by the mac address (it is not clear to me if this last part can be overwritten by esp_wifi_set_mac).

As far as I can see the data that can be added to frames using vendor information is limited to Vendor-Specific Information Elements. If it would be possible to set arbitrary 802.11 Information Elements using this function it would be a bit more useful, but we also require the ability to add non-Information Elements to the frame.

seppestas commented 6 years ago

Does esp_wifi_internal_tx calculate and add the Frame Check Sequence (FCS) to the frame? As far as I can see the old ieee80211_freedom_output did...

seppestas commented 6 years ago

The esp_wifi_80211_tx function seems to overwrite the frame counter of the frames I send, even if en_sys_seq is set to false.

When setting en_sys_seq to false the frame counter is always overwritten to 0. When setting en_sys_seq to true the frame counter follows the frame counter of frames sent by other components acting on WiFi (e.g AP beacons), but the frames sent by esp_wifi_80211_tx do not themselves cause the frame counter to increment. This happens both when WiFi was configured in AP and Station mode. Tested on ESP-IDF v2.1 and on the master branch (094e47f).

The old ieee80211_freedom_output function did not have this behaviour, allowing to send frames with arbitrary frame counter values.

Is it possible to somehow send frames with arbitrary frame counters using a new / supported function?

QuadCorei8085 commented 6 years ago

Is it normal that esp_wifi_80211_tx sends a packet 11 times when dst and src address is a valid MAC address? I'm using promiscuous mode on 2 ESP (they are in AP mode as well without any client connected). When sending using the esp_wifi_80211_tx and if the addr1 and addr2 (http://www.sharetechnote.com/html/WLAN_FrameStructure.html#MAC_Header_Structure) fields are the MAC addresses of the 2 ESP32 then on the listener side I receive the packet 1+10 times (1=retry flag is 0, and 10times the retry flag is 1). The following fields are set in the frame: type=0b10 sub_type=0b0000.

If the addr1 is broadcast (0xFF...0xFF) then packet is transmitted once. Is this normal? I couldn't find a specification that explains this.

liuzfesp commented 6 years ago

Yes, @QuadCorei8085 it is normal, for unicast packet, the WiFi driver re-transmit the packet until the 802.11 ACK, which is responded by the destination, is received or the max re-transmit time reaches; for broadcast, only send one time. Although the esp_wifi_80211_tx is existed in WiFi lib, it is not declared in the API header file in IDFv2.1/3.0 explicitly because it's not fully supported. Now the fully supported code is in review status and will be targeted into IDFv3.1

liuzfesp commented 6 years ago

@seppestas just as you pointed out, the implementation in IDFv3.0/v2.1, the last parameter en_sys_seq has no effect. The code is ready for IDFv3.1 and now is in review status.

malaimoo commented 6 years ago

@liuzfesp Hello, Can I set the retry flat to 0 to let esp send unicast only once manually?

liuzfesp commented 6 years ago

@malaimoo the retry should always be 0. Whether the packet should be retried and how many times the packet needs to be retried is totally controlled by internal WiFi driver.