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:
xinlei
Date:
Wed May 20 09:55:49 2015 +0000
Parent:
116:4eb3c7e945cf
Child:
118:e831cdb799ab
Commit message:
device bootstrap revamp

Changed in this revision

DeviceBootstrap.cpp Show annotated file Show diff for this revision Revisions of this file
DeviceBootstrap.h Show annotated file Show diff for this revision Revisions of this file
DeviceInfo.cpp Show annotated file Show diff for this revision Revisions of this file
DeviceInfo.h Show annotated file Show diff for this revision Revisions of this file
DeviceIntegration.cpp Show annotated file Show diff for this revision Revisions of this file
DeviceIntegration.h Show annotated file Show diff for this revision Revisions of this file
MbedAgent.cpp Show annotated file Show diff for this revision Revisions of this file
MbedAgent.h Show annotated file Show diff for this revision Revisions of this file
config/ConfigSync.cpp 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
measurement/Potentiometer.cpp Show annotated file Show diff for this revision Revisions of this file
operation/PollThread.cpp Show annotated file Show diff for this revision Revisions of this file
util/SmartRestConf.cpp Show annotated file Show diff for this revision Revisions of this file
util/SmartRestConf.h Show annotated file Show diff for this revision Revisions of this file
util/dict.h Show annotated file Show diff for this revision Revisions of this file
--- a/DeviceBootstrap.cpp	Mon May 18 09:29:12 2015 +0000
+++ b/DeviceBootstrap.cpp	Wed May 20 09:55:49 2015 +0000
@@ -1,15 +1,12 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include "rtos.h"
 #include "DeviceBootstrap.h"
 #include "Storage.h"
 #include "LCDDisplay.h"
-#include "ComposedRecord.h"
-#include "CharValue.h"
-#include "IntegerValue.h"
-#include "ParsedRecord.h"
 #include "SmartRestConf.h"
+#include "SmartRestSocket.h"
+#include "lex.h"
 #include "logging.h"
 
 // Device bootstrap tenant, username and password
@@ -17,13 +14,6 @@
 #define BOOTSTRAP_USERNAME "devicebootstrap"
 #define BOOTSTRAP_PASSWORD "Fhdt1bb1f"
 
