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.

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?

UserRevisionLine numberNew contents of line
RobMeades 0:5c46cb3be899 1 using System;
RobMeades 0:5c46cb3be899 2 using System.Collections.Generic;
RobMeades 0:5c46cb3be899 3 using System.Linq;
RobMeades 0:5c46cb3be899 4 using System.Text;
RobMeades 0:5c46cb3be899 5 using System.Diagnostics;
RobMeades 0:5c46cb3be899 6 using System.Runtime.InteropServices;
RobMeades 0:5c46cb3be899 7 using Microsoft.Win32.SafeHandles;
RobMeades 0:5c46cb3be899 8 using System.Threading;
RobMeades 0:5c46cb3be899 9
RobMeades 0:5c46cb3be899 10 namespace MessageCodec
RobMeades 0:5c46cb3be899 11 {
RobMeades 0:5c46cb3be899 12 /// <summary>
RobMeades 0:5c46cb3be899 13 /// This is a wrapper around the native dll for MessageCodec calls
RobMeades 0:5c46cb3be899 14 /// </summary>
RobMeades 0:5c46cb3be899 15 public class MessageCodec_dll
RobMeades 0:5c46cb3be899 16 {
RobMeades 0:5c46cb3be899 17
RobMeades 0:5c46cb3be899 18 [DllImport ("Kernel32.dll")]
RobMeades 0:5c46cb3be899 19 extern static SafeFileHandle GetStdHandle(Int32 nStdHandle);
RobMeades 0:5c46cb3be899 20
RobMeades 0:5c46cb3be899 21 /// <summary>
RobMeades 0:5c46cb3be899 22 /// Windows specific calls to load a library at runtime
RobMeades 0:5c46cb3be899 23 /// </summary>
RobMeades 0:5c46cb3be899 24
RobMeades 0:5c46cb3be899 25 [DllImport ("kernel32.dll")]
RobMeades 0:5c46cb3be899 26 internal static extern IntPtr LoadLibrary(String dllname);
RobMeades 0:5c46cb3be899 27
RobMeades 0:5c46cb3be899 28 /// <summary>
RobMeades 0:5c46cb3be899 29 /// Windows specific call to get the address of a entry in a dll
RobMeades 0:5c46cb3be899 30 /// </summary>
RobMeades 0:5c46cb3be899 31
RobMeades 0:5c46cb3be899 32 [DllImport ("kernel32.dll")]
RobMeades 0:5c46cb3be899 33 internal static extern IntPtr GetProcAddress(IntPtr hModule, String procname);
RobMeades 0:5c46cb3be899 34
RobMeades 0:5c46cb3be899 35 /// The outcome of message decoding.
RobMeades 0:5c46cb3be899 36 // !!! ORDER IS IMPORTANT AND THIS MUST align with the generic
RobMeades 0:5c46cb3be899 37 // and UL (but not DL as the C# DLL is not intended to decode
RobMeades 0:5c46cb3be899 38 // a DL message) portions of the C typedef DecodeResult_t.
RobMeades 0:5c46cb3be899 39 public enum CSDecodeResult
RobMeades 0:5c46cb3be899 40 {
RobMeades 0:5c46cb3be899 41 DECODE_RESULT_FAILURE = 0, //!< Generic failed decode.
RobMeades 0:5c46cb3be899 42 DECODE_RESULT_INPUT_TOO_SHORT, //!< Not enough input bytes.
RobMeades 0:5c46cb3be899 43 DECODE_RESULT_OUTPUT_TOO_SHORT, //!< Not enough room in the
RobMeades 0:5c46cb3be899 44 //! output.
RobMeades 0:5c46cb3be899 45 DECODE_RESULT_UNKNOWN_MSG_ID, //!< Rogue message ID.
RobMeades 0:5c46cb3be899 46 DECODE_RESULT_UL_MSG_BASE = 0x80, //!< From here on are the
RobMeades 0:5c46cb3be899 47 //! uplink messages.
RobMeades 0:5c46cb3be899 48 DECODE_RESULT_INIT_IND_UL_MSG = DECODE_RESULT_UL_MSG_BASE,
RobMeades 0:5c46cb3be899 49 DECODE_RESULT_SERIAL_NUMBER_IND_UL_MSG,
RobMeades 0:5c46cb3be899 50 DECODE_RESULT_SERIAL_NUMBER_CNF_UL_MSG,
RobMeades 0:5c46cb3be899 51 DECODE_RESULT_VOLUME_IND_UL_MSG,
RobMeades 0:5c46cb3be899 52 DECODE_RESULT_RSSI_IND_UL_MSG,
RobMeades 0:5c46cb3be899 53 DECODE_RESULT_READING_INTERVAL_SET_CNF_UL_MSG,
RobMeades 0:5c46cb3be899 54 DECODE_RESULT_READING_INTERVAL_GET_CNF_UL_MSG,
RobMeades 0:5c46cb3be899 55 DECODE_RESULT_GPIO_SET_CNF_UL_MSG,
RobMeades 0:5c46cb3be899 56 DECODE_RESULT_GPIO_GET_CNF_UL_MSG,
RobMeades 0:5c46cb3be899 57 DECODE_RESULT_LED_SET_CNF_UL_MSG,
RobMeades 0:5c46cb3be899 58 DECODE_RESULT_LED_GET_CNF_UL_MSG,
RobMeades 0:5c46cb3be899 59 DECODE_RESULT_FLASH_SET_CNF_UL_MSG,
RobMeades 0:5c46cb3be899 60 DECODE_RESULT_FLASH_GET_CNF_UL_MSG, // !!! If you add one here update
RobMeades 0:5c46cb3be899 61 // the next line !!!
RobMeades 0:5c46cb3be899 62 MAX_UL_REQ_MSG = DECODE_RESULT_FLASH_GET_CNF_UL_MSG,
RobMeades 0:5c46cb3be899 63 MAX_NUM_DECODE_RESULTS //!< The maximum number of
RobMeades 0:5c46cb3be899 64 //! decode results.
RobMeades 0:5c46cb3be899 65 };
RobMeades 0:5c46cb3be899 66
RobMeades 0:5c46cb3be899 67 // uint32_t __cdecl maxDatagramSizeRaw (void);
RobMeades 0:5c46cb3be899 68 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 69 public unsafe delegate UInt32 _maxDatagramSizeRaw ();
RobMeades 0:5c46cb3be899 70 public _maxDatagramSizeRaw maxDatagramSizeRaw;
RobMeades 0:5c46cb3be899 71
RobMeades 0:5c46cb3be899 72 // uint32_t __cdecl gpioWaterPump (void);
RobMeades 0:5c46cb3be899 73 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 74 public unsafe delegate UInt32 _gpioWaterPump();
RobMeades 0:5c46cb3be899 75 public _gpioWaterPump gpioWaterPump;
RobMeades 0:5c46cb3be899 76
RobMeades 0:5c46cb3be899 77 // uint32_t __cdecl encodeRebootReqDlMsg (char * pBuffer,
RobMeades 0:5c46cb3be899 78 // bool devModeOnNotOff);
RobMeades 0:5c46cb3be899 79 [UnmanagedFunctionPointer (CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 80 public unsafe delegate UInt32 _encodeRebootReqDlMsg(byte* pBuffer,
RobMeades 0:5c46cb3be899 81 Boolean devModeOnNotOff);
RobMeades 0:5c46cb3be899 82 public _encodeRebootReqDlMsg encodeRebootReqDlMsg;
RobMeades 0:5c46cb3be899 83
RobMeades 0:5c46cb3be899 84 // uint32_t __cdecl encodeSerialNumberGetReqDlMsg (char * pBuffer);
RobMeades 0:5c46cb3be899 85 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 86 public unsafe delegate UInt32 _encodeSerialNumberGetReqDlMsg(byte* pBuffer);
RobMeades 0:5c46cb3be899 87 public _encodeSerialNumberGetReqDlMsg encodeSerialNumberGetReqDlMsg;
RobMeades 0:5c46cb3be899 88
RobMeades 0:5c46cb3be899 89 // uint32_t __cdecl encodeReadingIntervalSetReqDlMsg (char * pBuffer,
RobMeades 0:5c46cb3be899 90 // UInt32 readingIntervalSeconds);
RobMeades 0:5c46cb3be899 91 [UnmanagedFunctionPointer (CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 92 public unsafe delegate UInt32 _encodeReadingIntervalSetReqDlMsg(byte* pBuffer,
RobMeades 0:5c46cb3be899 93 UInt32 readingIntervalSeconds);
RobMeades 0:5c46cb3be899 94 public _encodeReadingIntervalSetReqDlMsg encodeReadingIntervalSetReqDlMsg;
RobMeades 0:5c46cb3be899 95
RobMeades 0:5c46cb3be899 96 // uint32_t __cdecl encodeReadingIntervalGetReqDlMsg (char * pBuffer);
RobMeades 0:5c46cb3be899 97 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 98 public unsafe delegate UInt32 _encodeReadingIntervalGetReqDlMsg(byte* pBuffer);
RobMeades 0:5c46cb3be899 99 public _encodeReadingIntervalGetReqDlMsg encodeReadingIntervalGetReqDlMsg;
RobMeades 0:5c46cb3be899 100
RobMeades 0:5c46cb3be899 101 // uint32_t __cdecl encodeGpioSetReqDlMsg (char * pBuffer,
RobMeades 0:5c46cb3be899 102 // uint8_t gpio,
RobMeades 0:5c46cb3be899 103 // bool inputNotOutput,
RobMeades 0:5c46cb3be899 104 // bool onNotOff);
RobMeades 0:5c46cb3be899 105 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 106 public unsafe delegate UInt32 _encodeGpioSetReqDlMsg(byte* pBuffer,
RobMeades 0:5c46cb3be899 107 UInt32 gpio,
RobMeades 0:5c46cb3be899 108 Boolean inputNotOutput,
RobMeades 0:5c46cb3be899 109 Boolean onNotOff);
RobMeades 0:5c46cb3be899 110 public _encodeGpioSetReqDlMsg encodeGpioSetReqDlMsg;
RobMeades 0:5c46cb3be899 111
RobMeades 0:5c46cb3be899 112 // uint32_t __cdecl encodeGpioGetReqDlMsg (char * pBuffer,
RobMeades 0:5c46cb3be899 113 // uint8_t gpio);
RobMeades 0:5c46cb3be899 114 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 115 public unsafe delegate UInt32 _encodeGpioGetReqDlMsg(byte* pBuffer,
RobMeades 0:5c46cb3be899 116 UInt32 gpio);
RobMeades 0:5c46cb3be899 117 public _encodeGpioGetReqDlMsg encodeGpioGetReqDlMsg;
RobMeades 0:5c46cb3be899 118
RobMeades 0:5c46cb3be899 119 // uint32_t __cdecl encodeLedSetReqDlMsg (char * pBuffer,
RobMeades 0:5c46cb3be899 120 // bool onNotOff);
RobMeades 0:5c46cb3be899 121 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 122 public unsafe delegate UInt32 _encodeLedSetReqDlMsg(byte* pBuffer,
RobMeades 0:5c46cb3be899 123 Boolean onNotOff);
RobMeades 0:5c46cb3be899 124 public _encodeLedSetReqDlMsg encodeLedSetReqDlMsg;
RobMeades 0:5c46cb3be899 125
RobMeades 0:5c46cb3be899 126 // uint32_t __cdecl encodeLedGetReqDlMsg (char * pBuffer);
RobMeades 0:5c46cb3be899 127 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 128 public unsafe delegate UInt32 _encodeLedGetReqDlMsg(byte* pBuffer);
RobMeades 0:5c46cb3be899 129 public _encodeLedGetReqDlMsg encodeLedGetReqDlMsg;
RobMeades 0:5c46cb3be899 130
RobMeades 0:5c46cb3be899 131 // uint32_t __cdecl encodeFlashSetReqDlMsg (char * pBuffer,
RobMeades 0:5c46cb3be899 132 // bool onNotOff);
RobMeades 0:5c46cb3be899 133 [UnmanagedFunctionPointer (CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 134 public unsafe delegate UInt32 _encodeFlashSetReqDlMsg(byte * pBuffer,
RobMeades 0:5c46cb3be899 135 Boolean onNotOff);
RobMeades 0:5c46cb3be899 136 public _encodeFlashSetReqDlMsg encodeFlashSetReqDlMsg;
RobMeades 0:5c46cb3be899 137
RobMeades 0:5c46cb3be899 138 // uint32_t __cdecl encodeFlashGetReqDlMsg (char * pBuffer);
RobMeades 0:5c46cb3be899 139 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 140 public unsafe delegate UInt32 _encodeFlashGetReqDlMsg(byte* pBuffer);
RobMeades 0:5c46cb3be899 141 public _encodeFlashGetReqDlMsg encodeFlashGetReqDlMsg;
RobMeades 0:5c46cb3be899 142
RobMeades 0:5c46cb3be899 143 // void __cdecl unpackGpioState (uint32_t value,
RobMeades 0:5c46cb3be899 144 // uint32_t *pGpio,
RobMeades 0:5c46cb3be899 145 // bool * pInputNotOutput,
RobMeades 0:5c46cb3be899 146 // bool * pOnNotOff);
RobMeades 0:5c46cb3be899 147 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 148 public unsafe delegate void _unpackGpioState(UInt32 value,
RobMeades 0:5c46cb3be899 149 UInt32* pGpio,
RobMeades 0:5c46cb3be899 150 Boolean *pInputNotOutput,
RobMeades 0:5c46cb3be899 151 Boolean *pOnNotOff);
RobMeades 0:5c46cb3be899 152 public _unpackGpioState unpackGpioState;
RobMeades 0:5c46cb3be899 153
RobMeades 0:5c46cb3be899 154 // CsDecodeResult_t __cdecl decodeUlMsg (const char ** ppInBuffer,
RobMeades 0:5c46cb3be899 155 // uint32_t sizeInBuffer,
RobMeades 0:5c46cb3be899 156 // uint32_t * pContents);
RobMeades 0:5c46cb3be899 157 [UnmanagedFunctionPointer (CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 158 public unsafe delegate CSDecodeResult _decodeUlMsg(byte** ppInBuffer,
RobMeades 0:5c46cb3be899 159 UInt32 sizeInBuffer,
RobMeades 0:5c46cb3be899 160 UInt32* pContents);
RobMeades 0:5c46cb3be899 161 public _decodeUlMsg decodeUlMsg;
RobMeades 0:5c46cb3be899 162
RobMeades 0:5c46cb3be899 163 [UnmanagedFunctionPointer (CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 164 public delegate void guiPrintToConsoleCallback(StringBuilder data);
RobMeades 0:5c46cb3be899 165
RobMeades 0:5c46cb3be899 166 [UnmanagedFunctionPointer (CallingConvention.Cdecl)]
RobMeades 0:5c46cb3be899 167 public delegate void _initDll([MarshalAs (UnmanagedType.FunctionPtr)] guiPrintToConsoleCallback callbackPointer);
RobMeades 0:5c46cb3be899 168 public _initDll initDll;
RobMeades 0:5c46cb3be899 169
RobMeades 0:5c46cb3be899 170 void guiPrintToConsole(StringBuilder data)
RobMeades 0:5c46cb3be899 171 {
RobMeades 0:5c46cb3be899 172 if (onConsoleTrace != null)
RobMeades 0:5c46cb3be899 173 {
RobMeades 0:5c46cb3be899 174 onConsoleTrace (data.ToString ());
RobMeades 0:5c46cb3be899 175 }
RobMeades 0:5c46cb3be899 176 }
RobMeades 0:5c46cb3be899 177
RobMeades 0:5c46cb3be899 178 /// <summary>
RobMeades 0:5c46cb3be899 179 /// Load the dll and do the bindings
RobMeades 0:5c46cb3be899 180 /// </summary>
RobMeades 0:5c46cb3be899 181 /// <param name="dllLocation">location of dll</param>
RobMeades 0:5c46cb3be899 182 public void bindDll(string dllLocation)
RobMeades 0:5c46cb3be899 183 {
RobMeades 0:5c46cb3be899 184 IntPtr ptrDll = LoadLibrary (dllLocation);
RobMeades 0:5c46cb3be899 185
RobMeades 0:5c46cb3be899 186 if (ptrDll == IntPtr.Zero) throw new Exception (String.Format ("Cannot find {0}", dllLocation));
RobMeades 0:5c46cb3be899 187
RobMeades 0:5c46cb3be899 188 maxDatagramSizeRaw = (_maxDatagramSizeRaw)bindItem(ptrDll, "maxDatagramSizeRaw", typeof(_maxDatagramSizeRaw));
RobMeades 0:5c46cb3be899 189 gpioWaterPump = (_gpioWaterPump)bindItem(ptrDll, "gpioWaterPump", typeof(_gpioWaterPump));
RobMeades 0:5c46cb3be899 190 encodeRebootReqDlMsg = (_encodeRebootReqDlMsg)bindItem(ptrDll, "encodeRebootReqDlMsg", typeof(_encodeRebootReqDlMsg));
RobMeades 0:5c46cb3be899 191 encodeSerialNumberGetReqDlMsg = (_encodeSerialNumberGetReqDlMsg)bindItem(ptrDll, "encodeSerialNumberGetReqDlMsg", typeof(_encodeSerialNumberGetReqDlMsg));
RobMeades 0:5c46cb3be899 192 encodeReadingIntervalSetReqDlMsg = (_encodeReadingIntervalSetReqDlMsg)bindItem(ptrDll, "encodeReadingIntervalSetReqDlMsg", typeof(_encodeReadingIntervalSetReqDlMsg));
RobMeades 0:5c46cb3be899 193 encodeReadingIntervalGetReqDlMsg = (_encodeReadingIntervalGetReqDlMsg)bindItem(ptrDll, "encodeReadingIntervalGetReqDlMsg", typeof(_encodeReadingIntervalGetReqDlMsg));
RobMeades 0:5c46cb3be899 194 encodeGpioSetReqDlMsg = (_encodeGpioSetReqDlMsg)bindItem(ptrDll, "encodeGpioSetReqDlMsg", typeof(_encodeGpioSetReqDlMsg));
RobMeades 0:5c46cb3be899 195 encodeGpioGetReqDlMsg = (_encodeGpioGetReqDlMsg)bindItem(ptrDll, "encodeGpioGetReqDlMsg", typeof(_encodeGpioGetReqDlMsg));
RobMeades 0:5c46cb3be899 196 encodeLedSetReqDlMsg = (_encodeLedSetReqDlMsg)bindItem(ptrDll, "encodeLedSetReqDlMsg", typeof(_encodeLedSetReqDlMsg));
RobMeades 0:5c46cb3be899 197 encodeLedGetReqDlMsg = (_encodeLedGetReqDlMsg)bindItem(ptrDll, "encodeLedGetReqDlMsg", typeof(_encodeLedGetReqDlMsg));
RobMeades 0:5c46cb3be899 198 encodeFlashSetReqDlMsg = (_encodeFlashSetReqDlMsg)bindItem(ptrDll, "encodeFlashSetReqDlMsg", typeof(_encodeFlashSetReqDlMsg));
RobMeades 0:5c46cb3be899 199 encodeFlashGetReqDlMsg = (_encodeFlashGetReqDlMsg)bindItem(ptrDll, "encodeFlashGetReqDlMsg", typeof(_encodeFlashGetReqDlMsg));
RobMeades 0:5c46cb3be899 200 unpackGpioState = (_unpackGpioState)bindItem(ptrDll, "unpackGpioState", typeof(_unpackGpioState));
RobMeades 0:5c46cb3be899 201 decodeUlMsg = (_decodeUlMsg)bindItem(ptrDll, "decodeUlMsg", typeof(_decodeUlMsg));
RobMeades 0:5c46cb3be899 202 initDll = (_initDll)bindItem (ptrDll, "initDll", typeof (_initDll));
RobMeades 0:5c46cb3be899 203 initDll (guiPrintToConsole);
RobMeades 0:5c46cb3be899 204 }
RobMeades 0:5c46cb3be899 205
RobMeades 0:5c46cb3be899 206 public object bindItem(IntPtr ptrDll, string dllFuncName, Type type)
RobMeades 0:5c46cb3be899 207 {
RobMeades 0:5c46cb3be899 208 // Get pointer to dllexport function
RobMeades 0:5c46cb3be899 209 IntPtr procaddr = GetProcAddress (ptrDll, dllFuncName);
RobMeades 0:5c46cb3be899 210 if (procaddr == IntPtr.Zero) throw new Exception (String.Format ("Cannot find {0}", dllFuncName));
RobMeades 0:5c46cb3be899 211
RobMeades 0:5c46cb3be899 212 // Bind it to the function
RobMeades 0:5c46cb3be899 213 Object result = Marshal.GetDelegateForFunctionPointer (procaddr, type);
RobMeades 0:5c46cb3be899 214 if (result == null) throw new Exception (String.Format ("Cannot bind to {0}", dllFuncName));
RobMeades 0:5c46cb3be899 215
RobMeades 0:5c46cb3be899 216 return result;
RobMeades 0:5c46cb3be899 217 }
RobMeades 0:5c46cb3be899 218
RobMeades 0:5c46cb3be899 219 public delegate void ConsoleTrace(string data);
RobMeades 0:5c46cb3be899 220 public event ConsoleTrace onConsoleTrace;
RobMeades 0:5c46cb3be899 221 }
RobMeades 0:5c46cb3be899 222 }