2

I'm successfully sending a GET request (in the setup function, to load certificates,) but my POST request fails with a bunch of AT errors. I suspect this has to do with the way I'm formatting the POST. Any ideas would be appreciated.

Code follows:

// MKRGSM - Version: 1.5.0
#include <MKRGSM.h>
#include <ArduinoJson.h>
#include <Arduino_MKRGPS.h>

const char PINNUMBER[]     = "";
// APN data

const char GPRS_APN[]      = SECRET_GPRS_APN;

const char GPRS_LOGIN[]    = "";

const char GPRS_PASSWORD[] = "";

DynamicJsonDocument doc(1024);

// initialize the library instance

GSMSSLClient client;

GPRS gprs;

GSM gsmAccess(true);

// Specify IP address or hostname

char server[] = "webhook.site";
char path[] = "/ce480c43-95a8-4f1e-b996-bc02f6d1adaa";
int port = 443; 

void setup() {

  // initialize serial communications and wait for port to open:

  Serial.begin(9600);

  while (!Serial) {

    ; // wait for serial port to connect. Needed for native USB port only

  }

  // If you are using the MKR GPS as shield, change the next line to pass

  // the GPS_MODE_SHIELD parameter to the GPS.begin(...)
  delay(200);


  if (!GPS.begin()) {

    Serial.println("Failed to initialize GPS!");

    while (1);

  }
  Serial.println("Starting Arduino GSM ping.");
  // connection state
  bool connected = false;

  // After starting the modem with GSM.begin()
  // attach the shield to the GPRS network with the APN, login and password
  while (!connected)
  {
    if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &&
        (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY))
    {
      connected = true;
    } 
    else 
    {
      Serial.println("Not connected");
      delay(1000);
    }
  }

  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  // Use this to load Root Certs the first time
  if (client.connect(server, port)) 
  // Use this to not load Root Certs anymore as done last time and stored in modem's flash
//  if (client.connect(server, port, false)) 
  {
        Serial.println("connected");

    // Make a HTTP request:

    client.print("GET ");

    client.print(path);

    client.println(" HTTP/1.1");

    client.print("Host: ");

    client.println(server);

    client.println("Connection: close");

    client.println();
  } 
  else 
  {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop() {

  ...GPS stuff happens here

  // print GPS values

  Serial.println();

  Serial.print("Location: ");

  Serial.print(latitude, 7);

  Serial.print(", ");

  Serial.println(longitude, 7);

  Serial.print("Altitude: ");

  Serial.print(altitude);

  Serial.println("m");

  Serial.print("Number of satellites: ");

  Serial.println(satellites);

  doc["latitude"] = latitude;
  doc["longitude"] = longitude;
  doc["altitude"] = altitude;
  
  String location;
  serializeJson(doc, location);
  Serial.print("Location string: ");
  Serial.println(location);

  Serial.println();
  
  Serial.println("Starting Arduino web client.");

  // connection state
  
  if (client.available()) {
    Serial.println("Sending location");
    client.print("POST ");
    client.print(path);
    client.println(" HTTP/1.1");
    delay(5);
    client.println("Content-Type: application/json;");
    delay(5);
    client.print("Content-Length: ");
    client.println(location.length());
    client.print("Host: ");
    client.println(server);
    delay(5);
    client.println("Connection: close");
    delay(5);
    client.println();
    delay(5);
    client.println(location);
    Serial.print("Successfully sent location");

    if (!client.available() && !client.connected()) {
  
      Serial.println();
  
      Serial.println("disconnecting.");
  
      client.stop();
    }
  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
  
}

Here's what the output looks like:

Location: 32.1208382, 35.2468376 Altitude: 640.40m Number of satellites: 5 Location string: {"latitude":32.12084,"longitude":35.24684,"altitude":640.4}

Starting Arduino web client. Sending location AT+USOWR=0,13,"504F53542068747470733A2F2F"

ERROR AT+USOWR=0,37,"2F63653438306334332D393561382D346631652D623939362D626330326636643161646161"

ERROR AT+USOWR=0,9,"20485454502F312E31"

ERROR AT+USOWR=0,2,"0D0A"

ERROR AT+USOWR=0,31,"436F6E74656E742D547970653A206170706C69636174696F6E2F6A736F6E3B"

ERROR AT+USOWR=0,2,"0D0A"

ERROR AT+USOWR=0,16,"436F6E74656E742D4C656E6774683A20"

ERROR AT+USOWR=0,2,"3539"

ERROR AT+USOWR=0,2,"0D0A"

ERROR AT+USOWR=0,6,"486F73743A20"

ERROR AT+USOWR=0,12,"776562686F6F6B2E73697465"

ERROR AT+USOWR=0,2,"0D0A"

ERROR AT+USOWR=0,17,"436F6E6E656374696F6E3A20636C6F7365"

ERROR AT+USOWR=0,2,"0D0A"

ERROR AT+USOWR=0,2,"0D0A"

ERROR AT+USOWR=0,59,"7B226C61746974756465223A33322E31323038342C226C6F6E676974756465223A33352E32343638342C22616C746974756465223A3634302E347D"

ERROR AT+USOWR=0,2,"0D0A"

ERROR

I could send the data as parameters in the GET query, but that's ugly.

4
  • see the GSMWebClient example
    – Juraj
    Jun 22 at 15:08
  • I saw that example, but it's a GET.
    – Boris K
    Jun 22 at 15:39
  • 1
    Your HTTP request is badly formatted.
    – Majenko
    Jun 22 at 15:58
  • 1
    reading the response is same. and the HTTP request line shouldn't have a complete URL for POST either
    – Juraj
    Jun 22 at 17:40
2

Your HTTP request is badly formatted. You have:

POST https://webhook.site/ce480c43-95a8-4f1e-b996-bc02f6d1adaa HTTP/1.1
Content-Type: application/json

Instead the protocol is implied by the port you are connecting to, and the domain name does not go in the path on the server component - it has its own header.

Your request should look more like:

POST /ce480c43-95a8-4f1e-b996-bc02f6d1adaa HTTP/1.1
Host: webhook.site
Content-Type: application/json
Content-Length: [x]
Connection: close

[location]

Where [x] is location.length() and [location] is the content of the location string.

4
  • Thanks, I've updated the code as per your suggestions. Unfortunately, it's still failing. I'm not even seeing it go into the if (client.connect(server, port)) { block, which suggests that there is something wrong with the way I'm initializing the client.
    – Boris K
    Jun 22 at 20:24
  • @BorisK You need to add a second newline after Connection: close. In HTTP the headers and content are separated by two newlines. Your original question included this client.println();, but your updated code omitted this.
    – Gerben
    Jun 23 at 14:42
  • @gerben I'm not even seeing the "Sending location" output, which suggests the client is not connecting
    – Boris K
    Jun 23 at 21:39
  • @Gerben I have swapped SIMs and am now connecting on a GET but failing on a POST. I've updated the original question. If you could take a look, I would be grateful.
    – Boris K
    Jul 20 at 19:03
1

The problem was that GSM gsmAccess; needed to be GSM gsmAccess(true). Unfortunately, while that solves the immediate problem, which is that the client was not initializing, there are other issues which deserve a separate question.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.