Senet Packet API

Files at this revision

API Documentation at this revision

Comitter:
shaunkrnelson
Date:
Sat Mar 05 21:56:20 2016 +0000
Child:
1:c4435fed9eb9
Commit message:
Initial commit

Changed in this revision

senet_packet.cpp Show annotated file Show diff for this revision Revisions of this file
senet_packet.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/senet_packet.cpp	Sat Mar 05 21:56:20 2016 +0000
@@ -0,0 +1,268 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  senet_packet.cpp
+ *
+ *    Description:  Senet Packet Types implementation file 
+ *
+ *        Version:  1.0
+ *        Created:  03/05/2016 04:23:40 PM
+ *
+ *         Author:  S. Nelson  
+ *        Company:  Senet, Inc
+ *
+ * =====================================================================================
+ */
+
+
+#include "senet_packet.h"
+// #include <cstddef>
+
+
+int32_t SenetLoRaPacket::
+PacketHeader::serialize(uint8_t *frame, int32_t len)
+{
+    ASSERT(len > 2); 
+
+    frame[0] = version;
+    frame[1] = type;
+
+    return 2;
+}
+
+bool SenetLoRaPacket::
+PacketHeader::deserialize(uint8_t *frame, int32_t len)
+{
+    if((frame != NULL) && (len >= 2))
+    {
+        version = frame[0];
+        type    = frame[1];
+        return true;
+    }
+    return false;
+}
+
+bool SensorPacket::addSensorValue(uint8_t position, uint8_t type, uint16_t value)
+{
+    if (position < MAX_SENSOR_VALUES)
+    {
+        sensorValue[position].type  = type;
+        sensorValue[position].value = value;
+        sensorValue[position].isSet = true;
+        return true;
+    }
+    else
+        return false;
+}
+
+int32_t SensorPacket::serializeData(uint8_t *buffer, int32_t len)
+{
+    int32_t bytes   = 0;
+    int32_t dataLen = 0;
+
+    for(int32_t i = 0; i < MAX_SENSOR_VALUES; i++)
+    {
+        if(sensorValue[i].isSet == true)
+        {
+            dataLen = sensorValue[i].serialize(buffer+bytes, len - bytes);
+            if(dataLen == -1)
+                return -1;
+            bytes += dataLen;
+        }
+    }
+    return bytes; 
+}
+
+bool SelfIdPacket::setDeviceType(uint32_t model, uint8_t revision)
+{
+    if((model & 0x00FFFFFF) != model)
+        return false;
+
+    deviceType = (model<<8)|revision;
+    return true;
+}
+
+bool SelfIdPacket::setSwVersion(uint8_t major, uint8_t minor, uint8_t point, uint16_t build, uint8_t developerId)
+{
+ uint8_t  _major =  major & 0xf;
+ uint8_t  _minor =  minor & 0xf;
+ uint8_t  _point =  point & 0x3f;
+ uint16_t _build =  build & 0x3ff;
+ uint8_t  _devid =  developerId & 0xff;
+
+ if((_major != major) || (_minor != minor) || (_point != point) || (_build != build) || (_devid != developerId))
+     return false;
+
+  swVersion = (_major << 28) | (_minor << 24) | (_point << 18) | (_build << 8) | _devid; 
+  return true;
+}
+
+void SelfIdPacket::setBatteryFailState(bool failed)
+{
+    if(failed == true)
+        powerMask |= 1 << 3;
+    else
+        powerMask &= ~(1 << 3); 
+}
+
+bool SelfIdPacket::setBatteryLevel(uint8_t level)
+{
+    uint8_t _level = level & 0x7;
+
+    if(level != _level)
+        return false;
+
+    powerMask &= 0xf8;
+    powerMask |= _level;
+
+    return true;
+}
+
+bool SelfIdPacket::setExtPowerSupplyState(uint8_t id, bool isPresent)
+{
+    bool retVal = false;
+    if(id == EXT_POWER_SUPPLY_1)      
+    {
+        powerMask &= 0x7F; 
+        if(isPresent)
+            powerMask |= 0x80;
+        retVal = true;
+    }
+    else if(id == EXT_POWER_SUPPLY_2)      
+    {
+        powerMask &= 0xBF; 
+        if(isPresent)
+            powerMask |= 0x40;
+        retVal = true;
+    }
+    return retVal;
+}
+
+int32_t SelfIdPacket::serializeData(uint8_t *frame, int32_t len)
+{
+#define SELFID_PACKET_LEN 8
+
+    ASSERT(SELFID_PACKET_LEN <= len);
+
+    frame[0] = (deviceType>>16) & 0xff;
+    frame[1] = (deviceType>>8)  & 0xff;
+    frame[2] = deviceType & 0xff;
+
+    frame[3] = (swVersion >> 24) & 0xff;
+    frame[4] = (swVersion >> 16) & 0xff;
+    frame[5] = (swVersion >> 8)  & 0xff;
+    frame[6] = swVersion & 0xff;
+
+    frame[7] = powerMask;
+
+    return SELFID_PACKET_LEN;
+}
+
+int32_t ConfigWordPacket::serializeData(uint8_t *frame, int32_t len)
+{
+#define CONTROL_PACKET_LENGTH 9
+
+    ASSERT(CONTROL_PACKET_LENGTH <= len);
+
+    frame[0] = (config>>24) & 0xff;
+    frame[1] = (config>>16) & 0xff;
+    frame[2] = (config>>8) & 0xff;
+    frame[3] = config & 0xff;
+
+    frame[4] = (mask>>24) & 0xff;
+    frame[5] = (mask>>16) & 0xff;
+    frame[6] = (mask>>8) & 0xff;
+    frame[7] = mask & 0xff;
+
+    frame[8] = authKey;
+
+    return CONTROL_PACKET_LENGTH;
+
+}
+
+int32_t BootInfoPacket::serializeData(uint8_t *frame, int32_t len) 
+{
+#define BOOT_PACKET_LENGTH 8
+
+    ASSERT(BOOT_PACKET_LENGTH <= len);
+
+    frame[0] = (bootCount<<8) & 0xff;
+    frame[1] = bootCount & 0xff;
+
+    frame[2] = (resetCount<<8) & 0xff;
+    frame[3] = resetCount & 0xff;
+
+    frame[4] = (lastBootReason<<24) & 0xff;
+    frame[5] = (lastBootReason<<16)  & 0xff;
+    frame[6] = (lastBootReason<<8)  & 0xff;
+
+    return BOOT_PACKET_LENGTH;
+}
+
+bool GpsPacket::setCoordinates(uint32_t _latitude, uint32_t _longitude, uint16_t _elevation)
+{
+
+    if(((_latitude & 0x00ffffff) != _latitude) || ((_longitude & 0x00ffffff) != _longitude))
+        return false;
+
+    latitude  = _latitude; 
+    longitude = _longitude; 
+    elevation = _elevation;
+}
+
+int32_t GpsPacket::serializeData(uint8_t *frame, int32_t len)
+{
+#define GPS_PACKET_LENGTH 7
+
+    if(len <  GPS_PACKET_LENGTH )
+        return -1;
+
+    frame[0] = (latitude>>16) & 0xff;
+    frame[1] = (latitude>>8) & 0xff;
+    frame[2] = latitude & 0xff;
+
+    frame[3] = (longitude>>16) & 0xff;
+    frame[4] = (longitude>>8) & 0xff;
+    frame[5] = longitude & 0xff;
+
+    frame[6] = txPower;
+
+    return  GPS_PACKET_LENGTH;
+}
+
+int32_t RFDataPacket::serializeData(uint8_t *frame, int32_t len)
+{
+#define RFDATA_PACKET_LEN 8
+
+    ASSERT(len > RFDATA_PACKET_LEN);
+
+    frame[0] = channel;
+    frame[1] = txpower;
+    frame[2] = datarate;
+    frame[3] = snr;
+    frame[4] = rssi;
+    frame[5] = (timestamp >> 16)& 0xff;
+    frame[6] = (timestamp >> 8)& 0xff;
+    frame[7] = timestamp & 0xff;
+    return RFDATA_PACKET_LEN;
+
+}
+
+bool OctetStringPacket::setOctetString(uint8_t *os, uint8_t len)
+{
+    if(len > maxSize)
+        return false;
+
+    memcpy(osptr, os, len);
+    oslen = len;
+    return true;
+}
+
+int32_t OctetStringPacket::serializeData(uint8_t *frame, int32_t len)
+{
+    if(len < oslen)
+        oslen = len;
+    memcpy(frame, osptr, oslen);
+    return oslen;
+}
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/senet_packet.h	Sat Mar 05 21:56:20 2016 +0000
@@ -0,0 +1,355 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  senet_packet.h
+ *
+ *    Description: Senet Packet types 
+ *
+ *        Version:  1.0
+ *        Created:  03/05/2016 03:13:20 PM
+ *       Revision:  1
+ *
+ *         Author:  Shaun Nelson, coder extraodinaire
+ *        Company:  Senet, Inc  
+ *
+ * =====================================================================================
+ */
+#include <stdint.h>
+#include <assert.h>
+#include <string.h>
+
+#define ASSERT(_expr) assert(_expr)
+
+// Senet packet types
+enum SenetPacketT
+{
+    SELF_ID_PACKET      = 0,
+    RF_PACKET           = 1,
+    GPS_PACKET          = 2,
+    CONTROL_PACKET      = 3,
+    BOOT_INFO_PACKET    = 4,
+    SENSOR_PACKET       = 8,
+    OCTET_STRING_PACKET = 126,
+    UTF_8_STRING        = 127
+};
+
+
+/*
+ * =====================================================================================
+ *        Class:  SenetLoRaPacket
+ *  Description:  Senet Packet Base class 
+ * =====================================================================================
+ */
+struct SenetLoRaPacket
+{
+    static const uint32_t MAX_FRAME_SIZE = 242;
+    static const uint8_t  VERSION        = 1;
+
+
+    // Common packet header
+    struct PacketHeader
+    {
+        uint8_t version; // packet format versioni
+        uint8_t type;    // Senet packet type
+
+        PacketHeader(uint8_t _type=0)
+        {
+            version = VERSION;
+            type    = _type;
+        }
+
+        int32_t serialize  (uint8_t *frame, int32_t len);
+        bool    deserialize(uint8_t *frame, int32_t len);
+    } header;
+
+    uint8_t pkt[MAX_FRAME_SIZE]; // serialized packet buffer
+    uint8_t pktLen;              // serialized packet length
+
+    SenetLoRaPacket(uint8_t senetPktType)
+    {
+        header.type    = senetPktType;
+        header.version = VERSION;
+        pktLen         = 0;
+    }
+
+    /*
+     *--------------------------------------------------------------------------------------
+     *       Class:  SenetLoRaPacket
+     *      Method:  serialize
+     * Description:  Packet serializer 
+     *--------------------------------------------------------------------------------------
+     */
+    virtual int32_t serialize()
+    {
+        pktLen = header.serialize(pkt, MAX_FRAME_SIZE);
+
+        int32_t payloadLen = serializeData(pkt + pktLen, MAX_FRAME_SIZE - pktLen);
+        if(payloadLen > 0)
+        {
+            pktLen += payloadLen;
+            return pktLen;
+        }
+        return -1;
+    }
+
+    
+    /*
+     *--------------------------------------------------------------------------------------
+     *       Class:  SenetLoRaPacket
+     *      Method:  serializeData
+     * Description:  Each unique packet type implements this to serialize its data   
+     *--------------------------------------------------------------------------------------
+     */
+    virtual int32_t serializeData(uint8_t *frame, int32_t len) {return 0;}
+
+};
+
+
+/*
+ * =====================================================================================
+ *        Class:  BootInfoPacket
+ *  Description:  Device Boot information packet
+ * =====================================================================================
+ */
+struct BootInfoPacket : public SenetLoRaPacket
+{
+    uint16_t bootCount;       // number of device boots
+    uint16_t resetCount;      // number of device resets
+    uint32_t lastBootReason;  // last boot reason
+
+    BootInfoPacket() :
+        SenetLoRaPacket(BOOT_INFO_PACKET)
+    {
+        bootCount      = 0; 
+        resetCount     = 0;
+        lastBootReason = 0;
+    }
+
+    protected:
+    /*
+     *--------------------------------------------------------------------------------------
+     *       Class:  BootInfoPacket
+     *      Method:  serializeData
+     * Description:  Serialize packet data
+     *--------------------------------------------------------------------------------------
+     */
+    int32_t serializeData(uint8_t *frame, int32_t len); 
+};
+
+
+/*
+ * =====================================================================================
+ *        Class:  ControlWordPacket
+ *  Description:  Packet to configure device
+ * =====================================================================================
+ */
+struct ConfigWordPacket : public SenetLoRaPacket
+{
+    ConfigWordPacket() :
+        SenetLoRaPacket(CONTROL_PACKET) { config = 0; mask = 0; authKey = 0; }
+
+    uint32_t config;  // configuration word
+    uint32_t mask;    // valid bit mask applied to configuration word
+    uint8_t  authKey; // Downlink authentication key 
+
+    /*
+     *--------------------------------------------------------------------------------------
+     *       Class:  ConfigWordPacket 
+     *      Method:  serializeData
+     * Description:  Serialize packet data
+     *--------------------------------------------------------------------------------------
+     */
+    int32_t serializeData(uint8_t *frame, int32_t len);
+};
+
+
+/*
+ * =====================================================================================
+ *        Class:  GpsPacket
+ *  Description:  Transmit device location in Decimal degress (http://www.en.wikipedia.org/wiki/Decimal_degrees)
+ * =====================================================================================
+ */
+struct GpsPacket : public SenetLoRaPacket
+{
+           bool setCoordinates(uint32_t latitude, uint32_t longitude, uint16_t elevation);
+    inline void setTxPower(uint8_t dBm) { txPower = dBm; }
+
+    GpsPacket():
+        SenetLoRaPacket(GPS_PACKET)
+    {
+        latitude   = 0;
+        longitude  = 0;
+        elevation  = 0;
+        txPower    = 0;
+    }
+
+    protected:
+    uint32_t latitude;
+    uint32_t longitude;
+    uint16_t elevation;
+    uint8_t  txPower;
+
+    /*
+     *--------------------------------------------------------------------------------------
+     *       Class:  GpsPacket
+     *      Method:  serializeData
+     * Description:  Serialize the data 
+     *--------------------------------------------------------------------------------------
+     */
+    int32_t serializeData(uint8_t *frame, int32_t len); 
+};
+
+
+/*
+ * =====================================================================================
+ *        Class:  OctetStringPacket
+ *  Description:  Variable length Octet String packet 
+ * =====================================================================================
+ */
+struct OctetStringPacket : public SenetLoRaPacket
+{
+    bool setOctetString(uint8_t *os, uint8_t len);
+
+    OctetStringPacket(uint8_t size) 
+        : SenetLoRaPacket(OCTET_STRING_PACKET)
+    { 
+        osptr = new uint8_t[size];
+        ASSERT(osptr != NULL);
+        maxSize = size;
+        oslen   = 0;
+    }
+
+    protected:
+    uint8_t *osptr;
+    uint8_t  maxSize;
+    uint8_t  oslen;
+
+    virtual int32_t serializeData(uint8_t *frame, int32_t len);
+};
+
+
+/*
+ * =====================================================================================
+ *        Class:  RFDataPacket
+ *  Description: Radio Data packet 
+ * =====================================================================================
+ */
+struct RFDataPacket : public SenetLoRaPacket
+{
+    uint8_t  channel;   //  The channel the device sent on
+    uint8_t  txpower;   //  The transmit power in dBm used by the device
+    uint8_t  datarate;  //  The datarate used by the device
+    uint8_t  snr;       //  Signal to Noise ratio of the last frame received
+    uint8_t  rssi;      //  RSSI of the last frame received
+    uint32_t timestamp; //  The device's current timestamp
+
+    RFDataPacket():
+        SenetLoRaPacket(RF_PACKET)
+    { 
+        channel   = 0;
+        txpower   = 0;
+        datarate  = 0;
+        snr       = 0;
+        rssi      = 0;
+        timestamp = 0;
+    }
+
+    /*
+     *--------------------------------------------------------------------------------------
+     *       Class:  RFDataPacket
+     *      Method:  serializeData
+     * Description:  Serialize the data 
+     *--------------------------------------------------------------------------------------
+     */
+    int32_t serializeData(uint8_t *frame, int32_t len);
+};
+
+
+/*
+ * =====================================================================================
+ *        Class:  SelfIdPacket
+ *  Description:  
+ * =====================================================================================
+ */
+struct SelfIdPacket : public SenetLoRaPacket
+{
+    const static uint8_t EXT_POWER_SUPPLY_ID_MAX = 2;
+    const static uint8_t EXT_POWER_SUPPLY_1      = 1;
+    const static uint8_t EXT_POWER_SUPPLY_2      = 2;
+    const static uint8_t BATTERY_LEVEL_MAX       = 7;
+
+    bool setDeviceType          (uint32_t model, uint8_t revision);
+    bool setSwVersion           (uint8_t major, uint8_t minor, uint8_t point, uint16_t build, uint8_t developer);
+    void setBatteryFailState    (bool failed);
+    bool setBatteryLevel        (uint8_t level);
+    bool setExtPowerSupplyState (uint8_t id, bool isPresent);
+
+    SelfIdPacket() :
+        SenetLoRaPacket(SELF_ID_PACKET) { deviceType = 0; swVersion = 0; powerMask = 0; }
+
+    protected:
+    uint32_t deviceType;
+    uint32_t swVersion;
+    uint8_t  powerMask;
+
+    /*
+     *--------------------------------------------------------------------------------------
+     *       Class:  SelfIdPacket 
+     *      Method:  serializeData
+     * Description:  Serialize the data 
+     *--------------------------------------------------------------------------------------
+     */
+    virtual int32_t serializeData(uint8_t *frame, int32_t len); 
+};
+
+
+/*
+ * =====================================================================================
+ *        Class:  SensorPacket
+ *  Description:  
+ * =====================================================================================
+ */
+struct SensorPacket : public SenetLoRaPacket
+{
+    bool setPrimarySensor(uint16_t value) { return addSensorValue(0,1, value);};
+    bool setTemperature  (uint16_t value) { return addSensorValue(1,2, value);}
+    void reset();
+
+    SensorPacket() :
+        SenetLoRaPacket(SENSOR_PACKET) {}
+
+    protected:
+    static const uint8_t MAX_SENSOR_VALUES = 2;
+
+    struct SensorValue
+    {
+        uint8_t  type;
+        uint16_t value;
+        bool     isSet;
+
+        SensorValue() { type  = 0; value = 0; isSet = false;}
+
+        int32_t serialize(uint8_t *frame, int32_t len)
+        {
+            if(len < 3)
+                return -1;
+
+            frame[0] = type;
+            frame[1] = (value >> 8) & 0xff;
+            frame[2] = value & 0xff;
+            return 3;
+        }
+    } sensorValue[MAX_SENSOR_VALUES];
+
+            bool    addSensorValue(uint8_t position, uint8_t type, uint16_t value);
+
+    /*
+     *--------------------------------------------------------------------------------------
+     *       Class:  SelfIdPacket 
+     *      Method:  serializeData
+     * Description:  Serialize the data 
+     *--------------------------------------------------------------------------------------
+     */
+    virtual int32_t serializeData(uint8_t *frame, int32_t len);
+
+};