4

I'm trying to use the websocket_chat_client example on ESP-IDF platform but the value of status on MG_EV_CONNECT event is always -1, which is a Connection error. What I've done so far is I took the esp32-idf example, merged it with the websocket-client one, added stuff from a WiFi example and set the chat_server_url to a host where a WS server is listening. Based on the server logs it never seems to be hitting the server.

I'm new in this area, how to start investigating? How to debug?

Code (note the wifi_event_group lines are commented out due to causing different error...):

#include <string.h>

#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/task.h"

#include "esp_event.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "nvs_flash.h"

#include "lwip/err.h"
#include "lwip/sys.h"

#include "../components/mongoose/mongoose.h"

void connect_ws();

#define WIFI_SSID CONFIG_WIFI_SSID
#define WIFI_PASS CONFIG_WIFI_PASSWORD
#define LOG_TAG CONFIG_LOG_TAG

/* FreeRTOS event group to signal when we are connected*/
// static EventGroupHandle_t wifi_event_group;

/* The event group allows multiple bits for each event,
   but we only care about one event - are we connected
   to the AP with an IP? */
const int WIFI_CONNECTED_BIT = BIT0;

static const char *TAG = LOG_TAG;
static int ws_done = 0;
static int ws_connected = 0;
static int wifi_connected = 0;

static esp_err_t event_handler(void *ctx, system_event_t *event) {
  switch (event->event_id) {
    case SYSTEM_EVENT_STA_START:
      esp_wifi_connect();
      break;

    case SYSTEM_EVENT_STA_GOT_IP:
      ESP_LOGI(TAG, "got ip:%s", ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
      // xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT);

      wifi_connected = 1;
      connect_ws();
      break;

    case SYSTEM_EVENT_STA_DISCONNECTED:
      esp_wifi_connect();
      // xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT);

      wifi_connected = 0;
      break;

    default:
      break;
  }

  return ESP_OK;
}

static void mg_ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
  ESP_LOGD(TAG, "mg_ev_handler");

  struct websocket_message *wm = (struct websocket_message *)ev_data;

  switch (ev) {
    case MG_EV_CONNECT: {
      int status = *((int *)ev_data);
      if (status != 0) {
        ESP_LOGI(TAG, "Connection error");
        printf("-- Connection error: %d\n", status);
      }
      break;
    }

    case MG_EV_WEBSOCKET_HANDSHAKE_DONE: {
      ESP_LOGI(TAG, "Connected");
      printf("-- Connected\n");
      ws_connected = 1;
      break;
    }

    case MG_EV_POLL: {
      char msg[500];
      int n = 0;

      fd_set read_set, write_set, err_set;
      struct timeval timeout = {0, 0};
      FD_ZERO(&read_set);
      FD_ZERO(&write_set);
      FD_ZERO(&err_set);
      FD_SET(0 /* stdin */, &read_set);
      if (select(1, &read_set, &write_set, &err_set, &timeout) == 1) {
        n = read(0, msg, sizeof(msg));
      }
      if (n <= 0)
        break;
      while (msg[n - 1] == '\r' || msg[n - 1] == '\n')
        n--;
      mg_send_websocket_frame(nc, WEBSOCKET_OP_TEXT, msg, n);
      break;
    }

    case MG_EV_WEBSOCKET_FRAME: {
      ESP_LOGI(TAG, "New shit");
      printf("%.*s\n", (int)wm->size, wm->data);
      break;
    }

    case MG_EV_CLOSE: {
      if (ws_connected) {
        ESP_LOGI(TAG, "Disconnected");
        printf("-- Disconnected\n");
      }
      ws_done = 1;
      break;
    }

    default: {
      printf("Unknown ev: %d\n", ev);
    }
  }
}

void connect_ws() {
  ESP_LOGI(TAG, "WS Connecting...");

  struct mg_mgr mgr;
  struct mg_connection *nc;
  const char *chat_server_url = "ws://9808a798.ngrok.io";
  // const char *chat_server_url = "ws://api.screeny.live/";

  mg_mgr_init(&mgr, NULL);
  ESP_LOGD(TAG, "WS mg_mgr_init");

  nc = mg_connect_ws(&mgr, mg_ev_handler, chat_server_url, "ws_chat", NULL);
  ESP_LOGD(TAG, "WS mg_connect_ws");

  if (nc == NULL) {
    ESP_LOGE(TAG, "WS Connection failed.");
    fprintf(stderr, "Invalid address\n");
    // return 1;
  }

  while (!ws_done && wifi_connected) {
    mg_mgr_poll(&mgr, 1000);
    ESP_LOGD(TAG, "WS mg_mgr_poll");
  }
  mg_mgr_free(&mgr);
  ESP_LOGD(TAG, "WS mg_mgr_free");

  // if (wifi_connected) {
  //   connect_ws();
  // }

  // return 0;
}

