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 Vincent Wochnik

Files at this revision

API Documentation at this revision

Comitter:
vwochnik
Date:
Mon Feb 10 15:46:26 2014 +0000
Parent:
5:dee05a7c70f9
Child:
7:f77afd49c35d
Commit message:
fix

Changed in this revision

ATResultBuffer.cpp Show annotated file Show diff for this revision Revisions of this file
ATResultBuffer.h Show annotated file Show diff for this revision Revisions of this file
common.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
program.cpp Show annotated file Show diff for this revision Revisions of this file
--- /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