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.
IotMeterApi.hpp
- Committer:
- RobMeades
- Date:
- 2015-05-22
- Revision:
- 0:5c46cb3be899
File content as of revision 0:5c46cb3be899:
/* C027N/water-meter interface definition 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_API_HPP #define IOT_METER_API_HPP /** * @file iot_meter_api.h * This file defines the API to the C027N/water-meter device * for the MWC demo 2015. */ #include <IotMeterMsgs.hpp> // ---------------------------------------------------------------- // HARDWARE // The code in this library is setup to expect a Water Pump Relay, // a Crydom D2425, to be connected through this circuit: // // C027N board D2425 (Water Pump Relay) // // 5V o------------o // | // | | // | | 180 Ohm // | | // | // o--------------o '+3' pin // 10k Ohm | // ___ / // D7 o--|___|--| (transistor) // _\/ // | // | // | // Gnd o-----------o--------------o '4' pin // // ---------------------------------------------------------------- // ---------------------------------------------------------------- // GENERAL COMPILE-TIME CONSTANTS // ---------------------------------------------------------------- /// The maximum length of a raw datagram in bytes #define MAX_DATAGRAM_SIZE_RAW 20 // The GPIO that the water pump is connected to on the C027N board #define GPIO_WATER_PUMP 7 // ---------------------------------------------------------------- // CLASSES // ---------------------------------------------------------------- class MessageCodec { public: // ---------------------------------------------------------------- // MESSAGE ENCODING FUNCTIONS // ---------------------------------------------------------------- /// Encode an uplink message that is 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 indicated rate. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeInitIndUlMsg (char * pBuffer, InitIndUlMsg_t * pMsg); /// Encode a downlink message that reboots the device. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeRebootReqDlMsg (char * pBuffer, RebootReqDlMsg_t *pMsg); /// Encode an uplink message containing the current meter reading. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeVolumeIndUlMsg (char * pBuffer, VolumeIndUlMsg_t * pMsg); /// Encode an uplink message containing the current RSSI reading. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeRssiIndUlMsg (char * pBuffer, RssiIndUlMsg_t * pMsg); /// Encode a downlink message that sets the reading interval // of the water meter. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \return The number of bytes encoded. uint32_t encodeSerialNumberGetReqDlMsg (char * pBuffer); /// Encode an uplink message that is sent as a response to a // SerialNumberGetReqDlMsg. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeSerialNumberGetCnfUlMsg (char * pBuffer, SerialNumberGetCnfUlMsg_t * pMsg); /// Encode an uplink message that is sent at power-on of the // device and in response to an InitReqDlMsg. Indicates the // serial number of the device. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeSerialNumberIndUlMsg (char * pBuffer, SerialNumberIndUlMsg_t * pMsg); /// Encode a downlink message that retrieves the reading interval. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeReadingIntervalGetReqDlMsg (char * pBuffer); /// Encode an uplink message that is sent as a response to a // ReadingIntervalGetReqDlMsg. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeReadingIntervalGetCnfUlMsg (char * pBuffer, ReadingIntervalGetCnfUlMsg_t * pMsg); /// Encode a downlink message that sets the reading interval. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \return The number of bytes encoded. uint32_t encodeReadingIntervalSetReqDlMsg (char * pBuffer, ReadingIntervalSetReqDlMsg_t * pMsg); /// Encode an uplink message that is sent as a response to a // ReadingIntervalSetReqDlMsg. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeReadingIntervalSetCnfUlMsg (char * pBuffer, ReadingIntervalSetCnfUlMsg_t * pMsg); /// Encode a downlink message that gets the state of a GPIO // on the C027N board. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \return The number of bytes encoded. uint32_t encodeGpioGetReqDlMsg (char * pBuffer, GpioGetReqDlMsg_t *pMsg); /// Encode an uplink message that is sent as a response to a // GpioGetReqDlMsg. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeGpioGetCnfUlMsg (char * pBuffer, GpioGetCnfUlMsg_t * pMsg); /// Encode a downlink message that sets the state of a GPIO // on the C027N board. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeGpioSetReqDlMsg (char * pBuffer, GpioSetReqDlMsg_t * pMsg); /// Encode an uplink message that is sent as a response to a // GpioSetReqDlMsg. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeGpioSetCnfUlMsg (char * pBuffer, GpioSetCnfUlMsg_t * pMsg); /// Encode a downlink message that gets the steady state of the // red LED on the C027N board. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \return The number of bytes encoded. uint32_t encodeLedGetReqDlMsg (char * pBuffer); /// Encode an uplink message that is sent as a response to an // LedGetReqDlMsg. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeLedGetCnfUlMsg (char * pBuffer, LedGetCnfUlMsg_t * pMsg); /// Encode a downlink message that sets the steady state of // the red LED. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeLedSetReqDlMsg (char * pBuffer, LedSetReqDlMsg_t * pMsg); /// Encode an uplink message that is sent as a response to an // LedSetReqDlMsg. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeLedSetCnfUlMsg (char * pBuffer, LedSetCnfUlMsg_t * pMsg); /// Encode a downlink message that sets the red LED to flash when // a message is being sent/received (or not). If LedSetReqDlMsg // has set the LED to ON the flash will be 'inverted', i.e. the // red LED will blink off when a message is being transmitted // or received instead. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeFlashSetReqDlMsg (char * pBuffer, FlashSetReqDlMsg_t * pMsg); /// Encode an uplink message that is sent as a response to a // FlashSetReqDlMsg. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeFlashSetCnfUlMsg (char * pBuffer, FlashSetCnfUlMsg_t * pMsg); /// Encode a downlink message that gets the red LED to flash when // a message is being sent/received (or not). If LedSetReqDlMsg // has set the LED to ON the flash will be 'inverted', i.e. the // red LED will blink off when a message is being transmitted // or received instead. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeFlashGetReqDlMsg (char * pBuffer); /// Encode an uplink message that is sent as a response to a // FlashGetReqDlMsg. // \param pBuffer A pointer to the buffer to encode into. The // buffer length must be at least MAX_MESSAGE_SIZE long // \param pMsg A pointer to the message to send. // \return The number of bytes encoded. uint32_t encodeFlashGetCnfUlMsg (char * pBuffer, FlashGetCnfUlMsg_t * pMsg); // ---------------------------------------------------------------- // MESSAGE DECODING FUNCTIONS // ---------------------------------------------------------------- /// The outcome of message decoding. // // !!! When you add anything to the generic of UL sections // here (but not the DL bits as C# never decodes a DL thing), // align it with the DLL exported version in the dll wrapper files // so that the C# application can decode it. typedef enum DecodeResultTag_t { DECODE_RESULT_FAILURE = 0, //!< Generic failed decode. DECODE_RESULT_INPUT_TOO_SHORT, //!< Not enough input bytes. DECODE_RESULT_OUTPUT_TOO_SHORT, //!< Not enough room in the //! output. DECODE_RESULT_UNKNOWN_MSG_ID, //!< Rogue message ID. DECODE_RESULT_DL_MSG_BASE = 0x40, //!< From here on are the //! downlink messages. // !!! If you add one here // update the next line !!! DECODE_RESULT_REBOOT_REQ_DL_MSG = DECODE_RESULT_DL_MSG_BASE, DECODE_RESULT_SERIAL_NUMBER_GET_REQ_DL_MSG, DECODE_RESULT_READING_INTERVAL_SET_REQ_DL_MSG, DECODE_RESULT_READING_INTERVAL_GET_REQ_DL_MSG, DECODE_RESULT_GPIO_SET_REQ_DL_MSG, DECODE_RESULT_GPIO_GET_REQ_DL_MSG, DECODE_RESULT_LED_SET_REQ_DL_MSG, DECODE_RESULT_LED_GET_REQ_DL_MSG, DECODE_RESULT_FLASH_SET_REQ_DL_MSG, DECODE_RESULT_FLASH_GET_REQ_DL_MSG, // !!! If you add one here // update the next line !!! MAX_DL_REQ_MSG = DECODE_RESULT_FLASH_GET_REQ_DL_MSG, DECODE_RESULT_UL_MSG_BASE = 0x80, //!< From here on are the //! uplink messages. DECODE_RESULT_INIT_IND_UL_MSG = DECODE_RESULT_UL_MSG_BASE, DECODE_RESULT_SERIAL_NUMBER_IND_UL_MSG, DECODE_RESULT_SERIAL_NUMBER_GET_CNF_UL_MSG, DECODE_RESULT_VOLUME_IND_UL_MSG, DECODE_RESULT_RSSI_IND_UL_MSG, DECODE_RESULT_READING_INTERVAL_SET_CNF_UL_MSG, DECODE_RESULT_READING_INTERVAL_GET_CNF_UL_MSG, DECODE_RESULT_GPIO_SET_CNF_UL_MSG, DECODE_RESULT_GPIO_GET_CNF_UL_MSG, DECODE_RESULT_LED_SET_CNF_UL_MSG, DECODE_RESULT_LED_GET_CNF_UL_MSG, DECODE_RESULT_FLASH_SET_CNF_UL_MSG, DECODE_RESULT_FLASH_GET_CNF_UL_MSG, // !!! If you add one here update // the next line !!! MAX_UL_REQ_MSG = DECODE_RESULT_FLASH_GET_CNF_UL_MSG, MAX_NUM_DECODE_RESULTS //!< The maximum number of //! decode results. } DecodeResult_t; /// Decode a downlink message. When a datagram has been received // this function should be called iteratively to decode all the // messages contained within it. The result, in pOutputBuffer, // should be cast by the calling function to DlMsgUnion_t and // the relevant member selected according to the // DecodeResult_t code. // \param ppInBuffer A pointer to the pointer to decode from. // On completion this is pointing to the next byte that // could be decoded, after the currently decoded message, // in the buffer. // \param sizeInBuffer The number of bytes left to decode. // \param pOutBuffer A pointer to the buffer to write the // result into. // \param pBytesDecoded A pointer to a place to write the number // of bytes decoded. // \return The result of the decoding, which hopefully says // what message has been decoded. DecodeResult_t decodeDlMsg (const char ** ppInBuffer, uint32_t sizeInBuffer, DlMsgUnion_t * pOutBuffer); /// Decode an uplink message. When a datagram has been received // this function should be called iteratively to decode all the // messages contained within it. The result, in pOutputBuffer, // should be cast by the calling function to UlMsgUnion_t and // the relevant member selected according to the // DecodeResult_t code. // \param ppInBuffer A pointer to the pointer to decode from. // On completion this is pointing to the next byte that // could be decoded, after the currently decoded message, // in the buffer. // \param sizeInBuffer The number of bytes left to decode. // \param pOutBuffer A pointer to the buffer to write the // result into. // \return The result of the decoding, which hopefully says // what message has been decoded. DecodeResult_t decodeUlMsg (const char ** ppInBuffer, uint32_t sizeInBuffer, UlMsgUnion_t * pOutBuffer); // ---------------------------------------------------------------- // MISC FUNCTIONS // ---------------------------------------------------------------- /// Only used in the DLL form, sets up the "printf()" function // for logging. // \param guiPrintToConsole the printf function. void initDll (void (*guiPrintToConsole) (const char *)); /// User callback function for "printf()" logging. static void (*mp_guiPrintToConsole) (const char *); private: /// Encode a boolean value. // \param pBuffer A pointer to where the encoded // value should be placed. // \param value The Boolean value. // \return The number of bytes encoded. uint32_t encodeBool (char * pBuffer, bool value); /// Decode a Boolean value. // \param ppBuffer A pointer to the pointer to decode. // On completion this points to the location after the // bool in the input buffer. // \return The decoded value. bool decodeBool (const char ** ppBuffer); /// Encode a uint32_t value. // \param pBuffer A pointer to the value to decode. // \param value The value. // \return The number of bytes encoded. uint32_t encodeUint32 (char * pBuffer, uint32_t value); /// Decode a uint32_t value. // \param ppBuffer A pointer to the pointer to decode. // On completion this points to the location after the // uint32 in the input buffer. uint32_t decodeUint32 (const char ** ppBuffer); /// Encode GpioState. // \param pBuffer A pointer to the value to decode. // \param gGpioState A pointer to the place to put the // GPIO Sate. // \return The number of bytes encoded. uint32_t encodeGpioState (char * pBuffer, GpioState_t *pGpioState); /// Decode Gpio_State_t. // \param gGpioState_t a pointer to a place to put the // decoded GPIO state. // \param ppBuffer A pointer to the pointer to decode. // On completion this points to the location after the // uint32 in the input buffer. void decodeGpioState (GpioState_t * pGpioState, const char ** ppBuffer); /// Log a message for debugging, "printf()" style. // \param pFormat The printf() stle parameters. void logMsg (const char * pFormat, ...); }; #endif // End Of File