HTTPS Request via MKR NB 1500 does not work

Hello,

I would like to send a webhook via MKR NB 1500.
Generally the webhook works, but not in the sketch.

What am I doing wrong?

Thanks in advance!

#include <MKRNB.h>

NBSSLClient client;
GPRS gprs;
NB nbAccess;

char server[] = "<ID>.hom.ee";
char path[] = "/api/v2/webhook_trigger?webhooks_key=<KEY>&event=<EVENT>";
int port = 443;

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ;
  }

  Serial.println("Starting Arduino web client.");
  boolean connected = false;
  while (!connected) {
    if ((nbAccess.begin("","iot.1nce.net") == NB_READY) && (gprs.attachGPRS("iot.1nce.net") == GPRS_READY)) {
      connected = true;
    } else {
      Serial.println("Not connected");
      delay(1000);
    }
  }

  Serial.println("connecting...");
  if (client.connect(server, port)) {
    Serial.println("connected");
    client.print("GET ");
    client.print(path);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();
  } else {
    Serial.println("connection failed");
  }
}

void loop() {
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  if (!client.available() && !client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    for (;;)
      ;
  }
}

What does Serial Monitor say? (Copy the sketch output from Serial Monitor and paste it here.)

18:19:25.226 -> Starting Arduino web client.
18:19:30.713 -> connecting...

The internet connection is established, but nothing more happens.

The next thing it should say is “connected” or “connection failed”. Since it shows neither, it is hanging in the attempt to connect through the GPRS.

Try a few of the simpler examples to see if you can figure out how to get connected.

The Internet connection is established.
“Connecting…” refers to:

client.connect(server, port)

I have tested a simple page:

char server[] = "arduino.cc";
char path[] = "/";
int port = 443; // port 443 is the default for HTTPS

Here the result:

18:55:35.158 -> Starting Arduino web client.
18:55:41.331 -> connecting...
18:55:52.825 -> connected
18:55:55.094 -> HTTP/1.1 301 Moved Permanently
18:55:55.094 -> Server: nginx
18:55:55.094 -> Date: Sat, 08 May 2021 16:55:54 GMT
18:55:55.094 -> Content-Type: text/html
18:55:55.094 -> Content-Length: 178
18:55:55.094 -> Connection: close
18:55:55.094 -> Location: https://www.arduino.cc/
18:55:55.094 -> Strict-Transport-Security: max-age=500; includeSubDomains
18:55:55.094 -> X-Content-Type-Options: nosniff
18:55:55.094 -> X-XSS-Protection: 1; mode=block
18:55:55.094 -> 
18:55:55.094 -> <html>
18:55:55.094 -> <head><title>301 Moved Permanently</title></head>
18:55:55.094 -> <body bgcolor="white">
18:55:55.094 -> <center><h1>301 Moved Permanently</h1></center>
18:55:55.094 -> <hr><center>nginx</center>
18:55:55.094 -> </body>
18:55:55.094 -> </html>
18:55:55.712 -> 
18:55:55.712 -> disconnecting.

OK, so the “simple page” worked. The next step is to compare the two line-by-line to see what the non-working sketch is doing differently.

There differ only two lines.

Working:

char server[] = "arduino.cc";
char path[] = "/";

Not working:

char server[] = "<ID>.hom.ee";
char path[] = "/api/v2/webhook_trigger?webhooks_key=<KEY>&event=<EVENT>";

When I type the following in a browser, everything works:

<ID>.hom.ee/api/v2/webhook_trigger?webhooks_key=<KEY>&event=<EVENT>

I tried doing that but the Chrome browser gave me this error: “This site can’t be reached: %3Cid%3E.hom.ee”. I even put “https://” in front of it and got the same result. Do ‘ID’, ‘KEY’ and ‘EVENT’ get substituted in your browser somehow?

ID, KEY and EVENT are only placeholders because it is confidential data.

Oh, you are just substituting when you post.

OK, so the working sketch took 11 seconds to connect to arduino.cc and another 3 seconds to fetch the ‘303’ error page saying that “arduino.cc” had permanently moved to “www.arduino.cc”. How long did you wait for the non-working sketch to connect?

You can wait several minutes and nothing happens.

That’s weird. You’d expect it to either eventually succeed or eventually fail.

It might be necessary to debug the ‘client.connect()’ function to see if it hangs at a particular place.

Note: It might help to put “Serial.flush();” after your Serial.println(); statements. That way there won’t be any useful messages stuck in the output buffer when the sketch freezes.

Here are more details.
When it is supposed to connect to the host, an error comes up.
See almost at the very end.

22:09:51.391 -> Connecting to the internet.
22:09:53.033 -> AT

22:09:53.033 -> OK
22:09:53.127 -> AT+CMEE=0

