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:
Fri May 08 12:19:57 2015 +0000
Parent:
100:47ea098f8a47
Child:
102:ef2827b2d00a
Commit message:
v2.1rc3

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
DeviceIntegration.cpp 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/ConfigParser.cpp Show annotated file Show diff for this revision Revisions of this file
config/ConfigParser.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
config/ConfigSync.h Show annotated file Show diff for this revision Revisions of this file
config/ConfigurationProperties.cpp Show diff for this revision Revisions of this file
config/ConfigurationProperties.h Show diff for this revision Revisions of this file
config/DeviceConfiguration.cpp Show diff for this revision Revisions of this file
config/DeviceConfiguration.h Show diff for this revision Revisions of this file
io/DeviceMemory.cpp Show annotated file Show diff for this revision Revisions of this file
io/DeviceMemory.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
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
measurement/Acceleration.cpp Show annotated file Show diff for this revision Revisions of this file
measurement/Acceleration.h Show annotated file Show diff for this revision Revisions of this file
measurement/AccelerationMeasurement.cpp Show diff for this revision Revisions of this file
measurement/AccelerationMeasurement.h Show diff for this revision Revisions of this file
measurement/AnalogMeasurement.cpp Show diff for this revision Revisions of this file
measurement/AnalogMeasurement.h Show diff for this revision Revisions of this file
measurement/Location.cpp Show annotated file Show diff for this revision Revisions of this file
measurement/Location.h Show annotated file Show diff for this revision Revisions of this file
measurement/LocationUpdate.cpp Show diff for this revision Revisions of this file
measurement/LocationUpdate.h Show diff for this revision Revisions of this file
measurement/Potentiometer.cpp Show annotated file Show diff for this revision Revisions of this file
measurement/Potentiometer.h Show annotated file Show diff for this revision Revisions of this file
measurement/Signal.cpp Show annotated file Show diff for this revision Revisions of this file
measurement/Signal.h Show annotated file Show diff for this revision Revisions of this file
measurement/SignalQualityMeasurement.cpp Show diff for this revision Revisions of this file
measurement/SignalQualityMeasurement.h Show diff for this revision Revisions of this file
measurement/Temperature.cpp Show annotated file Show diff for this revision Revisions of this file
measurement/Temperature.h Show annotated file Show diff for this revision Revisions of this file
measurement/TemperatureMeasurement.cpp Show diff for this revision Revisions of this file
measurement/TemperatureMeasurement.h Show diff for this revision Revisions of this file
operation/ControlParser.cpp Show annotated file Show diff for this revision Revisions of this file
operation/ControlParser.h Show annotated file Show diff for this revision Revisions of this file
operation/OperationSupport.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
operation/PollThread.h Show annotated file Show diff for this revision Revisions of this file
operation/ReportThread.h Show annotated file Show diff for this revision Revisions of this file
util/AbstractReporter.h 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/SmartRestTemplate.cpp 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	Thu May 07 13:56:19 2015 +0000
+++ b/DeviceBootstrap.cpp	Fri May 08 12:19:57 2015 +0000
@@ -12,6 +12,12 @@
 #include "SmartRestConf.h"
 #include "logging.h"
 
+/** The username used for device bootstrapping. */
+#define BOOTSTRAP_USERNAME "management/devicebootstrap"
+
+/** The password used for device bootstrapping. */
+#define BOOTSTRAP_PASSWORD "Fhdt1bb1f"
+
 DeviceBootstrap::DeviceBootstrap(AbstractSmartRest& client,
     DeviceInfo& deviceInfo) :
     _client(client),
