Go Down

Topic: How to make a POST Request with MKRGSM/GSMSSLClient Library (Read 878 times) previous topic - next topic

wasio

Dear all

does enybody have an example of how to POST Data to a server with MKR GSM 1400 Board?

I have a Bearer authentification method and pass the token via client.print() function. If I pass wrong bearer token I get 401 http code.

So with correct token it's no more 401 and that is why I think I'm one step further. But then I crash against 400 - Bad Request. Using a REST Client I reproduce the issue with malformed or missing JSON request body.

It would be nice to have a look at a working example.
How do I pass the request body - still using the client.print() or client.write() function?

Thnx

fischerklas

I have had limited success sending the POST header and body information in smaller chunks.

noiasca

Are you shure that your problem is in the message body?
Why do you think your header is OK?

If you want us to check - post your hole message (html header + body) and compileable code how you made it.


DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

assddo1

Hi,

I am currently having the same error. The petition itself I know for sure that it does work, as I have tried on bash and works fine. I post bellow the code and the curl sentence which I try to replicate on the Arduino:

Code: [Select]
#include <ArduinoHttpClient.h>
#include <MKRGSM.h>

// PIN Number
const char PINNUMBER[]     = ""; //blank if no pin
// APN data: check settings on mobile for sim provider or contact carrier for network settings
const char GPRS_APN[]      = "<GPRS_APN>";
const char GPRS_LOGIN[]    = "<GPRS_LOGIN>";
const char GPRS_PASSWORD[] = "<GPRS_PASSWORD>";

// get this from the wia dashboard. it should start with `d_sk`

GSMClient client;
GPRS gprs;
GSM gsmAccess;

// Wia API parameters
char server[] = "<server>.servicebus.windows.net/<instance>/messages";
char path[] = "/";
int port = 443;