22:09:53.127 -> OK
22:09:53.362 -> AT+CFUN=0

22:09:53.362 -> OK
22:09:53.550 -> AT+CPIN?

22:09:53.550 -> +CPIN: READY
22:09:53.550 -> 
22:09:53.550 -> OK
22:09:53.738 -> AT+CMGF=1

22:09:53.738 -> OK
22:09:53.974 -> AT+UDCONF=1,1

22:09:53.974 -> OK
22:09:54.160 -> AT+CTZU=1

22:09:54.160 -> OK
22:09:54.348 -> AT+CGDCONT=1,"IP","iot.1nce.net"

22:09:54.348 -> OK
22:09:54.582 -> AT+UAUTHREQ=1,0

22:09:54.582 -> OK
22:09:54.770 -> AT+CFUN=1

22:09:54.770 -> OK
22:09:54.958 -> AT+CEREG?

22:09:54.958 -> +CEREG: 0,0
22:09:54.958 -> 
22:09:54.958 -> OK
22:09:55.195 -> AT+CEREG?

22:09:55.195 -> +CEREG: 0,0
22:09:55.195 -> 
22:09:55.195 -> OK
22:09:55.383 -> AT+CEREG?

22:09:55.383 -> +CEREG: 0,0
22:09:55.383 -> 
22:09:55.383 -> OK
22:09:55.570 -> AT+CEREG?

22:09:55.570 -> +CEREG: 0,2
22:09:55.570 -> 
22:09:55.570 -> OK
22:09:55.805 -> AT+CEREG?

22:09:55.805 -> +CEREG: 0,2
22:09:55.805 -> 
22:09:55.805 -> OK
22:09:55.993 -> AT+CEREG?

22:09:55.993 -> +CEREG: 0,2
22:09:55.993 -> 
22:09:55.993 -> OK
22:09:56.178 -> AT+CEREG?

22:09:56.178 -> +CEREG: 0,2
22:09:56.178 -> 
22:09:56.178 -> OK
22:09:56.413 -> AT+CEREG?

22:09:56.413 -> +CEREG: 0,2
22:09:56.413 -> 
22:09:56.413 -> OK
22:09:56.601 -> AT+CEREG?

22:09:56.601 -> +CEREG: 0,5
22:09:56.601 -> 
22:09:56.601 -> OK
22:09:57.115 -> AT+CGATT=1

22:09:57.115 -> OK
22:09:58.148 -> AT+CGACT?

22:09:58.148 -> +CGACT: 1,1
22:09:58.148 -> 
22:09:58.148 -> OK
22:09:58.148 -> Connected to the internet.
22:09:58.148 -> Connecting to the server.
22:09:58.148 -> AT+USECMNG=0,0,"AddTrust_External_CA_Root",1082

22:09:58.148 -> >
22:09:58.383 -> +USECMNG: 0,0,"AddTrust_External_CA_Root","1D3554048578B03F42424DBF20730A3F"
22:09:58.383 -> 
22:09:58.383 -> OK
22:09:58.383 -> AT+USECMNG=0,0,"Baltimore_CyberTrust_Root",891

22:09:58.383 -> >
22:09:58.572 -> +USECMNG: 0,0,"Baltimore_CyberTrust_Root","ACB694A59C17E0D791529BB19706A6E4"
22:09:58.572 -> 
22:09:58.572 -> OK
22:09:58.619 -> AT+USECMNG=0,0,"COMODO_RSA_Certification_Authority",1500

22:09:58.619 -> >
22:09:58.901 -> +USECMNG: 0,0,"COMODO_RSA_Certification_Authority","1B31B0714036CC143691ADC43EFDEC18"
22:09:58.901 -> 
22:09:58.901 -> OK
22:09:58.901 -> AT+USECMNG=0,0,"DST_Root_CA_X3",846

22:09:58.901 -> >
22:09:59.089 -> +USECMNG: 0,0,"DST_Root_CA_X3","410352DC0FF7501B16F0028EBA6F45C5"
22:09:59.089 -> 
22:09:59.089 -> OK
22:09:59.136 -> AT+USECMNG=0,0,"DigiCert_High_Assurance_EV_Root_CA",969

22:09:59.136 -> >
22:09:59.277 -> +USECMNG: 0,0,"DigiCert_High_Assurance_EV_Root_CA","D474DE575C39B2D39C8583C5C065498A"
22:09:59.323 -> 
22:09:59.323 -> OK
22:09:59.323 -> AT+USECMNG=0,0,"Entrust_Root_Certification_Authority",1173

22:09:59.323 -> >
22:09:59.558 -> +USECMNG: 0,0,"Entrust_Root_Certification_Authority","D6A5C3ED5DDD3E00C13D87921F1D3FE4"
22:09:59.558 -> 
22:09:59.558 -> OK
22:09:59.604 -> AT+USECMNG=0,0,"Equifax_Secure_Certificate_Authority",804