void app_main(void) {
  nvs_flash_init();
  tcpip_adapter_init();
  ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));

  /* Initializing WiFi */
  wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  ESP_ERROR_CHECK(esp_wifi_init(&cfg));
  ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
  ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
  wifi_config_t sta_config = {
      .sta = {
        .ssid = WIFI_SSID,
        .password = WIFI_PASS,
        .bssid_set = false
      }
  };
  ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &sta_config));
  ESP_ERROR_CHECK(esp_wifi_start());
  ESP_ERROR_CHECK(esp_wifi_connect());
}

From Mongoose src:

#define MG_EV_POLL 0    /* Sent to each connection on each mg_mgr_poll() call */
#define MG_EV_ACCEPT 1  /* New connection accepted. union socket_address * */
#define MG_EV_CONNECT 2 /* connect() succeeded or failed. int *  */
#define MG_EV_RECV 3    /* Data has been received. int *num_bytes */
#define MG_EV_SEND 4    /* Data has been written to a socket. int *num_bytes */
#define MG_EV_CLOSE 5   /* Connection is closed. NULL */
#define MG_EV_TIMER 6   /* now >= conn->ev_timer_time. double * */ 

Log (I'm not getting -1 this time, not sure why ... It seems to be some IO happening based on the unknown ev):

V (3169) event: exit default callback
D (7819) tcpip_adapter: if0 dhcpc cb
D (7819) tcpip_adapter: if0 ip changed=1
D (7819) event: SYSTEM_EVENT_STA_GOT_IP, ip:192.168.1.237, mask:255.255.255.0, gw:192.168.1.254
V (7819) event: enter default callback
I (7829) event: sta ip: 192.168.1.237, mask: 255.255.255.0, gw: 192.168.1.254
V (7829) event: exit default callback
I (7839) my-thing: got ip:192.168.1.237
I (7839) my-thing: WS Connecting...
D (7849) my-thing: WS mg_mgr_init
D (7849) my-thing: WS mg_connect_ws
D (7859) my-thing: WS mg_mgr_poll
D (8359) my-thing: WS mg_mgr_poll
D (9359) my-thing: mg_ev_handler
D (9359) my-thing: WS mg_mgr_poll
D (10359) my-thing: mg_ev_handler
D (10359) my-thing: WS mg_mgr_poll
D (11359) my-thing: mg_ev_handler
D (11359) my-thing: WS mg_mgr_poll
D (12359) my-thing: mg_ev_handler
D (12359) my-thing: WS mg_mgr_poll
D (13359) my-thing: mg_ev_handler
D (13359) my-thing: WS mg_mgr_poll
D (14359) my-thing: mg_ev_handler
D (14359) my-thing: WS mg_mgr_poll
D (15359) my-thing: mg_ev_handler
D (15359) my-thing: WS mg_mgr_poll
D (16359) my-thing: mg_ev_handler
D (16359) my-thing: WS mg_mgr_poll
D (17359) my-thing: mg_ev_handler
D (17359) my-thing: WS mg_mgr_poll
D (18319) my-thing: mg_ev_handler
D (18319) my-thing: mg_ev_handler
Unknown ev: 4
D (18319) my-thing: mg_ev_handler
D (18319) my-thing: WS mg_mgr_poll
D (19319) my-thing: mg_ev_handler
D (19319) my-thing: WS mg_mgr_poll
D (20319) my-thing: mg_ev_handler
D (20319) my-thing: WS mg_mgr_poll
D (21319) my-thing: mg_ev_handler
D (21319) my-thing: WS mg_mgr_poll
D (21439) my-thing: mg_ev_handler
Unknown ev: 3
D (21439) my-thing: mg_ev_handler
Unknown ev: 102
D (21439) my-thing: mg_ev_handler
D (21439) my-thing: WS mg_mgr_poll 
3
  • Hi haxpanel, do you have any sort of logs? What is the network setup? Is it all local? – Helmar May 25 '18 at 8:46
  • 1
    I'll provide you verbose logs and code once I arrived home later today. Stay tuned :) – haxpanel May 25 '18 at 11:11
  • Code & log added. Also, I've added a default clause to print unknown events. – haxpanel May 25 '18 at 20:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.