A simple CIoT message protocol, used in the Water Meter Demos.
Embed:
(wiki syntax)
Show/hide line numbers
IotMeterMsgCodec.cpp
00001 /* C027N/water-meter interface for Water Meter Demo 00002 * 00003 * Copyright (C) u-blox Melbourn Ltd 00004 * u-blox Melbourn Ltd, Melbourn, UK 00005 * 00006 * All rights reserved. 00007 * 00008 * This source file is the sole property of u-blox Melbourn Ltd. 00009 * Reproduction or utilization of this source in whole or part is 00010 * forbidden without the written consent of u-blox Melbourn Ltd. 00011 */ 00012 00013 /** 00014 * @file iot_meter_msg_handler.cpp 00015 * This file implements the API to the C027N/water-meter device 00016 * for the MWC demo 2015. 00017 */ 00018 00019 #include <stdint.h> 00020 #include <stdio.h> 00021 #include <stdarg.h> // for va_... 00022 #include <string.h> // for memcpy() 00023 #include <IotMeterApi.hpp> 00024 00025 #ifdef DEBUG 00026 #define MESSAGE_CODEC_LOGMSG(...) MessageCodec::logMsg(__VA_ARGS__) 00027 #else 00028 #define MESSAGE_CODEC_LOGMSG(...) 00029 #endif 00030 00031 // ---------------------------------------------------------------- 00032 // GENERAL COMPILE-TIME CONSTANTS 00033 // ---------------------------------------------------------------- 00034 00035 /// The max size of a debug message (including terminator) 00036 #define MAX_DEBUG_MESSAGE_LEN 128 00037 00038 // ---------------------------------------------------------------- 00039 // PRIVATE VARIABLES 00040 // ---------------------------------------------------------------- 00041 00042 void (*MessageCodec::mp_guiPrintToConsole) (const char*) = NULL; 00043 00044 // ---------------------------------------------------------------- 00045 // ON-AIR MESSAGE IDs 00046 // ---------------------------------------------------------------- 00047 00048 /// The message IDs in the downlink direction (i.e. to the 00049 // C027/water-meter device). Note that 'over the air' these 00050 // are cast into an uint8_t. 00051 typedef enum MsgIdDlTag_t 00052 { 00053 REBOOT_REQ_DL_MSG, //!< Reboot the C027N/water-meter 00054 //! device. 00055 SERIAL_NUMBER_GET_REQ_DL_MSG, //!< Get the serial number of the 00056 //! water-meter. 00057 READING_INTERVAL_SET_REQ_DL_MSG, //!< Set the rate at which readings 00058 //! are returned by the C027N/water-meter 00059 //! device. 00060 READING_INTERVAL_GET_REQ_DL_MSG, //!< Get the rate at which readings 00061 //! are returned by the C027N/water-meter 00062 //! device. 00063 GPIO_SET_REQ_DL_MSG, //!< Set the state of a GPIO on the 00064 //! C027N board. 00065 GPIO_GET_REQ_DL_MSG, //!< Get the state of a GPIO on the 00066 //! C027N board. 00067 LED_SET_REQ_DL_MSG, //!< Set the steady state of the red 00068 //! LED on the C027 board. 00069 LED_GET_REQ_DL_MSG, //!< Get the steady state of the red 00070 //! LED on the C027 board. 00071 FLASH_SET_REQ_DL_MSG, //!< Set the LED on the C027/water-meter 00072 //! device to flash when a reading is 00073 //! being sent (or not). 00074 FLASH_GET_REQ_DL_MSG, //!< Get whether the LED on the C027/ 00075 //! flashes when a mesage is 00076 //! being sent/received (or not). 00077 MAX_NUM_DL_MSGS //!< The maximum number of downlink 00078 //! messages. 00079 } MsgIdDl_t; 00080 00081 /// The message IDs in the uplink direction (i.e. from the 00082 // C027N/water-meter device). Note that 'over the air' these are 00083 // cast into an uint8_t. 00084 typedef enum MsgIdUlTag_t 00085 { 00086 INIT_IND_UL_MSG, //!< Power on of the C027N/water meter 00087 //! device has completed. 00088 SERIAL_NUMBER_IND_UL_MSG, //!< The serial number of the water meter. 00089 VOLUME_IND_UL_MSG, //!< The current water meter reading. 00090 RSSI_IND_UL_MSG, //!< The current RSSI reading from the 00091 //! radio module. 00092 SERIAL_NUMBER_GET_CNF_UL_MSG, //!< The serial number of the water-meter. 00093 READING_INTERVAL_SET_CNF_UL_MSG, //!< The rate at which readings are 00094 //! returned by the C027/water-meter device. 00095 READING_INTERVAL_GET_CNF_UL_MSG, //!< The rate at which readings are 00096 //! returned by the C027/water-meter device. 00097 GPIO_SET_CNF_UL_MSG, //!< The state of a GPIO on the C027 board. 00098 GPIO_GET_CNF_UL_MSG, //!< The state of a GPIO on the C027 board. 00099 LED_SET_CNF_UL_MSG, //!< The steady state of the red LED on 00100 //! the C027/water-meter device. 00101 LED_GET_CNF_UL_MSG, //!< The steady state of the red LED on 00102 //! the C027/water-meter device. 00103 FLASH_SET_CNF_UL_MSG, //!< Whether the LED on the C027/water 00104 //! meter device is set to flash when a 00105 //! message is being sent/received (or not). 00106 FLASH_GET_CNF_UL_MSG, //!< Whether the LED on the C027/water 00107 //! meter device is set to flash when a 00108 //! message is being sent/received (or not). 00109 MAX_NUM_UL_MSGS //!< The maximum number of uplink messages. 00110 } MsgIdUl_t; 00111 00112 // ---------------------------------------------------------------- 00113 // GENERIC PRIVATE FUNCTIONS 00114 // ---------------------------------------------------------------- 00115 00116 /// Encode a boolean value, noting that this is contained 00117 // in a 32 bytes coded value. 00118 uint32_t MessageCodec::encodeBool (char * pBuffer, bool value) 00119 { 00120 uint32_t numBytesEncoded = 4; 00121 00122 memset (pBuffer, 0, 4); 00123 pBuffer[3] = value; 00124 00125 return numBytesEncoded; 00126 } 00127 00128 /// Decode a boolean value, noting that this is contained 00129 // in a 32 bytes coded value. 00130 bool MessageCodec::decodeBool (const char ** ppBuffer) 00131 { 00132 uint32_t value = 0; 00133 bool boolValue = false; 00134 00135 value += ((**ppBuffer) & 0xFF) << 24; 00136 (*ppBuffer)++; 00137 value += ((**ppBuffer) & 0xFF) << 16; 00138 (*ppBuffer)++; 00139 value += ((**ppBuffer) & 0xFF) << 8; 00140 (*ppBuffer)++; 00141 value += ((**ppBuffer) & 0xFF) ; 00142 (*ppBuffer)++; 00143 00144 if (value) 00145 { 00146 boolValue = true; 00147 } 00148 00149 return boolValue; 00150 } 00151 00152 /// Encode an int32 00153 uint32_t MessageCodec::encodeUint32 (char * pBuffer, uint32_t value) 00154 { 00155 uint32_t numBytesEncoded = 4; 00156 00157 pBuffer[0] = 0xff & (value >> 24); 00158 pBuffer[1] = 0xff & (value >> 16); 00159 pBuffer[2] = 0xff & (value >> 8); 00160 pBuffer[3] = 0xff & value; 00161 00162 return numBytesEncoded; 00163 } 00164 00165 /// Decode an int32 00166 uint32_t MessageCodec::decodeUint32 (const char ** ppBuffer) 00167 { 00168 uint32_t value = 0; 00169 00170 value += ((**ppBuffer) & 0xFF) << 24; 00171 (*ppBuffer)++; 00172 value += ((**ppBuffer) & 0xFF) << 16; 00173 (*ppBuffer)++; 00174 value += ((**ppBuffer) & 0xFF) << 8; 00175 (*ppBuffer)++; 00176 value += ((**ppBuffer) & 0xFF); 00177 (*ppBuffer)++; 00178 00179 return value; 00180 } 00181 00182 /// Encode GpioState 00183 uint32_t MessageCodec::encodeGpioState (char * pBuffer, GpioState_t *pGpioState) 00184 00185 { 00186 uint32_t numBytesEncoded = 0; 00187 00188 pBuffer[numBytesEncoded] = 0; 00189 numBytesEncoded++; 00190 pBuffer[numBytesEncoded] = pGpioState->gpio; 00191 numBytesEncoded++; 00192 pBuffer[numBytesEncoded] = pGpioState->inputNotOutput; 00193 numBytesEncoded++; 00194 pBuffer[numBytesEncoded] = pGpioState->onNotOff; 00195 numBytesEncoded++; 00196 00197 return numBytesEncoded; 00198 } 00199 00200 00201 // Decode GpioState 00202 void MessageCodec::decodeGpioState (GpioState_t * pGpioState, const char ** ppBuffer) 00203 { 00204 // Ignore the first byte as it's empty 00205 (*ppBuffer)++; 00206 pGpioState->gpio = (uint8_t) ((**ppBuffer) & 0xFF); 00207 (*ppBuffer)++; 00208 pGpioState->inputNotOutput = (bool) ((**ppBuffer) & 0xFF); 00209 (*ppBuffer)++; 00210 pGpioState->onNotOff = (bool) ((**ppBuffer) & 0xFF); 00211 (*ppBuffer)++; 00212 } 00213 00214 // ---------------------------------------------------------------- 00215 // MESSAGE ENCODING FUNCTIONS 00216 // ---------------------------------------------------------------- 00217 00218 uint32_t MessageCodec::encodeInitIndUlMsg (char * pBuffer, 00219 InitIndUlMsg_t * pMsg) 00220 { 00221 uint32_t numBytesEncoded = 0; 00222 00223 MESSAGE_CODEC_LOGMSG ("Encoding InitIndUlMsg, ID 0x%.2x, ", INIT_IND_UL_MSG); 00224 pBuffer[numBytesEncoded] = INIT_IND_UL_MSG; 00225 numBytesEncoded++; 00226 numBytesEncoded += encodeUint32 (&(pBuffer[numBytesEncoded]), (uint32_t) pMsg->wakeUpCode); 00227 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00228 00229 return numBytesEncoded; 00230 } 00231 00232 uint32_t MessageCodec::encodeRebootReqDlMsg (char * pBuffer, 00233 RebootReqDlMsg_t *pMsg) 00234 { 00235 uint32_t numBytesEncoded = 0; 00236 00237 pBuffer[numBytesEncoded] = REBOOT_REQ_DL_MSG; 00238 numBytesEncoded++; 00239 numBytesEncoded += encodeBool (&(pBuffer[numBytesEncoded]), pMsg->devModeOnNotOff); 00240 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00241 00242 return numBytesEncoded; 00243 } 00244 00245 uint32_t MessageCodec::encodeSerialNumberIndUlMsg (char * pBuffer, 00246 SerialNumberIndUlMsg_t * pMsg) 00247 { 00248 uint32_t numBytesEncoded = 0; 00249 00250 MESSAGE_CODEC_LOGMSG ("Encoding SerialNumberIndUlMsg, ID 0x%.2x, ", SERIAL_NUMBER_IND_UL_MSG); 00251 pBuffer[numBytesEncoded] = SERIAL_NUMBER_IND_UL_MSG; 00252 numBytesEncoded++; 00253 numBytesEncoded += encodeUint32 (&(pBuffer[numBytesEncoded]), pMsg->serialNumber); 00254 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00255 00256 return numBytesEncoded; 00257 } 00258 00259 uint32_t MessageCodec::encodeVolumeIndUlMsg (char * pBuffer, 00260 VolumeIndUlMsg_t * pMsg) 00261 { 00262 uint32_t numBytesEncoded = 0; 00263 00264 MESSAGE_CODEC_LOGMSG ("Encoding VolumeIndUlMsg, ID 0x%.2x, ", VOLUME_IND_UL_MSG); 00265 pBuffer[numBytesEncoded] = VOLUME_IND_UL_MSG; 00266 numBytesEncoded++; 00267 numBytesEncoded += encodeUint32 (&(pBuffer[numBytesEncoded]), pMsg->volumeLitres); 00268 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00269 00270 return numBytesEncoded; 00271 } 00272 00273 uint32_t MessageCodec::encodeRssiIndUlMsg (char * pBuffer, 00274 RssiIndUlMsg_t * pMsg) 00275 { 00276 uint32_t numBytesEncoded = 0; 00277 00278 MESSAGE_CODEC_LOGMSG ("Encoding RssiIndUlMsg, ID 0x%.2x, ", RSSI_IND_UL_MSG); 00279 pBuffer[numBytesEncoded] = RSSI_IND_UL_MSG; 00280 numBytesEncoded++; 00281 numBytesEncoded += encodeUint32 (&(pBuffer[numBytesEncoded]), pMsg->rssi); 00282 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00283 00284 return numBytesEncoded; 00285 } 00286 00287 uint32_t MessageCodec::encodeSerialNumberGetReqDlMsg (char * pBuffer) 00288 { 00289 uint32_t numBytesEncoded = 0; 00290 00291 MESSAGE_CODEC_LOGMSG ("Encoding SerialNumberGetReqDlMsg, ID 0x%.2x, ", SERIAL_NUMBER_GET_REQ_DL_MSG); 00292 pBuffer[numBytesEncoded] = SERIAL_NUMBER_GET_REQ_DL_MSG; 00293 numBytesEncoded++; 00294 numBytesEncoded += encodeBool (&(pBuffer[numBytesEncoded]), 0); // Encode packing as all 00295 // messages must have a body 00296 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00297 00298 return numBytesEncoded; 00299 } 00300 00301 uint32_t MessageCodec::encodeSerialNumberGetCnfUlMsg (char * pBuffer, 00302 SerialNumberGetCnfUlMsg_t * pMsg) 00303 { 00304 uint32_t numBytesEncoded = 0; 00305 00306 MESSAGE_CODEC_LOGMSG ("Encoding SerialNumberGetCnfUlMsg, ID 0x%.2x, ", SERIAL_NUMBER_GET_CNF_UL_MSG); 00307 pBuffer[numBytesEncoded] = SERIAL_NUMBER_GET_CNF_UL_MSG; 00308 numBytesEncoded++; 00309 numBytesEncoded += encodeUint32 (&(pBuffer[numBytesEncoded]), pMsg->serialNumber); 00310 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00311 00312 return numBytesEncoded; 00313 } 00314 00315 uint32_t MessageCodec::encodeReadingIntervalSetReqDlMsg (char * pBuffer, 00316 ReadingIntervalSetReqDlMsg_t * pMsg) 00317 { 00318 uint32_t numBytesEncoded = 0; 00319 00320 MESSAGE_CODEC_LOGMSG ("Encoding ReadingIntervalSetReqDlMsg, ID 0x%.2x, ", READING_INTERVAL_SET_REQ_DL_MSG); 00321 pBuffer[numBytesEncoded] = READING_INTERVAL_SET_REQ_DL_MSG; 00322 numBytesEncoded++; 00323 numBytesEncoded += encodeUint32 (&(pBuffer[numBytesEncoded]), pMsg->readingIntervalSeconds); 00324 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00325 00326 return numBytesEncoded; 00327 } 00328 00329 uint32_t MessageCodec::encodeReadingIntervalSetCnfUlMsg (char * pBuffer, 00330 ReadingIntervalSetCnfUlMsg_t * pMsg) 00331 { 00332 uint32_t numBytesEncoded = 0; 00333 00334 MESSAGE_CODEC_LOGMSG ("Encoding ReadingIntervalSetCnfUlMsg, ID 0x%.2x, ", READING_INTERVAL_SET_CNF_UL_MSG); 00335 pBuffer[numBytesEncoded] = READING_INTERVAL_SET_CNF_UL_MSG; 00336 numBytesEncoded++; 00337 numBytesEncoded += encodeUint32 (&(pBuffer[numBytesEncoded]), pMsg->readingIntervalSeconds); 00338 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00339 00340 return numBytesEncoded; 00341 } 00342 00343 uint32_t MessageCodec::encodeReadingIntervalGetReqDlMsg (char * pBuffer) 00344 { 00345 uint32_t numBytesEncoded = 0; 00346 00347 MESSAGE_CODEC_LOGMSG ("Encoding ReadingIntervalGetReqDlMsg, ID 0x%.2x, ", READING_INTERVAL_GET_REQ_DL_MSG); 00348 pBuffer[numBytesEncoded] = READING_INTERVAL_GET_REQ_DL_MSG; 00349 numBytesEncoded++; 00350 numBytesEncoded += encodeBool (&(pBuffer[numBytesEncoded]), 0); // Encode packing as all 00351 // messages must have a body 00352 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00353 00354 return numBytesEncoded; 00355 } 00356 00357 uint32_t MessageCodec::encodeReadingIntervalGetCnfUlMsg (char * pBuffer, 00358 ReadingIntervalGetCnfUlMsg_t * pMsg) 00359 { 00360 uint32_t numBytesEncoded = 0; 00361 00362 MESSAGE_CODEC_LOGMSG ("Encoding ReadingIntervalGetCnfUlMsg, ID 0x%.2x, ", READING_INTERVAL_GET_CNF_UL_MSG); 00363 pBuffer[numBytesEncoded] = READING_INTERVAL_GET_CNF_UL_MSG; 00364 numBytesEncoded++; 00365 numBytesEncoded += encodeUint32 (&(pBuffer[numBytesEncoded]), pMsg->readingIntervalSeconds); 00366 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00367 00368 return numBytesEncoded; 00369 } 00370 00371 uint32_t MessageCodec::encodeGpioSetReqDlMsg (char * pBuffer, 00372 GpioSetReqDlMsg_t * pMsg) 00373 { 00374 uint32_t numBytesEncoded = 0; 00375 00376 MESSAGE_CODEC_LOGMSG ("Encoding GpioSetReqDlMsg, ID 0x%.2x, ", GPIO_SET_REQ_DL_MSG); 00377 pBuffer[numBytesEncoded] = GPIO_SET_REQ_DL_MSG; 00378 numBytesEncoded++; 00379 numBytesEncoded += encodeGpioState (&(pBuffer[numBytesEncoded]), &(pMsg->gpioState)); 00380 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00381 00382 return numBytesEncoded; 00383 } 00384 00385 uint32_t MessageCodec::encodeGpioSetCnfUlMsg (char * pBuffer, 00386 GpioSetCnfUlMsg_t * pMsg) 00387 { 00388 uint32_t numBytesEncoded = 0; 00389 00390 MESSAGE_CODEC_LOGMSG ("Encoding GpioSetCnfUlMsg, ID 0x%.2x, ", GPIO_SET_CNF_UL_MSG); 00391 pBuffer[numBytesEncoded] = GPIO_SET_CNF_UL_MSG; 00392 numBytesEncoded++; 00393 numBytesEncoded += encodeGpioState (&(pBuffer[numBytesEncoded]), &(pMsg->gpioState)); 00394 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00395 00396 return numBytesEncoded; 00397 } 00398 00399 uint32_t MessageCodec::encodeGpioGetReqDlMsg (char * pBuffer, 00400 GpioGetReqDlMsg_t * pMsg) 00401 { 00402 uint32_t numBytesEncoded = 0; 00403 00404 MESSAGE_CODEC_LOGMSG ("Encoding GpioGetReqDlMsg, ID 0x%.2x, ", LED_GET_REQ_DL_MSG); 00405 pBuffer[numBytesEncoded] = GPIO_GET_REQ_DL_MSG; 00406 numBytesEncoded++; 00407 numBytesEncoded += encodeUint32 (&(pBuffer[numBytesEncoded]), (uint32_t) pMsg->gpio); 00408 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00409 00410 return numBytesEncoded; 00411 } 00412 00413 uint32_t MessageCodec::encodeGpioGetCnfUlMsg (char * pBuffer, 00414 GpioGetCnfUlMsg_t * pMsg) 00415 { 00416 uint32_t numBytesEncoded = 0; 00417 00418 MESSAGE_CODEC_LOGMSG ("Encoding GpioGetCnfUlMsg, ID 0x%.2x, ", LED_GET_CNF_UL_MSG); 00419 pBuffer[numBytesEncoded] = GPIO_GET_CNF_UL_MSG; 00420 numBytesEncoded++; 00421 numBytesEncoded += encodeGpioState (&(pBuffer[numBytesEncoded]), &(pMsg->gpioState)); 00422 00423 return numBytesEncoded; 00424 } 00425 00426 uint32_t MessageCodec::encodeLedSetReqDlMsg (char * pBuffer, 00427 LedSetReqDlMsg_t * pMsg) 00428 { 00429 uint32_t numBytesEncoded = 0; 00430 00431 MESSAGE_CODEC_LOGMSG ("Encoding LedSetReqDlMsg, ID 0x%.2x, ", LED_SET_REQ_DL_MSG); 00432 pBuffer[numBytesEncoded] = LED_SET_REQ_DL_MSG; 00433 numBytesEncoded++; 00434 numBytesEncoded += encodeBool (&(pBuffer[numBytesEncoded]), pMsg->onNotOff); 00435 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00436 00437 return numBytesEncoded; 00438 } 00439 00440 uint32_t MessageCodec::encodeLedSetCnfUlMsg (char * pBuffer, 00441 LedSetCnfUlMsg_t * pMsg) 00442 { 00443 uint32_t numBytesEncoded = 0; 00444 00445 MESSAGE_CODEC_LOGMSG ("Encoding LedSetCnfUlMsg, ID 0x%.2x, ", LED_SET_CNF_UL_MSG); 00446 pBuffer[numBytesEncoded] = LED_SET_CNF_UL_MSG; 00447 numBytesEncoded++; 00448 numBytesEncoded += encodeBool (&(pBuffer[numBytesEncoded]), pMsg->onNotOff); 00449 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00450 00451 return numBytesEncoded; 00452 } 00453 00454 uint32_t MessageCodec::encodeLedGetReqDlMsg (char * pBuffer) 00455 { 00456 uint32_t numBytesEncoded = 0; 00457 00458 MESSAGE_CODEC_LOGMSG ("Encoding LedGetReqDlMsg, ID 0x%.2x, ", LED_GET_REQ_DL_MSG); 00459 pBuffer[numBytesEncoded] = LED_GET_REQ_DL_MSG; 00460 numBytesEncoded++; 00461 numBytesEncoded += encodeBool (&(pBuffer[numBytesEncoded]), 0); // Encode packing as all 00462 // messages must have a body 00463 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00464 00465 return numBytesEncoded; 00466 } 00467 00468 uint32_t MessageCodec::encodeLedGetCnfUlMsg (char * pBuffer, 00469 LedGetCnfUlMsg_t * pMsg) 00470 { 00471 uint32_t numBytesEncoded = 0; 00472 00473 MESSAGE_CODEC_LOGMSG ("Encoding LedGetCnfUlMsg, ID 0x%.2x, ", LED_GET_CNF_UL_MSG); 00474 pBuffer[numBytesEncoded] = LED_GET_CNF_UL_MSG; 00475 numBytesEncoded++; 00476 numBytesEncoded += encodeBool (&(pBuffer[numBytesEncoded]), pMsg->onNotOff); 00477 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00478 00479 return numBytesEncoded; 00480 } 00481 00482 uint32_t MessageCodec::encodeFlashSetReqDlMsg (char * pBuffer, 00483 FlashSetReqDlMsg_t * pMsg) 00484 { 00485 uint32_t numBytesEncoded = 0; 00486 00487 MESSAGE_CODEC_LOGMSG ("Encoding FlashSetReqDlMsg, ID 0x%.2x, ", FLASH_SET_REQ_DL_MSG); 00488 pBuffer[numBytesEncoded] = FLASH_SET_REQ_DL_MSG; 00489 numBytesEncoded++; 00490 numBytesEncoded += encodeBool (&(pBuffer[numBytesEncoded]), pMsg->onNotOff); 00491 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00492 00493 return numBytesEncoded; 00494 } 00495 00496 uint32_t MessageCodec::encodeFlashSetCnfUlMsg (char * pBuffer, 00497 FlashSetCnfUlMsg_t * pMsg) 00498 { 00499 uint32_t numBytesEncoded = 0; 00500 00501 MESSAGE_CODEC_LOGMSG ("Encoding FlashSetCnfUlMs, ID 0x%.2x, ", FLASH_SET_CNF_UL_MSG); 00502 pBuffer[numBytesEncoded] = FLASH_SET_CNF_UL_MSG; 00503 numBytesEncoded++; 00504 numBytesEncoded += encodeBool (&(pBuffer[numBytesEncoded]), pMsg->onNotOff); 00505 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00506 00507 return numBytesEncoded; 00508 } 00509 00510 uint32_t MessageCodec::encodeFlashGetReqDlMsg (char * pBuffer) 00511 { 00512 uint32_t numBytesEncoded = 0; 00513 00514 MESSAGE_CODEC_LOGMSG ("Encoding FlashGetReqDlMsg, ID 0x%.2x, ", FLASH_GET_REQ_DL_MSG); 00515 pBuffer[numBytesEncoded] = FLASH_GET_REQ_DL_MSG; 00516 numBytesEncoded++; 00517 numBytesEncoded += encodeBool (&(pBuffer[numBytesEncoded]), 0); // Encode packing as all 00518 // messages must have a body 00519 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00520 00521 return numBytesEncoded; 00522 } 00523 00524 uint32_t MessageCodec::encodeFlashGetCnfUlMsg (char * pBuffer, 00525 FlashGetCnfUlMsg_t * pMsg) 00526 { 00527 uint32_t numBytesEncoded = 0; 00528 00529 MESSAGE_CODEC_LOGMSG ("Encoding FlashGetCnfUlMs, ID 0x%.2x, ", FLASH_GET_CNF_UL_MSG); 00530 pBuffer[numBytesEncoded] = FLASH_GET_CNF_UL_MSG; 00531 numBytesEncoded++; 00532 numBytesEncoded += encodeBool (&(pBuffer[numBytesEncoded]), pMsg->onNotOff); 00533 MESSAGE_CODEC_LOGMSG ("%d bytes encoded.\n", numBytesEncoded); 00534 00535 return numBytesEncoded; 00536 } 00537 00538 // ---------------------------------------------------------------- 00539 // MESSAGE DECODING FUNCTIONS 00540 // ---------------------------------------------------------------- 00541 MessageCodec::DecodeResult_t MessageCodec::decodeDlMsg (const char ** ppInBuffer, 00542 uint32_t sizeInBuffer, 00543 DlMsgUnion_t * pOutBuffer) 00544 { 00545 MsgIdDl_t msgId; 00546 DecodeResult_t decodeResult = DECODE_RESULT_FAILURE; 00547 00548 if (sizeInBuffer < MAX_MESSAGE_SIZE) 00549 { 00550 decodeResult = DECODE_RESULT_INPUT_TOO_SHORT; 00551 } 00552 else 00553 { 00554 decodeResult = DECODE_RESULT_UNKNOWN_MSG_ID; 00555 // First byte should be a valid DL message ID 00556 msgId = (MsgIdDl_t) **ppInBuffer; 00557 (*ppInBuffer)++; 00558 if (msgId < MAX_NUM_DL_MSGS) 00559 { 00560 switch (msgId) 00561 { 00562 case REBOOT_REQ_DL_MSG: 00563 decodeResult = DECODE_RESULT_REBOOT_REQ_DL_MSG; 00564 pOutBuffer->rebootReqDlMsg.devModeOnNotOff = decodeBool (ppInBuffer); 00565 break; 00566 case SERIAL_NUMBER_GET_REQ_DL_MSG: 00567 decodeResult = DECODE_RESULT_SERIAL_NUMBER_GET_REQ_DL_MSG; 00568 decodeUint32 (ppInBuffer); // Must decode the rest of the dummy message; 00569 break; 00570 case READING_INTERVAL_SET_REQ_DL_MSG: 00571 decodeResult = DECODE_RESULT_READING_INTERVAL_SET_REQ_DL_MSG; 00572 pOutBuffer->readingIntervalSetReqDlMsg.readingIntervalSeconds = decodeUint32 (ppInBuffer); 00573 break; 00574 case READING_INTERVAL_GET_REQ_DL_MSG: 00575 decodeResult = DECODE_RESULT_READING_INTERVAL_GET_REQ_DL_MSG; 00576 decodeUint32 (ppInBuffer); // Must decode the rest of the dummy message; 00577 break; 00578 case GPIO_SET_REQ_DL_MSG: 00579 decodeResult = DECODE_RESULT_GPIO_SET_REQ_DL_MSG; 00580 decodeGpioState (&(pOutBuffer->gpioSetReqDlMsg.gpioState), ppInBuffer); 00581 break; 00582 case GPIO_GET_REQ_DL_MSG: 00583 decodeResult = DECODE_RESULT_GPIO_GET_REQ_DL_MSG; 00584 pOutBuffer->gpioGetReqDlMsg.gpio = (uint8_t) decodeUint32 (ppInBuffer); 00585 break; 00586 case LED_SET_REQ_DL_MSG: 00587 decodeResult = DECODE_RESULT_LED_SET_REQ_DL_MSG; 00588 pOutBuffer->ledSetReqDlMsg.onNotOff = decodeBool (ppInBuffer); 00589 break; 00590 case LED_GET_REQ_DL_MSG: 00591 decodeResult = DECODE_RESULT_LED_GET_REQ_DL_MSG; 00592 decodeUint32 (ppInBuffer); // Must decode the rest of the dummy message; 00593 break; 00594 case FLASH_SET_REQ_DL_MSG: 00595 decodeResult = DECODE_RESULT_FLASH_SET_REQ_DL_MSG; 00596 pOutBuffer->flashSetReqDlMsg.onNotOff = decodeBool (ppInBuffer); 00597 break; 00598 case FLASH_GET_REQ_DL_MSG: 00599 decodeResult = DECODE_RESULT_FLASH_GET_REQ_DL_MSG; 00600 decodeUint32 (ppInBuffer); // Must decode the rest of the dummy message; 00601 break; 00602 default: 00603 // The decodeResult will be left as Unknown message 00604 break; 00605 } 00606 } 00607 } 00608 00609 return decodeResult; 00610 } 00611 00612 MessageCodec::DecodeResult_t MessageCodec::decodeUlMsg (const char ** ppInBuffer, 00613 uint32_t sizeInBuffer, 00614 UlMsgUnion_t * pOutBuffer) 00615 { 00616 MsgIdUl_t msgId; 00617 DecodeResult_t decodeResult = DECODE_RESULT_FAILURE; 00618 00619 if (sizeInBuffer < MAX_MESSAGE_SIZE) 00620 { 00621 decodeResult = DECODE_RESULT_INPUT_TOO_SHORT; 00622 } 00623 else 00624 { 00625 decodeResult = DECODE_RESULT_UNKNOWN_MSG_ID; 00626 // First byte should be a valid UL message ID 00627 msgId = (MsgIdUl_t) **ppInBuffer; 00628 (*ppInBuffer)++; 00629 if (msgId < MAX_NUM_UL_MSGS) 00630 { 00631 switch (msgId) 00632 { 00633 case INIT_IND_UL_MSG: 00634 decodeResult = DECODE_RESULT_INIT_IND_UL_MSG; 00635 pOutBuffer->initIndUlMsg.wakeUpCode = (WakeUpCode_t) decodeUint32 (ppInBuffer); 00636 break; 00637 case SERIAL_NUMBER_IND_UL_MSG: 00638 decodeResult = DECODE_RESULT_SERIAL_NUMBER_IND_UL_MSG; 00639 pOutBuffer->serialNumberIndUlMsg.serialNumber = decodeUint32 (ppInBuffer); 00640 break; 00641 case VOLUME_IND_UL_MSG: 00642 decodeResult = DECODE_RESULT_VOLUME_IND_UL_MSG; 00643 pOutBuffer->volumeIndUlMsg.volumeLitres = decodeUint32 (ppInBuffer); 00644 break; 00645 case RSSI_IND_UL_MSG: 00646 decodeResult = DECODE_RESULT_RSSI_IND_UL_MSG; 00647 pOutBuffer->rssiIndUlMsg.rssi = decodeUint32 (ppInBuffer); 00648 break; 00649 case SERIAL_NUMBER_GET_CNF_UL_MSG: 00650 decodeResult = DECODE_RESULT_SERIAL_NUMBER_GET_CNF_UL_MSG; 00651 pOutBuffer->serialNumberCnfUlMsg.serialNumber = decodeUint32 (ppInBuffer); 00652 break; 00653 case READING_INTERVAL_SET_CNF_UL_MSG: 00654 decodeResult = DECODE_RESULT_READING_INTERVAL_SET_CNF_UL_MSG; 00655 pOutBuffer->readingIntervalSetCnfUlMsg.readingIntervalSeconds = decodeUint32 (ppInBuffer); 00656 break; 00657 case READING_INTERVAL_GET_CNF_UL_MSG: 00658 decodeResult = DECODE_RESULT_READING_INTERVAL_GET_CNF_UL_MSG; 00659 pOutBuffer->readingIntervalGetCnfUlMsg.readingIntervalSeconds = decodeUint32 (ppInBuffer); 00660 break; 00661 case GPIO_SET_CNF_UL_MSG: 00662 decodeResult = DECODE_RESULT_GPIO_SET_CNF_UL_MSG; 00663 pOutBuffer->gpioSetCnfUlMsg = decodeUint32 (ppInBuffer); // Decode as an int32 for later unpacking 00664 break; 00665 case GPIO_GET_CNF_UL_MSG: 00666 decodeResult = DECODE_RESULT_GPIO_GET_CNF_UL_MSG; 00667 pOutBuffer->gpioGetCnfUlMsg = decodeUint32 (ppInBuffer); // Decode as an int32 for later unpacking 00668 break; 00669 case LED_SET_CNF_UL_MSG: 00670 decodeResult = DECODE_RESULT_LED_SET_CNF_UL_MSG; 00671 pOutBuffer->ledSetCnfUlMsg.onNotOff = decodeBool (ppInBuffer); 00672 break; 00673 case LED_GET_CNF_UL_MSG: 00674 decodeResult = DECODE_RESULT_LED_GET_CNF_UL_MSG; 00675 pOutBuffer->ledGetCnfUlMsg.onNotOff = decodeBool (ppInBuffer); 00676 break; 00677 case FLASH_SET_CNF_UL_MSG: 00678 decodeResult = DECODE_RESULT_FLASH_SET_CNF_UL_MSG; 00679 pOutBuffer->flashSetCnfUlMsg.onNotOff = decodeBool (ppInBuffer); 00680 break; 00681 case FLASH_GET_CNF_UL_MSG: 00682 decodeResult = DECODE_RESULT_FLASH_GET_CNF_UL_MSG; 00683 pOutBuffer->flashGetCnfUlMsg.onNotOff = decodeBool (ppInBuffer); 00684 break; 00685 default: 00686 // The decodeResult will be left as Unknown message 00687 break; 00688 } 00689 } 00690 } 00691 00692 return decodeResult; 00693 } 00694 00695 // ---------------------------------------------------------------- 00696 // MISC FUNCTIONS 00697 // ---------------------------------------------------------------- 00698 00699 // Log debug messages 00700 void MessageCodec::logMsg (const char * pFormat, ...) 00701 { 00702 char buffer[MAX_DEBUG_MESSAGE_LEN]; 00703 00704 va_list args; 00705 va_start (args, pFormat); 00706 vsnprintf (buffer, sizeof (buffer), pFormat, args); 00707 va_end (args); 00708 #ifdef WIN32 00709 if (MessageCodec::mp_guiPrintToConsole) 00710 { 00711 (*MessageCodec::mp_guiPrintToConsole) (buffer); 00712 } 00713 #else 00714 // Must be on ARM 00715 printf (buffer); 00716 #endif 00717 } 00718 00719 void MessageCodec::initDll (void (*guiPrintToConsole) (const char *)) 00720 { 00721 #ifdef WIN32 00722 mp_guiPrintToConsole = guiPrintToConsole; 00723 // This is the signal to the GUI that we're done with initialisation 00724 logMsg ("MessageCodec::ready.\n"); 00725 #endif 00726 } 00727 00728 // End Of File
Generated on Sun Jul 17 2022 00:13:12 by
1.7.2