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: IotMeterDllWrapper.cpp.txt
- Revision:
- 0:5c46cb3be899
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/IotMeterDllWrapper.cpp.txt Fri May 22 11:41:38 2015 +0000 @@ -0,0 +1,234 @@ +/* DLL wrapper for C027N/water-meter message handling functions + * for MWC demo 2015 + * + * 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. + */ + +/** + * @file iot_meter_dll_wrapper.cpp + * This file implements the encapsulation necessary to + * call the CPP Message Handling functions from C#. + */ +#include <stdint.h> +#include <IotMeterApi.hpp> +#include <IotMeterDllWrapper.hpp> +#include "windows.h" + +#ifdef __cplusplus +extern "C" { +#endif + + // Instantiate a messageHandler + MessageCodec gMessageCodec; + + // ---------------------------------------------------------------- + // CONSTANTS + // ---------------------------------------------------------------- + + uint32_t __cdecl maxDatagramSizeRaw (void) + { + return MAX_DATAGRAM_SIZE_RAW; + } + + uint32_t __cdecl gpioWaterPump (void) + { + return GPIO_WATER_PUMP; + } + + // ---------------------------------------------------------------- + // PRIVATE FUNCTIONS + // ---------------------------------------------------------------- + + // ---------------------------------------------------------------- + // MESSAGE ENCODE WRAPPER FUNCTIONS + // ---------------------------------------------------------------- + + // Wrap encodeRebootReqDlMsg + uint32_t __cdecl encodeRebootReqDlMsg (char * pBuffer, + bool devModeOnNotOff) + { + RebootReqDlMsg_t msg; + msg.devModeOnNotOff = devModeOnNotOff; + + return gMessageCodec.encodeRebootReqDlMsg (pBuffer, &msg); + } + + // Wrap encodeSerialNumberGetReqDlMsg + uint32_t __cdecl encodeSerialNumberGetReqDlMsg (char * pBuffer) + { + return gMessageCodec.encodeSerialNumberGetReqDlMsg (pBuffer); + } + + // Wrap encodeReadingIntervalSetReqDlMsg + uint32_t __cdecl encodeReadingIntervalSetReqDlMsg (char * pBuffer, + uint32_t readingIntervalSeconds) + { + ReadingIntervalSetReqDlMsg_t msg; + msg.readingIntervalSeconds = readingIntervalSeconds; + + return gMessageCodec.encodeReadingIntervalSetReqDlMsg (pBuffer, &msg); + } + + // Wrap encodeReadingIntervalGetReqDlMsg + uint32_t __cdecl encodeReadingIntervalGetReqDlMsg (char * pBuffer) + { + return gMessageCodec.encodeReadingIntervalGetReqDlMsg (pBuffer); + } + + // Wrap encodeGpioSetReqDlMsg + uint32_t __cdecl encodeGpioSetReqDlMsg (char * pBuffer, + uint8_t gpio, + bool inputNotOutput, + bool onNotOff) + { + GpioSetReqDlMsg_t msg; + msg.gpioState.gpio = gpio; + msg.gpioState.inputNotOutput = inputNotOutput; + msg.gpioState.onNotOff = onNotOff; + + return gMessageCodec.encodeGpioSetReqDlMsg (pBuffer, &msg); + } + + // Wrap encodeGpioGetReqDlMsg + uint32_t __cdecl encodeGpioGetReqDlMsg (char * pBuffer, + uint32_t gpio) + { + GpioGetReqDlMsg_t msg; + msg.gpio = (uint8_t) gpio; + + return gMessageCodec.encodeGpioGetReqDlMsg (pBuffer, &msg); + } + + // Wrap encodeLedSetReqDlMsg + uint32_t __cdecl encodeLedSetReqDlMsg (char * pBuffer, + bool onNotOff) + { + LedSetReqDlMsg_t msg; + msg.onNotOff = onNotOff; + + return gMessageCodec.encodeLedSetReqDlMsg (pBuffer, &msg); + } + + // Wrap encodeLedGetReqDlMsg + uint32_t __cdecl encodeLedGetReqDlMsg (char * pBuffer) + { + return gMessageCodec.encodeLedGetReqDlMsg (pBuffer); + } + + // Wrap encodeFlashSetReqDlMsg + uint32_t __cdecl encodeFlashSetReqDlMsg (char * pBuffer, + bool onNotOff) + { + FlashSetReqDlMsg_t msg; + msg.onNotOff = onNotOff; + + return gMessageCodec.encodeFlashSetReqDlMsg (pBuffer, &msg); + } + + // Wrap encodeFlashGetReqDlMsg + uint32_t __cdecl encodeFlashGetReqDlMsg (char * pBuffer) + { + return gMessageCodec.encodeFlashGetReqDlMsg (pBuffer); + } + + // ---------------------------------------------------------------- + // MESSAGE DECODE WRAPPER FUNCTIONS + // ---------------------------------------------------------------- + + // Unpack a gpioState struct from with a uint32_t value + void __cdecl unpackGpioState (uint32_t value, + uint32_t *pGpio, + bool * pInputNotOutput, + bool * pOnNotOff) + { + *pGpio = (uint32_t) ((value & 0x00FF0000) >> 16); + if (pInputNotOutput != NULL) + { + *pInputNotOutput = (bool) ((value & 0x0000FF00) >> 8); + } + if (pOnNotOff != NULL) + { + *pOnNotOff = (bool) (value & 0x000000FF); + } + } + + // Wrap decodeUlMsg + uint32_t __cdecl decodeUlMsg (const char ** ppInBuffer, + uint32_t sizeInBuffer, + uint32_t * pContents) + { + MessageCodec::DecodeResult_t decodeResult; + UlMsgUnion_t outBuffer; + decodeResult = gMessageCodec.decodeUlMsg (ppInBuffer, + sizeInBuffer, + &outBuffer); + switch (decodeResult) + { + case (MessageCodec::DECODE_RESULT_INIT_IND_UL_MSG): + *pContents = (uint32_t) outBuffer.initIndUlMsg.wakeUpCode; + break; + case (MessageCodec::DECODE_RESULT_SERIAL_NUMBER_GET_CNF_UL_MSG): + *pContents = outBuffer.serialNumberCnfUlMsg.serialNumber; + break; + case (MessageCodec::DECODE_RESULT_SERIAL_NUMBER_IND_UL_MSG): + *pContents = outBuffer.serialNumberIndUlMsg.serialNumber; + break; + case (MessageCodec::DECODE_RESULT_VOLUME_IND_UL_MSG): + *pContents = outBuffer.volumeIndUlMsg.volumeLitres; + break; + case (MessageCodec::DECODE_RESULT_RSSI_IND_UL_MSG): + *pContents = outBuffer.rssiIndUlMsg.rssi; + break; + case (MessageCodec::DECODE_RESULT_READING_INTERVAL_SET_CNF_UL_MSG): + *pContents = outBuffer.readingIntervalSetCnfUlMsg.readingIntervalSeconds; + break; + case (MessageCodec::DECODE_RESULT_READING_INTERVAL_GET_CNF_UL_MSG): + *pContents = outBuffer.readingIntervalGetCnfUlMsg.readingIntervalSeconds; + break; + case (MessageCodec::DECODE_RESULT_GPIO_SET_CNF_UL_MSG): + *pContents = (uint32_t) outBuffer.gpioSetCnfUlMsg; + break; + case (MessageCodec::DECODE_RESULT_GPIO_GET_CNF_UL_MSG): + *pContents = (uint32_t) outBuffer.gpioGetCnfUlMsg; + break; + case (MessageCodec::DECODE_RESULT_LED_SET_CNF_UL_MSG): + *pContents = (uint32_t) outBuffer.ledSetCnfUlMsg.onNotOff; + break; + case (MessageCodec::DECODE_RESULT_LED_GET_CNF_UL_MSG): + *pContents = (uint32_t) outBuffer.ledGetCnfUlMsg.onNotOff; + break; + case (MessageCodec::DECODE_RESULT_FLASH_SET_CNF_UL_MSG): + *pContents = (uint32_t) outBuffer.flashSetCnfUlMsg.onNotOff; + break; + case (MessageCodec::DECODE_RESULT_FLASH_GET_CNF_UL_MSG): + *pContents = (uint32_t) outBuffer.flashGetCnfUlMsg.onNotOff; + break; + default: + // The decodeResult will be left as Unknown message + break; + } + + return decodeResult; + } + + // ---------------------------------------------------------------- + // MISC FUNCTIONS + // ---------------------------------------------------------------- + + void initDll (void (*printToConsole) (const char *)) + { + gMessageCodec.initDll (printToConsole); + } + +#ifdef __cplusplus +} // extern "C" +#endif + +// End Of File