Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTP POST in Arduino MKGSM to Eventhub

I'm using the Arduino library MKGSM in order to make an HTTP POST to my Azure Eventhub. I am confident with the parameters provided as I have tried them by hand with curl and the HTTP POST did work, so the problem is for sure in my Android syntax. Here is my approach:

#include <MKRGSM.h>

#include "arduino_secrets.h" 
// Please enter your sensitive data in the Secret tab or arduino_secrets.h
// PIN Number
const char PINNUMBER[]     = SECRET_PINNUMBER;
// APN data
const char GPRS_APN[]      = SECRET_GPRS_APN;
const char GPRS_LOGIN[]    = SECRET_GPRS_LOGIN;
const char GPRS_PASSWORD[] = SECRET_GPRS_PASSWORD;

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

// URL, path and port (for example: arduino.cc)
char server[] = "<namespace>.servicebus.windows.net";
char path[] = "/<myeventhubname>/messages";
int port = 443; // port 443 is the default for HTTPS

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 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.print(server);
    client.print(path);
    client.println(" HTTP/1.1");
    client.println("Authorization: SharedAccessSignature sr=https%3A%2F%2F<namespace>.servicebus.windows.net%2F<myeventhubname>&sig=<mysig>&se=<myse>&skn=RootManageSharedAccessKey");
    client.println();
    client.println("{\"HELLO\"}");
  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

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

  // if the server's disconnected, stop the client:
  if (!client.available() && !client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    for (;;)
      ;
  }
}

Basically, the original example was a GET that obtained the ascii symbol of Arduino and I am guessing if it is possible to use the same code to make an http post (in my case, to an Eventhub).

Update: After changing GSM gsmAccess to GSM gsmAccess(true) I start getting an output which is unreadable. I attach it bellow:

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
like image 750
Alvaro Gomez Avatar asked Nov 07 '22 02:11

Alvaro Gomez


1 Answers

Disclaimer - this is a suggestion only. I do not have the equipment or accounts to test/verify this.

Have you tried adding "https://" between POST and server ?

there might also be some parameters required before "HTTP/1.1" namely

?timeout=60&api-version=2014-01

also,

client.println("Authorization: SharedAccessSignature sr=https%3A%2F%2F<namespace>.servicebus.windows.net%2F<myeventhubname>&sig=<mysig>&se=<myse>&skn=RootManageSharedAccessKey");

might not be right. try removing the https%3A%2F%2F in front of < namespace >

finally, you may also need to send :

Content-Type: application/atom+xml;type=entry;charset=utf-8
Host: your-namespace.servicebus.windows.net

in all:

// Make a HTTP request:
  client.print("POST ");
  client.print("https://");
  client.print(server);
  client.print(path);
  client.print("?timeout=60&api-version=2014-01");
  client.println(" HTTP/1.1");
  client.println("Authorization: SharedAccessSignature sr=<namespace>.servicebus.windows.net/<myeventhubname>&sig=<mysig>&se=<myse>&skn=RootManageSharedAccessKey");
  client.println("Content-Type: application/atom+xml;type=entry;charset=utf-8");
  client.println("Host: <namespace>.servicebus.windows.net");
  client.println();
  client.println("{\"HELLO\"}");
} else {
.......

Cheers


So with the addition of the output by qwerty, I do not have much more to add yet.

The modem is not (it appears) sending out everything that is outlined in the code snippet I provided If you scroll down the output until you reach

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

the POST sequence starts next.

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

sends "POST"

the next output from the modem skips the "https://" and server (ie it's as if the following two lines are missing from the code)

client.print("https://");
client.print(server);

but instead skips to sending out the path, timeout and HTTP/1.1. The rest of the output is also missing CR/LF from several lines. It behaves as if the code in fact was

// Make a HTTP request:
client.print("POST ");
client.print(path);
client.print("?timeout=60&api-version=2014-01");
client.print(" HTTP/1.1");
client.print("Authorization: SharedAccessSignature sr=<namespace>.servicebus.windows.net/<myeventhubname>&sig=<mysig>&se=<myse>&skn=RootManageSharedAccessKey");
client.println("Content-Type: application/atom+xml;type=entry;charset=utf-8");
client.println("Host: <namespace>.servicebus.windows.net");
client.println();
client.println();
client.println("{\"value\": Hello World}");

I'm not sure what is causing this behaviour, but introducing delays might help

(Additionally, if server and path are constant strings, not likely to change for you application, you can concatenate the first 6 client.print() statements)

Giving you:

  // Make a HTTP request:
  client.print("POST https://<myserver>/<mypath>/?timeout=60&api-version=2014-01 HTTP/1.1");
  client.println();
  delay(5);
  client.print("Authorization: SharedAccessSignature sr=<namespace>.servicebus.windows.net/<myeventhubname>&sig=<mysig>&se=<myse>&skn=RootManageSharedAccessKey");
  client.println();
  delay(5);
  client.print("Content-Type: application/atom+xml;type=entry;charset=utf-8");
  client.println();
  delay(5);
  client.print("Host: <namespace>.servicebus.windows.net");
  client.println();
  delay(5);
  client.println();
  delay(5);
  client.print("{\"value\": Hello World}");
  client.println();
}
like image 94
darrob Avatar answered Nov 09 '22 23:11

darrob