@@ -22,14 +28,22 @@
 
 bool DeviceBootstrap::setUpCredentials()
 {
-    if ((*_username == '\0' || *_password == '\0') &&
-        (!obtainFromStorage())) {
-        if (!obtainFromPlatform())
-            return false;
-        if (!writeToStorage())
-            aWarning("Can not write credentials!\n");
+//    if ((*_username == '\0' || *_password == '\0') &&
+//        (!obtainFromStorage())) {
+//        if (!obtainFromPlatform())
+//            return false;
+//        if (!writeToStorage())
+//            aError("Can not write credentials!\n");
+//    }
+    if (loadCredential(_username, _password, CREDENTIAL_LENGTH)) {
+        return true;
+    } else if (obtainFromPlatform()) {
+        if (!saveCredential(_username, _password, CREDENTIAL_LENGTH))
+            aError("Write credentials!\n");
+        return true;
+    } else {
+        return false;
     }
-    return true;
 }
 
 const char * DeviceBootstrap::username()
@@ -44,11 +58,11 @@
 
 bool DeviceBootstrap::obtainFromStorage()
 {
-    return loadPlatformCredentials(_username, _password, DEVICE_BOOTSTRAP_CREDENTIALS_LENGTH);
+    return loadCredential(_username, _password, CREDENTIAL_LENGTH);
 }
 
 bool DeviceBootstrap::obtainFromPlatform()
-{    
+{
     ComposedRecord record;
     ParsedRecord recvdRecord;
 
@@ -58,7 +72,7 @@
         return false;
 
     // set authorization for bootstrap
-    setAuth(DEVICE_BOOTSTRAP_USERNAME, DEVICE_BOOTSTRAP_PASSWORD);
+    setAuth(BOOTSTRAP_USERNAME, BOOTSTRAP_PASSWORD);
 
     LCDDisplay::inst().setLines("Bootstrap", _deviceInfo.imei());
 
@@ -99,21 +113,21 @@
 
 bool DeviceBootstrap::writeToStorage()
 {
-    return savePlatformCredentials(_username, _password, DEVICE_BOOTSTRAP_CREDENTIALS_LENGTH);
+    return saveCredential(_username, _password, CREDENTIAL_LENGTH);
 }
 
 void DeviceBootstrap::setCredentials(const char *tenant, const char *username, const char *password)
 {
     *_username = '\0';
     if (tenant != NULL) {
-        strncpy(_username, tenant, DEVICE_BOOTSTRAP_CREDENTIALS_LENGTH);
-        _username[DEVICE_BOOTSTRAP_CREDENTIALS_LENGTH-1] = '\0';
-        if (strlen(_username)+1 < DEVICE_BOOTSTRAP_CREDENTIALS_LENGTH)
+        strncpy(_username, tenant, CREDENTIAL_LENGTH);
+        _username[CREDENTIAL_LENGTH-1] = '\0';
+        if (strlen(_username)+1 < CREDENTIAL_LENGTH)
             strcat(_username, "/");
     }
-    strncat(_username, username, DEVICE_BOOTSTRAP_CREDENTIALS_LENGTH-strlen(_username));
-    _username[DEVICE_BOOTSTRAP_CREDENTIALS_LENGTH-1] = '\0';
+    strncat(_username, username, CREDENTIAL_LENGTH-strlen(_username));
+    _username[CREDENTIAL_LENGTH-1] = '\0';
 
-    strncpy(_password, password, DEVICE_BOOTSTRAP_CREDENTIALS_LENGTH);
-    _password[DEVICE_BOOTSTRAP_CREDENTIALS_LENGTH-1] = '\0';
+    strncpy(_password, password, CREDENTIAL_LENGTH);
+    _password[CREDENTIAL_LENGTH-1] = '\0';
 }
--- a/DeviceBootstrap.h	Thu May 07 13:56:19 2015 +0000
+++ b/DeviceBootstrap.h	Fri May 08 12:19:57 2015 +0000
@@ -5,13 +5,7 @@
 #include "AbstractSmartRest.h"
 #include "DeviceInfo.h"
 
-/** The username used for device bootstrapping. */
-#define DEVICE_BOOTSTRAP_USERNAME "management/devicebootstrap"
-
-/** The password used for device bootstrapping. */
-#define DEVICE_BOOTSTRAP_PASSWORD "Fhdt1bb1f"
-
-#define DEVICE_BOOTSTRAP_CREDENTIALS_LENGTH 256
+#define CREDENTIAL_LENGTH 256
 
 class DeviceBootstrap
 {
@@ -33,8 +27,8 @@
 private:
     AbstractSmartRest& _client;
     DeviceInfo& _deviceInfo;
-    char _username[DEVICE_BOOTSTRAP_CREDENTIALS_LENGTH];
-    char _password[DEVICE_BOOTSTRAP_CREDENTIALS_LENGTH];
+    char _username[CREDENTIAL_LENGTH];
+    char _password[CREDENTIAL_LENGTH];
 };
 
 #endif
\ No newline at end of file
--- a/DeviceIntegration.cpp	Thu May 07 13:56:19 2015 +0000
+++ b/DeviceIntegration.cpp	Fri May 08 12:19:57 2015 +0000
@@ -3,6 +3,7 @@
 #include "ComposedRecord.h"
 #include "CharValue.h"
 #include "IntegerValue.h"
+#include "SmartRestConf.h"
 #include "logging.h"
 
 DeviceIntegration::DeviceIntegration(AbstractSmartRest& client, SmartRestTemplate& tpl,
--- a/MbedAgent.cpp	Thu May 07 13:56:19 2015 +0000
+++ b/MbedAgent.cpp	Fri May 08 12:19:57 2015 +0000
@@ -1,13 +1,12 @@
 #include "MbedAgent.h"
-#include "LCDDisplay.h"
 #include "logging.h"
 #include "watchdog.h"
 
 MbedAgent::MbedAgent(DeviceInfo& deviceInfo):
     _client(), tpl(), _bootstrap(_client, deviceInfo), 
-    _integration(_client, _tpl, deviceInfo), lcdThirdLineBlank(true), 
-    signal(), temp(), poti(), gps(), acc(), conf(), sock(),
-    pool(), _operationSupport(_client, _tpl, pool)
+    _integration(_client, tpl, deviceInfo), lcdThirdLineBlank(true),
+    signal(deviceInfo), temp(), poti(), gps(), acc(), conf(), sock(),
+    pool(), _operationSupport(_client, tpl, pool)
 {
     reporters[0] = &signal;
     reporters[1] = &temp;
@@ -20,6 +19,42 @@
 bool MbedAgent::init()
 {
     bool flag = true;
+
+    // Insert measurement Acceleration
+    // USAGE: 106,<DEVICE/ID>,<X>,<Y>,<Z>
+    if (!tpl.add("10,106,POST,/measurement/measurements,application/vnd.com.nsn.cumulocity.measurement+json,application/vnd.com.nsn.cumulocity.measurement+json,%%,NOW UNSIGNED NUMBER NUMBER NUMBER,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_MotionMeasurement\"\",\"\"c8y_MotionMeasurement\"\":{\"\"x\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"m/s^2\"\"},\"\"y\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"m/s^2\"\"},\"\"z\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"m/s^2\"\"}}}\"\r\n"))
+        flag = false;
+    
+    // Insert measurement Potentiometer
+    // USAGE: 107,<DEVICE/ID>,<ANALOG1>,<ANALOG2>
+    if (!tpl.add("10,107,POST,/measurement/measurements,application/vnd.com.nsn.cumulocity.measurement+json,application/vnd.com.nsn.cumulocity.measurement+json,%%,NOW UNSIGNED NUMBER NUMBER,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_AnalogMeasurement\"\",\"\"c8y_AnalogMeasurement\"\":{\"\"A1\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"A\"\"},\"\"A2\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"A\"\"}}}\"\r\n"))
+        flag = false;
+    
+    // Update device position
+    // USAGE: 108,<DEVICE/ID>,<ALTITUDE>,<LATITUDE>,<LONGITUDE>
+    if (!tpl.add("10,108,PUT,/inventory/managedObjects/%%,application/vnd.com.nsn.cumulocity.managedObject+json,application/vnd.com.nsn.cumulocity.managedObject+json,%%,UNSIGNED NUMBER NUMBER NUMBER,\"{\"\"c8y_Position\"\":{\"\"alt\"\":%%,\"\"lat\"\":%%,\"\"lng\"\":%%},\"\"c8y_MotionTracking\"\":{\"\"active\"\":true}}\"\r\n"))
+        flag = false;
+
+    // Insert measurement Location
+    // USAGE: 109,<DEVICE/ID>,<ALTITUDE>,<LATITUDE>,<LONGITUDE>
+    if (!tpl.add("10,109,POST,/event/events,application/vnd.com.nsn.cumulocity.event+json,application/vnd.com.nsn.cumulocity.event+json,%%,NOW UNSIGNED NUMBER NUMBER NUMBER,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_LocationUpdate\"\",\"\"text\"\":\"\"Mbed location update\"\",\"\"c8y_Position\"\":{\"\"alt\"\":%%,\"\"lat\"\":%%,\"\"lng\"\":%%}}\"\r\n"))
+        flag = false;
+
+    // Insert measurement Signal Quality
+    // USAGE: 104,<DEVICE/ID>,<RSSI>,<BER>
+    if (!tpl.add("10,104,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"))
+        flag = false;
+        
+    // Insert measurement Temperature
+    // USAGE: 105,<DEVICE/ID>,<TEMPERATURE>
+    if (!tpl.add("10,105,POST,/measurement/measurements,application/vnd.com.nsn.cumulocity.measurement+json,application/vnd.com.nsn.cumulocity.measurement+json,%%,NOW UNSIGNED NUMBER,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_TemperatureMeasurement\"\",\"\"c8y_TemperatureMeasurement\"\":{\"\"T\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"C\"\"}}}\"\r\n"))
+        flag = false;
+
+    // Update Configuration
+    // Usage: 130,<DEVICE/ID>,<CONFIG/STRING>,<RESPONSIBILITY>
+    if (!tpl.add("10,130,PUT,/inventory/managedObjects/%%,application/vnd.com.nsn.cumulocity.managedObject+json,application/vnd.com.nsn.cumulocity.managedObject+json,%%,UNSIGNED STRING NUMBER,\"{\"\"c8y_Configuration\"\":{\"\"config\"\":\"\"%%\"\"},\"\"c8y_RequiredAvailability\"\":{ \"\"responseInterval\"\":%%}}\"\r\n"))
+        flag = false;
+
     if (!_integration.init()) {
         LCDDisplay::inst().setLines("Integrate init fail");
         flag = false;
@@ -28,7 +63,12 @@
         LCDDisplay::inst().setLines("Operation init fail");
         flag = false;
     }
-    return flag;
+    for (size_t i = 0; i < N; ++i) {
+        if (!reporters[i]->init()) {
+            aError("Init %s", reporters[i]->name());
+        }
+    }
+   return flag;
 }
 
 int MbedAgent::run()
@@ -46,31 +86,39 @@
         return -2;
     }
     setX_ID(_client.getIdentifier());
-    aInfo("Set id: %s\n", srX_ID);
+    aInfo("Set X-ID: %s\n", srX_ID);
 
-    if (!_configSync.integrate()) {
-        return -3;
-    }
     return 0;
 }
 
 void MbedAgent::loop()
 {
-//    ReportThread reportThread(pool);
+    ReportThread reportThread(pool);
     _operationSupport.run();
-//    PollThread pollThread(pool, _configSync);
-//    pollThread.setChannel(_deviceId);
+    PollThread pollThread(pool, conf);
+    pollThread.setChannel(deviceID);
 
     Watchdog wdt;
-    wdt.kick(60.0);    // set a 60.0 seconds timeout on watchdog hardware timer
+    wdt.kick(60.0);    // set a 60.0 seconds watchdog
     while (true) {
-        _configSync.run();
-//        _analogMeasurement.run();
-//        _signalQualityMeasurement.run();
-//        _temperatureMeasurement.run();
-//        _accelerationMeasurement.run();
-//        _locationUpdate.run();
-//        Thread::wait(30000);
+        for (size_t i = 0; i < N; ++i) {
+//            if (reporters[i] == &conf) {
+            size_t l = reporters[i]->read(buf2, SMARRESTBODY_SIZE, status, DISPLAY_LEN);
+            bool b = l;
+            if (b) { // Refresh LCD display needed
+                LCDDisplay::inst().setThirdLine(status);
+            } else if (!lcdThirdLineBlank && !b) { // Clear LCD display needed
+                LCDDisplay::inst().setThirdLine("");
+            }
+            lcdThirdLineBlank = !b;
+            if (b) {
+                int l2 = snprintf(buf, SMARTREST_SIZE, fmtSmartRest, "/s", l, buf2);
+                l2 = sock.sendOnly(buf, l2);
+                if (l2 < 0)
+                    aError(status);
+            }
+//            }
+        }
         wdt.kick();    // reset watchdog timer
     }
 }
\ No newline at end of file
--- a/MbedAgent.h	Thu May 07 13:56:19 2015 +0000
+++ b/MbedAgent.h	Fri May 08 12:19:57 2015 +0000
@@ -18,6 +18,7 @@
 #include "SmartRestConf.h"
 #include "PollThread.h"
 #include "ReportThread.h"
+#include "LCDDisplay.h"
 
 const size_t N = 6;
 
@@ -43,9 +44,10 @@
     Acceleration acc;
     ConfigSync conf;
     char buf[SMARTREST_SIZE];
-    char line[DISPLAY_LEN];
+    char buf2[SMARRESTBODY_SIZE];
+    char status[DISPLAY_LEN];
     AbstractReporter *reporters[N];
-    SmartRestSock sock;
+    SmartRestSocket sock;
     OperationPool pool;
     OperationSupport _operationSupport;
 };
--- a/config/ConfigParser.cpp	Thu May 07 13:56:19 2015 +0000
+++ b/config/ConfigParser.cpp	Fri May 08 12:19:57 2015 +0000
@@ -66,7 +66,7 @@
 void ConfigParser::parseError(Token& tok)
 {
         parseOK = false;
-        aError("(%d) %.*s\n", tok.type, (int)tok.len, tok.p);
+        aError("ConfParse: (%d) %.*s\n", tok.type, (int)tok.len, tok.p);
         parseRecover(tok);
 }
 
--- a/config/ConfigParser.h	Thu May 07 13:56:19 2015 +0000
+++ b/config/ConfigParser.h	Fri May 08 12:19:57 2015 +0000
@@ -6,10 +6,13 @@
 class ConfigParser
 {
 public:
-        ConfigParser(Dict& d) : dict(d), parseOK(true) {}
+        Dict dict;
+public:
+        ConfigParser() : dict(), parseOK(true) {}
         virtual ~ConfigParser() {}
         bool parse(const char*);
 protected:
+        typedef void (ConfigParser::*PtrParseFunc) (Token&);
         void parseKey(Token&);
         void parseAssignOp(Token&);
         void parseValue(Token&);
@@ -17,8 +20,6 @@
         void parseError(Token&);
         void parseRecover(Token&);
 private:
-        typedef void (ConfigParser::*PtrParseFunc) (Token&);
-        Dict& dict;
         bool parseOK;
         PtrParseFunc ptrPF;
         char key[MAX_KEY_LEN];
--- a/config/ConfigSync.cpp	Thu May 07 13:56:19 2015 +0000
+++ b/config/ConfigSync.cpp	Fri May 08 12:19:57 2015 +0000
@@ -1,143 +1,68 @@
 #include <stdio.h>
-#include "ConfigSync.h"
 #include "DeviceMemory.h"
-#include "ComposedRecord.h"
-#include "CharValue.h"
-#include "IntegerValue.h"
+#include "ConfigSync.h"
+#include "SmartRestConf.h"
 #include "logging.h"
 
-ConfigSync::ConfigSync(
-    AbstractSmartRest& client, SmartRestTemplate& tpl) :
-    _init (false),
-    _changed (false),
-    _tpl(tpl),
-    _client(client),
-    _deviceConfiguration(),
-    _configurationProperties(_deviceConfiguration)
+// default connectivity checking interval [minutes].
+#define INTERVAL_KEY "interval"
+#define DEFAULT_INTERVAL "20"
+
+bool validateConfiguration(Dict& d)
 {
+        return d.get(INTERVAL_KEY);
 }
 
-bool ConfigSync::init()
-{
-    if (_init)
-        return false;
-    
-    // Update Configuration
-    // Usage: 130,<DEVICE/ID>,<CONFIG/STRING>,<RESPONSIBILITY>
-    if (!_tpl.add("10,130,PUT,/inventory/managedObjects/%%,application/vnd.com.nsn.cumulocity.managedObject+json,application/vnd.com.nsn.cumulocity.managedObject+json,%%,UNSIGNED STRING NUMBER,\"{\"\"c8y_Configuration\"\":{\"\"config\"\":\"\"%%\"\"},\"\"c8y_RequiredAvailability\"\":{ \"\"responseInterval\"\":%%}}\"\r\n"))
-        return false;
-
-    _init = true;
-    return true;
-}
-
-bool ConfigSync::integrate()
+size_t ConfigSync::read(char *buf, size_t maxLen, char *line, size_t num)
 {
-    if ((!loadConfiguration()) || (!_configurationProperties.validateProperties())) {
-        if ((!_configurationProperties.resetConfiguration()) || (!updateDeviceObject()) || (!saveConfiguration()))
-            return false;
-    } else {
-        if (!updateDeviceObject())
-            return false;
-    }
-    return true;
-}
-
-bool ConfigSync::run()
-{
-    if (!_changed)
-        return true;
-
-    if ((!updateDeviceObject()) || (!saveConfiguration()))
-        return false;
-    
-    _changed = false;
-    return true;
+        static const char *fmt = "130,%ld,%s,%.*s\r\n";
+        int l = 0;
+        if (changed) {
+                changed = false;
+                char s[MAX_ITEM_SIZE*(MAX_KEY_LEN+MAX_VALUE_LEN+2)+1];
+                dict.dump(s);
+                const char *p = dict.get("interval")->value;
+                l = snprintf(buf, maxLen, fmt, deviceID, s, MAX_VALUE_LEN, p);
+                snprintf(line, num, "%s", "Sync Config");
+        }
+        return l;
 }
 
-bool ConfigSync::updateConfiguration(const char *cfg)
+bool ConfigSync::updateConfiguration(const char *buf)
 {
-    if (!_deviceConfiguration.read(cfg)) {
-        aError("Read device config.\n");
-        return false;
-    }
-    
-    if (!_configurationProperties.validateProperties()) {
-        loadConfiguration();
-        return false;
-    }
-    
-    _changed = true;
-    return true;
+        bool b = cp.parse(buf);
+        if (b && validateConfiguration(cp.dict)) {
+                dict = cp.dict;
+                changed = true;
+                saveConfiguration();
+        }
+        return b;
+}
+
+void ConfigSync::resetConfiguration()
+{
+        dict.clear();
+        dict.set(INTERVAL_KEY, DEFAULT_INTERVAL);
+        aDebug("Reset conf\n");
+        changed = true;
 }
 
-bool ConfigSync::updateDeviceObject()
+void ConfigSync::loadConfiguration()
 {
-    char buf[256];
-    
-    if (!_deviceConfiguration.write(buf, sizeof(buf))) {
-        aError("Unable to write config.\n");
-        return false;
-    }
-
-    ComposedRecord record;
-    ParsedRecord received;
-
-    IntegerValue msgId(130);
-    IntegerValue deviceId(_deviceId);
-    CharValue config(buf);
-    IntegerValue responsibility(_configurationProperties.readInterval());
-    if (!record.add(msgId) || !record.add(deviceId) || !record.add(config) || !record.add(responsibility)) {
-        return false;
-    }
-    
-    if (_client.send(record) != SMARTREST_SUCCESS) {
-        _client.stop();
-        return false;
-    }
-    
-    if (_client.receive(received) != SMARTREST_SUCCESS) {
-        _client.stop();
-        return false;
-    }
-    _client.stop();
-
-    if (received.values() != 3) {
-        aError("Invalid config, %d (3) values received.\n", received.values());
-        return false;
-    } else if (received.value(0).integerValue() != 201) {
-        aError("updateDeviceObject: Message ID %ld .\n", received.value(0).integerValue());
-        return false;
-    }
-    return true;
+        char buf[(MAX_KEY_LEN+MAX_VALUE_LEN)*MAX_ITEM_SIZE+1];
+        int l = loadConfigFile(buf, sizeof(buf));
+        if (l > 0) {
+                updateConfiguration(buf);
+        }
 }
 
-bool ConfigSync::loadConfiguration()
+void ConfigSync::saveConfiguration() const
 {
-    char buf[256];
-    
-    if (!::loadConfiguration(buf, sizeof(buf))) {
-        aError("Load device config.\n");
-        return false;
-    }
-    if (!_deviceConfiguration.read(buf)) {
-        aError("Read device config.\n");
-        return false;
-    }
-    return true;
-}
-
-bool ConfigSync::saveConfiguration()
-{
-    char buf[256];
-    
-    if (!_deviceConfiguration.write(buf, sizeof(buf))) {
-        aError("Write device config.\n");
-        return false;
-    }
-    if (!::saveConfiguration(buf)) {
-        aError("Save device config.\n");
-        return false;
-    }
-    return true;
-}
+        char s[dict.size()*(MAX_KEY_LEN+MAX_VALUE_LEN+2)+1];
+        size_t l = dict.dump(s);
+        if (l) {
+                if (!saveConfigFile(s, l)) {
+                        aError("Save config.\n");
+                }
+        }
+}
\ No newline at end of file
--- a/config/ConfigSync.h	Thu May 07 13:56:19 2015 +0000
+++ b/config/ConfigSync.h	Fri May 08 12:19:57 2015 +0000
@@ -1,33 +1,29 @@
-#ifndef CONFIGURATIONSYNCHRONIZATION_H
-#define CONFIGURATIONSYNCHRONIZATION_H
+#ifndef CONFIGSYNC_H
+#define CONFIGSYNC_H
+#include "AbstractReporter.h"
+#include "ConfigParser.h"
 
-#include "AbstractSmartRest.h"
-#include "SmartRestTemplate.h"
-#include "ConfigurationProperties.h"
-
-class ConfigSync
+class ConfigSync : public AbstractReporter
 {
 public:
-    ConfigSync(AbstractSmartRest&, SmartRestTemplate&);
-    
-    bool init();
-    bool integrate();
-    bool run();
-    
-    bool updateConfiguration(const char*);
-
+        ConfigSync(): dict(), cp(), changed(true) {}
+        virtual ~ConfigSync() {}
+        virtual bool init() {
+                resetConfiguration();
+                loadConfiguration();
+                return true;
+        }
+        virtual const char* name() const { return "Conf"; }
+        virtual size_t read(char*, size_t, char*, size_t);
+        bool updateConfiguration(const char*);
 protected:
-    bool updateDeviceObject();
-    bool loadConfiguration();
-    bool saveConfiguration();
-
+        void resetConfiguration();
+        void loadConfiguration();
+        void saveConfiguration() const;
 private:
-    bool _init;
-    bool _changed;
-    SmartRestTemplate& _tpl;
-    AbstractSmartRest& _client;
-    DeviceConfiguration _deviceConfiguration;
-    ConfigurationProperties _configurationProperties;
+        Dict dict;
+        ConfigParser cp;
+        bool changed;
 };
 
-#endif
\ No newline at end of file
+#endif /* CONFIGSYNC_H */
\ No newline at end of file
--- a/config/ConfigurationProperties.cpp	Thu May 07 13:56:19 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "ConfigurationProperties.h"
-
-bool ConfigurationProperties::resetConfiguration()
-{
-    return (_deviceConfiguration.clear(), _deviceConfiguration.set("interval", CONFIGURATION_PROPERTY_INTERVAL));
-}
-
-bool ConfigurationProperties::validateProperties()
-{
-    return (readInterval() >= 0);
-}
-
-int ConfigurationProperties::readInterval()
-{
-    const char *prop = _deviceConfiguration.get("interval");    
-    if (prop == NULL)
-        prop = CONFIGURATION_PROPERTY_INTERVAL;
-
-    int res;
-    int ln = -1;
-    if ((sscanf(prop, "%d%n", &res, &ln) != 1) || (ln != strlen(prop)))
-        return 0;
-
-    return res;
-}
--- a/config/ConfigurationProperties.h	Thu May 07 13:56:19 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#ifndef CONFIGURATIONPROPERTIES_H
-#define CONFIGURATIONPROPERTIES_H
-
-#include <stddef.h>
-#include "DeviceConfiguration.h"
-
-#define CONFIGURATION_PROPERTY_INTERVAL "20"
-
-class ConfigurationProperties
-{
-public:
-    ConfigurationProperties(DeviceConfiguration& deviceConfiguration):
-        _deviceConfiguration(deviceConfiguration) {
-    }
-    bool resetConfiguration();
-    bool validateProperties();
-    int readInterval();
-
-private:
-    DeviceConfiguration& _deviceConfiguration;
-};
-
-#endif
\ No newline at end of file
--- a/config/DeviceConfiguration.cpp	Thu May 07 13:56:19 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "DeviceConfiguration.h"
-
-DeviceConfiguration::DeviceConfiguration()
-{
-    for (size_t i = 0; i < DEVICE_CONFIGURATION_SIZE; ++i) {
-        _items[i].key = NULL;
-        _items[i].value = NULL;
-    }
-}
-
-DeviceConfiguration::~DeviceConfiguration()
-{
-    clear();
-}
-
-bool DeviceConfiguration::read(const char *str)
-{
-    DeviceConfiguration::KeyValue items[DEVICE_CONFIGURATION_SIZE];    
-    size_t i;
-    for (i = 0; i < DEVICE_CONFIGURATION_SIZE; i++) {
-        items[i].key = NULL;
-        items[i].value = NULL;
-    }
-
-    const char *ptr = str;
-    const char *ptr2, *ptr3;
-    int len1, len2;
-    i = 0;
-    while (*ptr && i<DEVICE_CONFIGURATION_SIZE) {
-        if (((ptr2 = strchr(ptr, '=')) == NULL) ||
-            ((ptr3 = strchr(ptr2+1, ';')) == NULL))
-            goto failure;
-        
-        len1 = ptr2-ptr;
-        len2 = ptr3-ptr2 - 1;
-        
-        if ((memchr(ptr, ';', len1) != NULL) ||
-            (memchr(ptr2+1, '=', len2) != NULL))
-            goto failure;
-        
-        for (size_t j = 0; j < DEVICE_CONFIGURATION_SIZE; j++) {
-            if ((items[j].key != NULL) && (strlen(items[j].key) == len1) && (strncmp(items[j].key, ptr, len1) == 0))
-                goto failure;
-        }
-
-        if ((items[i].key = (char*)malloc(len1+1)) == NULL)
-            goto failure;
-        if ((items[i].value = (char*)malloc(len2+1)) == NULL) {
-            free(items[i].key);
-            items[i].key = NULL;
-            goto failure;
-        }
-        
-        strncpy(items[i].key, ptr, len1);
-        strncpy(items[i].value, ptr2+1, len2);
-        items[i].key[len1] = '\0';
-        items[i].value[len2] = '\0';
-
-        i++;
-        ptr = ptr3+1;
-    }
-    
-    if (*ptr != '\0')
-        goto failure;
-    
-    clear();
-    memcpy(_items, items, sizeof(DeviceConfiguration::KeyValue)*DEVICE_CONFIGURATION_SIZE);
-    return true;
-
-failure:
-    for (i = 0; i < DEVICE_CONFIGURATION_SIZE; i++) {
-        if (items[i].key != NULL) {
-            free(items[i].key);
-            free(items[i].value);
-        }
-    }
-    return false;
-}
-
-bool DeviceConfiguration::write(char *buf, size_t len)
-{
-    char *ptr= buf;
-    int ln;
-
-    for (size_t i = 0; i < DEVICE_CONFIGURATION_SIZE; i++) {
-        if (_items[i].key) {
-            snprintf(ptr, len, "%s=%s;%n", _items[i].key, _items[i].value, &ln);
-            ptr += ln;
-            len -= ln;
-        }
-    }
-    return true;
-}
-
-bool DeviceConfiguration::set(const char *key, const char *value)
-{
-    KeyValue *item = search(key);
-    
-    if (item == NULL) {
-        for (size_t i = 0; (i < DEVICE_CONFIGURATION_SIZE) && (item == NULL); i++) {
-            if (_items[i].key == NULL)
-                item = &_items[i];
-        }
-    }
-    
-    if (item == NULL)
-        return false;
-    
-    if ((item->key = (char*)malloc(strlen(key)+1)) == NULL)
-        return false;
-    if ((item->value = (char*)malloc(strlen(value)+1)) == NULL) {
-        free(item->key);
-        item->key = NULL;
-        return false;
-    }
-    
-    strcpy(item->key, key);
-    strcpy(item->value, value);
-    return true;
-}
-
-const char * DeviceConfiguration::get(const char *key)
-{
-    KeyValue *item = search(key);
-    
-    if (item)
-        return item->value;
-    else
-        return NULL;
-}
-
-bool DeviceConfiguration::unset(const char *key)
-{
-    KeyValue *item = search(key);
-    
-    if (item) {
-        free(item->key);
-        free(item->value);
-        item->key = NULL;
-        item->value = NULL;
-        return true;
-    } else
-        return false;
-}
-
-bool DeviceConfiguration::has(const char *key)
-{
-    return (search(key) != NULL);
-}
-
-void DeviceConfiguration::clear()
-{
-    for (size_t i = 0; i < DEVICE_CONFIGURATION_SIZE; i++) {
-        if (_items[i].key) {
-            free(_items[i].key);
-            free(_items[i].value);
-        }
-    }
-}
-
-DeviceConfiguration::KeyValue * DeviceConfiguration::search(const char *key)
-{
-    for (size_t i = 0; i < DEVICE_CONFIGURATION_SIZE; i++) {
-        if (strcmp(key, _items[i].key) == 0)
-            return &_items[i];
-    }    
-    return NULL;
-}
--- a/config/DeviceConfiguration.h	Thu May 07 13:56:19 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-#ifndef DEVICECONFIGURATION_H
-#define DEVICECONFIGURATION_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-#define DEVICE_CONFIGURATION_SIZE 8
-
-class DeviceConfiguration
-{
-public:
-    DeviceConfiguration();
-    ~DeviceConfiguration();
-    
-    bool read(const char*);
-    bool write(char*, size_t);
-    
-    bool set(const char*, const char*);
-    const char * get(const char*);
-    bool unset(const char*);
-    bool has(const char*);
-    void clear();
-    
-protected:
-    struct KeyValue {
-        char *key;
-        char *value;
-    };
-
-    KeyValue * search(const char*);
-
-private:
-    KeyValue _items[DEVICE_CONFIGURATION_SIZE];
-};
-
-#endif
\ No newline at end of file
--- a/io/DeviceMemory.cpp	Thu May 07 13:56:19 2015 +0000
+++ b/io/DeviceMemory.cpp	Fri May 08 12:19:57 2015 +0000
@@ -2,45 +2,46 @@
 #include <string.h>
 #include "MDM.h"
 
-#define PLATFORM_CREDENTIALS_FILE "001_CREDENTIALS"
+#define CREDENTIALS_FILE "001_CREDENTIALS"
 #define CONFIGURATION_FILE "002_CONFIGURATION"
 extern MDMSerial *pMdm;
 
-bool loadCredentials(char *username, char *password, size_t len)
+bool loadCredential(char *username, char *password, size_t len)
 {
     char buffer[len*2+3];
-    int res = pMdm->readFile(PLATFORM_CREDENTIALS_FILE, buffer, sizeof(buffer));
-    if (res < 0)
+    int res = pMdm->readFile(CREDENTIALS_FILE, buffer, sizeof(buffer));
+    if (res < 0) {
+        printf("Load credentials.\n");
         return false;
-    else {
+    } else {
         buffer[res] = 0;
-        int len2 = sscanf(buffer, "%s\n%s\n", username, password);
-        return res==len2;
+        int l = 0;
+        sscanf(buffer, "%s\n%s\n%n", username, password, &l);
+        printf("%d:%d\nload: %s\n", res, l, buffer);
+        return res==l;
     }
 }
 
-bool delCredentials()
+bool delCredential()
 {
-    return pMdm->delFile(PLATFORM_CREDENTIALS_FILE);
+    return pMdm->delFile(CREDENTIALS_FILE);
 }
 
-bool saveCredentials(char *username, char *password, size_t len)
+bool saveCredential(char *username, char *password, size_t len)
 {
-    char buffer[len*2+3]; 
+    char buffer[len*2+3];
     int res = snprintf(buffer, sizeof(buffer), "%s\n%s\n", username, password);
-    delCredentials();
-    return pMdm->writeFile(PLATFORM_CREDENTIALS_FILE, buffer, res)==res;
+    printf("save: %s\n", buffer);
+    delCredential();
+    return pMdm->writeFile(CREDENTIALS_FILE, buffer, res)==res;
 }
 
-bool loadConfigFile(char *cfg, size_t len)
+int loadConfigFile(char *cfg, size_t len)
 {
     int res = pMdm->readFile(CONFIGURATION_FILE, cfg, len);
-    if (res < 0)
-        return false;
-    else {
+    if (res >= 0)
         cfg[res] = 0;
-        return true;
-    }
+    return res;
 }
 
 bool delConfigFile()
--- a/io/DeviceMemory.h	Thu May 07 13:56:19 2015 +0000
+++ b/io/DeviceMemory.h	Fri May 08 12:19:57 2015 +0000
@@ -4,21 +4,20 @@
 #include <stddef.h>
 
 /** loads credentials from persistent memory */
-bool loadPlatformCredentials(char*, char*, size_t);
+bool loadCredential(char *username, char *password, size_t len);
 
 /** saves credentials to persistent memory */
-bool savePlatformCredentials(char*, char*, size_t);
+bool delCredential();
 
 /** removes credentials from persistent memory */
-bool resetPlatformCredentials();
+bool saveCredential(char *username, char *password, size_t len);
 
 /** loads configuration from persistent memory */
-bool loadConfiguration(char*, size_t);
+bool loadConfigFile(char *cfg, size_t len);
 
 /** saves configuration to persistent memory */
-bool saveConfiguration(char*);
+bool saveConfigFile(char *cfg, size_t len);
 
 /** removes configuration from persistent memory */
-bool resetConfiguration();
-
+bool delConfigFile();
 #endif
\ No newline at end of file
--- a/main.cpp	Thu May 07 13:56:19 2015 +0000
+++ b/main.cpp	Fri May 08 12:19:57 2015 +0000
@@ -4,11 +4,11 @@
 #include "rtos.h"
 #include "MDM.h"
 #include "GPS.h"
+
 #include "DeviceInfo.h"
 #include "DeviceMemory.h"
 #include "MbedAgent.h"
 #include "GPSTracker.h"
-#include "DeviceConfiguration.h"
 #include "LCDDisplay.h"
 #include "logging.h"
 
@@ -51,11 +51,13 @@
 int main()
 {
     set_time(1256729737);
-    openRelay();
     MDMRtos<MDMSerial> mdm;
     pMdm = &mdm;
     InterruptIn joystickUp(A2);
     InterruptIn joystickDown(A3);
+    joystickUp.rise(&enableDebug);
+    joystickDown.rise(&disableDebug);
+
     MDMParser::DevStatus devStatus;
     LCDDisplay::inst().setLines("Mbed Agent V2.1rc2", srHost);
     if (!mdm.init(SIM_PIN, &devStatus)) {
@@ -64,21 +66,17 @@
         mdm.powerOff();
         return 1;
     }
-    joystickUp.rise(&enableDebug);
-    joystickDown.rise(&disableDebug);
 
     DigitalIn fireButton(D4);
-
     if (fireButton) {
-        LCDDisplay::inst().setLines("Factory Reset");
-        if (resetPlatformCredentials()) {
+        if (delCredential()) {
             LCDDisplay::inst().setLines("Reset Success");
         } else {
             LCDDisplay::inst().setLines("Reset Failure");
         }
+        Thread::wait(2000);
         mdm.disconnect();
         mdm.powerOff();
-        Thread::wait(1000);
         return 0;
     }
     aInfo("Main Thread: %p\r\n", Thread::gettid());    
@@ -135,7 +133,6 @@
         switch (ret) {
             case -1: LCDDisplay::inst().setLines("Bootstrap error"); break;
             case -2: LCDDisplay::inst().setLines("Integrate failure"); break;
-            case -3: LCDDisplay::inst().setLines("Config sync failure"); break;
             default: agent.loop();
         }
         mdm.disconnect();
--- a/mbed-rtos.lib	Thu May 07 13:56:19 2015 +0000
+++ b/mbed-rtos.lib	Fri May 08 12:19:57 2015 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed-rtos/#d3d0e710b443
+http://mbed.org/users/mbed_official/code/mbed-rtos/#85a52b7ef44b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/Acceleration.cpp	Fri May 08 12:19:57 2015 +0000
@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include "SmartRestConf.h"
+#include "Acceleration.h"
+#include "logging.h"
+
+// Percentage cut-off for avoiding sending similar sensor reading.
+#define THRESHOLD_PERCENT_ACCE 0.1
+// Timeout for forcing a sending even if readings are similar [seconds].
+#define TIME_LIMIT_ACCE 900
+
+size_t Acceleration::read(char *buf, size_t maxLen, char *status, size_t num)
+{
+        static const char *fmt = "106,%ld,%f,%f,%f\r\n";
+        if (!deviceReady)
+                return 0;
+        float data[3] = { 0.0, 0.0, 0.0 };
+        sensor.readData(data);
+
+        if ((0.15 > abs(data[0]) || abs(oldValues[0]-data[0]) <= abs(oldValues[0])*THRESHOLD_PERCENT_ACCE) &&
+            (0.10 > abs(data[1]) || abs(oldValues[1]-data[1]) <= abs(oldValues[1])*THRESHOLD_PERCENT_ACCE)) {
+                time_t t_interval = time(NULL) - t_start;
+                if (t_interval < TIME_LIMIT_ACCE) {
+                        return 0;
+                } else {
+                        aDebug("Acc: Timeout at %d s.\n", t_interval);
+                }
+        }
+
+        size_t l = snprintf(buf, maxLen, fmt, deviceID, data[0], data[1], data[2]);
+        if (status) {
+                snprintf(status, num, "Send Acc %.1f,%.1f,%.1f",
+                         data[0], data[1], data[2]);
+        }
+        oldValues[0] = data[0];
+        oldValues[1] = data[1];
+        oldValues[2] = data[2];
+        t_start = time(NULL);
+        return l;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/Acceleration.h	Fri May 08 12:19:57 2015 +0000
@@ -0,0 +1,31 @@
+#ifndef ACCELERATION_H
+#define ACCELERATION_H
+#include "mbed.h"
+#include "MMA7660.h"
+#include "AbstractReporter.h"
+
+
+class Acceleration: public AbstractReporter
+{
+public:
+        Acceleration(): deviceReady(false), sensor(SDA, SCL) {
+                oldValues[0] = 0;
+                oldValues[1] = 0;
+                oldValues[2] = 0;
+                t_start = time(NULL);
+        }
+        virtual ~Acceleration() {}
+        virtual bool init() {
+                deviceReady = sensor.testConnection();
+                return deviceReady;
+        }
+        virtual const char* name() const { return "Acc"; }
+        virtual size_t read(char*, size_t, char*, size_t);
+private:
+        bool deviceReady;
+        MMA7660 sensor;
+        float oldValues[3];
+        time_t t_start;
+};
+
+#endif /* ACCELERATION_H */
\ No newline at end of file
--- a/measurement/AccelerationMeasurement.cpp	Thu May 07 13:56:19 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-#include "AccelerationMeasurement.h"
-#include "ComposedRecord.h"
-#include "CharValue.h"
-#include "IntegerValue.h"
-#include "FloatValue.h"
-#include "MbedClient.h"
-#include "LCDDisplay.h"
-#include "logging.h"
-
-#define THRESHOLD_PERCENT_ACCE 0.1       // Percentage cut-off for avoiding sending similar acceleration sensor data.
-// Time interval for forcing a sending even if acceleration sensor readings are constantly similar (in seconds).
-#define TIME_LIMIT_ACCE 900          
-
-AccelerationMeasurement::AccelerationMeasurement(AbstractSmartRest& client,
-    SmartRestTemplate& tpl, DeviceInfo& deviceInfo) :
-    _tpl(tpl),
-    _client(client),
-    _sensor(SDA,SCL),
-    _deviceInfo(deviceInfo)
-{
-    _init = false;
-    oldValues[0] = 0;
-    oldValues[1] = 0;
-    oldValues[2] = 0;
-    t_start = time(NULL);
-}
-
-bool AccelerationMeasurement::init()
-{
-    if (_init)
-        return false;
-    
-    // Insert measurement Acceleration
-    // USAGE: 106,<DEVICE/ID>,<X>,<Y>,<Z>
-    if (!_tpl.add("10,106,POST,/measurement/measurements,application/vnd.com.nsn.cumulocity.measurement+json,application/vnd.com.nsn.cumulocity.measurement+json,%%,NOW UNSIGNED NUMBER NUMBER NUMBER,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_MotionMeasurement\"\",\"\"c8y_MotionMeasurement\"\":{\"\"x\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"m/s^2\"\"},\"\"y\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"m/s^2\"\"},\"\"z\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"m/s^2\"\"}}}\"\r\n"))
-        return false;
-
-    _test = _sensor.testConnection();
-    _init = true;
-    return true;
-}
-
-bool AccelerationMeasurement::run()
-{
-    if (!_test)
-        return false;
-    
-    float data[3] = { 0.0, 0.0, 0.0 };
-    _sensor.readData(data);
-
-//    if (abs(oldValues[0]-data[0]) <= abs(oldValues[0])*THRESHOLD_PERCENT_ACCE &&
-//        abs(oldValues[1]-data[1]) <= abs(oldValues[1])*THRESHOLD_PERCENT_ACCE &&
-//        abs(oldValues[2]-data[2]) <= abs(oldValues[2])*THRESHOLD_PERCENT_ACCE) {
-    if (((0.15>abs(data[0])) || (abs(oldValues[0]-data[0]) <= abs(oldValues[0])*THRESHOLD_PERCENT_ACCE)) &&
-        ((0.1> abs(data[1])) || (abs(oldValues[1]-data[1]) <= abs(oldValues[1])*THRESHOLD_PERCENT_ACCE))) {
-        time_t t_interval = time(NULL) - t_start;
-        if (t_interval < TIME_LIMIT_ACCE) {
-//            printf("[N] Acc %f, %f, %f\r\n", data[0], data[1], data[2]);
-            if (strcmp(LCDDisplay::inst().getThirdLine(), "")) {
-                LCDDisplay::inst().setThirdLine("");
-            }
-            return true;
-        } else {
-            aDebug("Acc: Timeout at %d s.\n", t_interval);
-        }
-    }
-//    printf("[Y] Acc %f, %f, %f\r\n", data[0], data[1], data[2]);
-    char status[27] = {0};
-    snprintf(status, 27, "Send Acc %.1f,%.1f,%.1f", data[0], data[1], data[2]);
-    LCDDisplay::inst().setThirdLine(status);
-
-    ComposedRecord record;
-    IntegerValue msgId(106);
-    IntegerValue devId(deviceID);
-    FloatValue xValue(data[0], 2);
-    FloatValue yValue(data[1], 2);
-    FloatValue zValue(data[2], 2);
-    if ((!record.add(msgId)) || (!record.add(devId)) || (!record.add(xValue)) || (!record.add(yValue)) || (!record.add(zValue)))
-        return false;
-
-    time_t t0 = time(NULL);
-    if (_client.send(record) != SMARTREST_SUCCESS) {
-        aWarning("Acc: Send failed.\n");
-        _client.stop();
-        return false;
-    }
-    time_t t1 = time(NULL);
-    _client.stop();
-    aDebug("Acc: Sent in %d s.\n", t1-t0);
-    oldValues[0] = data[0];
-    oldValues[1] = data[1];
-    oldValues[2] = data[2];
-    t_start = time(NULL);
-    return true;
-}
--- a/measurement/AccelerationMeasurement.h	Thu May 07 13:56:19 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#ifndef ACCELERATIONMEASUREMENT_H
-#define ACCELERATIONMEASUREMENT_H
-
-#include "AbstractSmartRest.h"
-#include "SmartRestTemplate.h"
-#include "MMA7660.h"
-#include "DeviceInfo.h"
-
-class AccelerationMeasurement
-{
-public:
-    AccelerationMeasurement(AbstractSmartRest&, SmartRestTemplate&, DeviceInfo&);
-    
-    bool init();
-    bool run();
-
-private:
-    bool _init, _test;
-    SmartRestTemplate& _tpl;
-    AbstractSmartRest& _client;
-    MMA7660 _sensor;
-    float oldValues[3];
-    time_t t_start;
-    DeviceInfo& _deviceInfo;
-};
-
-#endif
\ No newline at end of file
--- a/measurement/AnalogMeasurement.cpp	Thu May 07 13:56:19 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-#include "AnalogMeasurement.h"
-#include "ComposedRecord.h"
-#include "CharValue.h"
-#include "IntegerValue.h"
-#include "FloatValue.h"
-#include "LCDDisplay.h"
-#include "logging.h"
-
-#define THRESHOLD_PERCENT_ANA 0.02       // Percentage cut-off for avoiding sending similar analog sensor data.
-// Time interval for forcing a sending even if analog sensor readings are constantly similar (in seconds).
-#define TIME_LIMIT_ANA 900               
-    
-AnalogIn _analog1(A0);
-AnalogIn _analog2(A1);
-
-AnalogMeasurement::AnalogMeasurement(AbstractSmartRest& client,
-    SmartRestTemplate& tpl, DeviceInfo& deviceInfo) :
-    _tpl(tpl),
-    _client(client),
-    _deviceInfo(deviceInfo)
-{
-    _init = false;
-    oldValues[0] = 0;
-    oldValues[1] = 0;
-    t_start = time(NULL);
-}
-
-bool AnalogMeasurement::init()
-{
-    if (_init)
-        return false;
-    
-    // Insert measurement
-    // USAGE: 107,<DEVICE/ID>,<ANALOG1>,<ANALOG2>
-    if (!_tpl.add("10,107,POST,/measurement/measurements,application/vnd.com.nsn.cumulocity.measurement+json,application/vnd.com.nsn.cumulocity.measurement+json,%%,NOW UNSIGNED NUMBER NUMBER,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_AnalogMeasurement\"\",\"\"c8y_AnalogMeasurement\"\":{\"\"A1\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"A\"\"},\"\"A2\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"A\"\"}}}\"\r\n"))
-        return false;
-
-    _init = true;
-    return true;
-}
-
-bool AnalogMeasurement::run()
-{
-    float data[2] = {(float)_analog1*100, (float)_analog2*100};
-
-    if (abs(oldValues[0]-data[0]) <= abs(oldValues[0])*THRESHOLD_PERCENT_ANA &&
-        abs(oldValues[1]-data[1]) <= abs(oldValues[1])*THRESHOLD_PERCENT_ANA) {
-        time_t t_interval = time(NULL) - t_start;
-        if (t_interval < TIME_LIMIT_ANA) {
-            if (strcmp(LCDDisplay::inst().getThirdLine(), "")) {
-                LCDDisplay::inst().setThirdLine("");
-            }
-//            printf("[N] %f, %f\r\n", data[0], data[1]);
-            return true;
-        } else {
-            aDebug("Poti: Timeout at %d s.\n", t_interval);
-        }
-    }
-
-//    printf("[Y] %f, %f (%f, %f)\r\n", data[0], data[1], oldValues[0], oldValues[1]);
-    char status[27] = {0};
-    snprintf(status, sizeof(status), "Send Poti %.1f,%.1f", data[0], data[1]);
-    LCDDisplay::inst().setThirdLine(status);
-    ComposedRecord record;
-    IntegerValue msgId(107);
-    IntegerValue devId(deviceID);
-    FloatValue analog1(data[0], 1);
-    FloatValue analog2(data[1], 1);
-    if ((!record.add(msgId)) || (!record.add(devId)) || (!record.add(analog1)) || (!record.add(analog2)))
-        return false;
-
-    time_t t0 = time(NULL);
-    if (_client.send(record) != SMARTREST_SUCCESS) {
-        aWarning("Poti: Send failed.\n");
-        _client.stop();
-        return false;
-    }
-    time_t t1 = time(NULL);
-    _client.stop();
-    aDebug("Poti: Sent in %d s.\n", t1-t0);
-    oldValues[0] = data[0];
-    oldValues[1] = data[1];
-    t_start = time(NULL);
-    return true;
-}
--- a/measurement/AnalogMeasurement.h	Thu May 07 13:56:19 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-#ifndef ANALOGMEASUREMENT_H
-#define ANALOGMEASUREMENT_H
-
-#include "SmartRest.h"
-#include "SmartRestTemplate.h"
-#include "mbed.h"
-#include "DeviceInfo.h"
-
-class AnalogMeasurement
-{
-public:
-    AnalogMeasurement(AbstractSmartRest&, SmartRestTemplate&, DeviceInfo&);
-    
-    bool init();
-    bool run();
-
-private:
-    bool _init;
-    SmartRestTemplate& _tpl;
-    AbstractSmartRest& _client;
-    float oldValues[2];
-    time_t t_start;
-    DeviceInfo& _deviceInfo;
-};
-
-#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/Location.cpp	Fri May 08 12:19:57 2015 +0000
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include "Location.h"
+#include "SmartRestConf.h"
+#include "logging.h"
+
+// Percentage cut-off for avoiding sending similar sensor readings.
+#define THRESHOLD_PERCENT_LOC 0.05
+// Timeout for forcing a sending even if readings are similar [seconds].
+#define TIME_LIMIT_LOC 900
+
+size_t Location::read(char *buf, size_t maxLen, char *status, size_t num)
+{
+        static const char *fmt = "108,%ld,%.2f,%.6f,%.6f\r\n109,%ld,%.2f,%.6f,%.6f";
+        GPSTracker::Position pos;
+        if (!gpsTracker.position(&pos)) {
+                return 0;
+        }
+        float data[3] = { pos.altitude, pos.latitude,
+                          pos.longitude };
+
+        if (abs(oldValues[0]-data[0]) <= abs(oldValues[0])*THRESHOLD_PERCENT_LOC &&
+            abs(oldValues[1]-data[1]) <= abs(oldValues[1])*THRESHOLD_PERCENT_LOC &&
+            abs(oldValues[2]-data[2]) <= abs(oldValues[2])*THRESHOLD_PERCENT_LOC) {
+                time_t t_interval = time(NULL) - t_start;
+                if (t_interval < TIME_LIMIT_LOC) {
+                        return 0;
+                } else {
+                        aDebug("GPS: Timeout at %d s.\n", t_interval);
+                }
+        }
+        size_t l = snprintf(buf, maxLen, fmt, deviceID, data[0], data[1],
+                            data[2], deviceID, data[0], data[1], data[2]);
+        if (status) {
+                snprintf(status, num, "Send GPS %.1f,%.1f,%.1f",
+                         data[0], data[1], data[2]);
+        }
+        oldValues[0] = data[0];
+        oldValues[1] = data[1];
+        oldValues[2] = data[2];
+        t_start = time(NULL);
+        return l;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/Location.h	Fri May 08 12:19:57 2015 +0000
@@ -0,0 +1,27 @@
+#ifndef LOCATION_H
+#define LOCATION_H
+#include "mbed.h"
+#include "GPSTracker.h"
+#include "AbstractReporter.h"
+
+
+class Location: public AbstractReporter
+{
+public:
+        Location(): gpsTracker() {
+                oldValues[0] = 0;
+                oldValues[1] = 0;
+                oldValues[2] = 0;
+                t_start = time(NULL);
+        }
+        virtual ~Location() {}
+        virtual bool init() { return true; }
+        virtual const char* name() const { return "GPS"; }
+        virtual size_t read(char*, size_t, char*, size_t);
+private:
+        GPSTracker gpsTracker;
+        float oldValues[3];
+        time_t t_start;
+};
+
+#endif /* LOCATION_H */
\ No newline at end of file
--- a/measurement/LocationUpdate.cpp	Thu May 07 13:56:19 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-#include "LocationUpdate.h"
-#include "Aggregator.h"
-#include "ComposedRecord.h"
-#include "CharValue.h"
-#include "IntegerValue.h"
-#include "FloatValue.h"
-#include "LCDDisplay.h"
-#include "logging.h"
-
-#define THRESHOLD_PERCENT_LOC 0.05       // Percentage cut-off for avoiding sending similar acceleration sensor data.
-// Time interval for forcing a sending even if analog sensor readings are constantly similar (in seconds).
-#define TIME_LIMIT_LOC 900
-
-LocationUpdate::LocationUpdate(AbstractSmartRest& client, SmartRestTemplate& tpl,
-    DeviceInfo& deviceInfo) :
-    _tpl(tpl),
-    _client(client),
-    _gpsTracker(),
-    _deviceInfo(deviceInfo)
-{
-    _init = false;
-    oldValues[0] = 0;
-    oldValues[1] = 0;
-    oldValues[2] = 0;
-    t_start = time(NULL);
-}
-
-bool LocationUpdate::init()
-{
-    if (_init)
-        return false;
-    
-    // Update device position
-    // USAGE: 108,<DEVICE/ID>,<ALTITUDE>,<LATITUDE>,<LONGITUDE>
-    if (!_tpl.add("10,108,PUT,/inventory/managedObjects/%%,application/vnd.com.nsn.cumulocity.managedObject+json,application/vnd.com.nsn.cumulocity.managedObject+json,%%,UNSIGNED NUMBER NUMBER NUMBER,\"{\"\"c8y_Position\"\":{\"\"alt\"\":%%,\"\"lat\"\":%%,\"\"lng\"\":%%},\"\"c8y_MotionTracking\"\":{\"\"active\"\":true}}\"\r\n"))
-        return false;
-
-    // Insert measurement
-    // USAGE: 109,<DEVICE/ID>,<ALTITUDE>,<LATITUDE>,<LONGITUDE>
-    if (!_tpl.add("10,109,POST,/event/events,application/vnd.com.nsn.cumulocity.event+json,application/vnd.com.nsn.cumulocity.event+json,%%,NOW UNSIGNED NUMBER NUMBER NUMBER,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_LocationUpdate\"\",\"\"text\"\":\"\"Mbed location update\"\",\"\"c8y_Position\"\":{\"\"alt\"\":%%,\"\"lat\"\":%%,\"\"lng\"\":%%}}\"\r\n"))
-        return false;
-
-    _init = true;
-    return true;
-}
-
-bool LocationUpdate::run()
-{
-    GPSTracker::Position position;    
-    if (!_gpsTracker.position(&position)) {
-        return false;
-    }
-    float data[3] = { position.altitude, position.latitude, position.longitude };
-
-    if (abs(oldValues[0]-data[0]) <= abs(oldValues[0])*THRESHOLD_PERCENT_LOC &&
-        abs(oldValues[1]-data[1]) <= abs(oldValues[1])*THRESHOLD_PERCENT_LOC &&
-        abs(oldValues[2]-data[2]) <= abs(oldValues[2])*THRESHOLD_PERCENT_LOC) {
-        time_t t_interval = time(NULL) - t_start;
-        if (t_interval < TIME_LIMIT_LOC) {
-            if (strcmp(LCDDisplay::inst().getThirdLine(), "")) {
-                LCDDisplay::inst().setThirdLine("");
-            }
-            return true;
-        } else {
-            aDebug("GPS: Timeout at %d s.\n", t_interval);
-        }
-    }
-    char status[27] = {0};
-    snprintf(status, 27, "Send GPS %.1f,%.1f,%.1f", data[0], data[1], data[2]);
-    LCDDisplay::inst().setThirdLine(status);
-        
-    Aggregator aggregator;
-    ComposedRecord record1, record2;
-    IntegerValue msgId1(108);
-    IntegerValue msgId2(109);
-    IntegerValue devId(deviceID);
-    FloatValue altitude(position.altitude, 2);
-    FloatValue latitude(position.latitude, 6);
-    FloatValue longitude(position.longitude, 6);
-    if ((!record1.add(msgId1)) || (!record1.add(devId)) || (!record1.add(altitude)) || (!record1.add(latitude)) || (!record1.add(longitude)))
-        return false;
-    if ((!record2.add(msgId2)) || (!record2.add(devId)) || (!record2.add(altitude)) || (!record2.add(latitude)) || (!record2.add(longitude)))
-        return false;
-    if ((!aggregator.add(record1)) || (!aggregator.add(record2)))
-        return false;
-
-    time_t t0 = time(NULL);
-    if (_client.send(aggregator) != SMARTREST_SUCCESS) {
-        aWarning("GPS: Send failed.\n");
-        _client.stop();
-        return false;
-    }
-    time_t t1 = time(NULL);
-    _client.stop();
-    aDebug("GPS: Sent in %d s.\n", t1-t0);
-    oldValues[0] = data[0];
-    oldValues[1] = data[1];
-    oldValues[2] = data[2];
-    t_start = time(NULL);
-    return true;
-}
--- a/measurement/LocationUpdate.h	Thu May 07 13:56:19 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#ifndef LOCATIONUPDATE_H
-#define LOCATIONUPDATE_H
-
-#include "AbstractSmartRest.h"
-#include "SmartRestTemplate.h"
-#include "GPSTracker.h"
-#include "DeviceInfo.h"
-
-class LocationUpdate
-{
-public:
-    LocationUpdate(AbstractSmartRest&, SmartRestTemplate&, DeviceInfo&);
-    
-    bool init();
-    bool run();
-
-private:
-    bool _init;
-    SmartRestTemplate& _tpl;
-    AbstractSmartRest& _client;
-    GPSTracker _gpsTracker;
-    float oldValues[3];
-    time_t t_start;
-    DeviceInfo& _deviceInfo;
-};
-
-#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/Potentiometer.cpp	Fri May 08 12:19:57 2015 +0000
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include "Potentiometer.h"
+#include "SmartRestConf.h"
+#include "logging.h"
+
+// Cutoff for avoiding sending similar sensor data.
+#define THRESHOLD_PERCENT_ANA 0.02
+// Timeout for forcing a sending even if  readings are similar [seconds]
+#define TIME_LIMIT_ANA 900
+
+AnalogIn analog1(A0);
+AnalogIn analog2(A1);
+
+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};
+
+        if (abs(oldValues[0]-data[0]) <= abs(oldValues[0])*THRESHOLD_PERCENT_ANA &&
+            abs(oldValues[1]-data[1]) <= abs(oldValues[1])*THRESHOLD_PERCENT_ANA) {
+                time_t t_interval = time(NULL) - t_start;
+                if (t_interval < TIME_LIMIT_ANA) {
+                        return 0;
+                } else {
+                        aDebug("Poti: Timeout at %d s.\n", t_interval);
+                }
+        }
+
+        size_t l = snprintf(buf, maxLen, fmt, deviceID, data[0], data[1]);
+        if (status) {
+                snprintf(status, num, "Send Poti %.1f,%.1f", data[0], data[1]);
+        }
+        oldValues[0] = data[0];
+        oldValues[1] = data[1];
+        t_start = time(NULL);
+        return l;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/Potentiometer.h	Fri May 08 12:19:57 2015 +0000
@@ -0,0 +1,24 @@
+#ifndef POTENTIOMETER_H
+#define POTENTIOMETER_H
+#include "mbed.h"
+#include "AbstractReporter.h"
+
+
+class Potentiometer: public AbstractReporter
+{
+public:
+        Potentiometer() {
+                oldValues[0] = 0;
+                oldValues[1] = 0;
+                t_start = time(NULL);
+        }
+        virtual ~Potentiometer() {}
+        virtual bool init() { return true; }
+        virtual const char* name() const { return "Poti"; }
+        virtual size_t read(char*, size_t, char*, size_t);
+private:
+        float oldValues[2];
+        time_t t_start;
+};
+
+#endif /* POTENTIOMETER_H */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/Signal.cpp	Fri May 08 12:19:57 2015 +0000
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include "Signal.h"
+#include "SmartRestConf.h"
+#include "LCDDisplay.h"
+#include "DeviceInfo.h"
+#include "logging.h"
+
+// Cut-off for avoiding sending similar sensor reading.
+#define THRESHOLD_PERCENT_SIG 0.06
+// Timeout for forcing a sending even if readings are similar [seconds].
+#define TIME_LIMIT_SIG 900
+
+
+size_t Signal::read(char *buf, size_t maxLen, char *status, size_t num)
+{
+        static const char *fmt = "104,%ld,%d,%d\r\n";
+        static char signal[27] = {0};
+        DeviceInfo::SignalQuality *p = deviceInfo.signalQuality();
+        if (p == NULL)
+                return 0;
+        else if (p && p->rssi)
+                snprintf(signal, sizeof(signal), "Network: %d dBm", p->rssi);
+        else
+                strncpy(signal, "Network: no coverage", sizeof(signal));
+        if (strcmp(LCDDisplay::inst().getSecondLine(), signal)) {
+                LCDDisplay::inst().setSecondLine(signal);
+        }
+
+        int data[2] = { p->rssi, p->ber };
+        if (abs(oldValues[0]-data[0]) <= abs(oldValues[0])*THRESHOLD_PERCENT_SIG &&
+            abs(oldValues[1]-data[1]) <= abs(oldValues[1])*THRESHOLD_PERCENT_SIG) {
+                time_t t_interval = time(NULL) - t_start;
+                if (t_interval < TIME_LIMIT_SIG) {
+                        return 0;
+                } else {
+                        aDebug("Signal: Timeout at %d s.\n", t_interval);
+                }
+        }
+
+        size_t l = snprintf(buf, maxLen, fmt, deviceID, data[0], data[1]);
+        if (status) {
+                snprintf(status, num, "Send dBm %d,%d", data[0], data[1]);
+        }
+        oldValues[0] = data[0];
+        oldValues[1] = data[1];
+        t_start = time(NULL);
+        return l;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/Signal.h	Fri May 08 12:19:57 2015 +0000
@@ -0,0 +1,26 @@
+#ifndef SIGNAL_H
+#define SIGNAL_H
+#include "mbed.h"
+#include "DeviceInfo.h"
+#include "AbstractReporter.h"
+
+
+class Signal: public AbstractReporter
+{
+public:
+        Signal(DeviceInfo& d): deviceInfo(d) {
+                oldValues[0] = 0;
+                oldValues[1] = 0;
+                t_start = time(NULL);
+        }
+        virtual ~Signal() {}
+        virtual bool init() { return true; }
+        virtual const char* name() const { return "dBm"; }
+        virtual size_t read(char*, size_t, char*, size_t);
+private:
+        int oldValues[2];
+        time_t t_start;
+        DeviceInfo& deviceInfo;
+};
+
+#endif /* SIGNAL_H */
\ No newline at end of file
--- a/measurement/SignalQualityMeasurement.cpp	Thu May 07 13:56:19 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-#include "SignalQualityMeasurement.h"
-#include "ComposedRecord.h"
-#include "CharValue.h"
-#include "IntegerValue.h"
-#include "FloatValue.h"
-#include "LCDDisplay.h"
-#include "logging.h"
-
-#define THRESHOLD_PERCENT_SIG 0.06       // Percentage cut-off for avoiding sending similar signal sensor data.
-// Time interval for forcing a sending even if analog sensor readings are constantly similar (in seconds).
-#define TIME_LIMIT_SIG 900               
-
-SignalQualityMeasurement::SignalQualityMeasurement(AbstractSmartRest& client, 
-    SmartRestTemplate& tpl, DeviceInfo& deviceInfo) :
-    _tpl(tpl),
-    _client(client),
-    _deviceInfo(deviceInfo)
-{
-    _init = false;
-    oldValues[0] = 0;
-    oldValues[1] = 0;
-    t_start = time(NULL);
-}
-
-bool SignalQualityMeasurement::init()
-{
-    if (_init)
-        return false;
-    
-    // Insert measurement
-    // USAGE: 104,<DEVICE/ID>,<RSSI>,<BER>
-    if (!_tpl.add("10,104,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"))
-        return false;
-
-    _init = true;
-    return true;
-}
-
-bool SignalQualityMeasurement::run()
-{
-    static char signal[25] = {0};
-    DeviceInfo::SignalQuality *signalQuality;
-    if ((signalQuality = _deviceInfo.signalQuality()) == NULL)
-        return false;
-    if (signalQuality && signalQuality->rssi)
-        snprintf(signal, sizeof(signal), "Network: %d dBm", signalQuality->rssi);
-    else
-        strncpy(signal, "Network: no coverage", sizeof(signal));
-    if (strcmp(LCDDisplay::inst().getSecondLine(), signal)) {
-        LCDDisplay::inst().setSecondLine(signal);
-    }
-
-    int data[2] = {signalQuality->rssi, signalQuality->ber};
-    if (abs(oldValues[0]-data[0]) <= abs(oldValues[0])*THRESHOLD_PERCENT_SIG &&
-        abs(oldValues[1]-data[1]) <= abs(oldValues[1])*THRESHOLD_PERCENT_SIG) {
-        time_t t_interval = time(NULL) - t_start;
-        if (t_interval < TIME_LIMIT_SIG) {
-            if (strcmp(LCDDisplay::inst().getThirdLine(), "")) {
-                LCDDisplay::inst().setThirdLine("");
-            }
-            return true;
-        } else {
-            aDebug("Signal: Timeout at %d s.\n", t_interval);
-        }
-    }
-
-    char status[25] = {0};
-    snprintf(status, 25, "Send dBm %d,%d", data[0], data[1]);
-    LCDDisplay::inst().setThirdLine(status);
-    ComposedRecord record;
-    IntegerValue msgId(104);
-    IntegerValue devId(deviceID);
-    IntegerValue rssi(signalQuality->rssi);
-    IntegerValue ber(signalQuality->ber);
-    if ((!record.add(msgId)) || (!record.add(devId)) || (!record.add(rssi)) || (!record.add(ber)))
-        return false;
-
-    time_t t0 = time(NULL);
-    if (_client.send(record) != SMARTREST_SUCCESS) {
-        aWarning("Signal: Send failed.\n");
-        _client.stop();
-        return false;
-    }
-    time_t t1 = time(NULL);
-    _client.stop();
-    aDebug("Signal: Sent in %d s.\n", t1-t0);
-    oldValues[0] = data[0];
-    oldValues[1] = data[1];
-    t_start = time(NULL);
-    return true;
-}
--- a/measurement/SignalQualityMeasurement.h	Thu May 07 13:56:19 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-#ifndef SIGNALQUALITYMEASUREMENT_H
-#define SIGNALQUALITYMEASUREMENT_H
-
-#include "AbstractSmartRest.h"
-#include "SmartRestTemplate.h"
-#include "DeviceInfo.h"
-
-class SignalQualityMeasurement
-{
-public:
-    SignalQualityMeasurement(AbstractSmartRest&, SmartRestTemplate&, DeviceInfo&);
-    
-    bool init();
-    bool run();
-
-private:
-    bool _init;
-    SmartRestTemplate& _tpl;
-    AbstractSmartRest& _client;
-    DeviceInfo& _deviceInfo;
-    int oldValues[2];
-    time_t t_start;
-};
-
-#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/Temperature.cpp	Fri May 08 12:19:57 2015 +0000
@@ -0,0 +1,33 @@
+#include <stdio.h>
+#include "Temperature.h"
+#include "SmartRestConf.h"
+#include "logging.h"
+
+// Cut-off for avoiding sending similar sensor reading.
+#define THRESHOLD_PERCENT_TEMP 0.02
+// Timeout for forcing a sending even if readings are similar [seconds].
+#define TIME_LIMIT_TEMP 900
+
+size_t Temperature::read(char *buf, size_t maxLen, char *status, size_t num)
+{
+        static const char *fmt = "105,%ld,%f\r\n";
+        if (!deviceReady)
+                return 0;
+
+        float data = sensor.temp();
+        if (abs(oldValue-data) <= abs(oldValue)*THRESHOLD_PERCENT_TEMP) {
+                time_t t_interval = time(NULL) - t_start;
+                if (t_interval < TIME_LIMIT_TEMP) {
+                        return 0;
+                } else {
+                        aDebug("Temp: Timeout at %d s.\n", t_interval);
+                }
+        }
+        size_t l = snprintf(buf, maxLen, fmt, deviceID, data);
+        if (status) {
+                snprintf(status, num, "Send Temp %.2f", data);
+        }
+        oldValue = data;
+        t_start = time(NULL);
+        return l;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/Temperature.h	Fri May 08 12:19:57 2015 +0000
@@ -0,0 +1,28 @@
+#ifndef TEMPERATURE_H
+#define TEMPERATURE_H
+#include "mbed.h"
+#include "LM75B.h"
+#include "AbstractReporter.h"
+
+
+class Temperature: public AbstractReporter
+{
+public:
+        Temperature(): deviceReady(false), oldValue(0), sensor(D14, D15) {
+                t_start = time(NULL);
+        }
+        virtual ~Temperature() {}
+        virtual bool init() {
+                deviceReady = sensor.open();
+                return deviceReady;
+        }
+        virtual const char* name() const { return "Temp"; }
+        virtual size_t read(char*, size_t, char*, size_t);
+private:
+        bool deviceReady;
+        float oldValue;
+        time_t t_start;
+        LM75B sensor;
+};
+
+#endif /* TEMPERATURE_H */
\ No newline at end of file
--- a/measurement/TemperatureMeasurement.cpp	Thu May 07 13:56:19 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-#include "TemperatureMeasurement.h"
-#include "ComposedRecord.h"
-#include "CharValue.h"
-#include "IntegerValue.h"
-#include "FloatValue.h"
-#include "LCDDisplay.h"
-#include "logging.h"
-
-#define THRESHOLD_PERCENT_TEMP 0.02       // Percentage cut-off for avoiding sending similar temperature sensor data.
-// Time interval for forcing a sending even if analog sensor readings are constantly similar (in seconds).
-#define TIME_LIMIT_TEMP 900               
-
-TemperatureMeasurement::TemperatureMeasurement(AbstractSmartRest& client,
-    SmartRestTemplate& tpl, DeviceInfo& deviceInfo) :
-    _tpl(tpl),
-    _client(client),
-    _sensor(D14,D15),
-    oldValue(0),
-    _deviceInfo(deviceInfo)
-{
-    _init = false;
-    t_start = time(NULL);
-}
-
-bool TemperatureMeasurement::init()
-{
-    if (_init)
-        return false;
-    
-    // Insert measurement
-    // USAGE: 105,<DEVICE/ID>,<TEMPERATURE>
-    if (!_tpl.add("10,105,POST,/measurement/measurements,application/vnd.com.nsn.cumulocity.measurement+json,application/vnd.com.nsn.cumulocity.measurement+json,%%,NOW UNSIGNED NUMBER,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_TemperatureMeasurement\"\",\"\"c8y_TemperatureMeasurement\"\":{\"\"T\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"C\"\"}}}\"\r\n"))
-        return false;
-
-    _open = _sensor.open();
-    _init = true;
-    return true;
-}
-
-bool TemperatureMeasurement::run()
-{
-    if (!_open)
-        return false;
-
-    float data = _sensor.temp();
-
-    if (abs(oldValue-data) <= abs(oldValue)*THRESHOLD_PERCENT_TEMP) {
-        time_t t_interval = time(NULL) - t_start;
-        if (t_interval < TIME_LIMIT_TEMP) {
-            if (strcmp(LCDDisplay::inst().getThirdLine(), "")) {
-                LCDDisplay::inst().setThirdLine("");
-            }
-            return true;
-        } else {
-            aDebug("Temp: Timeout at %d s.\n", t_interval);
-        } 
-    }
-
-    char status[25] = {0};
-    snprintf(status, 25, "Send Temp %.2f", data);
-    LCDDisplay::inst().setThirdLine(status);
-    ComposedRecord record;
-    IntegerValue msgId(105);
-    IntegerValue devId(deviceID);
-    FloatValue temperature(data, 1);
-    if ((!record.add(msgId)) || (!record.add(devId)) || (!record.add(temperature)))
-        return false;
-
-    time_t t0 = time(NULL);
-    if (_client.send(record) != SMARTREST_SUCCESS) {
-        aWarning("Temp: Send failed.\n");
-        _client.stop();
-        return false;
-    }
-    time_t t1 = time(NULL);
-    _client.stop();
-    aDebug("Temp: Sent in %d s.\n", t1-t0);
-    oldValue = data;
-    t_start = time(NULL);
-    return true;
-}
--- a/measurement/TemperatureMeasurement.h	Thu May 07 13:56:19 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#ifndef TEMPERATUREMEASUREMENT_H
-#define TEMPERATUREMEASUREMENT_H
-
-#include "AbstractSmartRest.h"
-#include "SmartRestTemplate.h"
-#include "LM75B.h"
-#include "DeviceInfo.h"
-
-class TemperatureMeasurement
-{
-public:
-    TemperatureMeasurement(AbstractSmartRest&, SmartRestTemplate&, DeviceInfo&);
-
-    bool init();
-    bool run();
-
-private:
-    bool _init, _open;
-    SmartRestTemplate& _tpl;
-    AbstractSmartRest& _client;
-    LM75B _sensor;
-    float oldValue;
-    time_t t_start;
-    DeviceInfo& _deviceInfo;
-};
-
-#endif
\ No newline at end of file
--- a/operation/ControlParser.cpp	Thu May 07 13:56:19 2015 +0000
+++ b/operation/ControlParser.cpp	Fri May 08 12:19:57 2015 +0000
@@ -198,7 +198,7 @@
 
 void ControlParser::parseError(Token& tok)
 {
-        aError("(%d) %.*s\n", tok.type, (int)tok.len, tok.p);
+        aError("CtrlParse: (%d) %.*s\n", tok.type, (int)tok.len, tok.p);
         parseRecover(tok);
 }
 
--- a/operation/ControlParser.h	Thu May 07 13:56:19 2015 +0000
+++ b/operation/ControlParser.h	Fri May 08 12:19:57 2015 +0000
@@ -20,6 +20,7 @@
         int getBayeuxTimeout() const { return bayeuxTimeout; }
         void parse(const char*);
 protected:
+        typedef void (ControlParser::*PtrParseFunc)(Token&);
         void parseAdviceInterval(Token& tok);
         void parseAdvicePolicy(Token& tok);
         void parseAdviceTimeout(Token& tok);
@@ -33,9 +34,8 @@
         void parseOpState(Token& tok);
         void parseOpType(Token& tok);
         void parseRecover(Token& tok);
-        void parseUnknownInt(Token& tok);
+        void parseRowNumber(Token& tok);
 private:
-        typedef void (ControlParser::*PtrParseFunc)(Token&);
         unsigned short opType;
         Operation op;
         BayeuxAdvice bayeuxAdvice;
--- a/operation/OperationSupport.cpp	Thu May 07 13:56:19 2015 +0000
+++ b/operation/OperationSupport.cpp	Fri May 08 12:19:57 2015 +0000
@@ -3,6 +3,7 @@
 #include "ComposedRecord.h"
 #include "ParsedRecord.h"
 #include "IntegerValue.h"
+#include "SmartRestConf.h"
 #include "logging.h"
 
 bool OperationSupport::init()
--- a/operation/PollThread.cpp	Thu May 07 13:56:19 2015 +0000
+++ b/operation/PollThread.cpp	Fri May 08 12:19:57 2015 +0000
@@ -22,10 +22,10 @@
 
 bool PollThread::subscribe()
 {
-        int l = snprintf(buf2, SMARRESTBODY_SIZE, "81,%s,/%s\r\n", bayeuxId, chn);
+        int l = snprintf(buf2, SMARRESTBODY_SIZE, "81,%s,%s\r\n", bayeuxId, chn);
         l = snprintf(buf, SMARTREST_SIZE, fmtSmartRest, uri, l, buf2);
         sock.set_blocking(false);
-        l = sock.sendOnly(buf, l, SMARTREST_SIZE);
+        l = sock.sendOnly(buf, l);
         return l>=0;
 }
 
--- a/operation/PollThread.h	Thu May 07 13:56:19 2015 +0000
+++ b/operation/PollThread.h	Fri May 08 12:19:57 2015 +0000
@@ -15,7 +15,7 @@
                 strncpy(uri, "/devicecontrol/notifications", sizeof(uri));
                 sock.set_blocking(true);
         }
-        virtual ~PollThread() { sock.close(); }
+        virtual ~PollThread() {}
         bool handshake();
         bool subscribe();
         bool connect();
--- a/operation/ReportThread.h	Thu May 07 13:56:19 2015 +0000
+++ b/operation/ReportThread.h	Fri May 08 12:19:57 2015 +0000
@@ -11,7 +11,7 @@
                 thread(ReportThread::threadWrapper, this) {
                 strncpy(uri, "/s", sizeof(uri));
         }
-        virtual ~ReportThread() { sock.close(); }
+        virtual ~ReportThread() { }
         void threadFunc();
         static void threadWrapper(const void *p) { ((ReportThread*)p)->threadFunc(); }
 private:
--- a/util/AbstractReporter.h	Thu May 07 13:56:19 2015 +0000
+++ b/util/AbstractReporter.h	Fri May 08 12:19:57 2015 +0000
@@ -1,11 +1,28 @@
 #ifndef ABSTRACTREPORTER_H
 #define ABSTRACTREPORTER_H
+#include <stddef.h>
 
 class AbstractReporter
 {
 public:
-        virtual ~AbstractReporter() = 0;
-        virtual size_t read(const char*) = 0;
+        virtual ~AbstractReporter() {}
+        virtual bool init() = 0;
+
+        /* A string representation of the actual report.
+           \return identifying name of the class.
+         */
+        virtual const char* name() const = 0;
+
+        /* Dump a SmartRest report to buf.
+           \param buf  buffer for the report.
+           \param maxLen  maximum length of buf.
+           \param status  a short summary of the report.
+                          Pass NULL if the status is not interested.
+           \param num  maximum length of status.
+           \return  number of characters written to buf, 0 means no report.
+         */
+        virtual size_t read(char* buf, size_t maxLen,
+                            char* status, size_t num) = 0;
 };
 
 #endif /* ABSTRACTREPORTER_H */
\ No newline at end of file
--- a/util/SmartRestConf.cpp	Thu May 07 13:56:19 2015 +0000
+++ b/util/SmartRestConf.cpp	Fri May 08 12:19:57 2015 +0000
@@ -8,7 +8,7 @@
 char srAuthStr[100] = {0};
 const char *srX_ID = "com_cumulocity_MbedAgent_1.5.2";
 const char *srHost = "developer.cumulocity.com";
-// const char *_host = "management.m2m-devicecloud.com"
+//const char *srHost = "management.m2m-devicecloud.com";
 const int srPort = 80;
 long deviceID = 0;
 char fmtSmartRest[200] = {0};
--- a/util/SmartRestConf.h	Thu May 07 13:56:19 2015 +0000
+++ b/util/SmartRestConf.h	Fri May 08 12:19:57 2015 +0000
@@ -14,6 +14,6 @@
 
 void setDeviceID(long id);
 void setAuth(const char* username, const char* password);
-void setIdentifier(const char* id);
+void setX_ID(const char* id);
 
 #endif /* SMARTRESTCONF_H */
--- a/util/SmartRestTemplate.cpp	Thu May 07 13:56:19 2015 +0000
+++ b/util/SmartRestTemplate.cpp	Fri May 08 12:19:57 2015 +0000
@@ -1,5 +1,5 @@
+#include <string.h>
 #include "SmartRestTemplate.h"
-#include <string.h>
 
 SmartRestTemplate::SmartRestTemplate()
 {
--- a/util/dict.h	Thu May 07 13:56:19 2015 +0000
+++ b/util/dict.h	Fri May 08 12:19:57 2015 +0000
@@ -1,6 +1,7 @@
 #ifndef DICH_H
 #define DICH_H
 #include <string.h>
+#include <stdio.h>
 #define MAX_KEY_LEN 50
 #define MAX_VALUE_LEN 50
 #define MAX_ITEM_SIZE 3
@@ -14,6 +15,19 @@
         };
 
         Dict(): count(0) {}
+        
+        Dict(const Dict& d): count(0) {
+                *this = d;
+        }
+
+        Dict& operator= (const Dict& d) {
+                clear();
+                for (size_t i = 0; i < d.size(); ++i) {
+                        const Item* p = d.at(i);
+                        set(p->key, p->value);
+                }
+                return *this;
+        }
 
         const Item* at(const size_t i) const {
                 if (i < count) return &items[i];
@@ -42,19 +56,20 @@
                         return NULL;
         }
 
+        size_t dump(char* buf) const {
+                size_t l = 0;
+                for (size_t i = 0; i < count; ++i) {
+                        l += sprintf(buf+l, "%s=%s;", items[i].key, items[i].value);
+                }
+                buf[l] = 0;
+                return l;
+        }
+
         size_t maxSize() const { return MAX_ITEM_SIZE; }
         size_t size() const { return count; }
         bool empty() const { return count==0; }
         bool full() const { return count == MAX_ITEM_SIZE; }
         void clear() { count = 0; }
-        size_t dump(char* buf) {
-                size_t l = 0;
-                for (size_t i = 0; i < count; ++i) {
-                        l + sprintf(buf+l, "%s=%s;", items[i].key, items[i].value);
-                }
-                buf[l] = 0;
-                return l;
-        }
         virtual ~Dict() {}
 protected:
         size_t find(const char* k) const {
@@ -69,4 +84,4 @@
         size_t count;
 };
 
-#endif /* DICH_H */
+#endif /* DICH_H */
\ No newline at end of file