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:
Tue Mar 03 14:10:09 2015 +0000
Parent:
76:b07effe83fb8
Child:
78:bf32dfe6c47f
Commit message:
Working device push, DNS caching, change logging level when running and more.

Changed in this revision

C027_Support.lib Show annotated file Show diff for this revision Revisions of this file
DeviceBootstrap.cpp 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
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/ConfigurationSynchronization.cpp Show annotated file Show diff for this revision Revisions of this file
logging/logging.cpp Show annotated file Show diff for this revision Revisions of this file
logging/logging.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
measurement/AccelerationMeasurement.cpp Show annotated file Show diff for this revision Revisions of this file
measurement/AnalogMeasurement.cpp Show annotated file Show diff for this revision Revisions of this file
measurement/LocationUpdate.cpp Show annotated file Show diff for this revision Revisions of this file
measurement/SignalQualityMeasurement.cpp Show annotated file Show diff for this revision Revisions of this file
measurement/SignalQualityMeasurement.h Show annotated file Show diff for this revision Revisions of this file
measurement/TemperatureMeasurement.cpp Show annotated file Show diff for this revision Revisions of this file
operation/OperationExecutor.cpp Show annotated file Show diff for this revision Revisions of this file
operation/OperationStore.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
util/RtosSmartRest.cpp Show annotated file Show diff for this revision Revisions of this file
util/RtosSmartRest.h Show annotated file Show diff for this revision Revisions of this file
--- a/C027_Support.lib	Wed Feb 25 10:06:11 2015 +0000
+++ b/C027_Support.lib	Tue Mar 03 14:10:09 2015 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/teams/ublox/code/C027_Support/#7d7ab5314caa
+http://mbed.org/teams/ublox/code/C027_Support/#eb1902489fdd
--- a/DeviceBootstrap.cpp	Wed Feb 25 10:06:11 2015 +0000
+++ b/DeviceBootstrap.cpp	Tue Mar 03 14:10:09 2015 +0000
@@ -73,8 +73,7 @@
             _client.stop();
             Thread::wait(2000);
             continue;
-        }
-        
+        }        
         if (_client.receive(recvdRecord) != SMARTREST_SUCCESS) {
             _client.stop();
             Thread::wait(2000);
@@ -82,15 +81,15 @@
         }
         _client.stop();
         
-        for (size_t q = 0; q < recvdRecord.values(); q++)
-            aDebug(recvdRecord.rawValue(q));
-            
+        if (getLevel() == A_DEBUG) {
+            for (size_t q = 0; q < recvdRecord.values(); q++)
+                aDebug("Bootstrap, received: %s\r\n", recvdRecord.rawValue(q));
+        }    
         if ((recvdRecord.values() < 1) ||
             (recvdRecord.value(0).integerValue() == 50)) {
             Thread::wait(2000);
             continue;
         }
-        
         if ((recvdRecord.value(0).integerValue() != 70) ||
             (recvdRecord.values() != 6)) {
             return false;
@@ -98,10 +97,8 @@
         
         setCredentials(recvdRecord.value(3).characterValue(),
                        recvdRecord.value(4).characterValue(),
-                       recvdRecord.value(5).characterValue());
-        
+                       recvdRecord.value(5).characterValue());        
         _io.lcdPrint("Bootstrap Success", _username, _password);
-
         return true;
     } while (--tries > 0);
 
--- a/DeviceInfo.cpp	Wed Feb 25 10:06:11 2015 +0000
+++ b/DeviceInfo.cpp	Tue Mar 03 14:10:09 2015 +0000
@@ -37,8 +37,11 @@
     return _devStatus.ccid;
 }
 
