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.
IotMeterDllWrapper.cpp.txt@0:5c46cb3be899, 2015-05-22 (annotated)
- Committer:
- RobMeades
- Date:
- Fri May 22 11:41:38 2015 +0000
- Revision:
- 0:5c46cb3be899
Initial commit of CIoT message protocol, used for water meter demo demonstrations, to mbed cloud.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
RobMeades | 0:5c46cb3be899 | 1 | /* DLL wrapper for C027N/water-meter message handling functions |
RobMeades | 0:5c46cb3be899 | 2 | * for MWC demo 2015 |
RobMeades | 0:5c46cb3be899 | 3 | * |
RobMeades | 0:5c46cb3be899 | 4 | * Copyright (C) u-blox Melbourn Ltd |
RobMeades | 0:5c46cb3be899 | 5 | * u-blox Melbourn Ltd, Melbourn, UK |
RobMeades | 0:5c46cb3be899 | 6 | * |
RobMeades | 0:5c46cb3be899 | 7 | * All rights reserved. |
RobMeades | 0:5c46cb3be899 | 8 | * |
RobMeades | 0:5c46cb3be899 | 9 | * This source file is the sole property of u-blox Melbourn Ltd. |
RobMeades | 0:5c46cb3be899 | 10 | * Reproduction or utilization of this source in whole or part is |
RobMeades | 0:5c46cb3be899 | 11 | * forbidden without the written consent of u-blox Melbourn Ltd. |
RobMeades | 0:5c46cb3be899 | 12 | */ |
RobMeades | 0:5c46cb3be899 | 13 | |
RobMeades | 0:5c46cb3be899 | 14 | /** |
RobMeades | 0:5c46cb3be899 | 15 | * @file iot_meter_dll_wrapper.cpp |
RobMeades | 0:5c46cb3be899 | 16 | * This file implements the encapsulation necessary to |
RobMeades | 0:5c46cb3be899 | 17 | * call the CPP Message Handling functions from C#. |
RobMeades | 0:5c46cb3be899 | 18 | */ |
RobMeades | 0:5c46cb3be899 | 19 | #include <stdint.h> |
RobMeades | 0:5c46cb3be899 | 20 | #include <IotMeterApi.hpp> |
RobMeades | 0:5c46cb3be899 | 21 | #include <IotMeterDllWrapper.hpp> |
RobMeades | 0:5c46cb3be899 | 22 | #include "windows.h" |
RobMeades | 0:5c46cb3be899 | 23 | |
RobMeades | 0:5c46cb3be899 | 24 | #ifdef __cplusplus |
RobMeades | 0:5c46cb3be899 | 25 | extern "C" { |
RobMeades | 0:5c46cb3be899 | 26 | #endif |
RobMeades | 0:5c46cb3be899 | 27 | |
RobMeades | 0:5c46cb3be899 | 28 | // Instantiate a messageHandler |
RobMeades | 0:5c46cb3be899 | 29 | MessageCodec gMessageCodec; |
RobMeades | 0:5c46cb3be899 | 30 | |
RobMeades | 0:5c46cb3be899 | 31 | // ---------------------------------------------------------------- |
RobMeades | 0:5c46cb3be899 | 32 | // CONSTANTS |
RobMeades | 0:5c46cb3be899 | 33 | // ---------------------------------------------------------------- |
RobMeades | 0:5c46cb3be899 | 34 | |
RobMeades | 0:5c46cb3be899 | 35 | uint32_t __cdecl maxDatagramSizeRaw (void) |
RobMeades | 0:5c46cb3be899 | 36 | { |
RobMeades | 0:5c46cb3be899 | 37 | return MAX_DATAGRAM_SIZE_RAW; |
RobMeades | 0:5c46cb3be899 | 38 | } |
RobMeades | 0:5c46cb3be899 | 39 | |
RobMeades | 0:5c46cb3be899 | 40 | uint32_t __cdecl gpioWaterPump (void) |
RobMeades | 0:5c46cb3be899 | 41 | { |
RobMeades | 0:5c46cb3be899 | 42 | return GPIO_WATER_PUMP; |
RobMeades | 0:5c46cb3be899 | 43 | } |
RobMeades | 0:5c46cb3be899 | 44 | |
RobMeades | 0:5c46cb3be899 | 45 | // ---------------------------------------------------------------- |
RobMeades | 0:5c46cb3be899 | 46 | // PRIVATE FUNCTIONS |
RobMeades | 0:5c46cb3be899 | 47 | // ---------------------------------------------------------------- |
RobMeades | 0:5c46cb3be899 | 48 | |
RobMeades | 0:5c46cb3be899 | 49 | // ---------------------------------------------------------------- |
RobMeades | 0:5c46cb3be899 | 50 | // MESSAGE ENCODE WRAPPER FUNCTIONS |
RobMeades | 0:5c46cb3be899 | 51 | // ---------------------------------------------------------------- |
RobMeades | 0:5c46cb3be899 | 52 | |
RobMeades | 0:5c46cb3be899 | 53 | // Wrap encodeRebootReqDlMsg |
RobMeades | 0:5c46cb3be899 | 54 | uint32_t __cdecl encodeRebootReqDlMsg (char * pBuffer, |
RobMeades | 0:5c46cb3be899 | 55 | bool devModeOnNotOff) |
RobMeades | 0:5c46cb3be899 | 56 | { |
RobMeades | 0:5c46cb3be899 | 57 | RebootReqDlMsg_t msg; |
RobMeades | 0:5c46cb3be899 | 58 | msg.devModeOnNotOff = devModeOnNotOff; |
RobMeades | 0:5c46cb3be899 | 59 | |
RobMeades | 0:5c46cb3be899 | 60 | return gMessageCodec.encodeRebootReqDlMsg (pBuffer, &msg); |
RobMeades | 0:5c46cb3be899 | 61 | } |
RobMeades | 0:5c46cb3be899 | 62 | |
RobMeades | 0:5c46cb3be899 | 63 | // Wrap encodeSerialNumberGetReqDlMsg |
RobMeades | 0:5c46cb3be899 | 64 | uint32_t __cdecl encodeSerialNumberGetReqDlMsg (char * pBuffer) |
RobMeades | 0:5c46cb3be899 | 65 | { |
RobMeades | 0:5c46cb3be899 | 66 | return gMessageCodec.encodeSerialNumberGetReqDlMsg (pBuffer); |
RobMeades | 0:5c46cb3be899 | 67 | } |
RobMeades | 0:5c46cb3be899 | 68 | |
RobMeades | 0:5c46cb3be899 | 69 | // Wrap encodeReadingIntervalSetReqDlMsg |
RobMeades | 0:5c46cb3be899 | 70 | uint32_t __cdecl encodeReadingIntervalSetReqDlMsg (char * pBuffer, |
RobMeades | 0:5c46cb3be899 | 71 | uint32_t readingIntervalSeconds) |
RobMeades | 0:5c46cb3be899 | 72 | { |
RobMeades | 0:5c46cb3be899 | 73 | ReadingIntervalSetReqDlMsg_t msg; |
RobMeades | 0:5c46cb3be899 | 74 | msg.readingIntervalSeconds = readingIntervalSeconds; |
RobMeades | 0:5c46cb3be899 | 75 | |
RobMeades | 0:5c46cb3be899 | 76 | return gMessageCodec.encodeReadingIntervalSetReqDlMsg (pBuffer, &msg); |
RobMeades | 0:5c46cb3be899 | 77 | } |
RobMeades | 0:5c46cb3be899 | 78 | |
RobMeades | 0:5c46cb3be899 | 79 | // Wrap encodeReadingIntervalGetReqDlMsg |
RobMeades | 0:5c46cb3be899 | 80 | uint32_t __cdecl encodeReadingIntervalGetReqDlMsg (char * pBuffer) |
RobMeades | 0:5c46cb3be899 | 81 | { |
RobMeades | 0:5c46cb3be899 | 82 | return gMessageCodec.encodeReadingIntervalGetReqDlMsg (pBuffer); |
RobMeades | 0:5c46cb3be899 | 83 | } |
RobMeades | 0:5c46cb3be899 | 84 | |
RobMeades | 0:5c46cb3be899 | 85 | // Wrap encodeGpioSetReqDlMsg |
RobMeades | 0:5c46cb3be899 | 86 | uint32_t __cdecl encodeGpioSetReqDlMsg (char * pBuffer, |
RobMeades | 0:5c46cb3be899 | 87 | uint8_t gpio, |
RobMeades | 0:5c46cb3be899 | 88 | bool inputNotOutput, |
RobMeades | 0:5c46cb3be899 | 89 | bool onNotOff) |
RobMeades | 0:5c46cb3be899 | 90 | { |
RobMeades | 0:5c46cb3be899 | 91 | GpioSetReqDlMsg_t msg; |
RobMeades | 0:5c46cb3be899 | 92 | msg.gpioState.gpio = gpio; |
RobMeades | 0:5c46cb3be899 | 93 | msg.gpioState.inputNotOutput = inputNotOutput; |
RobMeades | 0:5c46cb3be899 | 94 | msg.gpioState.onNotOff = onNotOff; |
RobMeades | 0:5c46cb3be899 | 95 | |
RobMeades | 0:5c46cb3be899 | 96 | return gMessageCodec.encodeGpioSetReqDlMsg (pBuffer, &msg); |
RobMeades | 0:5c46cb3be899 | 97 | } |
RobMeades | 0:5c46cb3be899 | 98 | |
RobMeades | 0:5c46cb3be899 | 99 | // Wrap encodeGpioGetReqDlMsg |
RobMeades | 0:5c46cb3be899 | 100 | uint32_t __cdecl encodeGpioGetReqDlMsg (char * pBuffer, |
RobMeades | 0:5c46cb3be899 | 101 | uint32_t gpio) |
RobMeades | 0:5c46cb3be899 | 102 | { |
RobMeades | 0:5c46cb3be899 | 103 | GpioGetReqDlMsg_t msg; |
RobMeades | 0:5c46cb3be899 | 104 | msg.gpio = (uint8_t) gpio; |
RobMeades | 0:5c46cb3be899 | 105 | |
RobMeades | 0:5c46cb3be899 | 106 | return gMessageCodec.encodeGpioGetReqDlMsg (pBuffer, &msg); |
RobMeades | 0:5c46cb3be899 | 107 | } |
RobMeades | 0:5c46cb3be899 | 108 | |
RobMeades | 0:5c46cb3be899 | 109 | // Wrap encodeLedSetReqDlMsg |
RobMeades | 0:5c46cb3be899 | 110 | uint32_t __cdecl encodeLedSetReqDlMsg (char * pBuffer, |
RobMeades | 0:5c46cb3be899 | 111 | bool onNotOff) |
RobMeades | 0:5c46cb3be899 | 112 | { |
RobMeades | 0:5c46cb3be899 | 113 | LedSetReqDlMsg_t msg; |
RobMeades | 0:5c46cb3be899 | 114 | msg.onNotOff = onNotOff; |
RobMeades | 0:5c46cb3be899 | 115 | |
RobMeades | 0:5c46cb3be899 | 116 | return gMessageCodec.encodeLedSetReqDlMsg (pBuffer, &msg); |
RobMeades | 0:5c46cb3be899 | 117 | } |
RobMeades | 0:5c46cb3be899 | 118 | |
RobMeades | 0:5c46cb3be899 | 119 | // Wrap encodeLedGetReqDlMsg |
RobMeades | 0:5c46cb3be899 | 120 | uint32_t __cdecl encodeLedGetReqDlMsg (char * pBuffer) |
RobMeades | 0:5c46cb3be899 | 121 | { |
RobMeades | 0:5c46cb3be899 | 122 | return gMessageCodec.encodeLedGetReqDlMsg (pBuffer); |
RobMeades | 0:5c46cb3be899 | 123 | } |
RobMeades | 0:5c46cb3be899 | 124 | |
RobMeades | 0:5c46cb3be899 | 125 | // Wrap encodeFlashSetReqDlMsg |
RobMeades | 0:5c46cb3be899 | 126 | uint32_t __cdecl encodeFlashSetReqDlMsg (char * pBuffer, |
RobMeades | 0:5c46cb3be899 | 127 | bool onNotOff) |
RobMeades | 0:5c46cb3be899 | 128 | { |
RobMeades | 0:5c46cb3be899 | 129 | FlashSetReqDlMsg_t msg; |
RobMeades | 0:5c46cb3be899 | 130 | msg.onNotOff = onNotOff; |
RobMeades | 0:5c46cb3be899 | 131 | |
RobMeades | 0:5c46cb3be899 | 132 | return gMessageCodec.encodeFlashSetReqDlMsg (pBuffer, &msg); |
RobMeades | 0:5c46cb3be899 | 133 | } |
RobMeades | 0:5c46cb3be899 | 134 | |
RobMeades | 0:5c46cb3be899 | 135 | // Wrap encodeFlashGetReqDlMsg |
RobMeades | 0:5c46cb3be899 | 136 | uint32_t __cdecl encodeFlashGetReqDlMsg (char * pBuffer) |
RobMeades | 0:5c46cb3be899 | 137 | { |
RobMeades | 0:5c46cb3be899 | 138 | return gMessageCodec.encodeFlashGetReqDlMsg (pBuffer); |
RobMeades | 0:5c46cb3be899 | 139 | } |
RobMeades | 0:5c46cb3be899 | 140 | |
RobMeades | 0:5c46cb3be899 | 141 | // ---------------------------------------------------------------- |
RobMeades | 0:5c46cb3be899 | 142 | // MESSAGE DECODE WRAPPER FUNCTIONS |
RobMeades | 0:5c46cb3be899 | 143 | // ---------------------------------------------------------------- |
RobMeades | 0:5c46cb3be899 | 144 | |
RobMeades | 0:5c46cb3be899 | 145 | // Unpack a gpioState struct from with a uint32_t value |
RobMeades | 0:5c46cb3be899 | 146 | void __cdecl unpackGpioState (uint32_t value, |
RobMeades | 0:5c46cb3be899 | 147 | uint32_t *pGpio, |
RobMeades | 0:5c46cb3be899 | 148 | bool * pInputNotOutput, |
RobMeades | 0:5c46cb3be899 | 149 | bool * pOnNotOff) |
RobMeades | 0:5c46cb3be899 | 150 | { |
RobMeades | 0:5c46cb3be899 | 151 | *pGpio = (uint32_t) ((value & 0x00FF0000) >> 16); |
RobMeades | 0:5c46cb3be899 | 152 | if (pInputNotOutput != NULL) |
RobMeades | 0:5c46cb3be899 | 153 | { |
RobMeades | 0:5c46cb3be899 | 154 | *pInputNotOutput = (bool) ((value & 0x0000FF00) >> 8); |
RobMeades | 0:5c46cb3be899 | 155 | } |
RobMeades | 0:5c46cb3be899 | 156 | if (pOnNotOff != NULL) |
RobMeades | 0:5c46cb3be899 | 157 | { |
RobMeades | 0:5c46cb3be899 | 158 | *pOnNotOff = (bool) (value & 0x000000FF); |
RobMeades | 0:5c46cb3be899 | 159 | } |
RobMeades | 0:5c46cb3be899 | 160 | } |
RobMeades | 0:5c46cb3be899 | 161 | |
RobMeades | 0:5c46cb3be899 | 162 | // Wrap decodeUlMsg |
RobMeades | 0:5c46cb3be899 | 163 | uint32_t __cdecl decodeUlMsg (const char ** ppInBuffer, |
RobMeades | 0:5c46cb3be899 | 164 | uint32_t sizeInBuffer, |
RobMeades | 0:5c46cb3be899 | 165 | uint32_t * pContents) |
RobMeades | 0:5c46cb3be899 | 166 | { |
RobMeades | 0:5c46cb3be899 | 167 | MessageCodec::DecodeResult_t decodeResult; |
RobMeades | 0:5c46cb3be899 | 168 | UlMsgUnion_t outBuffer; |
RobMeades | 0:5c46cb3be899 | 169 | decodeResult = gMessageCodec.decodeUlMsg (ppInBuffer, |
RobMeades | 0:5c46cb3be899 | 170 | sizeInBuffer, |
RobMeades | 0:5c46cb3be899 | 171 | &outBuffer); |
RobMeades | 0:5c46cb3be899 | 172 | switch (decodeResult) |
RobMeades | 0:5c46cb3be899 | 173 | { |
RobMeades | 0:5c46cb3be899 | 174 | case (MessageCodec::DECODE_RESULT_INIT_IND_UL_MSG): |
RobMeades | 0:5c46cb3be899 | 175 | *pContents = (uint32_t) outBuffer.initIndUlMsg.wakeUpCode; |
RobMeades | 0:5c46cb3be899 | 176 | break; |
RobMeades | 0:5c46cb3be899 | 177 | case (MessageCodec::DECODE_RESULT_SERIAL_NUMBER_GET_CNF_UL_MSG): |
RobMeades | 0:5c46cb3be899 | 178 | *pContents = outBuffer.serialNumberCnfUlMsg.serialNumber; |
RobMeades | 0:5c46cb3be899 | 179 | break; |
RobMeades | 0:5c46cb3be899 | 180 | case (MessageCodec::DECODE_RESULT_SERIAL_NUMBER_IND_UL_MSG): |
RobMeades | 0:5c46cb3be899 | 181 | *pContents = outBuffer.serialNumberIndUlMsg.serialNumber; |
RobMeades | 0:5c46cb3be899 | 182 | break; |
RobMeades | 0:5c46cb3be899 | 183 | case (MessageCodec::DECODE_RESULT_VOLUME_IND_UL_MSG): |
RobMeades | 0:5c46cb3be899 | 184 | *pContents = outBuffer.volumeIndUlMsg.volumeLitres; |
RobMeades | 0:5c46cb3be899 | 185 | break; |
RobMeades | 0:5c46cb3be899 | 186 | case (MessageCodec::DECODE_RESULT_RSSI_IND_UL_MSG): |
RobMeades | 0:5c46cb3be899 | 187 | *pContents = outBuffer.rssiIndUlMsg.rssi; |
RobMeades | 0:5c46cb3be899 | 188 | break; |
RobMeades | 0:5c46cb3be899 | 189 | case (MessageCodec::DECODE_RESULT_READING_INTERVAL_SET_CNF_UL_MSG): |
RobMeades | 0:5c46cb3be899 | 190 | *pContents = outBuffer.readingIntervalSetCnfUlMsg.readingIntervalSeconds; |
RobMeades | 0:5c46cb3be899 | 191 | break; |
RobMeades | 0:5c46cb3be899 | 192 | case (MessageCodec::DECODE_RESULT_READING_INTERVAL_GET_CNF_UL_MSG): |
RobMeades | 0:5c46cb3be899 | 193 | *pContents = outBuffer.readingIntervalGetCnfUlMsg.readingIntervalSeconds; |
RobMeades | 0:5c46cb3be899 | 194 | break; |
RobMeades | 0:5c46cb3be899 | 195 | case (MessageCodec::DECODE_RESULT_GPIO_SET_CNF_UL_MSG): |
RobMeades | 0:5c46cb3be899 | 196 | *pContents = (uint32_t) outBuffer.gpioSetCnfUlMsg; |
RobMeades | 0:5c46cb3be899 | 197 | break; |
RobMeades | 0:5c46cb3be899 | 198 | case (MessageCodec::DECODE_RESULT_GPIO_GET_CNF_UL_MSG): |
RobMeades | 0:5c46cb3be899 | 199 | *pContents = (uint32_t) outBuffer.gpioGetCnfUlMsg; |
RobMeades | 0:5c46cb3be899 | 200 | break; |
RobMeades | 0:5c46cb3be899 | 201 | case (MessageCodec::DECODE_RESULT_LED_SET_CNF_UL_MSG): |
RobMeades | 0:5c46cb3be899 | 202 | *pContents = (uint32_t) outBuffer.ledSetCnfUlMsg.onNotOff; |
RobMeades | 0:5c46cb3be899 | 203 | break; |
RobMeades | 0:5c46cb3be899 | 204 | case (MessageCodec::DECODE_RESULT_LED_GET_CNF_UL_MSG): |
RobMeades | 0:5c46cb3be899 | 205 | *pContents = (uint32_t) outBuffer.ledGetCnfUlMsg.onNotOff; |
RobMeades | 0:5c46cb3be899 | 206 | break; |
RobMeades | 0:5c46cb3be899 | 207 | case (MessageCodec::DECODE_RESULT_FLASH_SET_CNF_UL_MSG): |
RobMeades | 0:5c46cb3be899 | 208 | *pContents = (uint32_t) outBuffer.flashSetCnfUlMsg.onNotOff; |
RobMeades | 0:5c46cb3be899 | 209 | break; |
RobMeades | 0:5c46cb3be899 | 210 | case (MessageCodec::DECODE_RESULT_FLASH_GET_CNF_UL_MSG): |
RobMeades | 0:5c46cb3be899 | 211 | *pContents = (uint32_t) outBuffer.flashGetCnfUlMsg.onNotOff; |
RobMeades | 0:5c46cb3be899 | 212 | break; |
RobMeades | 0:5c46cb3be899 | 213 | default: |
RobMeades | 0:5c46cb3be899 | 214 | // The decodeResult will be left as Unknown message |
RobMeades | 0:5c46cb3be899 | 215 | break; |
RobMeades | 0:5c46cb3be899 | 216 | } |
RobMeades | 0:5c46cb3be899 | 217 | |
RobMeades | 0:5c46cb3be899 | 218 | return decodeResult; |
RobMeades | 0:5c46cb3be899 | 219 | } |
RobMeades | 0:5c46cb3be899 | 220 | |
RobMeades | 0:5c46cb3be899 | 221 | // ---------------------------------------------------------------- |
RobMeades | 0:5c46cb3be899 | 222 | // MISC FUNCTIONS |
RobMeades | 0:5c46cb3be899 | 223 | // ---------------------------------------------------------------- |
RobMeades | 0:5c46cb3be899 | 224 | |
RobMeades | 0:5c46cb3be899 | 225 | void initDll (void (*printToConsole) (const char *)) |
RobMeades | 0:5c46cb3be899 | 226 | { |
RobMeades | 0:5c46cb3be899 | 227 | gMessageCodec.initDll (printToConsole); |
RobMeades | 0:5c46cb3be899 | 228 | } |
RobMeades | 0:5c46cb3be899 | 229 | |
RobMeades | 0:5c46cb3be899 | 230 | #ifdef __cplusplus |
RobMeades | 0:5c46cb3be899 | 231 | } // extern "C" |
RobMeades | 0:5c46cb3be899 | 232 | #endif |
RobMeades | 0:5c46cb3be899 | 233 | |
RobMeades | 0:5c46cb3be899 | 234 | // End Of File |