HttpClient httpClient = HttpClient(client, server, port);
//JsonObject& root = jsonBuffer.to<JsonObject>();
String response;
int statusCode = 0;
String dataStr;
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
  }

  Serial.println("Starting GSM connection to Wia!.");
  // connection state
  boolean 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:
  if (client.connect(server, port)) {
    Serial.println("connected");
  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop() {
  //root["name"] = "temperature";
  //root["data"] = 21.5;

  // if you get a connection, report back via serial:
  if (client.connect(server, port)) {

    postToWia("{\"name\": \"adrian\"}");

  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
  // read the status code and body of the response
  statusCode = httpClient.responseStatusCode();
  response = httpClient.responseBody();



  Serial.print("Status code: ");
  Serial.println(statusCode);
  Serial.print("Response: ");
  Serial.println(response);

  delay(3000); // Wait for 3 seconds to post again
}

void postToWia(String data) {

  httpClient.beginRequest();
  httpClient.post(path);
  httpClient.sendHeader("Authorization", "SharedAccessSignature sr=https%3A%2F%2F<server>.servicebus.windows.net%2F<instance>&sig=<sig>&se=1576319028&skn=RootManageSharedAccessKey");
  httpClient.beginBody();
  httpClient.print(data);
  httpClient.endRequest();

}



The curl operation is the following:
Code: [Select]
curl -X POST -k -H 'Authorization: SharedAccessSignature sr=https%3A%2F%2F<server>.servicebus.windows.net%2F<instance>&sig=<sig>&se=1576319028&skn=RootManageSharedAccessKey' -H -i 'https://<server>.servicebus.windows.net/<instance>/messages?timeout=60' --data "{\"name\": \"adrian\"}"

And according to Microsoft's documentation, I believe that I am posting the event in the Arduino following the right syntax.

Any guesses?

assddo1

I have also seen that there is a possibility to make it work with the library SPI, but still does not work. I also attach the code, altough I¡m more confident with the previously attached solution.

Code: [Select]

#include <MKRGSM.h>
#include <SPI.h>

// PIN Number
const char PINNUMBER[]     = ""; //blank if no pin
// APN data: check settings on mobile for sim provider or contact carrier for network settings
const char GPRS_APN[]      = "<GPRS_APN>";
const char GPRS_LOGIN[]    = "<GPRS_LOGIN>";
const char GPRS_PASSWORD[] = "<GPRS_PASSWORD>";

// initialize the library instance
GSMClient client;
GPRS gprs;
GSM gsmAccess;

// URL, path and port (for example: arduino.cc)
char server[] = "https://<server>.servicebus.windows.net/<instance>/messages";
char path[] = "https://<server>.servicebus.windows.net/<instance>";
char sas[]= "Authorization: SharedAccessSignature sr=https%3A%2F%2F<server>.servicebus.windows.net%2F<instance>&sig=<sig>&se=1576319028&skn=RootManageSharedAccessKey";
int port = 443; // port 80 is the default for HTTP
char buffer[64];

int value = 465;

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
  //}

  delay(1000);
 
  pinMode(LED_BUILTIN,OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  envioCloud();
}

void loop() {
 digitalWrite(LED_BUILTIN, HIGH);
 delay(1000); 
 digitalWrite(LED_BUILTIN, LOW);
 delay(1000);
}


void envioCloud(){
 
  Serial.println("Starting Arduino web client.");
  // connection state
  boolean 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:
  if (client.connect(server, port)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.print("POST ");
    client.println("/");
    client.print("Authorization: SharedAccessSignature sr=https%3A%2F%2F<server>.servicebus.windows.net%2F<instance>&sig=<sig>&se=1576319028&skn=RootManageSharedAccessKey");
    sprintf(buffer, "{\"value\": %s}", "Hello World");
    client.println();
    client.println(buffer);
   
  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }

 // if there are incoming bytes available
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }
 
  Serial.println("disconnecting.");
  client.stop();
   
}


assddo1

Updates:

1) The library version I am using is the latest one, MKRGSM 1.2.1.
2) After changing GSM gsmAccess for GSM gsmAccess(true) I start to get responses but they are unreadable and the HTTP POST never gets done:
Code: [Select]

AT

OK
AT+IPR=921600

OK
AT

OK
AT+UPSV=3

OK
AT+CPIN?

ERROR
AT+CPIN?

ERROR
AT+CPIN?

ERROR
AT+CPIN?

+CPIN: READY

OK
AT+CMGF=1

OK
AT+UDCONF=1,1

OK
AT+CTZU=1

OK
AT+UDTMFD=1,2

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK

+UMWI: 0,1

+UMWI: 0,2

+UMWI: 0,3

+UMWI: 0,4
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,1

OK
AT+UCALLSTAT=1

OK
AT+CGATT=1

OK
AT+UPSD=0,1,""

OK
AT+UPSD=0,6,3

OK
AT+UPSD=0,2,""

OK
AT+UPSD=0,3,""

OK
AT+UPSD=0,7,"0.0.0.0"

OK
AT+UPSDA=0,3

OK
AT+UPSND=0,8

+UPSND: 0,8,1

OK
AT+USOCR=6

+USOCR: 0

OK
AT+USOCO=0,"https://efor01.servicebus.windows.net/myeventhub/messages",443

ERROR

sandeepmistry

Two things off hand:

1) the server must just be the domain

Code: [Select]

char server[] = "<server>.servicebus.windows.net";


2) You HTTP request is invalid, missing the HTTP version


Code: [Select]

// Make a HTTP request:
client.print("POST ");
client.println("/ HTTP/1.1"); <- line modified
client.print("Authorization: SharedAccessSignature sr=https%3A%2F%2F<server>.servicebus.windows.net%2F<instance>&sig=<sig>&se=1576319028&skn=RootManageSharedAccessKey");
sprintf(buffer, "{\"value\": %s}", "Hello World");
client.println();
client.println(buffer);

assddo1

Hi,

