Set headers Sara r410

I try to set HTTP headers using the R4x Library. I am using the following code:

r4x.httpSetCustomHeader(0,"token","e4c9e3ae315952416bac1398df64cf3069c");
char i =  r4x.httpRequest(HTTP_HOST, HTTP_PORT, HTTP_QUERY,
                      HttpRequestTypes::POST,
                      buffer, sizeof(buffer),
                      sendbuffer, sizeof(sendbuffer));

Unfortunately i don’t see the headers (see screenshot). Should i change something?

I am using firmware:

L0.0.00.00.05.06,A.02.01

Thanks!

Hi Thijs,

To rule out that it’s an firmware issue.
Please update the firmware to the latest available version.

Best regards,
Jan

Hi Jan,

Thanks for your reply, i’ve updated the firmware to
L0.0.00.00.05.08,A.02.04
Unfortunately it is still not working as expected.

This is the full code I’m using:

/*
  Copyright (c) 2019, SODAQ
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

  3. Neither the name of the copyright holder nor the names of its contributors
  may be used to endorse or promote products derived from this software without
  specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE.
*/

#include <Sodaq_R4X.h>
#include <SHA256.h>

#define CONSOLE_STREAM   SerialUSB
#define MODEM_STREAM     Serial1


#define CURRENT_APN      "ltem.internet.m2m"
#define CURRENT_OPERATOR AUTOMATIC_OPERATOR
#define CURRENT_URAT     SODAQ_R4X_LTEM_URAT
#define CURRENT_MNO_PROFILE MNOProfiles::STANDARD_EUROPE

#define HTTP_HOST        "webhook.site"
#define HTTP_PORT        80
#define HTTP_QUERY       "/345a33dc-b15f-4256-a8d6-22b4cf6f3a3d"

static Sodaq_R4X r4x;
static Sodaq_SARA_R4XX_OnOff saraR4xxOnOff;
static bool isReady;

#ifndef NBIOT_BANDMASK
#define NBIOT_BANDMASK BAND_MASK_UNCHANGED
#endif

void setup()
{
  while ((!CONSOLE_STREAM) && (millis() < 10000)) {
    // Wait max 10 sec for the CONSOLE_STREAM to open
  }

  CONSOLE_STREAM.begin(115200);
  MODEM_STREAM.begin(r4x.getDefaultBaudrate());

  r4x.setDiag(CONSOLE_STREAM);
  r4x.init(&saraR4xxOnOff, MODEM_STREAM);

  isReady = r4x.connect(CURRENT_APN, CURRENT_URAT, CURRENT_MNO_PROFILE, CURRENT_OPERATOR, BAND_MASK_UNCHANGED, NBIOT_BANDMASK);
  CONSOLE_STREAM.println(isReady ? "Network connected" : "Network connection failed");

  CONSOLE_STREAM.println("Setup done");
  if (isReady) {
    postHTTP();
  }
}

void loop()
{
  if (CONSOLE_STREAM.available()) {
    int i = CONSOLE_STREAM.read();
    CONSOLE_STREAM.write(i);
    MODEM_STREAM.write(i);
  }

  if (MODEM_STREAM.available()) {
    CONSOLE_STREAM.write(MODEM_STREAM.read());
  }
}

void postHTTP()
{
  char buffer[2048];
  char sendbuffer[1024] = "{temp: \"27,2\", user: \"787878\"}";
  r4x.httpSetCustomHeader(0, "content-type", "application/json");
  r4x.httpSetCustomHeader(1, "token", "e4c9e3ae315952416bac1398df64cf3069c");
  char i =  r4x.httpRequest(HTTP_HOST, HTTP_PORT, HTTP_QUERY,
                            HttpRequestTypes::POST,
                            buffer, sizeof(buffer),
                            sendbuffer, sizeof(sendbuffer));


  CONSOLE_STREAM.print("Read bytes: ");
  CONSOLE_STREAM.println(i);

  if (i > 0) {
    buffer[i] = 0;
    CONSOLE_STREAM.println("Buffer:");
    CONSOLE_STREAM.println(buffer);
  }
}

This is the server response:

Network connected
Setup done
Read bytes: ⸮
Buffer:
HTTP/1.1 200 OK
Server: nginx/1.14.2
Content-Type: text/plain; charset=UTF-8
Connection: close
Vary: Accept-Encoding
X-Request-Id: c75ec00e-ac34-417c-bed5-4ad82f6290e0
X-Token-Id: 345a33dc-b15f-4256-a8d6-22b4cf6f3a

This is the webhook response from the Sodaq Board:

And this if I use Postman for the same request (here token header is shown):

I have tried to clear the headers using
r4x.httpClearCustomHeader(0)

but had no succes.

Thanks if you can look into it!

Maybe you have some sample code / examples using HTTP post I can use?