-DeviceInfo::SignalQuality * DeviceInfo::signalQuality()
+DeviceInfo::SignalQuality * DeviceInfo::signalQuality(bool realTime)
 {
+    if (!realTime && _signalQuality.rssi)
+        return &_signalQuality;
+
     memset(&_signalQuality, 0, sizeof(DeviceInfo::SignalQuality));
     if (!refreshNetStatus()) {
         aError("Can not refresh network status!\r\n");
--- a/DeviceInfo.h	Wed Feb 25 10:06:11 2015 +0000
+++ b/DeviceInfo.h	Tue Mar 03 14:10:09 2015 +0000
@@ -19,7 +19,7 @@
     const char * imei();
     const char * cellId();
     const char * iccid();
-    SignalQuality * signalQuality();
+    SignalQuality * signalQuality(bool realTime=true);
 
 protected:
     bool refreshNetStatus();
--- a/DeviceIntegration.cpp	Wed Feb 25 10:06:11 2015 +0000
+++ b/DeviceIntegration.cpp	Tue Mar 03 14:10:09 2015 +0000
@@ -85,20 +85,20 @@
         return false;
 
     if (_client.send(record) != SMARTREST_SUCCESS) {
-        aWarning("Send failed.");
+        aWarning("Send failed.\r\n");
         _client.stop();
         return false;
     }
 
     if (_client.receive(received) != SMARTREST_SUCCESS) {
-        aError("No device found.");
+        aError("No device found.\r\n");
         _client.stop();
         return false;
     }
     _client.stop();
 
     if (received.values() == 0) {
-        aWarning("Received no values.");
+        aError("Received no values.\r\n");
         return false;
     }
 
@@ -107,7 +107,7 @@
     }
     
     if (received.value(0).integerValue() != 200) {
-        puts("Bad response.");
+        aError("Bad response.\r\n");
         return false;
     }
 
@@ -121,7 +121,7 @@
     ComposedRecord record;
     ParsedRecord received;
 
-    puts("Creating device...");
+    aInfo("Creating device...\r\n");
 
     IntegerValue msgId(101);
     CharValue imei(_deviceInfo.imei());
@@ -129,25 +129,25 @@
         return false;
 
     if (_client.send(record) != SMARTREST_SUCCESS) {
-        puts("Send failed.");
+        aError("Failed to sending data when creating device.\r\n");
         _client.stop();
         return 0;
     }
 
     if (_client.receive(received) != SMARTREST_SUCCESS) {
-        puts("No device found.");
+        aError("No device found.\r\n");
         _client.stop();
         return false;
     }
     _client.stop();
 
     if (received.values() != 3) {
-        puts("Bad received data.");
+        aError("Received incomplete data when creating device.\r\n");
         return false;
     }
     
     if (received.value(0).integerValue() != 201) {
-        puts("Bad received data.");
+        aError("Received invalid data when creating device.\r\n");
         return false;
     }
 
@@ -160,7 +160,7 @@
     ComposedRecord record;
     ParsedRecord received;
 
-    puts("Adding global identifier...");
+    aInfo("Adding global identifier...\r\n");
 
     IntegerValue msgId(102);
     IntegerValue deviceId(_deviceId);
@@ -169,25 +169,25 @@
         return false;
 
     if (_client.send(record) != SMARTREST_SUCCESS) {
-        puts("Sending failed.");
+        aWarning("Adding global identifier failed.\r\n");
         _client.stop();
         return false;
     }
 
     if (_client.receive(received) != SMARTREST_SUCCESS) {
-        puts("Failed.");
+        aError("Received data failed when adding global identifier.\r\n");
         _client.stop();
         return false;
     }
     _client.stop();
 
     if (received.values() != 3) {
-        puts("Received bad data.");
+        aError("Received incomplete data when adding global identifier.\r\n");
         return false;
     }
     
     if (received.value(0).integerValue() != 200) {
-        puts("Received bad data.");
+        aError("Received invalid data when adding global identifier.\r\n");
         return false;
     }
 
@@ -208,25 +208,25 @@
         return false;
 
     if (_client.send(record) != SMARTREST_SUCCESS) {
-        puts("Send failed.");
+        aError("Sending data failed when updating device.\r\n");
         _client.stop();
         return false;
     }
 
     if (_client.receive(received) != SMARTREST_SUCCESS) {
-        puts("Update failed.");
+        aError("Updating device failed.\r\n");
         _client.stop();
         return false;
     }
     _client.stop();
 
     if (received.values() != 3) {
-        puts("Bad received data.");
+        aError("Received incomplete data when updating device.\r\n");
         return false;
     }
     
     if (received.value(0).integerValue() != 201) {
-        puts("Bad received data.");
+        aError("Received invalid data when updating device.\r\n");
         return false;
     }
 
--- a/MbedAgent.cpp	Wed Feb 25 10:06:11 2015 +0000
+++ b/MbedAgent.cpp	Tue Mar 03 14:10:09 2015 +0000
@@ -9,7 +9,7 @@
     _deviceInfo(deviceInfo),
     _deviceMemory(deviceMemory),
     _configurationProperties(_deviceConfiguration),
-    _client(MBED_AGENT_HOST, MBED_AGENT_PORT, MBED_AGENT_DEVICE_IDENTIFIER),
+    _client(MBED_AGENT_HOST, MBED_AGENT_PORT, MBED_AGENT_DEVICE_IDENTIFIER, mdm),
     _bootstrap(_client, _io, _deviceInfo, _deviceMemory),
     _integration(_client, _tpl, _deviceId, _deviceInfo),
     _configurationSynchronization(_client, _tpl, _deviceId, _deviceMemory, _deviceConfiguration, _configurationProperties),
@@ -90,16 +90,35 @@
 void MbedAgent::loop()
 {
     Watchdog wdt;
+    DigitalIn joystickUp(A2);
+    DigitalIn joystickDown(A3);
+//    DigitalIn joystickLeft(A4);
+//    AnalogIn joystickRight(A5);
+    
     wdt.kick(60.0);    // set a 60.0 seconds timeout on watchdog hardware timer
     while (true) {
-        _configurationSynchronization.run();
-        _signalQualityMeasurement.run();
-        _temperatureMeasurement.run();
-        _analogMeasurement.run();
-        _accelerationMeasurement.run();
-        _locationUpdate.run();
+        if (joystickDown) {
+            setLevel(A_INFO);
+            _mdm.setDebug(1);
+            printf("***Disabled debug mode.***\r\n");
+        } else if (joystickUp) {
+            setLevel(A_DEBUG);
+            _mdm.setDebug(3);
+            printf("***Enabled debug mode.***\r\n");
+        }
+//        _configurationSynchronization.run();
+//        _operationSupport.run();
+//        _signalQualityMeasurement.run();
+//        _operationSupport.run();
+//        _temperatureMeasurement.run();
+//        _operationSupport.run();
+//        _analogMeasurement.run();
+//        _operationSupport.run();
+//        _accelerationMeasurement.run();
+//        _operationSupport.run();
+//        _locationUpdate.run();
         _operationSupport.run();
-        
+                
 //        if ((interval = _configurationProperties.readInterval()) < 0)
 //            break;
 //
--- a/MbedAgent.h	Wed Feb 25 10:06:11 2015 +0000
+++ b/MbedAgent.h	Tue Mar 03 14:10:09 2015 +0000
@@ -20,10 +20,10 @@
 #include "LocationUpdate.h"
 #include "OperationSupport.h"
 
-#define MBED_AGENT_HOST "management.m2m-devicecloud.com"
-// #define MBED_AGENT_HOST "developer.cumulocity.com"
+//#define MBED_AGENT_HOST "management.m2m-devicecloud.com"
+#define MBED_AGENT_HOST "developer.cumulocity.com"
 #define MBED_AGENT_PORT 80
-#define MBED_AGENT_DEVICE_IDENTIFIER "com_cumulocity_MbedAgent_1.5.1"
+#define MBED_AGENT_DEVICE_IDENTIFIER "com_cumulocity_MbedAgent_1.5.2"
 
 class MbedAgent
 {
--- a/config/ConfigurationSynchronization.cpp	Wed Feb 25 10:06:11 2015 +0000
+++ b/config/ConfigurationSynchronization.cpp	Tue Mar 03 14:10:09 2015 +0000
@@ -25,7 +25,6 @@
     // 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"))
-//    if (!_tpl.add("10,130,PUT,/inventory/managedObjects/%%,application/vnd.com.nsn.cumulocity.managedObject+json,application/vnd.com.nsn.cumulocity.managedObject+json,%%,UNSIGNED NUMBER,\"{\"\"c8y_RequiredAvailability\"\":{ \"\"responseInterval\"\":%%}}\"\r\n"))
         return false;
 
     _init = true;
@@ -89,25 +88,25 @@
         return false;
 
     if (_client.send(record) != SMARTREST_SUCCESS) {
-        aWarning("Sending configuration failed.");
+        aError("Sending configuration failed.\r\n");
         _client.stop();
         return false;
     }
 
     if (_client.receive(received) != SMARTREST_SUCCESS) {
-        aWarning("Receiving configuration failed.");
+        aError("Connection failure or invalid configuration.\r\n");
         _client.stop();
         return false;
     }
     _client.stop();
 
     if (received.values() != 3) {
-        aWarning("Incomplete configuration data received.");
+        aError("Unmatching configuration data received, expected 3, but %d received.\r\n", received.values());
         return false;
     }
     
     if (received.value(0).integerValue() != 201) {
-        aWarning("Bad configuration data received.");
+        aError("Bad configuration data received.\r\n");
         return false;
     }
     return true;
--- a/logging/logging.cpp	Wed Feb 25 10:06:11 2015 +0000
+++ b/logging/logging.cpp	Tue Mar 03 14:10:09 2015 +0000
@@ -13,8 +13,8 @@
                 switch (lvl)
                 {
                 case A_DEBUG:    n += printf("[DEBUG] ");    break;
+                case A_INFO:     n += printf("[INFO] ");     break;
                 case A_WARNING:  n += printf("[WARN] ");     break;
-                case A_INFO:     n += printf("[INFO] ");     break;
                 case A_ERROR:    n += printf("[ERROR] ");    break;
                 case A_CRITICAL: n += printf("[CRITICAL] "); break;
                 default:         n += printf("[UNKNOWN] ");  break;
@@ -79,3 +79,27 @@
 {
         _level = lvl;
 }
+
+void higherOneLevel()
+{
+    switch (_level)
+    {
+    case A_DEBUG:    _level = A_INFO;     break;
+    case A_INFO:     _level = A_WARNING;  break;
+    case A_WARNING:  _level = A_ERROR;    break;
+    case A_ERROR:    _level = A_CRITICAL; break;
+    case A_CRITICAL: _level = A_NONE;     break;
+    }
+}
+
+void lowerOneLevel()
+{
+    switch (_level)
+    {
+    case A_INFO:     _level = A_DEBUG;    break;
+    case A_WARNING:  _level = A_INFO;     break;
+    case A_ERROR:    _level = A_WARNING;  break;
+    case A_CRITICAL: _level = A_ERROR;    break;
+    case A_NONE:     _level = A_CRITICAL; break;
+    }
+}
\ No newline at end of file
--- a/logging/logging.h	Wed Feb 25 10:06:11 2015 +0000
+++ b/logging/logging.h	Tue Mar 03 14:10:09 2015 +0000
@@ -5,11 +5,12 @@
    Logging levels below have higher severity than the above levels.
  */
 enum aLogLevel{
-        A_DEBUG=10,
-        A_INFO=20,
-        A_WARNING=30,
-        A_ERROR=40,
-        A_CRITICAL=50
+        A_DEBUG=1,
+        A_INFO,
+        A_WARNING,
+        A_ERROR,
+        A_CRITICAL,
+        A_NONE     // No logging
 };
 
 /* All logging functions.
@@ -25,4 +26,6 @@
 
 aLogLevel getLevel();
 void setLevel(aLogLevel lvl);
+void higherOneLevel();  // Set log level one severity higher (terser), does nothing when already highest
+void lowerOneLevel();   // Set log level one severity lower (chattier), does nothing when already lowerest
 #endif /* LOGGING_H */
--- a/main.cpp	Wed Feb 25 10:06:11 2015 +0000
+++ b/main.cpp	Tue Mar 03 14:10:09 2015 +0000
@@ -25,16 +25,25 @@
 
 int main()
 {
-    setLevel(A_DEBUG);
     MDMParser::DevStatus devStatus;
     int res;
     uint8_t status = 0;
 
     MDMRtos<MDMSerial> mdm;
     GPSI2C gps;
-    DeviceIO io(gps);
+    DeviceIO io(gps);    
     
-    mdm.setDebug(4);
+    DigitalIn joystickUp(A2);
+    DigitalIn joystickDown(A3);
+    if (joystickUp) {
+        setLevel(A_DEBUG);
+        mdm.setDebug(3);
+        printf("Enable debug mode.\r\n");
+    } else {
+        setLevel(A_INFO);
+        mdm.setDebug(1);
+    }        
+    
     io.lcdPrint("Device Init");
     if (!mdm.init(SIM_PIN, &devStatus)) {
         status = 1;
@@ -48,7 +57,7 @@
     
     io.lcdPrint("Register Network", "IMEI", devStatus.imei);
     if (!mdm.registerNet()) {
-        io.lcdPrint("Network Reg Error");
+        io.lcdPrint("No Network Coverage");
         goto error;
     }
 
@@ -58,7 +67,7 @@
 #else
     if (mdm.join() == NOIP) {
 #endif
-        io.lcdPrint("Network join failure", "Check your APN settting,", "username or password");
+        io.lcdPrint("Network join failure", "Wrong APN settting,", "username and password");
         goto error;
     }
     
@@ -84,7 +93,7 @@
     
         io.lcdPrint("Agent Init");
         if (!agent.init()) {
-            io.lcdPrint("Agent Init Failure");
+            io.lcdPrint("Agent Init Failure", "Debug via serial port");
             goto error;
         }
         
@@ -96,7 +105,7 @@
         } while (--tries > 0);
 
         if (tries == 0) {
-            io.lcdPrint("Agent Run Failure");
+            io.lcdPrint("Integration/Config Failure");
             goto error;
         }
     }
--- a/measurement/AccelerationMeasurement.cpp	Wed Feb 25 10:06:11 2015 +0000
+++ b/measurement/AccelerationMeasurement.cpp	Tue Mar 03 14:10:09 2015 +0000
@@ -46,19 +46,26 @@
 {
     if (!_test)
         return false;
-        
+    
+    static char tenant[25];
+    static bool firstTime = true;
+    if (firstTime) {
+        firstTime = false;
+        const char* user= _bootstrap.username();
+        int len = strchr(user, '/')-user+1+8;  // 8: length of "Tenant: "
+        len = len <= 25 ? len : 25;
+        snprintf(tenant, len, "Tenant: %s", user);
+    }
+
     float data[3] = { 0.0, 0.0, 0.0 };
-    _sensor.readData(data);    
-    char tenant[25] = {0};
-    const char* user= _bootstrap.username();
-    int len = strchr(user, '/')-user+1+8;  // 8: length of "Tenant: "
-    len = len <= 25 ? len : 25;
-    snprintf(tenant, len, "Tenant: %s", user);
+    _sensor.readData(data);
+    DeviceInfo::SignalQuality *p = _deviceInfo.signalQuality(false);
     char signal[25] = {0};
-    if (_deviceInfo.signalQuality())
-        snprintf(signal, 25, "Network: %d dBm", _deviceInfo.signalQuality()->rssi);
+    if (p && p->rssi)
+        snprintf(signal, sizeof(signal), "Network: %d dBm", p->rssi);
     else
-        strncpy(signal, "Network: ? dBm", 25);
+        strncpy(signal, "Network: no coverage", sizeof(signal));
+
     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) {
@@ -67,13 +74,13 @@
             aDebug("Similar acceleration readings found, no sending!\r\n");
             return true;
         } else {
-            aDebug("Sending timer of acceleration sensor timed out at %f s, a sending is forced.\r\n", sendingTimer.read());
+            aDebug("Acceleration sensor timed out at %f s, a sending is forced.\r\n", sendingTimer.read());
         }
     }
     char status[27] = {0};
     snprintf(status, 27, "Sending Acc %.1f,%.1f,%.1f", data[0], data[1], data[2]);
     _io.lcdPrint(tenant, signal, status);
-        
+
     ComposedRecord record;
     IntegerValue msgId(106);
     IntegerValue devId(_deviceId);
--- a/measurement/AnalogMeasurement.cpp	Wed Feb 25 10:06:11 2015 +0000
+++ b/measurement/AnalogMeasurement.cpp	Tue Mar 03 14:10:09 2015 +0000
@@ -5,7 +5,7 @@
 #include "FloatValue.h"
 #include "logging.h"
 
-#define THRESHOLD_PERCENT_ANA 0.03       // Percentage cut-off for avoiding sending similar analog sensor data.
+#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               
 
@@ -42,19 +42,26 @@
 
 bool AnalogMeasurement::run()
 {
+    static char tenant[25];
+    static bool firstTime = true;
+    if (firstTime) {
+        firstTime = false;
+        const char* user= _bootstrap.username();
+        int len = strchr(user, '/')-user+1+8;  // 8: length of "Tenant: "
+        len = len <= 25 ? len : 25;
+        snprintf(tenant, len, "Tenant: %s", user);
+    }
+
     float data[2] = {0, 0};
     data[0] = _analog1.read()*100;
     data[1] = _analog2.read()*100;
-    char tenant[25] = {0};
-    const char* user= _bootstrap.username();
-    int len = strchr(user, '/')-user+1+8;  // 8: length of "Tenant: ";
-    len = len <= 25 ? len : 25;
-    snprintf(tenant, len, "Tenant: %s", user);
+    DeviceInfo::SignalQuality *p = _deviceInfo.signalQuality(false);
     char signal[25] = {0};
-    if (_deviceInfo.signalQuality())
-        snprintf(signal, 25, "Network: %d dBm", _deviceInfo.signalQuality()->rssi);
+    if (p && p->rssi)
+        snprintf(signal, sizeof(signal), "Network: %d dBm", p->rssi);
     else
-        strncpy(signal, "Network: ? dBm", 25);
+        strncpy(signal, "Network: no coverage", sizeof(signal));
+        
     if (abs(oldValues[0]-data[0]) <= abs(oldValues[0])*THRESHOLD_PERCENT_ANA &&
         abs(oldValues[1]-data[1]) <= abs(oldValues[1])*THRESHOLD_PERCENT_ANA) {
         if (sendingTimer.read() < TIME_LIMIT_ANA) {
@@ -62,7 +69,7 @@
             aDebug("Similar analog readings found, no sending!\r\n");
             return true;
         } else {
-            aDebug("Sending timer of analog sensor timed out at %f s, a sending is forced.\r\n", sendingTimer.read());
+            aDebug("Analog sensor timed out at %f s, a sending is forced.\r\n", sendingTimer.read());
         } 
     }
     
--- a/measurement/LocationUpdate.cpp	Wed Feb 25 10:06:11 2015 +0000
+++ b/measurement/LocationUpdate.cpp	Tue Mar 03 14:10:09 2015 +0000
@@ -48,26 +48,31 @@
 
 bool LocationUpdate::run()
 {
-    GPSTracker::Position position;
-    
+    GPSTracker::Position position;    
     if (!_gpsTracker.position(&position)) {
         aError("No GPS data available.\r\n");
         return false;
     }
+    static char tenant[25];
+    static bool firstTime = true;
+    if (firstTime) {
+        firstTime = false;
+        const char* user= _bootstrap.username();
+        int len = strchr(user, '/')-user+1+8;  // 8: length of "Tenant: "
+        len = len <= 25 ? len : 25;
+        snprintf(tenant, len, "Tenant: %s", user);
+    }
     float data[3] = { 0.0, 0.0, 0.0 };
     data[0] = position.altitude;
     data[1] = position.latitude;
     data[2] = position.longitude;
-    char tenant[25] = {0};
-    const char* user= _bootstrap.username();
-    int len = strchr(user, '/')-user+1+8;  // 8: length of "Tenant: ";
-    len = len <= 25 ? len : 25;
-    snprintf(tenant, len, "Tenant: %s", user);
+    DeviceInfo::SignalQuality *p = _deviceInfo.signalQuality(false);
     char signal[25] = {0};
-    if (_deviceInfo.signalQuality())
-        snprintf(signal, 25, "Network: %d dBm", _deviceInfo.signalQuality()->rssi);
+    if (p && p->rssi)
+        snprintf(signal, sizeof(signal), "Network: %d dBm", p->rssi);
     else
-        strncpy(signal, "Network: ? dBm", 25);
+        strncpy(signal, "Network: no coverage", sizeof(signal));
+
     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) {
@@ -76,7 +81,7 @@
             aDebug("Similar location readings found, no sending!\r\n");
             return true;
         } else {
-            aDebug("Sending timer of location sensor timed out at %f s, a sending is forced.\r\n", sendingTimer.read());
+            aDebug("Location sensor timed out at %f s, a sending is forced.\r\n", sendingTimer.read());
         }
     }
     char status[27] = {0};
--- a/measurement/SignalQualityMeasurement.cpp	Wed Feb 25 10:06:11 2015 +0000
+++ b/measurement/SignalQualityMeasurement.cpp	Tue Mar 03 14:10:09 2015 +0000
@@ -40,24 +40,25 @@
 
 bool SignalQualityMeasurement::run()
 {
-    DeviceInfo::SignalQuality *signalQuality;
-    
+    DeviceInfo::SignalQuality *signalQuality;   
     if ((signalQuality = _deviceInfo.signalQuality()) == NULL)
         return false;
-        
-    float data[2] = {0, 0};
-    data[0] = signalQuality->rssi;
-    data[1] = signalQuality->ber;
-    char tenant[25] = {0};
-    const char* user= _bootstrap.username();
-    int len = strchr(user, '/')-user+1+8;  // 8: length of "Tenant: ";
-    len = len <= 25 ? len : 25;
-    snprintf(tenant, len, "Tenant: %s", user);
+
+    static char tenant[25];
+    static bool firstTime = true;
+    if (firstTime) {
+        firstTime = false;
+        const char* user= _bootstrap.username();
+        int len = strchr(user, '/')-user+1+8;  // 8: length of "Tenant: "
+        len = len <= 25 ? len : 25;
+        snprintf(tenant, len, "Tenant: %s", user);
+    }
+    int data[2] = {signalQuality->rssi, signalQuality->ber};
     char signal[25] = {0};
-    if (_deviceInfo.signalQuality())
-        snprintf(signal, 25, "Network: %d dBm", _deviceInfo.signalQuality()->rssi);
+    if (signalQuality && signalQuality->rssi)
+        snprintf(signal, sizeof(signal), "Network: %d dBm", signalQuality->rssi);
     else
-        strncpy(signal, "Network: ? dBm", 25);
+        strncpy(signal, "Network: no coverage", sizeof(signal));
     if (abs(oldValues[0]-data[0]) <= abs(oldValues[0])*THRESHOLD_PERCENT_SIG &&
         abs(oldValues[1]-data[1]) <= abs(oldValues[1])*THRESHOLD_PERCENT_SIG) {
         if (sendingTimer.read() < TIME_LIMIT_SIG) {
@@ -65,12 +66,12 @@
             aDebug("Similar signal readings found, no sending!\r\n");
             return true;
         } else {
-            aDebug("Sending timer of signal sensor timed out at %f s, a sending is forced.\r\n", sendingTimer.read());
-        } 
-    }    
-        
+            aDebug("Signal sensor timed out at %f s, a sending is forced.\r\n", sendingTimer.read());
+        }
+    }
+
     char status[25] = {0};
-    snprintf(status, 25, "Sending dBm %d,%d", (int)data[0], (int)data[1]);
+    snprintf(status, 25, "Sending dBm %d,%d", data[0], data[1]);
     _io.lcdPrint(tenant, signal, status);
     ComposedRecord record;
     IntegerValue msgId(104);
--- a/measurement/SignalQualityMeasurement.h	Wed Feb 25 10:06:11 2015 +0000
+++ b/measurement/SignalQualityMeasurement.h	Tue Mar 03 14:10:09 2015 +0000
@@ -21,7 +21,7 @@
     SmartRestTemplate& _tpl;
     AbstractSmartRest& _client;
     DeviceInfo& _deviceInfo;
-    float oldValues[2];
+    int oldValues[2];
     Timer sendingTimer;
     DeviceIO& _io;
     DeviceBootstrap& _bootstrap;
--- a/measurement/TemperatureMeasurement.cpp	Wed Feb 25 10:06:11 2015 +0000
+++ b/measurement/TemperatureMeasurement.cpp	Tue Mar 03 14:10:09 2015 +0000
@@ -44,25 +44,31 @@
     if (!_open)
         return false;
 
+    static char tenant[25];
+    static bool firstTime = true;
+    if (firstTime) {
+        firstTime = false;
+        const char* user= _bootstrap.username();
+        int len = strchr(user, '/')-user+1+8;  // 8: length of "Tenant: "
+        len = len <= 25 ? len : 25;
+        snprintf(tenant, len, "Tenant: %s", user);
+    }
     float data = 0;
     data = _sensor.temp();
-    char tenant[25] = {0};
-    const char* user= _bootstrap.username();
-    int len = strchr(user, '/')-user+1+8;  // 8: length of "Tenant: ";
-    len = len <= 25 ? len : 25;
-    snprintf(tenant, len, "Tenant: %s", user);
+    DeviceInfo::SignalQuality *p = _deviceInfo.signalQuality(false);
     char signal[25] = {0};
-    if (_deviceInfo.signalQuality())
-        snprintf(signal, 25, "Network: %d dBm", _deviceInfo.signalQuality()->rssi);
+    if (p && p->rssi)
+        snprintf(signal, sizeof(signal), "Network: %d dBm", p->rssi);
     else
-        strncpy(signal, "Network: ? dBm", 25);
+        strncpy(signal, "Network: no coverage", sizeof(signal));
+
     if (abs(oldValue-data) <= abs(oldValue)*THRESHOLD_PERCENT_TEMP) {
         if (sendingTimer.read() < TIME_LIMIT_TEMP) {
             _io.lcdPrint(tenant, signal);
             aDebug("Similar temperature readings found, no sending!\r\n");
             return true;
         } else {
-            aDebug("Sending timer of temperature sensor timed out at %f s, a sending is forced.\r\n", sendingTimer.read());
+            aDebug("Temperature sensor timed out at %f s, a sending is forced.\r\n", sendingTimer.read());
         } 
     }
 
--- a/operation/OperationExecutor.cpp	Wed Feb 25 10:06:11 2015 +0000
+++ b/operation/OperationExecutor.cpp	Tue Mar 03 14:10:09 2015 +0000
@@ -1,9 +1,10 @@
+#include <string.h>
+#include <stdio.h>
 #include "OperationExecutor.h"
 #include "ComposedRecord.h"
 #include "CharValue.h"
 #include "IntegerValue.h"
-#include <string.h>
-#include <stdio.h>
+#include "logging.h"
 
 #define FOUND_RELAY 1
 #define FOUND_MESSAGE 2
@@ -50,7 +51,7 @@
 
 bool OperationExecutor::executeOperation(OperationStore::Operation& op)
 {
-    uint8_t ret; uint8_t found; bool relayState; char message[256];
+    uint8_t found; bool relayState; char message[256];
     ComposedRecord record;
     ParsedRecord received;
     
@@ -65,7 +66,7 @@
     }
     
     found = 0;
-    while ((ret = _client.receive(received)) == SMARTREST_SUCCESS) {
+    while (_client.receive(received) == SMARTREST_SUCCESS) {
         if ((received.values() == 4) &&
             (received.value(0).valueType() == VALUE_INTEGER) &&
             (received.value(0).integerValue() == 220) &&
@@ -75,8 +76,7 @@
             relayState = (strcmp("CLOSED", received.value(3).characterValue()) == 0);
             found = FOUND_RELAY;
             break;
-        }
-        
+        }       
         if ((received.values() == 4) &&
             (received.value(0).valueType() == VALUE_INTEGER) &&
             (received.value(0).integerValue() == 221) &&
@@ -87,8 +87,7 @@
             message[127] = '\0';
             found = FOUND_MESSAGE;
             break;
-        }
-        
+        }     
         if ((received.values() == 4) &&
             (received.value(0).valueType() == VALUE_INTEGER) &&
             (received.value(0).integerValue() == 222) &&
@@ -111,6 +110,12 @@
     case FOUND_CONFIGURATION:
         return executeUpdateConfiguration(message);
     default:
+        aWarning("Unsupported configuration received.\r\n");
+        if (getLevel() == A_DEBUG) {
+            aDebug("Configuration received: \r\n");
+            for (size_t q = 0; q < received.values(); q++)
+                aDebug("\t%s", received.rawValue(q));
+        }
         return false;
     }
 }
@@ -126,6 +131,9 @@
 
 bool OperationExecutor::executeMessageDisplay(const char *message)
 {
+//    char msg[78];   // Length of text that the LCD display can hold
+//    strncpy(msg, message, sizeof(msg));
+//    _io.lcdPrint(msg);
     _io.lcdPrint(message);
     return true;
 }
--- a/operation/OperationStore.h	Wed Feb 25 10:06:11 2015 +0000
+++ b/operation/OperationStore.h	Tue Mar 03 14:10:09 2015 +0000
@@ -28,7 +28,7 @@
         const char *descriptor;
         uint8_t state;
     };
-    
+
     /**
      * Enqueues a pending-state operation.
      * A defensive copy of the operation is madw.
--- a/operation/OperationSupport.cpp	Wed Feb 25 10:06:11 2015 +0000
+++ b/operation/OperationSupport.cpp	Tue Mar 03 14:10:09 2015 +0000
@@ -1,5 +1,5 @@
+#include <string.h>
 #include "OperationSupport.h"
-#include <string.h>
 #include "Aggregator.h"
 #include "ComposedRecord.h"
 #include "CharValue.h"
@@ -62,7 +62,6 @@
         if (!requestPendingOperations())
             return false;
     }
-        
     return true;
 }
 
@@ -94,8 +93,7 @@
     if ((ret != SMARTREST_END_OF_RESPONSE) &&
         (ret != SMARTREST_CONNECTION_CLOSED)) {
         return false;
-    }
-    
+    }   
     return true;
 }
 
@@ -129,10 +127,8 @@
 
 bool OperationSupport::updateOperation(OperationStore::Operation& op)
 {
-    uint8_t ret; bool found;
     ComposedRecord record;
-    ParsedRecord received;
-    
+    ParsedRecord received;   
     IntegerValue msgId(111);
     IntegerValue operationId(op.identifier);
     if ((!record.add(msgId)) || (!record.add(operationId)) ||
@@ -144,7 +140,8 @@
         return false;
     }
     
-    found = false;
+    bool found = false;
+    uint8_t ret;
     while ((ret = _client.receive(received)) == SMARTREST_SUCCESS) {
         if ((received.values() == 4) &&
             (received.value(0).valueType() == VALUE_INTEGER) &&
@@ -230,7 +227,6 @@
 void OperationSupport::thread3()
 {
     char bayeuxId[33];
-
     ComposedRecord record;
     ParsedRecord received;
     OperationStore::Operation op;
@@ -241,7 +237,6 @@
     // request Bayeux ID
     {
         const char *str;
-
         IntegerValue msgId(80);
         if (!record.add(msgId))
             return;
@@ -251,7 +246,6 @@
             _client.stop();
             return;
         }
-
         _client.stop();
 
         str = received.value(0).characterValue();
@@ -264,9 +258,8 @@
     
     // set channel
     {
-        char chn[16]; int len;
-        
-        len = 0;
+        char chn[16];
+        int len = 0;
         snprintf(chn, sizeof(chn), "/%ld%n", _deviceId, &len);
         if ((len == 0) || (len == sizeof(chn)))
             return;
--- a/util/RtosSmartRest.cpp	Wed Feb 25 10:06:11 2015 +0000
+++ b/util/RtosSmartRest.cpp	Tue Mar 03 14:10:09 2015 +0000
@@ -1,13 +1,14 @@
 #include "RtosSmartRest.h"
 
-RtosSmartRest::RtosSmartRest(const char *host, uint16_t port, const char *identifier, uint8_t tries) :
+RtosSmartRest::RtosSmartRest(const char *host, uint16_t port, const char *identifier, MDMSerial& mdm, uint8_t tries) :
     _host(host),
     _port(port),
     _identifier(identifier),
     _tries(tries),
     _username(NULL),
     _password(NULL),
-    _count(0)
+    _count(0),
+    _mdm(mdm)
 {
 }
 
@@ -111,7 +112,7 @@
     if (_count == RTOS_SMARTREST_SLOTS)
         return NULL;
     
-    inst = new MbedSmartRest(_host, _port, _identifier, _tries);
+    inst = new MbedSmartRest(_host, _port, _identifier, _mdm, _tries);
     inst->setAuthorization(_username, _password);
 
     slot.tid = tid;
--- a/util/RtosSmartRest.h	Wed Feb 25 10:06:11 2015 +0000
+++ b/util/RtosSmartRest.h	Tue Mar 03 14:10:09 2015 +0000
@@ -10,7 +10,7 @@
 class RtosSmartRest : public AbstractSmartRest
 {
 public:
-    RtosSmartRest(const char*, uint16_t, const char*, uint8_t = MBEDSMARTREST_TRIES);
+    RtosSmartRest(const char*, uint16_t, const char*, MDMSerial&, uint8_t = MBEDSMARTREST_TRIES);
     ~RtosSmartRest();
     
     struct Slot {
@@ -36,6 +36,7 @@
     
     Slot _slots[RTOS_SMARTREST_SLOTS];
     size_t _count;
+    MDMSerial& _mdm;
 };
 
 #endif
\ No newline at end of file