Official reference client implementation for Cumulocity SmartREST on u-blox C027.
Dependencies: C027_Support C12832 LM75B MMA7660 MbedSmartRest mbed-rtos mbed
Fork of MbedSmartRestMain by
Revision 6:642e7c233e83, committed 2014-02-10
- Comitter:
- vwochnik
- Date:
- Mon Feb 10 15:46:26 2014 +0000
- Parent:
- 5:dee05a7c70f9
- Child:
- 7:f77afd49c35d
- Commit message:
- fix
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ATResultBuffer.cpp Mon Feb 10 15:46:26 2014 +0000 @@ -0,0 +1,39 @@ +#include "ATResultBuffer.h" +#include <stdlib.h> +#include <string.h> + +ATResultBuffer::ATResultBuffer() : _buffer(NULL) +{ +} + +ATResultBuffer::~ATResultBuffer() +{ + if (_buffer != NULL) + free((char*)_buffer); +} + +const char * ATResultBuffer::getLastLine() +{ + return _buffer; +} + +int ATResultBuffer::onNewATResponseLine(ATCommandsInterface* pInst, const char* line) +{ + size_t len; + + if (_buffer != NULL) + free((char*)_buffer); + _buffer = NULL; + + len = strlen(line); + + if (len) { + _buffer = (const char*)malloc(len+1); + strcpy((char*)_buffer, line); + } +} + +int ATResultBuffer::onNewEntryPrompt(ATCommandsInterface* pInst) +{ +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ATResultBuffer.h Mon Feb 10 15:46:26 2014 +0000 @@ -0,0 +1,22 @@ +#ifndef ATRESULTBUFFER_H +#define ATRESULTBUFFER_H + +#include "ATCommandsInterface.h" + +class ATResultBuffer : public IATCommandsProcessor +{ +public: + ATResultBuffer(); + ~ATResultBuffer(); + + const char * getLastLine(); + +protected: + virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line); + virtual int onNewEntryPrompt(ATCommandsInterface* pInst); + +private: + const char *_buffer; +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common.h Mon Feb 10 15:46:26 2014 +0000 @@ -0,0 +1,23 @@ +#include <stdint.h> +#include <stddef.h> +#include "mbed.h" +#include "C027.h" +#include "UbloxUSBGSMModem.h" +#include "UbloxUSBCDMAModem.h" +#include "MbedSmartRest.h" + +/** signal quality type */ +typedef struct +{ + int8_t rssi; // RSSI in dBm + uint8_t ber; // BER in % +} sigq_t; + +extern C027 c027; +//extern UbloxUSBGSMModem modem; +extern MbedSmartRest client; + +const char * imei(); +const char * cellId(); +sigq_t * signalQuality(); +int program(void); \ No newline at end of file
--- a/main.cpp Wed Feb 05 16:22:22 2014 +0000 +++ b/main.cpp Mon Feb 10 15:46:26 2014 +0000 @@ -1,210 +1,123 @@ -#include "mbed.h" -#include "C027.h" -#include "UbloxUSBGSMModem.h" -#include "UbloxUSBCDMAModem.h" - -#include "MbedSmartRest.h" -#include "StaticData.h" -#include "ComposedRecord.h" -#include "CharValue.h" -#include "IntegerValue.h" -#include "FloatValue.h" - -const char * const serialNumber = "ublox-123456789"; -StaticData srtpl( -// get device by identity -// Usage: 100,<SERIAL/NR> -"10,100,GET,/identity/externalIds/c8y_Serial/%%,,application/vnd.com.nsn.cumulocity.externalId+json,%%,STRING,\r\n" -// get device id from identity -// Response: 200,<DEVICE/ID> -"11,200,\"$.managedObject\",,\"$.id\"\r\n" -// Create device -// Usage: 101,<SERIAL/NR> -"10,101,POST,/inventory/managedObjects,application/vnd.com.nsn.cumulocity.managedObject+json,application/vnd.com.nsn.cumulocity.managedObject+json,%%,STRING,\"{\"\"name\"\":\"\"Curl Test Device\"\",\"\"type\"\":\"\"com_yourcompany?CurlDevice_1.0\"\",\"\"c8y_Hardware\"\":{\"\"revision\"\":\"\"1\"\",\"\"model\"\":\"\"Curl Test Device\"\",\"\"serialNumber\"\":\"\"%%\"\"},\"\"c8y_SupportedMeasurements\"\":[\"\"c8y_SignalStrength\"\"],\"\"c8y_IsDevice\"\":{}}\"\r\n" -// Get device id -// Response: 201,<DEVICE/ID> -"11,201,,\"$.c8y_IsDevice\",\"$.id\"\r\n" -// Insert global ID -// Usage: 102,<DEVICE/ID>,<SERIAL/NR> -"10,102,POST,/identity/globalIds/%%/externalIds,application/vnd.com.nsn.cumulocity.externalId+json,application/vnd.com.nsn.cumulocity.externalId+json,%%,UNSIGNED STRING,\"{\"\"type\"\":\"\"c8y_Serial\"\",\"\"externalId\"\":\"\"%%\"\"}\"\r\n" -// Insert measurement -// USAGE: 103,<DEVICE/ID>,<RSSI>,<BER> -"10,103,POST,/measurement/measurements,application/vnd.com.nsn.cumulocity.measurement+json,application/vnd.com.nsn.cumulocity.measurement+json,%%,NOW UNSIGNED NUMBER UNSIGNED,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_SignalStrength\"\",\"\"c8y_SignalStrength\"\":{\"\"rssi\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"dBm\"\"},\"\"ber\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"%\"\"}}}\"\r\n" -); - -long existing(); -long create(); -bool identify(long deviceId); -bool measurement(long deviceId, double rssi, int ber); +#include "common.h" +#include "ATResultBuffer.h" C027 c027; -MbedSmartRest client("http://developer.cumulocity.com/s", "vaillant/admin", "klanpi", "com_u-blox_C027_REV-A_0.3"); -//MbedSmartRest client("http://nocore.info:8888/", "vaillant/admin", "klanpi", "com_cumulocity_MbedTestDevice_2.0"); +ATCommandsInterface *cmdIface = NULL; +char cIMEI[21] = ""; +char cCellId[9] = ""; +sigq_t sigQ = {0, 0}; int main() { - long deviceId; double rssi; int ber; - - puts("Hello!"); - + int ret; + + puts("Started..."); c027.mdmWakeup(); c027.mdmReset(); c027.mdmPower(true); UbloxUSBGSMModem modem; - + cmdIface = modem.getATCommandsInterface(); + + puts("Connecting..."); if (modem.connect("public4.m2minternet.com")) { puts("GPRS connection failure."); return 2; } - puts("Bootstrapping"); - if (client.bootstrap(srtpl) != SMARTREST_SUCCESS) { - puts("Bootstrapping failed."); - return 2; - } - - puts("Starting action..."); - - if ((deviceId = existing()) == 0) { - deviceId = create(); - if (deviceId != 0) - identify(deviceId); - } + printf("IMEI: %s\r\n", imei()); + printf("Cell-ID: %s\r\n", cellId()); + sigq_t *sq = signalQuality(); + printf("RSSI: %d dBm, BER: %d %%\r\n", sq->rssi, sq->ber); - printf("Device ID: %ld\r\n", deviceId); - - if (deviceId != 0) { - rssi = -50; - ber = 50; - - while (true) { - printf("[MEASUREMENT] RSSI: %lf, BER: %d %%\n", rssi, ber); - measurement(deviceId, rssi, ber); - wait(60000); - } - } + //puts("Starting program..."); + //ret = program(); modem.disconnect(); - c027.mdmPower(false); - return 0; + c027.mdmPower(false); + + return ret; } -long existing() +const char * imei() { - ComposedRecord newMoRec(true); // set copy=true b/c tmp objects - ParsedRecord received; - - puts("Checking for device existance..."); - - newMoRec.add(IntegerValue(100)).add(CharValue(serialNumber)); - - if (client.send(newMoRec) != SMARTREST_SUCCESS) { - puts("Send failed."); - return 0; - } + ATCommandsInterface::ATResult result; + ATResultBuffer buffer; + + if ((cmdIface == NULL) || (strlen(cIMEI))) + return cIMEI; - if (client.receive(received) != SMARTREST_SUCCESS) { - puts("No device found."); - return 0; - } + cmdIface->execute("AT+CGSN", &buffer, &result); + if (ATCommandsInterface::ATResult::AT_OK == result.result) + strcpy(cIMEI, buffer.getLastLine()); + else + cIMEI[0] = '\0'; - if (received.values() == 0) { - puts("Received no values."); - return 0; - } - if (received.value(0).integerValue() == 50) { - client.stop(); - return 0; - } - - if (received.value(0).integerValue() != 200) { - puts("Bad response."); - return 0; - } - - client.stop(); - return received.value(2).integerValue(); + return cIMEI; } -long create() +const char * cellId() { - ComposedRecord newMoRec(true); // set copy=true b/c tmp objects - ParsedRecord received; - - puts("Creating device..."); + int len; uint32_t cellId; + + ATCommandsInterface::ATResult result; + ATResultBuffer buffer; + + cCellId[0] = '\0'; - newMoRec.add(IntegerValue(101)).add(CharValue(serialNumber)); - - if (client.send(newMoRec) != SMARTREST_SUCCESS) { - puts("Send failed."); - return 0; - } + if (cmdIface == NULL) + return cCellId; - if (client.receive(received) != SMARTREST_SUCCESS) { - puts("No device found."); - return 0; - } + cmdIface->executeSimple("AT+CREG=2", &result); + if (ATCommandsInterface::ATResult::AT_OK != result.result) + return cCellId; - if (received.values() != 3) { - puts("Bad received data."); - return 0; - } - - if (received.value(0).integerValue() != 201) { - puts("Bad received data."); - return 0; - } + cmdIface->execute("AT+CREG?", &buffer, &result); + if (buffer.getLastLine() == NULL) + return cCellId; + sscanf(buffer.getLastLine(), "+CREG: 2,%*d,\"%*lx\",\"%lx\",%*d%n", &cellId, &len); + if (len != strlen(buffer.getLastLine())) + return cCellId; + snprintf(cCellId, sizeof(cCellId), "%lX", cellId); - client.stop(); - return received.value(2).integerValue(); + return cCellId; } -bool identify(long deviceId) +sigq_t * signalQuality() { - ComposedRecord newMoRec(true); // set copy=true b/c tmp objects - ParsedRecord received; + int rssi = 0, ber = 0, len = 0; - puts("Adding global identifier..."); + ATCommandsInterface::ATResult result; + ATResultBuffer buffer; + + sigQ.rssi = 0; sigQ.ber = 0; - newMoRec.add(IntegerValue(102)).add(IntegerValue(deviceId)).add(CharValue(serialNumber)); + if (cmdIface == NULL) + return &sigQ; - if (client.send(newMoRec) != SMARTREST_SUCCESS) { - puts("Sending failed."); - return false; - } + cmdIface->execute("AT+CSQ", &buffer, &result); + if (buffer.getLastLine() == NULL) + return &sigQ; + + sscanf(buffer.getLastLine(), "+CSQ: %d,%d%n", &rssi, &ber, &len); + if (len != strlen(buffer.getLastLine())) + return &sigQ; + + if (rssi <= 31) + sigQ.rssi = -113 + (2 * rssi); + else + sigQ.rssi = 0; - if (client.receive(received) != SMARTREST_SUCCESS) { - puts("Failed."); - return false; + switch (ber) { + case 0: sigQ.ber = 49; break; + case 1: sigQ.ber = 43; break; + case 2: sigQ.ber = 37; break; + case 3: sigQ.ber = 31; break; + case 4: sigQ.ber = 25; break; + case 5: sigQ.ber = 19; break; + case 6: sigQ.ber = 13; break; + case 7: sigQ.ber = 7; break; + default: sigQ.ber = 0; } - if (received.values() != 3) { - puts("Received bad data."); - return false; - } - - if (received.value(0).integerValue() != 200) { - puts("Received bad data."); - return false; - } - - client.stop(); - return true; + return &sigQ; } - -bool measurement(long deviceId, double rssi, int ber) -{ - ComposedRecord newMoRec(true); // set copy=true b/c tmp objects - - puts("Creating measurement..."); - - newMoRec.add(IntegerValue(103)).add(IntegerValue(deviceId)).add(FloatValue(rssi, 0)).add(IntegerValue(ber)); - - if (client.send(newMoRec) != SMARTREST_SUCCESS) { - puts("Send failed."); - return false; - } - - client.stop(); - return true; -} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/program.cpp Mon Feb 10 15:46:26 2014 +0000 @@ -0,0 +1,192 @@ +#include "common.h" +#include "StaticData.h" +#include "ComposedRecord.h" +#include "CharValue.h" +#include "IntegerValue.h" +#include "FloatValue.h" + +const char * const serialNumber = "ublox-123456789"; +StaticData srtpl( +// get device by identity +// Usage: 100,<SERIAL/NR> +"10,100,GET,/identity/externalIds/c8y_Serial/%%,,application/vnd.com.nsn.cumulocity.externalId+json,%%,STRING,\r\n" +// get device id from identity +// Response: 200,<DEVICE/ID> +"11,200,\"$.managedObject\",,\"$.id\"\r\n" +// Create device +// Usage: 101,<SERIAL/NR> +"10,101,POST,/inventory/managedObjects,application/vnd.com.nsn.cumulocity.managedObject+json,application/vnd.com.nsn.cumulocity.managedObject+json,%%,STRING,\"{\"\"name\"\":\"\"Curl Test Device\"\",\"\"type\"\":\"\"com_yourcompany?CurlDevice_1.0\"\",\"\"c8y_Hardware\"\":{\"\"revision\"\":\"\"1\"\",\"\"model\"\":\"\"Curl Test Device\"\",\"\"serialNumber\"\":\"\"%%\"\"},\"\"c8y_SupportedMeasurements\"\":[\"\"c8y_SignalStrength\"\"],\"\"c8y_IsDevice\"\":{}}\"\r\n" +// Get device id +// Response: 201,<DEVICE/ID> +"11,201,,\"$.c8y_IsDevice\",\"$.id\"\r\n" +// Insert global ID +// Usage: 102,<DEVICE/ID>,<SERIAL/NR> +"10,102,POST,/identity/globalIds/%%/externalIds,application/vnd.com.nsn.cumulocity.externalId+json,application/vnd.com.nsn.cumulocity.externalId+json,%%,UNSIGNED STRING,\"{\"\"type\"\":\"\"c8y_Serial\"\",\"\"externalId\"\":\"\"%%\"\"}\"\r\n" +// Insert measurement +// USAGE: 103,<DEVICE/ID>,<RSSI>,<BER> +"10,103,POST,/measurement/measurements,application/vnd.com.nsn.cumulocity.measurement+json,application/vnd.com.nsn.cumulocity.measurement+json,%%,NOW UNSIGNED NUMBER UNSIGNED,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_SignalStrength\"\",\"\"c8y_SignalStrength\"\":{\"\"rssi\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"dBm\"\"},\"\"ber\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"%\"\"}}}\"\r\n" +); + +long existing(); +long create(); +bool identify(long deviceId); +bool measurement(long deviceId, double rssi, int ber); + +MbedSmartRest client("http://developer.cumulocity.com/s", "vaillant/admin", "klanpi", "com_u-blox_C027_REV-A_0.3"); +//MbedSmartRest client("http://nocore.info:8888/", "vaillant/admin", "klanpi", "com_cumulocity_MbedTestDevice_2.0"); + +int program(void) +{ + long deviceId; double rssi; int ber; + + puts("Hello!"); + + puts("Bootstrapping"); + if (client.bootstrap(srtpl) != SMARTREST_SUCCESS) { + puts("Bootstrapping failed."); + return 2; + } + + puts("Starting action..."); + + if ((deviceId = existing()) == 0) { + deviceId = create(); + if (deviceId != 0) + identify(deviceId); + } + + printf("Device ID: %ld\r\n", deviceId); + + if (deviceId != 0) { + rssi = -50; + ber = 50; + + while (true) { + printf("[MEASUREMENT] RSSI: %lf, BER: %d %%\n", rssi, ber); + measurement(deviceId, rssi, ber); + wait(60000); + } + } + + return 0; +} + +long existing() +{ + ComposedRecord newMoRec(true); // set copy=true b/c tmp objects + ParsedRecord received; + + puts("Checking for device existance..."); + + newMoRec.add(IntegerValue(100)).add(CharValue(serialNumber)); + + if (client.send(newMoRec) != SMARTREST_SUCCESS) { + puts("Send failed."); + return 0; + } + + if (client.receive(received) != SMARTREST_SUCCESS) { + puts("No device found."); + return 0; + } + + if (received.values() == 0) { + puts("Received no values."); + return 0; + } + if (received.value(0).integerValue() == 50) { + client.stop(); + return 0; + } + + if (received.value(0).integerValue() != 200) { + puts("Bad response."); + return 0; + } + + client.stop(); + return received.value(2).integerValue(); +} + +long create() +{ + ComposedRecord newMoRec(true); // set copy=true b/c tmp objects + ParsedRecord received; + + puts("Creating device..."); + + newMoRec.add(IntegerValue(101)).add(CharValue(serialNumber)); + + if (client.send(newMoRec) != SMARTREST_SUCCESS) { + puts("Send failed."); + return 0; + } + + if (client.receive(received) != SMARTREST_SUCCESS) { + puts("No device found."); + return 0; + } + + if (received.values() != 3) { + puts("Bad received data."); + return 0; + } + + if (received.value(0).integerValue() != 201) { + puts("Bad received data."); + return 0; + } + + client.stop(); + return received.value(2).integerValue(); +} + +bool identify(long deviceId) +{ + ComposedRecord newMoRec(true); // set copy=true b/c tmp objects + ParsedRecord received; + + puts("Adding global identifier..."); + + newMoRec.add(IntegerValue(102)).add(IntegerValue(deviceId)).add(CharValue(serialNumber)); + + if (client.send(newMoRec) != SMARTREST_SUCCESS) { + puts("Sending failed."); + return false; + } + + if (client.receive(received) != SMARTREST_SUCCESS) { + puts("Failed."); + return false; + } + + if (received.values() != 3) { + puts("Received bad data."); + return false; + } + + if (received.value(0).integerValue() != 200) { + puts("Received bad data."); + return false; + } + + client.stop(); + return true; +} + +bool measurement(long deviceId, double rssi, int ber) +{ + ComposedRecord newMoRec(true); // set copy=true b/c tmp objects + + puts("Creating measurement..."); + + newMoRec.add(IntegerValue(103)).add(IntegerValue(deviceId)).add(FloatValue(rssi, 0)).add(IntegerValue(ber)); + + if (client.send(newMoRec) != SMARTREST_SUCCESS) { + puts("Send failed."); + return false; + } + + client.stop(); + return true; +} \ No newline at end of file