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.

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