Rob Meades / CIoT_MessagingCommon
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers IotMeterMsgCodec.cpp Source File

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