Problems with converting espnow code to C++

senudajayalath
Posts: 17
Joined: Sun Jan 03, 2021 8:00 am

Problems with converting espnow code to C++

Postby senudajayalath » Fri Oct 29, 2021 4:21 am

I have compiled and run the example code which written in C and it works perfectly. But now I want to integrate that example(Written in C) to my main code which is in C++. I made couple of changes where I replaced malloc keyword with new keyword and I compiled it. It compiles successfully but when I flash the code espnow_send does not work. This is the function where the problem is at,

Code: Select all

extern "C" void example_espnow_task(void *pvParameter)
{
  example_espnow_event_t evt;
  uint8_t recv_state = 0;
  uint16_t recv_seq = 0;
  int recv_magic = 0;
  bool is_broadcast = false;
  int ret;

  vTaskDelay(5000 / portTICK_RATE_MS);
  ESP_LOGI(TAG, "Start sending broadcast data");

  /* Start sending broadcast ESPNOW data. */
  example_espnow_send_param_t *send_param = (example_espnow_send_param_t *)pvParameter;
  ESP_LOGI(TAG, "MAC : %d", esp_now_send(send_param->dest_mac, send_param->buffer, send_param->len));
  
  if (esp_now_send(send_param->dest_mac, send_param->buffer, send_param->len) != ESP_OK)
  {
    ESP_LOGE(TAG, "Send error");
    example_espnow_deinit(send_param);
    vTaskDelete(NULL);
  }

  while (xQueueReceive(s_example_espnow_queue, &evt, portMAX_DELAY) == pdTRUE)
  {
    switch (evt.id)
    {
    case EXAMPLE_ESPNOW_SEND_CB:
    {
      example_espnow_event_send_cb_t *send_cb = &evt.info.send_cb;
      is_broadcast = IS_BROADCAST_ADDR(send_cb->mac_addr);

      ESP_LOGD(TAG, "Send data to " MACSTR ", status1: %d", MAC2STR(send_cb->mac_addr), send_cb->status);

      if (is_broadcast && (send_param->broadcast == false))
      {
        break;
      }

      if (!is_broadcast)
      {
        send_param->count--;
        if (send_param->count == 0)
        {
          ESP_LOGI(TAG, "Send done");
          example_espnow_deinit(send_param);
          vTaskDelete(NULL);
        }
      }

      /* Delay a while before sending the next data. */
      if (send_param->delay > 0)
      {
        vTaskDelay(send_param->delay / portTICK_RATE_MS);
      }

      ESP_LOGI(TAG, "send data to " MACSTR "", MAC2STR(send_cb->mac_addr));

      memcpy(send_param->dest_mac, send_cb->mac_addr, ESP_NOW_ETH_ALEN);
      example_espnow_data_prepare(send_param);

      /* Send the next data after the previous data is sent. */
      if (esp_now_send(send_param->dest_mac, send_param->buffer, send_param->len) != ESP_OK)
      {
        ESP_LOGE(TAG, "Send error");
        example_espnow_deinit(send_param);
        vTaskDelete(NULL);
      }
      break;
    }
    case EXAMPLE_ESPNOW_RECV_CB:
    {
      example_espnow_event_recv_cb_t *recv_cb = &evt.info.recv_cb;

      ret = example_espnow_data_parse(recv_cb->data, recv_cb->data_len, &recv_state, &recv_seq, &recv_magic);

      free(recv_cb->data);
      if (ret == EXAMPLE_ESPNOW_DATA_BROADCAST)
      {
        ESP_LOGI(TAG, "Receive %dth broadcast data from: " MACSTR ", len: %d", recv_seq, MAC2STR(recv_cb->mac_addr), recv_cb->data_len);

        /* If MAC address does not exist in peer list, add it to peer list. */
        if (esp_now_is_peer_exist(recv_cb->mac_addr) == false)
        {
          esp_now_peer_info_t *peer = new esp_now_peer_info_t[sizeof(esp_now_peer_info_t)];
          if (peer == NULL)
          {
            ESP_LOGE(TAG, "Malloc peer information fail");
            example_espnow_deinit(send_param);
            vTaskDelete(NULL);
          }
          memset(peer, 0, sizeof(esp_now_peer_info_t));
          peer->channel = CONFIG_ESPNOW_CHANNEL;
          peer->ifidx = ESPNOW_WIFI_IF;
          peer->encrypt = true;
          memcpy(peer->lmk, CONFIG_ESPNOW_LMK, ESP_NOW_KEY_LEN);
          memcpy(peer->peer_addr, recv_cb->mac_addr, ESP_NOW_ETH_ALEN);
          ESP_ERROR_CHECK(esp_now_add_peer(peer));
          free(peer);
        }

        /* Indicates that the device has received broadcast ESPNOW data. */
        if (send_param->state == 0)
        {
          send_param->state = 1;
        }
      }
      else if (ret == EXAMPLE_ESPNOW_DATA_UNICAST)
      {
        ESP_LOGI(TAG, "Receive %dth unicast data from: " MACSTR ", len: %d", recv_seq, MAC2STR(recv_cb->mac_addr), recv_cb->data_len);

        /* If receive unicast ESPNOW data, also stop sending broadcast ESPNOW data. */
        send_param->broadcast = false;
      }
      else
      {
        ESP_LOGI(TAG, "Receive error data from: " MACSTR "", MAC2STR(recv_cb->mac_addr));
      }
      break;
    }
    default:
      ESP_LOGE(TAG, "Callback type error: %d", evt.id);
      break;
    }
  }
}

