A simple CIoT message protocol, used in the Water Meter Demos.
This library provides a small messaging protocol for a CIoT device, intended for use with the Water Meter Demo. As well as building for the C027 target, files are included for building a C DLL and, from that, a C Sharp DLL which can be linked into the PC-end of the Water Meter Demo (see the .ZIP file stored in the Wiki of the Water Meter Demo project) to provide end-to-end messaging with complete transparency. Since these PC files cannot be built inside mbed the source files are post-fixed with a ".txt" extension to keep them out of the way.
If a water pump is to be switched on/off as part of the demo, an interface circuit is required, which is described on the Wiki of the WaterMeterSupport library.
Diff: IotMeterMsgs.hpp
- Revision:
- 0:5c46cb3be899
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/IotMeterMsgs.hpp Fri May 22 11:41:38 2015 +0000 @@ -0,0 +1,281 @@ +/* C027N/water-meter message definitions for Water Meter Demo + * + * Copyright (C) u-blox Melbourn Ltd + * u-blox Melbourn Ltd, Melbourn, UK + * + * All rights reserved. + * + * This source file is the sole property of u-blox Melbourn Ltd. + * Reproduction or utilization of this source in whole or part is + * forbidden without the written consent of u-blox Melbourn Ltd. + */ + +#ifndef IOT_METER_MSGS_HPP +#define IOT_METER_MSGS_HPP + +/** + * @file iot_meter_msgs.h + * This file defines the messages sent between the + * C027N/water-meter device and a PC app for the MWC demo + * 2015. + * + * The message format is as follows: + * + * uint8_t id + * uint32_t value + * + * The IDs are defined in an enumerated type and there are + * separately defined ID sets for the downlink and uplink + * directions (i.e. they may overlap). When transmitted the + * messages are packed such that the 32-bit content byte + * immediately follows the 8-bit ID with no packing, resulting + * in a fixed message length of 5 bytes. Multiple fixed + * length messages may be packed into a datagram, hence it can + * be assumed that a datagram of length < 10 bytes contains + * one message, a datagram of length < 15 bytes contains two + * messages, etc. + * + * Boolean values are expressed as uint32_t zero (false) or + * uint32_t one (true). For multibyte values the highest + * value bytes is stored first, so a message with ID 0xa5 and + * value 0x12345678 would be stored in the datagram as: + * + * Location: 0 1 2 3 4 + * Contents: a512345678 + * + * There are some messages (Gpio setters for instance) which + * encode more than a single value into the value field. See + * the individual encode/decode functions for how these values + * are packed. + */ + +// ---------------------------------------------------------------- +// GENERAL COMPILE-TIME CONSTANTS +// ---------------------------------------------------------------- + +/// The maximum length of a single messages in bytes +#define MAX_MESSAGE_SIZE 5 + +/// The default meter reading interval. +#define DEFAULT_READING_INTERVAL_SECONDS 10 + + +// ---------------------------------------------------------------- +// TYPES +// ---------------------------------------------------------------- + +/// The wake up code sent from the device +typedef enum WakeUpCodeTag_t +{ + WAKE_UP_CODE_OK, //!< A good wake-up, no problems. + WAKE_UP_CODE_WATER_METER_PROBLEM, //!< Wake-up after assert due to + //! problems reading the water meter. + WAKE_UP_CODE_AT_COMMAND_PROBLEM, //!< Wake-up after assert due to + //! problems with AT commands. + WAKE_UP_CODE_NETWORK_SEND_PROBLEM, //!< Wake-up after assert due to + //! problems sending to the network. + WAKE_UP_CODE_MEMORY_ALLOC_PROBLEM, //!< Wake-up after assert due to + //! memory allocation issues. + WAKE_UP_CODE_PROTOCOL_PROBLEM, //!< Wake-up after assert due to + //! a protocol problem. + WAKE_UP_CODE_GENERIC_FAILURE, //!< Wake-up after a generic failure. + WAKE_UP_CODE_REBOOT, //!< Waking up after a commanded reboot. + MAX_NUM_WAKE_UP_CODES //!< The maximum number of + //! decode results. +} WakeUpCode_t; + +// ---------------------------------------------------------------- +// MESSAGE BODIES +// ---------------------------------------------------------------- + +/// InitIndUlMsg_t. Sent at power-on of the device. Indicates that the +// device has been initialised. +// After transmission of this message meter readings will be returned +// at the requested rate (or DEFAULT_READING_INTERVAL_SECONDS if no +// InitReqDlMsg_t has been received by the device). +typedef struct InitIndUlMsgTag_t +{ + WakeUpCode_t wakeUpCode; //!< A wake-up code from the device. +} InitIndUlMsg_t; + +/// RebootReqDlMsg_t. Sent to reboot the device and set the development +// mode on or off. By default development mode is OFF. +typedef struct RebootReqDlMsgTag_t +{ + bool devModeOnNotOff; //!< If true development mode is on, else it is off. +} RebootReqDlMsg_t; + +/// SerialNumberGetCnfUlMsg_t. Sent in response to a SerialNumberGetReqDlMsg_t (which +// is empty and so not represented here). +typedef struct SerialNumberGetCnfUlMsgTag_t +{ + uint32_t serialNumber; //!< The serial number of the meter. +} SerialNumberGetCnfUlMsg_t; + +/// SerialNumberIndUlMsg_t. Sent at power-on of the device and in response to +// an InitReqDlMsg_t. Indicates the serial number of the device. +typedef struct SerialNumberIndUlMsgTag_t +{ + uint32_t serialNumber; //!< The serial number of the meter. +} SerialNumberIndUlMsg_t; + +/// VolumeIndUlMsg_t. The current meter reading. +typedef struct VolumeIndUlMsgTag_t +{ + uint32_t volumeLitres; +} VolumeIndUlMsg_t; + +/// RssiIndUlMsg_t. The current RSSI reading. +typedef struct RssiIndUlMsgTag_t +{ + uint32_t rssi; //!< The RSSI reading in arbitrary units, range 0 to 255. +} RssiIndUlMsg_t; + +/// ReadingIntervalSetReqDlMsg_t. Set the meter reading interval. +typedef struct ReadingIntervalSetReqDlMsgTag_t +{ + uint32_t readingIntervalSeconds; //!< The interval at which the device + //! should send readings. +} ReadingIntervalSetReqDlMsg_t; + +/// ReadingIntervalSetCnfUlMsg_t. Sent in response to a +// ReadingIntervalSetReqDlMsg_t. +// After transmission of this message meter readings will be returned +// at the requested rate (or DEFAULT_READING_INTERVAL_SECONDS if no +// command setting it otherwise has been received by the device). +typedef struct ReadingIntervalSetCnfUlMsgTag_t +{ + uint32_t readingIntervalSeconds; //!< The interval at which readings are sent. +} ReadingIntervalSetCnfUlMsg_t; + +/// ReadingIntervalGetCnfUlMsg_t. Sent in response to a +// ReadingIntervalGetReqDlMsg_t (which is empty and so not represented +// here). +// After transmission of this message meter readings will be returned +// at the requested rate (or DEFAULT_READING_INTERVAL_SECONDS if no +// command setting it otherwise has been received by the device). +typedef struct ReadingIntervalGetCnfUlMsgTag_t +{ + uint32_t readingIntervalSeconds; //!< The interval at which readings are sent. +} ReadingIntervalGetCnfUlMsg_t; + +/// GpioState_t. Data concerning how a GPIO is set up. +typedef struct GpioStateTag_t +{ + uint8_t gpio; //!< The GPIO in question: 0 for D0, 1 for D1, etc. + bool inputNotOutput; //!< true if this is an input, else it is an output. + bool onNotOff; //!< If the GPIO is an output then this gives its state. + //! If the GPIO is an input this is not set. +} GpioState_t; + +/// GpioSetReqDlMsg_t. Set the state of a GPIO on the C027N board. +typedef struct GpioSetReqDlMsgTag_t +{ + GpioState_t gpioState; //!< The state of the GPIO. +} GpioSetReqDlMsg_t; + +/// GpioSetCnfUlMsg_t. Response to GpioSetReqDlMsg_t. +typedef struct GpioSetCnfUlMsgTag_t +{ + GpioState_t gpioState; //!< The state of the GPIO. +} GpioSetCnfUlMsg_t; + +/// GpioGetReqDlMsg_t. Gets the state of a GPIO on the C027N board. +typedef struct GpioGetReqDlMsgTag_t +{ + uint8_t gpio; //!< The GPIO to get. +} GpioGetReqDlMsg_t; + +/// GpioGetCnfUlMsg_t. Sent in response to a GpioGetReqDlMsg. +typedef struct GpioGetCnfUlMsgTag_t +{ + GpioState_t gpioState; //!< The state of the GPIO. +} GpioGetCnfUlMsg_t; + +/// LedSetReqDlMsg_t. Set the steady state of the red LED on +// the C027N board. +typedef struct LedSetReqDlMsgTag_t +{ + bool onNotOff; //!< Make the steady state ON if true, otherwise OFF. + //! OFF is the default state. +} LedSetReqDlMsg_t; + +/// LedSetCnfUlMsg_t. Response to LedSetReqDlMsg_t. +typedef struct LedSetCnfUlMsgTag_t +{ + bool onNotOff; //!< The LED is steady-state ON if true, otherwise + //! OFF. +} LedSetCnfUlMsg_t; + +/// LedGetCnfUlMsg_t. Sent in response to an LedGetReqDlMsg +// (which is an empty ID and so not represented here). +typedef struct LedGetCnfUlMsgTag_t +{ + bool onNotOff; //!< The steady state is ON if true, otherwise OFF. +} LedGetCnfUlMsg_t; + +/// FlashSetReqDlMsg_t. Set the red LED to flash when a reading is +// being sent (or not). If LedSetReqDlMsg_t has been set to ON the +// flash will be 'inverted', i.e. the red LED will blink off when a +// reading is being transmitted instead. +typedef struct FlashSetReqDlMsgTag_t +{ + bool onNotOff; //!< If true then the red LED will flash when a + //! reading is being sent, else it will remain in + //! steady state. The default is to flash when a + //! reading is being sent. +} FlashSetReqDlMsg_t; + +/** + * FlashSetCnfUlMsg_t. Response to FlashSetReqDlMsg_t. + */ +typedef struct FlashSetCnfUlMsgTag_t +{ + bool onNotOff; //!< If true then the red LED flashes when a + //! reading is being sent, else it will remain in + //! steady state. +} FlashSetCnfUlMsg_t; + +/// FlashGetCnfUlMsg_t. Sent in response to a FlashGetReqDlMsg +// (which is an empty ID and so not represented here). +typedef struct FlashGetCnfUlMsgTag_t +{ + bool onNotOff; //!< The steady state is ON if true, otherwise OFF. +} FlashGetCnfUlMsg_t; + +// ---------------------------------------------------------------- +// MESSAGE UNIONS +// ---------------------------------------------------------------- + +/// Union of all downlink messages. +typedef union DlMsgUnionTag_t +{ + RebootReqDlMsg_t rebootReqDlMsg; + ReadingIntervalSetReqDlMsg_t readingIntervalSetReqDlMsg; + GpioSetReqDlMsg_t gpioSetReqDlMsg; + GpioGetReqDlMsg_t gpioGetReqDlMsg; + LedSetReqDlMsg_t ledSetReqDlMsg; + FlashSetReqDlMsg_t flashSetReqDlMsg; +} DlMsgUnion_t; + +/// Union of all uplink messages. +typedef union UlMsgUnionTag_t +{ + InitIndUlMsg_t initIndUlMsg; + VolumeIndUlMsg_t volumeIndUlMsg; + RssiIndUlMsg_t rssiIndUlMsg; + SerialNumberIndUlMsg_t serialNumberIndUlMsg; + SerialNumberGetCnfUlMsg_t serialNumberCnfUlMsg; + ReadingIntervalSetCnfUlMsg_t readingIntervalSetCnfUlMsg; + ReadingIntervalGetCnfUlMsg_t readingIntervalGetCnfUlMsg; + uint32_t gpioSetCnfUlMsg; // These are left packed inside a uint32_t so that + uint32_t gpioGetCnfUlMsg; // they can be passed to C# without a struct. + LedSetCnfUlMsg_t ledSetCnfUlMsg; + LedGetCnfUlMsg_t ledGetCnfUlMsg; + FlashSetCnfUlMsg_t flashSetCnfUlMsg; + FlashGetCnfUlMsg_t flashGetCnfUlMsg; +} UlMsgUnion_t; + +#endif + +// End Of File