22:09:59.604 -> >
22:09:59.744 -> +USECMNG: 0,0,"Equifax_Secure_Certificate_Authority","67CB9DC013248A829BB2171ED11BECD4"
22:09:59.744 -> 
22:09:59.744 -> OK
22:09:59.791 -> AT+USECMNG=0,0,"GeoTrust_Global_CA",856

22:09:59.791 -> >
22:09:59.934 -> +USECMNG: 0,0,"GeoTrust_Global_CA","F775AB29FB514EB7775EFF053C998EF5"
22:09:59.934 -> 
22:09:59.934 -> OK
22:09:59.979 -> AT+USECMNG=0,0,"GeoTrust_Primary_Certification_Authority_G3",1026

22:09:59.979 -> >
22:10:00.166 -> +USECMNG: 0,0,"GeoTrust_Primary_Certification_Authority_G3","B5E83436C910445848706D2E83D4B805"
22:10:00.213 -> 
22:10:00.213 -> OK
22:10:00.213 -> AT+USECMNG=0,0,"GlobalSign",958

22:10:00.213 -> >
22:10:00.400 -> +USECMNG: 0,0,"GlobalSign","9414777E3E5EFD8F30BD41B0CFE7D030"
22:10:00.400 -> 
22:10:00.400 -> OK
22:10:00.447 -> AT+USECMNG=0,0,"Go_Daddy_Root_Certificate_Authority_G2",969

22:10:00.447 -> >
22:10:00.635 -> +USECMNG: 0,0,"Go_Daddy_Root_Certificate_Authority_G2","803ABC22C1E6FB8D9B3B274A321B9A01"
22:10:00.635 -> 
22:10:00.635 -> OK
22:10:00.682 -> AT+USECMNG=0,0,"VeriSign_Class_3_Public_Primary_Certification_Authority_G5",1239

22:10:00.682 -> >
22:10:00.915 -> +USECMNG: 0,0,"VeriSign_Class_3_Public_Primary_Certification_Authority_G5","CB17E431673EE209FE455793F30AFA1C"
22:10:00.915 -> 
22:10:00.915 -> OK
22:10:00.915 -> AT+USECMNG=2,0,"AmazonRootCA1"

22:10:00.961 -> ERROR
22:10:00.961 -> AT+USECMNG=0,0,"Starfield_Services_Root_Certificate_Authority_G2",1011

22:10:00.961 -> >
22:10:01.149 -> +USECMNG: 0,0,"Starfield_Services_Root_Certificate_Authority_G2","173574AF7B611CEBF4F93CE2EE40F9A2"
22:10:01.196 -> 
22:10:01.196 -> OK
22:10:01.290 -> AT+USOCR=6

22:10:01.290 -> +USOCR: 0
22:10:01.290 -> 
22:10:01.290 -> OK
22:10:01.479 -> AT+USOSEC=0,1,0

22:10:01.479 -> OK
22:10:01.713 -> AT+USECPRF=0,0,1

22:10:01.713 -> OK
22:10:01.902 -> AT+USOCO=0,"<ID>.hom.ee",443

22:12:05.220 -> ERROR
22:12:05.314 -> 
22:12:05.314 -> +UUSOCL: 0
22:12:05.406 -> AT+USOCL=0

22:12:05.453 -> ERROR
22:12:05.453 -> connection failed
22:12:05.453 -> AT+USOER

22:12:05.453 -> +USOER: 9
22:12:05.453 -> 
22:12:05.453 -> OK
22:12:05.453 -> 
22:12:05.453 -> disconnecting.

I wonder if the “USOER” message is reporting error type ‘9’. You’ll have to dive into the documentation to see what the
AT+USOCO=0,"<ID>.hom.ee",443
command is trying to do and what ‘9’ might mean.

The error means the following:
EBADF - Bad file descriptor (internal error)

But what does that mean in detail?

The firmware that Arduino.cc is selling on the modems on this device is 3 years old and this is apparently a known bug with that firmware. I'm having this exact same problem and that's what I've found from researching online. Upgrading it requires that you solder a USB cable to pads on the board and getting the FW from UBlox.

Reference for the crazy soldering you will likely have to do: Firmware upgrade for UBLOX SARA-R410M-02B on the MKR NB 1500 #2 - #11 by zbelding

I'm waiting to hear back from Arduino support about this issue... Though the fact that the thread I link here is already on their forums... I don't put too much hope in a reasonable solution that avoids USB soldering.

I would like to apologize for the late reply.

Thank you for your hint.
I have written to several departments of UBLOX in the meantime. Unfortunately they can not or do not want to help me, because the board is from Arduino.