I have many those modifications and the response I get is unreadable. I attach it bellow:

Code: [Select]
⸮AT

OK
AT+IPR=921600

OK
AT

OK
AT+UPSV=3

OK
AT+CPIN?

ERROR
AT+CPIN?

ERROR
AT+CPIN?

ERROR
AT+CPIN?

+CPIN: READY


Also, I do not really know what this output is.

sandeepmistry

The output you attached in the last post appears cut off, btw do you have a lipo battery attached?

assddo1

Sure, I thought the ouput did not make any sense, but as it does, I attach the whole execution output. And no, I have no Lippo attach to the Arduino.

Code: [Select]
AT

OK
AT+IPR=921600

OK
AT

OK
AT+UPSV=3

OK
AT+CPIN?

ERROR
AT+CPIN?

ERROR
AT+CPIN?

ERROR
AT+CPIN?

+CPIN: READY

OK
AT+CMGF=1

OK
AT+UDCONF=1,1

OK
AT+CTZU=1

OK
AT+UDTMFD=1,2

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK

+UMWI: 0,1

+UMWI: 0,2

+UMWI: 0,3

+UMWI: 0,4
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,1

OK
AT+UCALLSTAT=1

OK
AT+CGATT=1

OK
AT+UPSD=0,1,""

OK
AT+UPSD=0,6,3

OK
AT+UPSD=0,2,""

OK
AT+UPSD=0,3,""

OK
AT+UPSD=0,7,"0.0.0.0"

OK
AT+UPSDA=0,3

OK
AT+UPSND=0,8

+UPSND: 0,8,1

OK
AT+USOCR=6

+USOCR: 0

OK
AT+USOCO=0,"<server>.servicebus.windows.net",443

OK
connected
AT+USOWR=0,5,"504F535420"

+USOWR: 0,5

OK
AT+USOWR=0,60,"2F6D796576656E746875622F6D657373616765733F74696D656F75743D3630266170692D76657273696F6E3D323031342D303120485454502F312E31"

+USOWR: 0,60

OK
AT+USOWR=0,193,"417574686F72697A6174696F6E3A205368617265644163636573735369676E61747572652073723D687474707325334125324625324665666F7230312E736572766963656275732E77696E646F77732E6E65742532466D796576656E74687562267369673D683977624C78673467306E50764E6E347977696F462532426C623244446E6556306863353833757A496B7462302533442673653D3135373633313930323826736B6E3D526F6F744D616E6167655368617265644163636573734B6579"

+USOWR: 0,193

OK
AT+USOWR=0,59,"436F6E74656E742D547970653A206170706C69636174696F6E2F61746F6D2B786D6C3B747970653D656E7472793B636861727365743D7574662D38"

+USOWR: 0,59

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

+USOWR: 0,2

OK
AT+USOWR=0,35,"486F73743A2065666F7230312E736572766963656275732E77696E646F77732E6E6574"

+USOWR: 0,35

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

+USOWR: 0,2

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

+USOWR: 0,2

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

+USOWR: 0,2

OK
AT+USOWR=0,22,"7B2276616C7565223A2048656C6C6F20576F726C647D"

+USOWR: 0,22

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

+USOWR: 0,2

OK
disconnecting.
AT+USOCL=0

OK

sandeepmistry

It seems you didn't update the server value in the sketch:

Quote
AT+USOCO=0,"<server>.servicebus.windows.net",443

OK

assddo1

Yes, I changed that by hand before publishing the answer on the forum. I also tried inserting delays between the different client.println() in case the whole string was not being put together on time, but it did not changed nothing.

BTW, is there any Arduino documentation that can be used to interpret the given output?

smgs

My project here does a POST, the sequence of headers and body text took a little bit of time to get right:


https://www.hackster.io/smgs/mkr-gsm-1400-send-sensor-data-to-thingspeak-via-json-6b0de2

