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

Committer:
RobMeades
Date:
2015-05-22
Revision:
0:5c46cb3be899

File content as of revision 0:5c46cb3be899:

/* DLL wrapper for C027N/water-meter message handling functions
 * for MWC demo 2015
 * 
 * Copyright (C) u-blox Melbourn Ltd
 * u-blox Melbourn Ltd, Melbourn, UK
 * 
 * All rights reserved.
 *
 * This source file is the sole property of u-blox Melbourn Ltd.
 * Reproduction or utilization of this source in whole or part is
 * forbidden without the written consent of u-blox Melbourn Ltd.
 */

/**
 * @file iot_meter_dll_wrapper.cpp
 * This file implements the encapsulation necessary to
 * call the CPP Message Handling functions from C#.
 */
#include <stdint.h>
#include <IotMeterApi.hpp>
#include <IotMeterDllWrapper.hpp>
#include "windows.h"

#ifdef __cplusplus
extern "C" {
#endif

    // Instantiate a messageHandler 
    MessageCodec gMessageCodec;

    // ----------------------------------------------------------------
    // CONSTANTS
    // ----------------------------------------------------------------

    uint32_t __cdecl maxDatagramSizeRaw (void)
    {
        return MAX_DATAGRAM_SIZE_RAW;
    }
    
    uint32_t __cdecl gpioWaterPump (void)
    {
        return GPIO_WATER_PUMP;
    }
    
    // ----------------------------------------------------------------
    // PRIVATE FUNCTIONS
    // ----------------------------------------------------------------

    // ----------------------------------------------------------------
    // MESSAGE ENCODE WRAPPER FUNCTIONS
    // ----------------------------------------------------------------

    // Wrap encodeRebootReqDlMsg 
    uint32_t __cdecl encodeRebootReqDlMsg (char * pBuffer,
                                           bool devModeOnNotOff)
    {
        RebootReqDlMsg_t msg;
        msg.devModeOnNotOff = devModeOnNotOff;

        return gMessageCodec.encodeRebootReqDlMsg (pBuffer, &msg);
    }

    // Wrap encodeSerialNumberGetReqDlMsg 
    uint32_t __cdecl encodeSerialNumberGetReqDlMsg (char * pBuffer)
    {
        return gMessageCodec.encodeSerialNumberGetReqDlMsg (pBuffer);
    }

    // Wrap encodeReadingIntervalSetReqDlMsg 
    uint32_t __cdecl encodeReadingIntervalSetReqDlMsg (char * pBuffer,
                                                       uint32_t readingIntervalSeconds)
    {
        ReadingIntervalSetReqDlMsg_t msg;
        msg.readingIntervalSeconds = readingIntervalSeconds;

        return gMessageCodec.encodeReadingIntervalSetReqDlMsg (pBuffer, &msg);
    }

    // Wrap encodeReadingIntervalGetReqDlMsg 
    uint32_t __cdecl encodeReadingIntervalGetReqDlMsg (char * pBuffer)
    {
        return gMessageCodec.encodeReadingIntervalGetReqDlMsg (pBuffer);
    }

    // Wrap encodeGpioSetReqDlMsg
    uint32_t __cdecl encodeGpioSetReqDlMsg (char * pBuffer,
                                            uint8_t gpio,
                                            bool inputNotOutput,
                                            bool onNotOff)
    {
        GpioSetReqDlMsg_t msg;
        msg.gpioState.gpio = gpio;
        msg.gpioState.inputNotOutput = inputNotOutput;
        msg.gpioState.onNotOff = onNotOff;

        return gMessageCodec.encodeGpioSetReqDlMsg (pBuffer, &msg);
    }

    // Wrap encodeGpioGetReqDlMsg
    uint32_t __cdecl encodeGpioGetReqDlMsg (char * pBuffer,
                                            uint32_t gpio)
    {
        GpioGetReqDlMsg_t msg;
        msg.gpio = (uint8_t) gpio;

        return gMessageCodec.encodeGpioGetReqDlMsg (pBuffer, &msg);
    }

    // Wrap encodeLedSetReqDlMsg 
    uint32_t __cdecl encodeLedSetReqDlMsg (char * pBuffer,
                                           bool onNotOff)
    {
        LedSetReqDlMsg_t msg;
        msg.onNotOff = onNotOff;

        return gMessageCodec.encodeLedSetReqDlMsg (pBuffer, &msg);
    }

    // Wrap encodeLedGetReqDlMsg 
    uint32_t __cdecl encodeLedGetReqDlMsg (char * pBuffer)
    {
        return gMessageCodec.encodeLedGetReqDlMsg (pBuffer);
    }

    // Wrap encodeFlashSetReqDlMsg 
    uint32_t __cdecl encodeFlashSetReqDlMsg (char * pBuffer,
                                             bool onNotOff)
    {
        FlashSetReqDlMsg_t msg;
        msg.onNotOff = onNotOff;

        return gMessageCodec.encodeFlashSetReqDlMsg (pBuffer, &msg);
    }

    // Wrap encodeFlashGetReqDlMsg 
    uint32_t __cdecl encodeFlashGetReqDlMsg (char * pBuffer)
    {
        return gMessageCodec.encodeFlashGetReqDlMsg (pBuffer);
    }

    // ----------------------------------------------------------------
    // MESSAGE DECODE WRAPPER FUNCTIONS
    // ----------------------------------------------------------------

    // Unpack a gpioState struct from with a uint32_t value
    void __cdecl unpackGpioState (uint32_t value,
                                  uint32_t *pGpio,
                                  bool * pInputNotOutput,
                                  bool * pOnNotOff)
    {
        *pGpio = (uint32_t) ((value & 0x00FF0000) >> 16);
        if (pInputNotOutput != NULL)
        {
            *pInputNotOutput = (bool) ((value & 0x0000FF00) >> 8);
        }
        if (pOnNotOff != NULL)
        {
            *pOnNotOff = (bool) (value & 0x000000FF);
        }
    }

    // Wrap decodeUlMsg 
    uint32_t __cdecl decodeUlMsg (const char ** ppInBuffer,
                                  uint32_t sizeInBuffer,
                                  uint32_t * pContents)
    {
        MessageCodec::DecodeResult_t decodeResult;
        UlMsgUnion_t outBuffer;
        decodeResult = gMessageCodec.decodeUlMsg (ppInBuffer,
                                                    sizeInBuffer,
                                                    &outBuffer);
        switch (decodeResult)
        {
            case (MessageCodec::DECODE_RESULT_INIT_IND_UL_MSG):
                *pContents = (uint32_t) outBuffer.initIndUlMsg.wakeUpCode;
            break;
            case (MessageCodec::DECODE_RESULT_SERIAL_NUMBER_GET_CNF_UL_MSG):
                *pContents = outBuffer.serialNumberCnfUlMsg.serialNumber;
            break;
            case (MessageCodec::DECODE_RESULT_SERIAL_NUMBER_IND_UL_MSG):
                *pContents = outBuffer.serialNumberIndUlMsg.serialNumber;
            break;
            case (MessageCodec::DECODE_RESULT_VOLUME_IND_UL_MSG):
                *pContents = outBuffer.volumeIndUlMsg.volumeLitres;
            break;
            case (MessageCodec::DECODE_RESULT_RSSI_IND_UL_MSG):
                *pContents = outBuffer.rssiIndUlMsg.rssi;
            break;
            case (MessageCodec::DECODE_RESULT_READING_INTERVAL_SET_CNF_UL_MSG):
                *pContents = outBuffer.readingIntervalSetCnfUlMsg.readingIntervalSeconds;
            break;
            case (MessageCodec::DECODE_RESULT_READING_INTERVAL_GET_CNF_UL_MSG):
                *pContents = outBuffer.readingIntervalGetCnfUlMsg.readingIntervalSeconds;
            break;
            case (MessageCodec::DECODE_RESULT_GPIO_SET_CNF_UL_MSG):
                *pContents = (uint32_t) outBuffer.gpioSetCnfUlMsg;
            break;
            case (MessageCodec::DECODE_RESULT_GPIO_GET_CNF_UL_MSG):
                *pContents = (uint32_t) outBuffer.gpioGetCnfUlMsg;
            break;
            case (MessageCodec::DECODE_RESULT_LED_SET_CNF_UL_MSG):
                *pContents = (uint32_t) outBuffer.ledSetCnfUlMsg.onNotOff;
            break;
            case (MessageCodec::DECODE_RESULT_LED_GET_CNF_UL_MSG):
                *pContents = (uint32_t) outBuffer.ledGetCnfUlMsg.onNotOff;
            break;
            case (MessageCodec::DECODE_RESULT_FLASH_SET_CNF_UL_MSG):
                *pContents = (uint32_t) outBuffer.flashSetCnfUlMsg.onNotOff;
            break;
            case (MessageCodec::DECODE_RESULT_FLASH_GET_CNF_UL_MSG):
                *pContents = (uint32_t) outBuffer.flashGetCnfUlMsg.onNotOff;
            break;
            default:
            // The decodeResult will be left as Unknown message
            break;
        }

        return decodeResult;
    }

    // ----------------------------------------------------------------
    // MISC FUNCTIONS
    // ----------------------------------------------------------------

    void  initDll (void (*printToConsole) (const char *))
    {
        gMessageCodec.initDll (printToConsole);
    } 

#ifdef __cplusplus
}  // extern "C"
#endif

// End Of File