Thanks!

Hello.

I had this problem a few days ago - httpRequest(…) uses the httpRequestFromFile(…) method, which, if you look at the source code, right at the begining resets the HTTP profile by issuing “AT+UHTTP=0” for some reason. I resolved it by just removing this block of code (line 1747 of Sodaq_R4X.cpp).

Thanks for your reply! This doesn’t seem to fix it either. But it did inspire me to get started with AT commands myself using passthrough and see if it is working that way.

Now it works, I had to remove the block in both httpRequest(…) and httpRequestFromFile(…) methods. To be able to clear the HTTP profile on request I’ve added a httpClear method as a replacement. @Jan I have created two pull requests on the Sodaq git.

For anyone interested or experiencing same problems, here is the code I use:

/*
  Copyright (c) 2019, SODAQ
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

  3. Neither the name of the copyright holder nor the names of its contributors
  may be used to endorse or promote products derived from this software without
  specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE.
*/

#include <Sodaq_R4X.h>
#include <SHA256.h>

#define CONSOLE_STREAM   SerialUSB
#define MODEM_STREAM     Serial1


#define CURRENT_APN      "ltem.internet.m2m"
#define CURRENT_OPERATOR AUTOMATIC_OPERATOR
#define CURRENT_URAT     SODAQ_R4X_LTEM_URAT
#define CURRENT_MNO_PROFILE MNOProfiles::STANDARD_EUROPE

#define HTTP_HOST        "webhook.site"
#define HTTP_PORT        80
#define HTTP_QUERY       "/345a33dc-b15f-4256-a8d6-22b4cf6f3a3d"

static Sodaq_R4X r4x;
static Sodaq_SARA_R4XX_OnOff saraR4xxOnOff;
static bool isReady;

#ifndef NBIOT_BANDMASK
#define NBIOT_BANDMASK BAND_MASK_UNCHANGED
#endif

void setup()
{
  while ((!CONSOLE_STREAM) && (millis() < 10000)) {
    // Wait max 10 sec for the CONSOLE_STREAM to open
  }

  CONSOLE_STREAM.begin(115200);
  MODEM_STREAM.begin(r4x.getDefaultBaudrate());

  r4x.setDiag(CONSOLE_STREAM);
  r4x.init(&saraR4xxOnOff, MODEM_STREAM);

  isReady = r4x.connect(CURRENT_APN, CURRENT_URAT, CURRENT_MNO_PROFILE, CURRENT_OPERATOR, BAND_MASK_UNCHANGED, NBIOT_BANDMASK);
  CONSOLE_STREAM.println(isReady ? "Network connected" : "Network connection failed");

  CONSOLE_STREAM.println("Setup done");
  if (isReady) {
    postHTTP();
  }
}

void loop()
{
  if (CONSOLE_STREAM.available()) {
    int i = CONSOLE_STREAM.read();
    CONSOLE_STREAM.write(i);
    MODEM_STREAM.write(i);
  }

  if (MODEM_STREAM.available()) {
    CONSOLE_STREAM.write(MODEM_STREAM.read());
  }
}

void postHTTP()
{
  char buffer[2048];
  char sendbuffer[1024] = "{temp: \"30,2\", user: \"787878\"}";
  r4x.httpClear();
  r4x.httpSetCustomHeader(0, "content-type", "application/json");
  r4x.httpSetCustomHeader(1 , "token", "e4c9e3ae315952416bac1398df64cf3069c");
  char i =  r4x.httpRequest(HTTP_HOST, HTTP_PORT, HTTP_QUERY,
                            HttpRequestTypes::POST,
                            buffer,   sizeof(buffer),
                            sendbuffer, sizeof(sendbuffer));


  CONSOLE_STREAM.print("Read bytes: ");
  CONSOLE_STREAM.println(i);

  if (i > 0) {
    buffer[i] = 0;
    CONSOLE_STREAM.println("Buffer:");
    CONSOLE_STREAM.println(buffer);
  }
}

I had some troubles with sending data, char arrays have an terminating null at the end. This null will also be sent using the library. I have edited the writeFile method to exclude this last character.

bool Sodaq_R4X::writeFile(const char* filename, const uint8_t* buffer, size_t size)
{
    // TODO escape filename characters
    print("AT+UDWNFILE=\"");
    print(filename);
    print("\",");
    println(size-1);
    if (readResponse() != GSMResponsePrompt) {
        return false;
    }
    for (size_t i = 0; i < size-1; i++) {
        writeByte(buffer[i]);
    }
    return (readResponse() == GSMResponseOK);
}

Hi @Thijs_Franssen,

I’m glad you have it working.
We will look into the request you made in GitHub.
We are working on an update of the R4X library, so it can take up a bit of time before we add your request.

Best regards,
Jan