Senet Packet API
Dependents: MTDOT-UDKDemo_Senet Senet NAMote mDot-IKS01A1 unh-hackathon-example ... more
Diff: senet_packet.cpp
- Revision:
- 0:cc9f4010bba6
- Child:
- 1:3e0cc8ad24f1
- Child:
- 2:9c971be7692b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/senet_packet.cpp Tue Mar 08 09:08:44 2016 -0500 @@ -0,0 +1,359 @@ +/* + * ===================================================================================== + * + * 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 <assert.h> +#include <stdio.h> + +#define ASSERT(_expr) assert(_expr) + + +int32_t SenetPacket:: +PacketHeader::serialize(uint8_t *frame, int32_t len) +{ + int32_t serializedLen = 0; + + if(len >= PacketHeader::HEADER_SIZE) + { + frame[0] = version; + frame[1] = type; + serializedLen = PacketHeader::HEADER_SIZE; + } + + return serializedLen; +} + +bool SenetPacket:: +PacketHeader::deserialize(uint8_t *frame, int32_t len) +{ + if((frame != NULL) && (len >= PacketHeader::HEADER_SIZE)) + { + version = frame[0]; + type = frame[1]; + return true; + } + return false; +} + + +SenetPacket::SenetPacket(uint8_t senetPktType, uint8_t *_buffer, uint8_t _buflen) +{ + header.type = senetPktType; + header.version = VERSION; + pktLen = 0; + + if(_buffer != NULL) + { + buffer = _buffer; + bufferLen = _buflen; + ownBuffer = false; + } + else + { + if(_buflen != 0) + bufferLen = _buflen; + else + bufferLen = MAX_FRAME_SIZE; + + buffer = new uint8_t[bufferLen]; + ASSERT(buffer != NULL); + ownBuffer = true; + } + memset(buffer, 0, bufferLen); +} + + +SenetPacket::~SenetPacket() +{ + if(ownBuffer == true) + delete buffer; +} + + +int32_t SenetPacket::serialize() +{ + pktLen = header.serialize(buffer, bufferLen); + ASSERT(pktLen > 0); + + if(pktLen > 0) + { + int32_t payloadLen = serializePayload(buffer + pktLen, bufferLen - pktLen); + + ASSERT(payloadLen > 0); + + if(payloadLen > 0) + { + pktLen += payloadLen; + return pktLen; + } + } + + return -1; +} + + +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::serializePayload(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::serializePayload(uint8_t *frame, int32_t len) +{ + int32_t out = -1; + + if(SELFID_PAYLOAD_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; + + out = SELFID_PAYLOAD_LEN; + } + + return out; +} + +int32_t ConfigWordPacket::serializePayload(uint8_t *frame, int32_t len) +{ + int32_t out = -1; + + if(CONTROL_PAYLOAD_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; + out = CONTROL_PAYLOAD_LENGTH; + } + + return out; + +} + +int32_t BootInfoPacket::serializePayload(uint8_t *frame, int32_t len) +{ + int32_t out = -1; + + if(BOOT_PAYLOAD_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; + + out = BOOT_PAYLOAD_LENGTH; + } + + return out; +} + +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; + + return true; +} + +int32_t GpsPacket::serializePayload(uint8_t *frame, int32_t len) +{ + int32_t out = -1; + + if(GPS_PAYLOAD_LENGTH <= len) + { + 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] = (elevation>>8) & 0xff; + frame[7] = elevation & 0xff; + + frame[8] = txPower; + + out = GPS_PAYLOAD_LENGTH; + } + + return out; +} + +int32_t RFDataPacket::serializePayload(uint8_t *frame, int32_t len) +{ + int32_t out = -1; + + if(RFDATA_PAYLOAD_LEN <= 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; + out = RFDATA_PAYLOAD_LEN; + } + return out; +} + + +OctetStringPacket::OctetStringPacket(uint8_t size) : + SenetPacket(OCTET_STRING_PACKET, NULL, size + SenetPacket::PacketHeader::HEADER_SIZE) +{ + max = size; + oslen = 0; +} + +bool OctetStringPacket::setOctetString(uint8_t *os, uint8_t len) +{ + if(len > max) + return false; + + oslen = len; + memcpy(buffer+PacketHeader::HEADER_SIZE, os, oslen); + return true; +} + +int32_t OctetStringPacket::serializePayload(uint8_t *frame, int32_t len) +{ + int32_t out = -1; + + if(oslen >= len) + { + memcpy(frame, buffer + PacketHeader::HEADER_SIZE, oslen); + out = oslen; + } + + return out; +} +