Page 1 of 1

怎么使用ieee802154实现确认超时重发机制的可靠单播?

Posted: Mon Dec 02, 2024 12:12 pm
by weimeijia
  1. #include <string.h>
  2. #include <nvs.h>
  3. #include <nvs_flash.h>
  4. #include <esp_ieee802154.h>
  5. #include <esp_log.h>
  6. #include <esp_phy_init.h>
  7. #include <esp_mac.h>
  8.  
  9. #include "freertos/FreeRTOS.h"
  10. #include "freertos/task.h"
  11. #include "sdkconfig.h"
  12.  
  13. #include "ieee802154.h"
  14.  
  15. #define TAG "main"
  16. #define RADIO_TAG "ieee802154"
  17.  
  18. #define PAN_BROADCAST 0xFFFF
  19. #define PANID 0x4242
  20. #define CHANNEL 19
  21.  
  22. #define SHORT_BROADCAST 0xFFFF
  23. #define SHORT_NOT_CONFIGURED 0xFFFE
  24. #define SHORT_TEST_SENDER 0x1111
  25. #define SHORT_TEST_RECEIVER 0x2222
  26.  
  27. void esp_ieee802154_receive_done(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info)
  28. {
  29. ESP_EARLY_LOGI(RADIO_TAG, "rx OK, received %d bytes", frame[0]);
  30. esp_ieee802154_receive_handle_done(frame);
  31. }
  32.  
  33. void esp_ieee802154_receive_failed(uint16_t error)
  34. {
  35. ESP_EARLY_LOGI(RADIO_TAG, "rx failed, error %d", error);
  36. }
  37.  
  38. void esp_ieee802154_receive_sfd_done(void)
  39. {
  40. ESP_EARLY_LOGI(RADIO_TAG, "rx sfd done, Radio state: %d", esp_ieee802154_get_state());
  41. }
  42. void esp_ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack, esp_ieee802154_frame_info_t *ack_frame_info)
  43. {
  44. ESP_EARLY_LOGI(RADIO_TAG, "tx OK, sent %d bytes, ack %d", frame[0], ack != NULL);
  45. if (ack != NULL)
  46. {
  47. ESP_EARLY_LOGI(TAG, "Rx ack %d bytes", ack[0]);
  48. for (uint8_t idx = 1; idx < ack[0]; idx += 8)
  49. {
  50. ESP_EARLY_LOGI(TAG, "%02x %02x %02x %02x %02x %02x %02x %02x",
  51. ack[idx], ack[idx + 1], ack[idx + 2], ack[idx + 3],
  52. ack[idx + 4], ack[idx + 5], ack[idx + 6], ack[idx + 7]);
  53. }
  54. esp_ieee802154_receive_handle_done(ack);
  55. }
  56. }
  57.  
  58. void esp_ieee802154_transmit_failed(const uint8_t *frame, esp_ieee802154_tx_error_t error)
  59. {
  60. ESP_EARLY_LOGI(RADIO_TAG, "tx failed, error %d", error);
  61. }
  62.  
  63. void esp_ieee802154_transmit_sfd_done(uint8_t *frame)
  64. {
  65. ESP_EARLY_LOGI(RADIO_TAG, "tx sfd done");
  66. }
  67.  
  68. void send_direct_short(uint16_t pan_id, uint16_t dst_short, bool ack);
  69.  
  70. void app_main()
  71. {
  72. ESP_LOGI(TAG, "Initializing NVS from flash...");
  73. esp_err_t err = nvs_flash_init();
  74. if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
  75. {
  76. ESP_ERROR_CHECK(nvs_flash_erase());
  77. err = nvs_flash_init();
  78. }
  79. ESP_ERROR_CHECK(err);
  80.  
  81. ESP_ERROR_CHECK(esp_ieee802154_enable());
  82. ESP_ERROR_CHECK(esp_ieee802154_set_coordinator(false));
  83. ESP_ERROR_CHECK(esp_ieee802154_set_promiscuous(false));
  84. ESP_ERROR_CHECK(esp_ieee802154_set_rx_when_idle(true));
  85.  
  86. ESP_ERROR_CHECK(esp_ieee802154_set_panid(PANID));
  87. ESP_ERROR_CHECK(esp_ieee802154_set_channel(CHANNEL));
  88.  
  89. uint8_t eui64[8] = {0};
  90. esp_read_mac(eui64, ESP_MAC_IEEE802154);
  91. esp_ieee802154_set_extended_address(eui64);
  92. esp_ieee802154_set_short_address(SHORT_TEST_SENDER);
  93.  
  94. ESP_ERROR_CHECK(esp_ieee802154_receive());
  95.  
  96. uint8_t extended_address[8];
  97. esp_ieee802154_get_extended_address(extended_address);
  98. ESP_LOGI(TAG, "Ready, panId=0x%04x, channel=%d, long=%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, short=%04x",
  99.          esp_ieee802154_get_panid(), esp_ieee802154_get_channel(),
  100.          extended_address[0], extended_address[1], extended_address[2], extended_address[3],
  101.          extended_address[4], extended_address[5], extended_address[6], extended_address[7],
  102.          esp_ieee802154_get_short_address());
  103.  
  104. // This device should try to communicate with the
  105. // ieee802154-receiver app. It will send a sequence of packets using various
  106. // addressing methods to see what works.
  107. uint8_t peer[8] = {0x40, 0x4c, 0xca, 0x40, 0x28, 0xdc, 0xfe, 0xff};
  108. uint16_t peer_short = 0x2222;
  109. while (true)
  110. {
  111.     send_direct_long(PANID, peer, true);
  112.  
  113.     vTaskDelay(pdMS_TO_TICKS(5000));
  114.  
  115. }
  116. }
  117.  
  118. void send_direct_short(uint16_t pan_id, uint16_t dst_short, bool ack)
  119. {
  120. ESP_LOGI(TAG, "Send direct message to %04x on pan %04x%s", dst_short, pan_id, ack ? " with ack" : "");
  121. uint8_t buffer[256];
  122.  
  123. esp_ieee802154_set_panid(pan_id);
  124.  
  125. uint8_t eui64[8];
  126. esp_ieee802154_get_extended_address(eui64);
  127.  
  128. ieee802154_address_t src = {
  129.     .mode = ADDR_MODE_LONG,
  130.     .long_address = {eui64[0], eui64[1], eui64[2], eui64[3], eui64[4], eui64[5], eui64[6], eui64[7]}};
  131.  
  132. ieee802154_address_t dst = {
  133.     .mode = ADDR_MODE_SHORT,
  134.     .short_address = dst_short};
  135.  
  136. uint16_t dst_pan = PANID;
  137.  
  138. uint8_t hdr_len = ieee802154_header(&pan_id, &src, &dst_pan, &dst, ack, &buffer[1], sizeof(buffer) - 1);
  139.  
  140. // Add the local eui64 as payload
  141. memcpy(&buffer[1 + hdr_len], eui64, 8);
  142.  
  143. // packet length
  144. buffer[0] = hdr_len + 8;
  145.  
  146. esp_ieee802154_transmit(buffer, false);
  147. }`