After seeing the terminal output it appeared to me that the error was in

Code: Select all

esp_now_send(send_param->dest_mac, send_param->buffer, send_param->len)
where it did not return a ESP_OK. Can anyone help me understand why this error is given and how to overcome this. The whole code is attached as an attachment below
This is the error printed on the terminal,

E (5897) espnow_example: Send error

Thanks
Attachments
espnow_example.h
(3.94 KiB) Downloaded 297 times
main.cpp
(14.72 KiB) Downloaded 296 times
Last edited by senudajayalath on Fri Oct 29, 2021 11:08 am, edited 2 times in total.

ESP_Sprite
Posts: 9578
Joined: Thu Nov 26, 2015 4:08 am

Re: Problems with converting espnow code to C++

Postby ESP_Sprite » Fri Oct 29, 2021 4:48 am

Not without seeing a. the error code, and b, the rest of the code.

boarchuz
Posts: 599
Joined: Tue Aug 21, 2018 5:28 am

Re: Problems with converting espnow code to C++

Postby boarchuz » Fri Oct 29, 2021 5:00 am

senudajayalath wrote:
Fri Oct 29, 2021 4:21 am

Code: Select all

  ESP_LOGI(TAG, "MAC : %d", esp_now_send(send_param->dest_mac, send_param->buffer, send_param->len));
Likely culprit here

senudajayalath
Posts: 17
Joined: Sun Jan 03, 2021 8:00 am

Re: Problems with converting espnow code to C++

Postby senudajayalath » Fri Oct 29, 2021 11:08 am

ESP_Sprite wrote:
Fri Oct 29, 2021 4:48 am
Not without seeing a. the error code, and b, the rest of the code.
I have attached the whole code and also updated my question with the error. Please take a look. Thanks

senudajayalath
Posts: 17
Joined: Sun Jan 03, 2021 8:00 am

Re: Problems with converting espnow code to C++

Postby senudajayalath » Fri Oct 29, 2021 11:14 am

boarchuz wrote:
Fri Oct 29, 2021 5:00 am
senudajayalath wrote:
Fri Oct 29, 2021 4:21 am

Code: Select all

  ESP_LOGI(TAG, "MAC : %d", esp_now_send(send_param->dest_mac, send_param->buffer, send_param->len));
This just prints, I (5887) espnow_example: MAC : 12396. So I'm assuming there is an error whencalling esp_now-send because ideally this should return 0
Likely culprit here

boarchuz
Posts: 599
Joined: Tue Aug 21, 2018 5:28 am

Re: Problems with converting espnow code to C++

Postby boarchuz » Fri Oct 29, 2021 1:28 pm

example_espnow_init:

Code: Select all

esp_now_peer_info_t *peer = new esp_now_peer_info_t[sizeof(esp_now_peer_info_t)];
send_param = new example_espnow_send_param_t[sizeof(example_espnow_send_param_t)];
I don't think your intention is to allocate arrays of these objects.

Code: Select all

send_param->buffer = new uint8_t(13);
I try to avoid C++ but I understand this allocates memory for a uint8_t and initialises it to 13. It doesn't allocate 13 bytes.

example_espnow_data_prepare:

Code: Select all

example_espnow_data_t *buf = (example_espnow_data_t *)send_param->buffer;
You then dereference the above uint8_t* and write a bunch of stuff to memory you don't own, corrupting the heap.

senudajayalath
Posts: 17
Joined: Sun Jan 03, 2021 8:00 am

Re: Problems with converting espnow code to C++

Postby senudajayalath » Sat Oct 30, 2021 9:53 am

I reworked on the main.cpp. I have attached the modified file below. But it still gives the same error of ,

"espnow_example: Send error".

Any other tip? Much appreciated.
Attachments
main.cpp
(14.36 KiB) Downloaded 391 times

Who is online

Users browsing this forum: Google [Bot] and 410 guests