0

Sending Structs over HTTP_POST_start
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Sending Structs over HTTP_POST_start

by Dygear on Thu May 30, 2019 6:31 pm

I have this struct that contains all of the GPS and Hardware information that I need in order to track a device. VechLocFrame is 75 bytes long.

Code: Select all | TOGGLE FULL SIZE
struct VecLocFrame {
    char    IEMID[15];               // FONA Hardware IEMID
    char    CCID[20];               // FONA Sim Card ID
    struct GPS {
        char    DateTime[19];       // YYYYMMDDTHHMMSS.000
        struct Fix {
            bool    Fix: 1;         // TRUE If GPS Has Fix
            bool    GPS: 1;         // TRUE If Fix Type = GPS
            bool    DGPS: 1;        // TRUE If Fix Type = DGPS
            bool    FONA: 1;        // TRUE If Fix Type = FONA
            uint8_t Satellites: 4;  // Number of Satellites
        } Fix;
        float   Latitude;           // Latitude Decimal Degrees
        float   Longitude;          // Longitude Decimal Degrees
        float   Knots;              // Speed Over Ground In Knots
        float   Angle;              // Course in Degrees from True North
        float   Altitude;           // Altitude in Meters Above MSL
    } GPS;
} VecLocFrame;


  • IEMID = 15 Bytes / 15 Bytes Total
  • CCID = 20 Bytes / 35 Bytes Total
    • GPS.DateTime = 19 Bytes / 54 Bytes Total
      • GPS.Fix.Fix = 1 Bit / 54 Bytes & 1 Bit Total
      • GPS.Fix.GPS = 1 Bit / 54 Bytes & 2 Bits Total
      • GPS.Fix.DGPS = 1 Bit / 54 Bytes & 3 Bits Total
      • GPS.Fix.FONA = 1 Bit / 54 Bytes & 4 Bits Total
      • GPS.Fix.Satellites = 4 Bits / 55 Bytes Total
    • GPS.Latitude = 4 Bytes / 59 Bytes Total
    • GPS.Longitude = 4 Bytes / 63 Bytes Total
    • GPS.Knots = 4 Bytes / 67 Bytes Total
    • GPS.Angle = 4 Bytes / 71 Bytes Total
    • GPS.Altitude = 4 Bytes / 75 Bytes Total

What I want to do is, send that information to my server. Right now, I'm trying to do that with HTTP_POST_start, because I can't find how to do raw socket connections yet. So I instatinate the struct and fill out the information ...

Code: Select all | TOGGLE FULL SIZE
        struct VecLocFrame Frame;
        strcpy(Frame.IEMID, IEMID);
        strcpy(Frame.CCID, CCID);

        strcpy(Frame.GPS.DateTime, DateTime);

        Frame.GPS.Fix.Satellites = GPS.satellites;
        Frame.GPS.Fix.Fix = GPS.fix;
        Frame.GPS.Fix.GPS = GPS.fixquality;
        Frame.GPS.Fix.DGPS = GPS.fixquality;
        Frame.GPS.Fix.FONA = false;

        Frame.GPS.Latitude = GPS.latitude;
        Frame.GPS.Longitude = GPS.longitude;
        Frame.GPS.Knots = GPS.speed;
        Frame.GPS.Angle = GPS.angle;
        Frame.GPS.Altitude = GPS.altitude;


But ... It will not allow me to send the struct over the HTTP_POST_start function because of a type mismatch.

Code: Select all | TOGGLE FULL SIZE
/Users/dygear/Documents/Arduino/VecLoc/VecLoc.ino: In function 'void loop()':
VecLoc:185:75: error: cannot convert 'VecLocFrame' to 'const char*' for argument '1' to 'size_t strlen(const char*)'
         if (fona.HTTP_POST_start(url, F("text/plain"), Frame, strlen(Frame), &statuscode, (uint16_t *)&length)) {
                                                                           ^


So here is my question, how do I convert my struct into something that the HTTP_POST_start function will accept?

I can't use the true phrase that I'm looking for because I.M.E.I. is a banned word on the forum so it's been replaced with IEMID.
Dygear
 
Posts: 20
Joined: Mon Aug 04, 2014 6:55 pm

Re: Sending Structs over HTTP_POST_start

by Dygear on Thu May 30, 2019 8:43 pm

Code: Select all | TOGGLE FULL SIZE
        /**
         * Convert the VecLoc Frame into Char Array.
         */
        uint8_t FrameLen = sizeof(Frame);
        char FrameBuf[FrameLen] = {0};
        memcpy(FrameBuf, &Frame, sizeof(VecLocFrame));


That copies the struct VecLocFrame named Frame into a variable called FrameBuf that is of type Char. This allows you to send that structure as an array of chars.
Dygear
 
Posts: 20
Joined: Mon Aug 04, 2014 6:55 pm

Re: Sending Structs over HTTP_POST_start

by adafruit_support_mike on Fri May 31, 2019 3:16 am

Yep, that's the general process.

A POST query would generally report all the values one by one in the body of the message, with a separator between the items. If you're going to flatten the data to a single item, you can probably use a GET query and a text-based encoding.

I often use base-64 encoded JSON strings for that kind of communication. Both formats are well known, widely supported, and fairly simple. Base-64 encoded data travels safely in a URL, and JSON is designed to flatten and re-expand data structures.

adafruit_support_mike
 
Posts: 58480
Joined: Thu Feb 11, 2010 2:51 pm

Re: Sending Structs over HTTP_POST_start

by Dygear on Fri May 31, 2019 11:49 pm

I ended up using a TCP socket, to send 64 bytes of data on each packet. That code is linked below in the gist.

https://gist.github.com/Dygear/049bf68a ... da12a3b598

The problem is that, the data seems to be cruppted. After about the ... 10th iteration of the code, what I actually end up getting over the TCP connection is, the Serial Connection information for building the TCP connection and keeping it alive. So clearly I've crossed a pointer or something somewhere, but I don't know where!
Dygear
 
Posts: 20
Joined: Mon Aug 04, 2014 6:55 pm

Re: Sending Structs over HTTP_POST_start

by adafruit_support_mike on Sat Jun 01, 2019 4:07 am

Add some diagnostic Serial.print()s to check the contents of your variables at various points in the code. The point where a variable stops doing what you expected is a flag that help isolate the source of the problem.

adafruit_support_mike
 
Posts: 58480
Joined: Thu Feb 11, 2010 2:51 pm

Please be positive and constructive with your questions and comments.