-DeviceBootstrap::DeviceBootstrap(AbstractSmartRest& client,
-    DeviceInfo& deviceInfo):
-    _client(client),
-    _deviceInfo(deviceInfo)
-{
-}
-
 bool DeviceBootstrap::bootstrap()
 {
     char tenant[CREDENTIAL_LENGTH];
@@ -44,48 +34,50 @@
 
 bool DeviceBootstrap::obtainFromPlatform()
 {
-    ComposedRecord record;
-    ParsedRecord recvdRecord;
+        char buf[SMARTREST_SIZE];
+        char buf2[SMARTREST_BODY_SIZE];
+        SmartRestSocket sock;
+        int l2 = snprintf(buf2, sizeof(buf2), "61,%s\r\n", deviceInfo.imei());
 
-    IntegerValue msgId(61);
-    CharValue identifier(_deviceInfo.imei());
-    if (!record.add(msgId) || !record.add(identifier))
-        return false;
-
-    LCDDisplay::inst().setLines("Bootstrap", _deviceInfo.imei());
+        // set authorization for bootstrap
+        setAuth(BOOTSTRAP_TENANT, BOOTSTRAP_USERNAME, BOOTSTRAP_PASSWORD);
+        LCDDisplay::inst().setLines("Bootstrap", deviceInfo.imei());
+        for (unsigned short i = 0; i < 255; ++i) {
+                int l = snprintf(buf, sizeof(buf), fmtSmartRest, "/s", l2, buf2);
+                l = sock.sendAndReceive(buf, l, sizeof(buf));
+                if (l <= 0) continue;
 
-    // set authorization for bootstrap
-    setAuth(BOOTSTRAP_TENANT, BOOTSTRAP_USERNAME, BOOTSTRAP_PASSWORD);
-    for (uint8_t tries = 255; tries; --tries) {
-        if (_client.send(record, "") != SMARTREST_SUCCESS) {
-            _client.stop();
-            Thread::wait(2000);
-            continue;
-        }
-        if (_client.receive(recvdRecord) != SMARTREST_SUCCESS) {
-            _client.stop();
-            Thread::wait(2000);
-            continue;
+                const char *p = skipHTTPHeader(buf);
+                if (p) {
+                        Token tok;
+                        p = lex(p, tok);
+                        if (tok.len==2 && strncmp(tok.p, "70", tok.len)==0) {
+                                for (unsigned short j = 0; *p && j < 3; ++j) {
+                                        p = lex(p, tok);
+                                }
+                                if (tok.type == Token::STRING) {
+                                        char tenant[CREDENTIAL_LENGTH] = {0};
+                                        char username[CREDENTIAL_LENGTH] = {0};
+                                        char password[CREDENTIAL_LENGTH] = {0};
+                                        strncpy(tenant, tok.p, tok.len);
+                                        p = lex(p, tok);
+                                        if (tok.type == Token::STRING)
+                                                strncpy(username, tok.p, tok.len);
+                                        else
+                                                return false;
+                                        p = lex(p, tok);
+                                        if (tok.type == Token::STRING)
+                                                strncpy(password, tok.p, tok.len);
+                                        else
+                                                return false;
+                                        setAuth(tenant, username, password);
+                                        LCDDisplay::inst().setLines("Bootstrap Success", srTenant, srUsername);
+                                        aInfo("%s/%s:%s\n", srTenant, srUsername, srPassword);
+                                        return true;
+                                } else
+                                        return false;
+                        }
+                }
         }
-        _client.stop();
-
-        if ((recvdRecord.values() < 1) ||
-            (recvdRecord.value(0).integerValue() == 50)) {
-            Thread::wait(2000);
-            continue;
-        }
-        if ((recvdRecord.value(0).integerValue() != 70) ||
-            (recvdRecord.values() != 6)) {
-            return false;
-        }
-
-        setAuth(recvdRecord.value(3).characterValue(),
-                recvdRecord.value(4).characterValue(),
-                recvdRecord.value(5).characterValue());
-        LCDDisplay::inst().setLines("Bootstrap Success", srTenant, srUsername);
-        aInfo("Set auth: %s/%s:%s(%s)\n", srTenant, srUsername, srPassword, srAuthStr);
-        return true;
-    }
-    LCDDisplay::inst().setLines("Bootstrap Failure");
-    return false;
+        return false;
 }
\ No newline at end of file
--- a/DeviceBootstrap.h	Mon May 18 09:29:12 2015 +0000
+++ b/DeviceBootstrap.h	Wed May 20 09:55:49 2015 +0000
@@ -2,22 +2,20 @@
 #define DEVICEBOOTSTRAP_H
 
 #include <stddef.h>
-#include "AbstractSmartRest.h"
 #include "DeviceInfo.h"
 
 
 class DeviceBootstrap
 {
 public:
-    DeviceBootstrap(AbstractSmartRest&, DeviceInfo&);
+    DeviceBootstrap(DeviceInfo& d): deviceInfo(d) {}
     bool bootstrap();
 
 protected:
     bool obtainFromPlatform();
 
 private:
-    AbstractSmartRest& _client;
-    DeviceInfo& _deviceInfo;
+    DeviceInfo& deviceInfo;
 };
 
 #endif
\ No newline at end of file
--- a/DeviceInfo.cpp	Mon May 18 09:29:12 2015 +0000
+++ b/DeviceInfo.cpp	Wed May 20 09:55:49 2015 +0000
@@ -1,4 +1,3 @@
-#include <stdlib.h>
 #include <string.h>
 #include "DeviceInfo.h"
 #include "logging.h"
--- a/DeviceInfo.h	Mon May 18 09:29:12 2015 +0000
+++ b/DeviceInfo.h	Wed May 20 09:55:49 2015 +0000
@@ -17,10 +17,10 @@
         memset(&_signalQuality, 0, sizeof(DeviceInfo::SignalQuality));
     }
     
-    const char* imsi() const { return _devStatus.imsi; }
-    const char* imei() const { return _devStatus.imei; }
     const char* cellId();
     const char* iccid() const { return _devStatus.ccid; }
+    const char* imei() const { return _devStatus.imei; }
+    const char* imsi() const { return _devStatus.imsi; }
     SignalQuality * signalQuality(bool realTime=true);
 
 private:
--- a/DeviceIntegration.cpp	Mon May 18 09:29:12 2015 +0000
+++ b/DeviceIntegration.cpp	Wed May 20 09:55:49 2015 +0000
@@ -6,15 +6,6 @@
 #include "SmartRestConf.h"
 #include "logging.h"
 
-DeviceIntegration::DeviceIntegration(AbstractSmartRest& client, SmartRestTemplate& tpl,
-    DeviceInfo& deviceInfo) :
-    _init(false),
-    _tpl(tpl),
-    _client(client),
-    _deviceInfo(deviceInfo)
-{
-}
-
 bool DeviceIntegration::init()
 {
     if (_init)
--- a/DeviceIntegration.h	Mon May 18 09:29:12 2015 +0000
+++ b/DeviceIntegration.h	Wed May 20 09:55:49 2015 +0000
@@ -1,15 +1,15 @@
 #ifndef DEVICEINTEGRATION_H
 #define DEVICEINTEGRATION_H
 
-#include "AbstractSmartRest.h"
+#include "SmartRest.h"
 #include "SmartRestTemplate.h"
 #include "DeviceInfo.h"
 
 class DeviceIntegration
 {
 public:
-    DeviceIntegration(AbstractSmartRest&, SmartRestTemplate&, DeviceInfo&);
-    
+    DeviceIntegration(SmartRest& c, SmartRestTemplate& t, DeviceInfo& d):
+    _init(false), _tpl(t), _client(c), _deviceInfo(d) {}
     bool init();
     bool integrate();
 
@@ -22,7 +22,7 @@
 private:
     bool _init;
     SmartRestTemplate& _tpl;
-    AbstractSmartRest& _client;
+    SmartRest& _client;
     DeviceInfo& _deviceInfo;
 };
 
--- a/MbedAgent.cpp	Mon May 18 09:29:12 2015 +0000
+++ b/MbedAgent.cpp	Wed May 20 09:55:49 2015 +0000
@@ -3,10 +3,9 @@
 #include "logging.h"
 
 MbedAgent::MbedAgent(DeviceInfo& deviceInfo):
-    _client(), tpl(), _bootstrap(_client, deviceInfo), 
-    _integration(_client, tpl, deviceInfo), lcdThirdLineBlank(true),
-    signal(deviceInfo), temp(), poti(), gps(), acc(), sock(),
-    pool(), _operationSupport(tpl, pool)
+    client(), tpl(), _bootstrap(deviceInfo), _integration(client, tpl, deviceInfo),
+    lcdThirdLineBlank(true), signal(deviceInfo), temp(), poti(), gps(),
+    acc(), sock(), pool(), _operationSupport(tpl, pool)
 {
     reporters[0] = &ConfigSync::inst();
     reporters[1] = &temp;
@@ -75,16 +74,18 @@
 {
     // device bootstrapping process
     if (!_bootstrap.bootstrap()) {
+        LCDDisplay::inst().setLines("Bootstrap Failure");
         return -1;
     }
+
     Thread::wait(2000);
-
     LCDDisplay::inst().setLines("Connect to Cloud", srHost);
+    setX_ID(UBLOX_SMARTREST_VERSION);
     if (!_integration.integrate()) {
         LCDDisplay::inst().setLines("Integrate failure");
         return -2;
     }
-    setX_ID(_client.getIdentifier());
+    setX_ID(client.getIdentifier());
     aInfo("Set X-ID: %s\n", srX_ID);
 
     return 0;
@@ -117,8 +118,7 @@
         }
         if (l) {
             l = snprintf(buf, sizeof(buf), fmtSmartRest, "/s", l, buf2);
-//            l = sock.sendOnly(buf, l);
-            l = sock.sendAndReceive(buf, l, sizeof(buf));
+            l = sock.sendOnly(buf, l);
             if (l < 0)
                 aWarning("%s\n", status);
         }
--- a/MbedAgent.h	Mon May 18 09:29:12 2015 +0000
+++ b/MbedAgent.h	Wed May 20 09:55:49 2015 +0000
@@ -32,7 +32,7 @@
     void loop();
 
 private:
-    SmartRest _client;
+    SmartRest client;
     SmartRestTemplate tpl;
     DeviceBootstrap _bootstrap;
     DeviceIntegration _integration;
--- a/config/ConfigSync.cpp	Mon May 18 09:29:12 2015 +0000
+++ b/config/ConfigSync.cpp	Wed May 20 09:55:49 2015 +0000
@@ -39,10 +39,13 @@
 
 bool ConfigSync::updateConfiguration(const char *buf)
 {
+        // compromise for the platform, which requires a conf report despite
+        // the conf is updated or NOT. More appropriately would be setting
+        // `changed=true` inside the `if` block, when the conf is actually updated.
+        changed = true; 
         bool b = cp.parse(buf);
         if (b && validateConfiguration(cp.dict)) {
                 dict = cp.dict;
-                changed = true;
                 saveConfiguration();
                 return true;
         } else {
--- a/main.cpp	Mon May 18 09:29:12 2015 +0000
+++ b/main.cpp	Wed May 20 09:55:49 2015 +0000
@@ -139,7 +139,7 @@
         if (p) {
             snprintf(s, sizeof(s), "%.*s-%.*s", 3, p, getMNCLen(p), p+3);
         }
-        LCDDisplay::inst().setLines("Wrong APN Settting", "MCC-MNC:", s);
+        LCDDisplay::inst().setLines("Unknown APN Settting", "MCC-MNC:", s);
         shutdown();
         return 4;
     }
--- a/measurement/Potentiometer.cpp	Mon May 18 09:29:12 2015 +0000
+++ b/measurement/Potentiometer.cpp	Wed May 20 09:55:49 2015 +0000
@@ -24,7 +24,25 @@
 size_t Potentiometer::read(char *buf, size_t maxLen, char *status, size_t num)
 {
         static const char *fmt = "107,%ld,%f,%f\r\n";
-        float data[2] = {(float)analog1*100, (float)analog2*100};
+        float data[2] = {0, 0};
+        float min[2] = {100, 100};
+        float max[2] = {0, 0};
+        // multiple sampling for data smoothing
+        const unsigned short N = 10;
+        for (unsigned short i = 0; i < N; ++i) {
+                float d0 = (float)analog1*100;
+                float d1 = (float)analog2*100;
+                data[0] += d0;
+                data[1] += d1;
+                min[0] = min[0] <= d0 ? min[0] : d0;
+                min[1] = min[1] <= d1 ? min[1] : d1;
+                max[0] = max[0] >= d0 ? max[0] : d0;
+                max[1] = max[1] >= d1 ? max[1] : d1;
+                Thread::wait(10);
+        }
+        data[0] = (data[0]-min[0]-max[0]) / (N-2);
+        data[1] = (data[1]-min[1]-max[1]) / (N-2);
+
         if (!valueChanged(oldValues, data)) {
                 time_t t_interval = time(NULL) - t_start;
                 if (t_interval < TIME_LIMIT_ANA) {
@@ -32,28 +50,6 @@
                 } else {
                         aDebug("Poti: Timeout at %d s.\n", t_interval);
                 }
-        } else {
-                float min[2] = {100, 100};
-                float max[2] = {0, 0};
-                data[0] = 0;
-                data[1] = 0;
-                // multiple sampling for data smoothing
-                const unsigned short N = 10;
-                for (unsigned short i = 0; i < N; ++i) {
-                        float d0 = (float)analog1*100;
-                        float d1 = (float)analog2*100;
-                        data[0] += d0;
-                        data[1] += d1;
-                        min[0] = min[0] <= d0 ? min[0] : d0;
-                        min[1] = min[1] <= d1 ? min[1] : d1;
-                        max[0] = max[0] >= d0 ? max[0] : d0;
-                        max[1] = max[1] >= d1 ? max[1] : d1;
-                        Thread::wait(10);
-                }
-                data[0] = (data[0]-min[0]-max[0]) / (N-2);
-                data[1] = (data[1]-min[1]-max[1]) / (N-2);
-                if (!valueChanged(oldValues, data))
-                        return 0;
         }
 
         size_t l = snprintf(buf, maxLen, fmt, deviceID, data[0], data[1]);
--- a/operation/PollThread.cpp	Mon May 18 09:29:12 2015 +0000
+++ b/operation/PollThread.cpp	Wed May 20 09:55:49 2015 +0000
@@ -15,7 +15,7 @@
         for (const char* p = skipHTTPHeader(buf); isalnum(*p); ++p, ++i) {
                 bayeuxId[i] = *p;
         }
-        bayeuxId[i] = '\0';
+        bayeuxId[i] = 0;
         return bayeuxId[0];
 }
 
--- a/util/SmartRestConf.cpp	Mon May 18 09:29:12 2015 +0000
+++ b/util/SmartRestConf.cpp	Wed May 20 09:55:49 2015 +0000
@@ -7,7 +7,8 @@
 char srUsername[CREDENTIAL_LENGTH] = {0};
 char srPassword[CREDENTIAL_LENGTH] = {0};
 char srAuthStr[100] = {0};
-const char *srX_ID = "com_cumulocity_MbedAgent_1.5.2";
+//const char *srX_ID = "com_cumulocity_MbedAgent_1.5.2";
+const char *srX_ID = NULL;
 const char *srHost = "developer.cumulocity.com";
 //const char *srHost = "management.m2m-devicecloud.com";
 long deviceID = 0;
@@ -55,8 +56,13 @@
 
 static void setSmartRestFmt()
 {
-        const char fmt[] = "POST %%s HTTP/1.0\r\nHost: %s\r\nAuthorization: Basic %s\r\nX-Id: %s\r\nContent-Length: %%d\r\n\r\n%%s";
-        snprintf(fmtSmartRest, sizeof(fmtSmartRest), fmt, srHost, srAuthStr, srX_ID);
+        if (srX_ID) {
+                const char fmt[] = "POST %%s HTTP/1.0\r\nHost: %s\r\nAuthorization: Basic %s\r\nX-Id: %s\r\nContent-Length: %%d\r\n\r\n%%s";
+                snprintf(fmtSmartRest, sizeof(fmtSmartRest), fmt, srHost, srAuthStr, srX_ID);
+        } else {
+                const char fmt[] = "POST %%s HTTP/1.0\r\nHost: %s\r\nAuthorization: Basic %s\r\nContent-Length: %%d\r\n\r\n%%s";
+                snprintf(fmtSmartRest, sizeof(fmtSmartRest), fmt, srHost, srAuthStr);
+        }
 }
 
 void setX_ID(const char* id)
--- a/util/SmartRestConf.h	Mon May 18 09:29:12 2015 +0000
+++ b/util/SmartRestConf.h	Wed May 20 09:55:49 2015 +0000
@@ -7,6 +7,7 @@
 #define SMARTREST_SSL_BODY_SIZE 5000
 
 #define CREDENTIAL_LENGTH 128
+#define UBLOX_SMARTREST_VERSION "com_cumulocity_MbedAgent_1.5.2"
 
 extern char srTenant[];
 extern char srUsername[];
--- a/util/dict.h	Mon May 18 09:29:12 2015 +0000
+++ b/util/dict.h	Wed May 20 09:55:49 2015 +0000
@@ -59,7 +59,7 @@
         size_t dump(char* buf) const {
                 size_t l = 0;
                 for (size_t i = 0; i < count; ++i) {
-                        l += sprintf(buf+l, "%s=%s;\r\n", items[i].key, items[i].value);
+                        l += sprintf(buf+l, "%s=%s;", items[i].key, items[i].value);
                 }
                 buf[l] = 0;
                 return l;