It took me a while to remember that the extra blank line after sending the header data through is required before you can send the body data, as it indicates that the header data is terminated.

Although my code uses JSON, you should be right copying the Syntax of the header section, and making your own section to send the Body data through.

Relevant code section of my "POST" of data through to Thingspeak is extracted here, for the full details and the declaration of all the variables such as the server and port etc, look at the full sketch at the link above. But maybe this Syntax will help you out in your project....

   
Code: [Select]
Serial.println("connected to: ");
    Serial.println(server);
    Serial.println(port);
    Serial.println("Beginnning JSON Post Sequence");
    Serial.println();
    client.print("POST /channels/");
    client.print(secretChannelID);
    client.println("/bulk_update.json HTTP/1.1");
    Serial.print("POST /channels/");
    Serial.print(secretChannelID);
    Serial.println("/bulk_update.json HTTP/1.1");
    client.println("Host: api.thingspeak.com");
    Serial.println("Host: api.thingspeak.com");
    client.println("User-Agent: mw.doc.bulk-update (Arduino MKR GSM 1400)");
    Serial.println("User-Agent: mw.doc.bulk-update (Arduino MKR GSM 1400)");
    client.println("Connection: close");
    Serial.println("Connection: close");
    client.println("Content-Type: application/json");
    Serial.println("Content-Type: application/json");
    client.print("Content-Length: ");
    Serial.print("Content-Length: ");
    client.println(root.measurePrettyLength());
    Serial.println(root.measurePrettyLength());
   
    // Terminate headers
    client.println();
    Serial.println();

    // Send body
    root.prettyPrintTo(client);
    root.prettyPrintTo(Serial);

    delay(350); //Wait to receive the response
    client.parseFloat();
    cResp = String(client.parseInt());
    Serial.println();
    Serial.println("Response code: "+cResp); // Print the response code. 202 indicates that the server has accepted the response

assddo1

If I get it right, root.prettyPrintTo(Serial); is the same as directly writing the JSON string to the Serial, no? I have tried using a similar format (code bellow) and I have obtained the following response:

Code: [Select]
if (client.connect("https://<server>.servicebus.windows.net/<eventhub>/messages", 443)) {
    // Make a HTTP request:
    client.print("POST https://<server>.servicebus.windows.net/<eventhub>/messages?timeout=60&api-version=2014-01 HTTP/1.1");
    delay(3);
    client.println("Authorization: SharedAccessSignature <signature>");
    delay(3);
    client.println("Content-Type: application/atom+xml;type=entry;charset=utf-8");
    delay(3);
    client.println();
    delay(3);
    sprintf(buffer, "{\"value\": %s}", "Hello World");
    client.println(buffer);


And the response:
Code: [Select]

AT

OK
AT+IPR=921600

OK
AT

OK
AT+UPSV=3

OK
AT+CPIN?

ERROR
AT+CPIN?

ERROR
AT+CPIN?

ERROR
AT+CPIN?

+CPIN: READY

OK
AT+CMGF=1

OK
AT+UDCONF=1,1

OK
AT+CTZU=1

OK
AT+UDTMFD=1,2

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK

+UMWI: 0,1

+UMWI: 0,2

+UMWI: 0,3

+UMWI: 0,4
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,1

OK
AT+UCALLSTAT=1

OK
AT+CGATT=1

OK
AT+UPSD=0,1,""

OK
AT+UPSD=0,6,3

OK
AT+UPSD=0,2,""

OK
AT+UPSD=0,3,""

OK
AT+UPSD=0,7,"0.0.0.0"

OK
AT+UPSDA=0,3

OK
AT+UPSND=0,8

+UPSND: 0,8,1

OK
AT+USOCR=6

+USOCR: 0

OK
AT+USOCO=0,"https://<server>.servicebus.windows.net/<eventhub>/messages",443

ERROR

+UUSOCL: 0
AT+USOCL=-1

ERROR
connected
disconnecting.

Go Up