REST API for POST request in JSON-format

#1

Hey folks!

Hope you are well. I am reaching out to you with an issue in our project. The project comprises 3 main components: (1) an ESP-12S Wifi Module (ESP8266), (2) a Firebase real-time database, and (3) Google Cloud Platform (GCP) cloud functions. The ESP8266 is flashed with a firmware written in C++ and with the aid of Mongoose OS. After flashing it, the device is registered to GCP via a cloud IoT core registry. Once registered, the GCP cloud functions create a device entry in the Firebase database, and the functions also take care of the MQTT communication between the cloud and the ESP8266.

  1. My goal is:

My goal is to use the Mongoose REST API to send a POST request to the ESP8266 with a JSON string that includes an SSID and its corresponding password, so the ESP8266 can connect to this network.

  1. My actions are:

I use the function included below to extract the body of the JSON POST request after which I use the mg_get_http_var() Mongoose function to extract the SSID and the password parameters.

void wifi_ap::handle_set_wifi_config(struct mg_connection *c, int ev, void *p, void *user_data) {

    if (ev != MG_EV_HTTP_REQUEST) return;
    LOG(LL_INFO, ("Http request: wifi config"));

    // Get the ssid and password
    char wifi_ssid[32]; 
    char wifi_password[64];
    struct http_message *hm = (struct http_message *) p;
    mg_get_http_var(&(hm->body),"ssid", wifi_ssid, 32);
    mg_get_http_var(&(hm->body),"password", wifi_password, 64);
    LOG(LL_INFO, ("Connecting to Wifi"));
    LOG(LL_INFO, ("SSID: %s", wifi_ssid));
    LOG(LL_INFO, ("Pass.: %s", wifi_password));

    // Set and save ssid and password
    mgos_sys_config_set_wifi_sta_ssid(wifi_ssid);
    mgos_sys_config_set_wifi_sta_pass(wifi_password);
    char *err = NULL;
    save_cfg(&mgos_sys_config, &err); // Writes conf9.json
    LOG(LL_INFO, ("Saving configuration: %s\n", err ? err : "no error"));
    free(err);
    mg_send_response_line(c, 200, "Content-Type: application/json\r\n");
    c->flags |= (MG_F_SEND_AND_CLOSE);
    (void) user_data;
}

I would like to use the following CLI command to send the POST request to the ESP8266:

curl --header “Content-Type: application/json” --request POST --data ‘{“ssid”:“name of wifi network”,“password”:“password to wifi network”}’ http://IP_address_of_ESP8266/set_wifi_config/

The handle_set_wifi_config function is registered at the /set_wifi_config HTTP endpoint via mgos_register_http_endpoint("/set_wifi_config", handle_set_wifi_config, NULL);.

I seek to use the above functionality in both AP and STA mode.

  1. The result I see is:

This is what I see when I monitor the serial port of the ESP8266.

mgos_http_server.c:176 0x3fff3624 HTTP connection from :40878
ap.cpp:24 Http request: wifi config
ap.cpp:32 Connecting to Wifi
ap.cpp:33 SSID:
ap.cpp:34 Pass.:
ap.cpp:43 Saving configuration: STA SSID must be between 1 and 31 chars

mgos_wifi.c:263 WiFi STA: STA SSID must be between 1 and 31 chars
sta.cpp:15 Wifi STA setup failed

  1. My expectation & question is:

I expect to successfully extract the SSID and password parameters from the POST request JSON, but I seem to end up with empty strings - both of which I try to print out and get nothing. My question is: am I missing something obvious here? I read the corresponding documentation and checked my code against other examples online, and I am quite positive that it should work. This leads me to think that I am missing something fundamental, which is why I decided to post this question.

Your help would be greatly appreciated!
\Mark

#2

mg_get_http_var fetches a HTTP form variable.

You send a JSON string, so you have to parse it with json_scanf:

    char *ssid = NULL;
    char *pass = NULL;
    if (json_scanf(hm->body.p, hm->body.len, "{ssid:%Q,password:%Q}", &ssid,
                   &pass) == 2) {
      LOG(LL_INFO, ("ssid: %s, pass: %s", ssid, pass));
      free(ssid);
      free(pass);
    }
1 Like
#3

Thanks a lot for the reply!