An application to log WiFi SSIDs for position lookup testing

Dependencies:   C027_Support SWO mbed-rtos mbed picojson

Fork of lpc4088_ebb_ublox_Cellular_PubNubDemo_rtos by EmbeddedArtists AB

Files at this revision

API Documentation at this revision

Comitter:
rosterloh84
Date:
Sun Feb 15 22:04:12 2015 +0000
Parent:
0:713518ea5028
Commit message:
First working version. Lots to do still.

Changed in this revision

C027_Support.lib Show annotated file Show diff for this revision Revisions of this file
ConfigurationProperties.cpp Show annotated file Show diff for this revision Revisions of this file
ConfigurationProperties.h Show annotated file Show diff for this revision Revisions of this file
EALib.lib Show diff for this revision Revisions of this file
LM75B.lib 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
PubNub.lib Show diff for this revision Revisions of this file
PubNubDemo.cpp Show diff for this revision Revisions of this file
SWO.lib Show annotated file Show diff for this revision Revisions of this file
device/DeviceConfiguration.cpp Show annotated file Show diff for this revision Revisions of this file
device/DeviceConfiguration.h Show annotated file Show diff for this revision Revisions of this file
device/DeviceFeedback.cpp Show annotated file Show diff for this revision Revisions of this file
device/DeviceFeedback.h Show annotated file Show diff for this revision Revisions of this file
device/DeviceIO.cpp Show annotated file Show diff for this revision Revisions of this file
device/DeviceIO.h Show annotated file Show diff for this revision Revisions of this file
device/DeviceInfo.cpp Show annotated file Show diff for this revision Revisions of this file
device/DeviceInfo.h Show annotated file Show diff for this revision Revisions of this file
device/DeviceMemory.cpp Show annotated file Show diff for this revision Revisions of this file
device/DeviceMemory.h Show annotated file Show diff for this revision Revisions of this file
device/GPSTracker.cpp Show annotated file Show diff for this revision Revisions of this file
device/GPSTracker.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
mbed.bld 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/AnalogMeasurement.h 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/LocationUpdate.h 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
pubnub_acc.html Show diff for this revision Revisions of this file
diff -r 713518ea5028 -r cac9b2960637 C027_Support.lib
--- a/C027_Support.lib	Wed Oct 01 11:39:10 2014 +0000
+++ b/C027_Support.lib	Sun Feb 15 22:04:12 2015 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/teams/ublox/code/C027_Support/#f524fd9aa13d
+http://mbed.org/teams/ublox/code/C027_Support/#74e4e0109a9e
diff -r 713518ea5028 -r cac9b2960637 ConfigurationProperties.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ConfigurationProperties.cpp	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,33 @@
+#include "ConfigurationProperties.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+ConfigurationProperties::ConfigurationProperties(DeviceConfiguration& deviceConfiguration) :
+    _deviceConfiguration(deviceConfiguration)
+{
+}
+
+bool ConfigurationProperties::resetConfiguration()
+{
+    return (_deviceConfiguration.clear(), _deviceConfiguration.set("interval", CONFIGURATION_PROPERTY_INTERVAL));
+}
+
+bool ConfigurationProperties::validateProperties()
+{
+    return (readInterval() > 0);
+}
+
+int ConfigurationProperties::readInterval()
+{
+    const char *prop; int res, ln;
+    
+    if ((prop = _deviceConfiguration.get("interval")) == NULL)
+        prop = CONFIGURATION_PROPERTY_INTERVAL;
+    
+    ln = -1;
+    if ((sscanf(prop, "%d%n", &res, &ln) != 1) || (ln != strlen(prop)))
+        return 0;
+
+    return res;
+}
diff -r 713518ea5028 -r cac9b2960637 ConfigurationProperties.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ConfigurationProperties.h	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <stddef.h>
+#include "DeviceConfiguration.h"
+
+#define CONFIGURATION_PROPERTY_INTERVAL "300"
+
+class ConfigurationProperties
+{
+public:
+    ConfigurationProperties(DeviceConfiguration&);
+    
+    bool resetConfiguration();
+    bool validateProperties();
+    
+    int readInterval();
+
+private:
+    DeviceConfiguration& _deviceConfiguration;
+};
diff -r 713518ea5028 -r cac9b2960637 EALib.lib
--- a/EALib.lib	Wed Oct 01 11:39:10 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://mbed.org/users/embeddedartists/code/EALib/#b3a179cc3d88
diff -r 713518ea5028 -r cac9b2960637 LM75B.lib
--- a/LM75B.lib	Wed Oct 01 11:39:10 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/neilt6/code/LM75B/#7ac462ba84ac
diff -r 713518ea5028 -r cac9b2960637 MbedAgent.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MbedAgent.cpp	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,55 @@
+#include "MbedAgent.h"
+#include "rtos.h"
+
+MbedAgent::MbedAgent(DeviceIO& io, MDMSerial& mdm, DeviceInfo& deviceInfo, DeviceMemory& deviceMemory) :
+    _io(io),
+    _mdm(mdm),
+    _deviceInfo(deviceInfo),
+    _deviceMemory(deviceMemory),
+    _configurationProperties(_deviceConfiguration),
+    _signalQualityMeasurement(_deviceInfo),
+    _analogMeasurement(_io.analog1(), _io.analog2()),
+    _locationUpdate(_io.gpsTracker())
+{
+}
+
+bool MbedAgent::init()
+{
+    if ((!_signalQualityMeasurement.init()) ||
+        (!_analogMeasurement.init()) ||
+        (!_locationUpdate.init())) {
+        puts("Initialization failed.");
+        return false;
+    }
+    return true;
+}
+
+bool MbedAgent::run()
+{
+    // add some config setup if needed
+    
+    loop();
+
+    return true;
+}
+
+void MbedAgent::loop()
+{
+    Timer timer; int interval;
+    
+    timer.start();
+    while (true) {
+        timer.reset();
+        
+        _signalQualityMeasurement.run();
+        _analogMeasurement.run();
+        _locationUpdate.run();
+        
+        if ((interval = _configurationProperties.readInterval()) == 0)
+            break;
+
+        while (timer.read() < interval) {
+            Thread::yield();
+        }
+    }
+}
\ No newline at end of file
diff -r 713518ea5028 -r cac9b2960637 MbedAgent.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MbedAgent.h	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <stddef.h>
+#include "MDM.h"
+#include "DeviceIO.h"
+#include "DeviceInfo.h"
+#include "DeviceMemory.h"
+#include "DeviceConfiguration.h"
+#include "ConfigurationProperties.h"
+#include "SignalQualityMeasurement.h"
+#include "AnalogMeasurement.h"
+#include "LocationUpdate.h"
+
+class MbedAgent
+{
+public:
+    MbedAgent(DeviceIO&, MDMSerial&, DeviceInfo&, DeviceMemory&);
+    
+    bool init();
+    bool run();
+
+protected:
+    void loop();
+    
+private:
+    DeviceIO& _io;
+    MDMSerial& _mdm;
+    DeviceInfo& _deviceInfo;
+    DeviceMemory& _deviceMemory;
+    DeviceConfiguration _deviceConfiguration;
+    ConfigurationProperties _configurationProperties;
+    SignalQualityMeasurement _signalQualityMeasurement;
+    AnalogMeasurement _analogMeasurement;
+    LocationUpdate _locationUpdate;
+};
diff -r 713518ea5028 -r cac9b2960637 PubNub.lib
--- a/PubNub.lib	Wed Oct 01 11:39:10 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/embeddedartists/code/PubNub/#55eb53c78b47
diff -r 713518ea5028 -r cac9b2960637 PubNubDemo.cpp
--- a/PubNubDemo.cpp	Wed Oct 01 11:39:10 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,313 +0,0 @@
-#include <cstring>
-
-#include "mbed.h"
-#include "rtos.h"
-//#include "C12832.h"
-//#include "MMA7660.h"
-#include "MMA7455.h"
-#include "LM75B.h"
-
-#include "picojson.h"
-#include "PubNub.h"
-
-#include "sdram.h"
-
-//------------------------------------------------------------------------------------
-// You need to configure these cellular modem / SIM parameters.
-// These parameters are ignored for LISA-C200 variants and can be left NULL.
-//------------------------------------------------------------------------------------
-#include "MDM.h"
-//! Set your secret SIM pin here (e.g. "1234"). Check your SIM manual.
-#define SIMPIN      NULL
-/*! The APN of your network operator SIM, sometimes it is "internet" check your 
-    contract with the network operator. You can also try to look-up your settings in 
-    google: https://www.google.de/search?q=APN+list */
-#define APN         "online.telia.se"
-//! Set the user name for your APN, or NULL if not needed
-#define USERNAME    NULL
-//! Set the password for your APN, or NULL if not needed
-#define PASSWORD    NULL 
-//------------------------------------------------------------------------------------
-
-/* Demo of PubNub + the mbed application board. */
-
-/* How to get things set up: */
-/* 1. Tune in at the PubNub Developer Console, with the following
- * keys (press Subscribe afterwards): */
-const char pubkey[] = "demo";
-const char subkey[] = "demo";
-//const char channel[] = "mbed";
-const char channel_pub[] = "mbed_data";
-const char channel_sub[] = "mbed_cmd";
-/* 2. Attach your mbed board to your computer. A folder should pop up like
- * if you plug in a USB memory stick. */
-/* 3. Open this example in the mbed web IDE and hit the Compile button. */
-/* 4. A download popup with a .bin file will appear; save it in the USB
- * mbed folder. */
-/* 5. Press reset button on the mbed to start things up. */
-
-/* You will see the board publish a "status" message that shows its
- * current temperature and physical tilt.  The board's LCD should
- * print some progress messages regarding that. */
-/* You can make the board do things too, by sending messages like:
- * { "send_status": true }
- * { "lcd": "Hi there!" }
- * { "beep": true }
- * { "led": {"r": 0.5, "g": 1, "b": 0} }
- * Try it out! Paste these in the Message window and press the send icon.
- */
-
-Serial pc(USBTX, USBRX); // tx, rx
-//MMA7660 MMA(P0_27, P0_28);
-MMA7455 MMA(P0_27, P0_28);
-LM75B tmp(P0_27, P0_28, LM75B::ADDRESS_1);
-//C12832 lcd(D11, D13, D12, D7, D10);
-
-PwmOut led_r(p25); // RGB LED with 3 PWM outputs for dimmer control
-PwmOut led_g(p28);
-PwmOut led_b(p26);
-//PwmOut speaker(D6); // Speaker with PWM driver
-
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-DigitalOut led3(LED3);
-DigitalOut led4(LED4);
-
-
-bool forceStatusUpdate = true;
-
-Mutex stdio_mutex; 
-
-#define safe_printf(...) do { \
-        stdio_mutex.lock(); \
-        pc.printf(__VA_ARGS__); \
-        stdio_mutex.unlock(); \
-    } while(0)
-
-#define safe_print_pnub_err(__prefix) do { \
-        stdio_mutex.lock(); \
-        if (pnub_err) { \
-            pc.printf("%s: ERR, code = %d, line = %d\n", (__prefix), pnub_code, pnub_line); \
-            pnub_err = false; \
-        } \
-        stdio_mutex.unlock(); \
-    } while(0)
-
-void pnub_err_handler(PubNubRes code, int line) {
-    stdio_mutex.lock();
-    if (code != PNR_OK) {
-        pc.printf("PbuNub:%d  ERROR %d\n", line, code);
-    }
-    stdio_mutex.unlock();
-}
-
-void process_msg(PubNub &pn, const char *jsonmsg)
-{
-    /* Use the picojson parser since we want to deal with complex messages.
-     * If you are short on memory, you can find an example for parsing simple
-     * JSON messages in the PubNub::subscribe() API docs. */
-    picojson::value msg;
-    std::string err = picojson::parse(msg, jsonmsg, jsonmsg + strlen(jsonmsg));
-    do {
-        if (!err.empty()) {
-            safe_printf("JSON parse: %s  \n", err.c_str());
-            break;
-        }
-    
-        if (msg.get("send_status").get<bool>()) {
-            //status_msg(pn);
-            forceStatusUpdate = true;
-            safe_printf("force_update\n");
-            break;
-        }
-        if (msg.get("lcd").is<std::string>()) {
-            safe_printf("in: %s  \n", msg.get("lcd").get<std::string>().c_str());
-            break;
-        }
-        if (msg.get("beep").is<bool>()) {
-            //speaker = msg.get("beep").get<bool>() ? 0.5 : 0;
-            break;
-        }
-        if (msg.get("led").is<picojson::object>()) {
-            picojson::value led = msg.get("led");
-            safe_printf("Old RGB { %.3f, %.3f, %.3f }\n", led_r.read(), led_g.read(), led_b.read());
-            if (led.get("r").is<double>()) led_r = 1.0 - led.get("r").get<double>();
-            if (led.get("g").is<double>()) led_g = 1.0 - led.get("g").get<double>();
-            if (led.get("b").is<double>()) led_b = 1.0 - led.get("b").get<double>();
-            safe_printf("New RGB { %.3f, %.3f, %.3f }\n", led_r.read(), led_g.read(), led_b.read());
-            break;
-        }
-    } while(0);
-}
-
-void publish_thread(void const *args)
-{
-    PubNub pn(pubkey, subkey);
-    Timer t;
-    t.start();
-    Timer tDbg;
-    int nDbg = 0;
-    float lastTemp = -3.75f;
-    while (true) {
-            
-        /* Read sensors. */
-        int m[3];
-        MMA.read(m[0], m[1], m[2]);
-        float temp = (float)tmp;
-    
-        /* Print on LCD. */
-        safe_printf("cur: mx=%3d, my=%3d, mz=%3d, t=%.2f  \n", m[0], m[1], m[2], temp);
-    
-        if (forceStatusUpdate || (temp != lastTemp)) {
-            lastTemp = temp;
-            forceStatusUpdate = false;
-            
-            /* Prepare JSON message. */
-            char jsonmsg[128];
-//            snprintf(jsonmsg, sizeof(jsonmsg),
-//                    "{\"status\":{\"mx\":%3d,\"my\":%3d,\"mz\":%3d,\"temp\":%.2f}}",
-//                    m[0], m[1], m[2], temp);
-            snprintf(jsonmsg, sizeof(jsonmsg),
-                    "%%7B%%22status%%22:%%7B%%22mx%%22:%3d,%%22my%%22:%3d,%%22mz%%22:%3d,%%22temp%%22:%.2f%%7D%%7D",
-                    m[0], m[1], m[2], temp);
-
-            /* Publish on PubNub. */
-            safe_printf("before publishing\n");
-            led_r = 0;
-            tDbg.start();
-//            PubNubRes ret = pn.publish(channel_pub, jsonmsg);
-            PubNubRes ret = pn.publish_urlenc(channel_pub, jsonmsg);
-            tDbg.stop();
-            if (++nDbg == 10) {
-                safe_printf("10 requests took %d ms, i.e %d ms/req\n", tDbg.read_ms(), tDbg.read_ms()/10);
-                tDbg.reset();
-                nDbg = 0;
-            }
-
-            if (ret != PNR_OK) {
-                safe_printf("puberr: %d  \n", ret);
-                //safe_print_pnub_err("pub");
-                forceStatusUpdate = true; // so that we can try again
-            }
-            led_r = 1;
-            safe_printf("after publishing\n");
-        }
-        
-        wait_ms(100);
-    }
-}
-
-void subscribe_thread(void const *args)
-{
-    PubNub pn(pubkey, subkey);
-    while(true) {
-        char *reply = NULL;
-        PubNubRes ret = pn.subscribe(channel_sub, &reply);
-        if (ret != PNR_OK) {
-            safe_printf("suberr: %d  \n", ret);
-            //safe_print_pnub_err("sub");
-            wait(1.0);
-            continue;
-        }
-
-        if (reply) {
-            safe_printf("recv(%s)\n", reply);
-            process_msg(pn, reply);
-        }
-
-        wait(0.5); // avoid busy loop in bad situations
-    }
-}
-
-/** Cause the mbed to flash the BLOD (Blue LEDs Of Death) sequence
- */
-void mbed_die(void)
-{
-    led1 = led2 = 1; led3 = led4 = 0;  // lights out
-    while(1) {
-        led1 = 1;
-        led3 = 1;
-        wait_ms(100);
-        led2 = 1;
-        led1 = 0;
-        wait_ms(100);
-        led4 = 0;
-        led2 = 0;
-        wait_ms(100);
-        led3 = 0;
-        led4 = 1;
-        wait_ms(100);
-    }
-}
-
-int main()
-{
-    if (sdram_init()) {
-        pc.printf("Failed to initialize SDRAM\n");
-    }
-    
-    /* For debugging, you may find it useful to print memory usage
-     * stats. AvailableMemory may be flaky, but the following is nice.
-     * It will get printed to the USB serial port interface. */
-    //printf("%d: ", __LINE__); __heapstats((__heapprt)fprintf, stdout);
-
-    /* Generate a 800Hz tone using PWM hardware output */
-    //speaker.period(1.0/800.0); // 800hz period
-    led_r = led_g = led_b = 1.0; // lights out
-    led1 = led2 = 1; led3 = led4 = 0;  // lights out
-
-    //lcd.cls();
-    //lcd.locate(0,0);
-    
-    if (!tmp.open()) {
-        pc.printf("Failed to open LM75 temperature sensor\n");
-    }
-
-//    if (!MMA.testConnection())
-//        pc.printf("MMA error  \n");
-
-    // Initialize the accelerometer
-    if (!MMA.setMode(MMA7455::ModeMeasurement)) {
-        printf("Unable to set mode for MMA7455!\n");
-    }
-
-    // Calibrate it. It does not matter if it is on a level surface
-    // as this test is only interested in relative values.
-    if (!MMA.calibrate()) {
-        printf("Failed to calibrate MMA7455!\n");
-    }
-
-    MDMRtos<MDMSerial> mdm;
-    //mdm.setDebug(4); // enable this for debugging issues 
-    int i;
-    for (i = 1; i <= 10; i++) {
-        if (mdm.connect(SIMPIN, APN,USERNAME,PASSWORD)) {
-            printf("Connected\n");
-            mdm.setDebug(0); // disable debug again
-            break;
-        } else {
-            printf("Attempt %2d to connect to the modem FAILED.\n", i);
-            wait(1);
-            mdm.setDebug(min(i, 4)); // to add more and more debug output
-        }
-    }
-    if (i > 10) {
-        printf("Failed to connect to the modem\n");
-        mbed_die();
-    }
-    
-    forceStatusUpdate = true;
-    //status_msg(pn);
-    // lcd.printf("pub... ");
-
-    Thread t_p(publish_thread);
-    Thread t_s(subscribe_thread);
-
-    while (1) {
-        Thread::wait(2000);
-        safe_printf(".\n");
-    }
-
-    mdm.disconnect();
-    mdm.powerOff();
-}
diff -r 713518ea5028 -r cac9b2960637 SWO.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SWO.lib	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/wim/code/SWO/#e5af2e131b95
diff -r 713518ea5028 -r cac9b2960637 device/DeviceConfiguration.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/device/DeviceConfiguration.cpp	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,183 @@
+#include "DeviceConfiguration.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+DeviceConfiguration::DeviceConfiguration()
+{
+    size_t i;
+    
+    for (i = 0; i < DEVICE_CONFIGURATION_SIZE; i++) {
+        _items[i].key = NULL;
+        _items[i].value = NULL;
+    }
+}
+
+DeviceConfiguration::~DeviceConfiguration()
+{
+    clear();
+}
+
+bool DeviceConfiguration::read(const char *str)
+{
+    const char *ptr, *ptr2, *ptr3; size_t i, j, len1, len2;
+    DeviceConfiguration::KeyValue items[DEVICE_CONFIGURATION_SIZE];
+    
+    for (i = 0; i < DEVICE_CONFIGURATION_SIZE; i++) {
+        items[i].key = NULL;
+        items[i].value = NULL;
+    }
+
+    ptr = str;
+    i = 0;
+    while ((*ptr != '\0') && (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 (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; size_t i; int ret, ln;
+    
+    ptr = buf;
+    for (i = 0; i < DEVICE_CONFIGURATION_SIZE; i++) {
+        if (_items[i].key == NULL)
+            continue;
+
+        ret = snprintf(ptr, len, "%s=%s;%n", _items[i].key, _items[i].value, &ln);
+        if ((ret < 0) || (ret >= len))
+            return false;
+
+        ptr += ln;
+        len -= ln;
+    }
+    
+    return true;
+}
+
+bool DeviceConfiguration::set(const char *key, const char *value)
+{
+    KeyValue *item; size_t i;
+    
+    if ((item = search(key)) == NULL) {
+        for (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;
+    
+    if ((item = search(key)) == NULL)
+        return NULL;
+    
+    return item->value;
+}
+
+bool DeviceConfiguration::unset(const char *key)
+{
+    KeyValue *item;
+    
+    if ((item = search(key)) == NULL)
+        return false;
+    
+    free(item->key);
+    free(item->value);
+    item->key = NULL;
+    item->value = NULL;
+    return true;
+}
+
+bool DeviceConfiguration::has(const char *key)
+{
+    return (search(key) != NULL);
+}
+
+void DeviceConfiguration::clear()
+{
+    size_t i;
+    
+    for (i = 0; i < DEVICE_CONFIGURATION_SIZE; i++) {
+        if (_items[i].key != NULL) {
+            free(_items[i].key);
+            free(_items[i].value);
+        }
+    }
+}
+
+DeviceConfiguration::KeyValue * DeviceConfiguration::search(const char *key)
+{
+    size_t i;
+    
+    for (i = 0; i < DEVICE_CONFIGURATION_SIZE; i++) {
+        if (strcmp(key, _items[i].key) == 0)
+            return &_items[i];
+    }
+    
+    return NULL;
+}
diff -r 713518ea5028 -r cac9b2960637 device/DeviceConfiguration.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/device/DeviceConfiguration.h	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,33 @@
+#pragma once
+
+#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];
+};
diff -r 713518ea5028 -r cac9b2960637 device/DeviceFeedback.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/device/DeviceFeedback.cpp	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,71 @@
+#include "DeviceFeedback.h"
+#include <stdlib.h>
+#include <string.h>
+
+#define MSG_SHOW_SUCCESS 1
+#define MSG_SHOW_FAILURE 2
+
+DeviceFeedback::DeviceFeedback(PwmOut led) :
+    _led(led),
+    _thread(DeviceFeedback::thread_func, this)
+{
+}
+
+void DeviceFeedback::showSuccess()
+{
+    sendMessage(MSG_SHOW_SUCCESS);
+}
+
+void DeviceFeedback::showFailure()
+{
+    sendMessage(MSG_SHOW_FAILURE);
+}
+
+void DeviceFeedback::sendMessage(uint8_t msg)
+{
+    uint8_t *msgPtr;
+    
+    msgPtr = _mail.alloc();
+    *msgPtr = msg;
+    _mail.put(msgPtr);
+}
+
+void DeviceFeedback::thread()
+{
+    osEvent evt; 
+    uint8_t *msg;
+    
+    while (true) {
+        if ((evt = _mail.get(1000)).status == osEventMail) {
+            msg = (uint8_t*)evt.value.p;
+            switch (*msg) {
+            case MSG_SHOW_SUCCESS:
+                for (float i=2000.0; i<10000.0; i+=2000.0) {
+                    _led.period(1.0/i);
+                    _led = 0.5;
+                    Thread::wait(200);
+                    _led = 0.0;
+                    Thread::wait(50);
+                }
+                break;
+            case MSG_SHOW_FAILURE:
+                for (float i=10000.0; i>2000.0; i-=2000.0) {
+                    _led.period(1.0/i);
+                    _led = 0.5;
+                    Thread::wait(200);
+                    _led = 0.0;
+                    Thread::wait(50);
+                }
+                break;
+            }
+            _mail.free(msg);
+        }
+    }
+}
+
+void DeviceFeedback::thread_func(void const *arg)
+{
+    DeviceFeedback *that;
+    that = (DeviceFeedback*)arg;
+    that->thread();
+}
diff -r 713518ea5028 -r cac9b2960637 device/DeviceFeedback.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/device/DeviceFeedback.h	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <stddef.h>
+#include "mbed.h"
+#include "rtos.h"
+
+/**
+ * Device Feedback handler
+ */
+class DeviceFeedback
+{
+public:
+    DeviceFeedback(PwmOut led);
+    
+    void showSuccess();
+    void showFailure();
+    
+protected:
+    void sendMessage(uint8_t);
+    void thread();
+    static void thread_func(void const*);
+
+private:
+    PwmOut _led;
+    Thread _thread;
+    Mail<uint8_t, 16> _mail;
+};
diff -r 713518ea5028 -r cac9b2960637 device/DeviceIO.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/device/DeviceIO.cpp	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,46 @@
+#include "DeviceIO.h"
+
+#define DEF "\033[39m"
+#define GRE "\033[32m"
+#define CYA "\033[36m"
+
+DeviceIO::DeviceIO(GPSI2C& gps) :
+    _userButton(PC_13),
+    _analog1(A0),
+    _analog2(A1),
+    _led1(PA_5),
+    _gpsTracker(gps),
+    _deviceFeedback(_led1)
+{
+}
+
+bool DeviceIO::userButtonPressed()
+{
+    return _userButton;
+}
+
+GPSTracker& DeviceIO::gpsTracker()
+{
+    return _gpsTracker;
+}
+
+DeviceFeedback& DeviceIO::deviceFeedback()
+{
+    return _deviceFeedback;
+}
+
+AnalogIn& DeviceIO::analog1()
+{
+    return _analog1;
+}
+
+AnalogIn& DeviceIO::analog2()
+{
+    return _analog2;
+}
+
+void DeviceIO::debugPrint(const char *line)
+{
+    _debug.printf(GRE "io::debugPrint" DEF "\r\n");
+    _debug.printf(GRE "> " CYA "%s\r\n" DEF, line);
+}
diff -r 713518ea5028 -r cac9b2960637 device/DeviceIO.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/device/DeviceIO.h	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "mbed.h"
+#include "GPS.h"
+#include "GPSTracker.h"
+#include "DeviceFeedback.h"
+#include "SWO.h"
+
+class DeviceIO
+{
+public:
+    DeviceIO(GPSI2C&);
+
+    bool userButtonPressed();
+    GPSTracker& gpsTracker();
+    DeviceFeedback& deviceFeedback();
+    AnalogIn& analog1();
+    AnalogIn& analog2();
+    void debugPrint(const char*);
+
+private:
+    DigitalIn _userButton;
+    AnalogIn _analog1;
+    AnalogIn _analog2;
+    PwmOut _led1;
+    GPSTracker _gpsTracker;
+    DeviceFeedback _deviceFeedback;
+    SWO_Channel _debug;
+};
diff -r 713518ea5028 -r cac9b2960637 device/DeviceInfo.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/device/DeviceInfo.cpp	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,56 @@
+#include "DeviceInfo.h"
+#include <stdlib.h>
+#include <string.h>
+
+DeviceInfo::DeviceInfo(MDMSerial& mdm, MDMParser::DevStatus& devStatus) :
+    _mdm(mdm)
+{
+    *_cellId = '\0';
+    memcpy(&_devStatus, &devStatus, sizeof(MDMParser::DevStatus));
+    memset(&_netStatus, 0, sizeof(MDMParser::NetStatus));
+    memset(&_signalQuality, 0, sizeof(DeviceInfo::SignalQuality));
+}
+
+const char * DeviceInfo::imsi()
+{
+    return _devStatus.imsi;
+}
+
+const char * DeviceInfo::imei()
+{
+    return _devStatus.imei;
+}
+
+const char * DeviceInfo::cellId()
+{
+    if (!refreshNetStatus())
+        return NULL;
+
+    if (snprintf(_cellId, sizeof(_cellId), "%X", _netStatus.ci) < 1)
+        return NULL;
+    return _cellId;
+}
+
+const char * DeviceInfo::iccid()
+{
+    return _devStatus.ccid;
+}
+
+DeviceInfo::SignalQuality * DeviceInfo::signalQuality()
+{
+    memset(&_signalQuality, 0, sizeof(DeviceInfo::SignalQuality));
+    if (!refreshNetStatus())
+        return NULL;
+    
+    if ((_netStatus.rssi == 0) || (_netStatus.ber == 0))
+        return NULL;
+
+    _signalQuality.rssi = _netStatus.rssi;
+    _signalQuality.ber = _netStatus.ber;
+    return &_signalQuality;
+}
+
+bool DeviceInfo::refreshNetStatus()
+{
+    return _mdm.checkNetStatus(&_netStatus);
+}
diff -r 713518ea5028 -r cac9b2960637 device/DeviceInfo.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/device/DeviceInfo.h	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+#include "MDM.h"
+
+class DeviceInfo
+{
+public:
+    DeviceInfo(MDMSerial& mdm, MDMParser::DevStatus& devStatus);
+    
+    typedef struct {
+        int rssi;  // RSSI in dBm
+        int ber; // BER in %
+    } SignalQuality;
+    
+    const char * imsi();
+    const char * imei();
+    const char * cellId();
+    const char * iccid();
+    SignalQuality * signalQuality();
+
+protected:
+    bool refreshNetStatus();
+
+private:
+    MDMSerial& _mdm;
+    MDMParser::DevStatus _devStatus;
+    MDMParser::NetStatus _netStatus;
+    char _cellId[9];
+    SignalQuality _signalQuality;
+};
diff -r 713518ea5028 -r cac9b2960637 device/DeviceMemory.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/device/DeviceMemory.cpp	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,37 @@
+#include "DeviceMemory.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define CONFIGURATION_FILE "001_CONFIGURATION"
+
+DeviceMemory::DeviceMemory(MDMSerial& mdm) :
+    _mdm(mdm)
+{
+}
+
+bool DeviceMemory::loadConfiguration(char *cfg, size_t len)
+{
+    int res;
+
+    if ((res = _mdm.readFile(CONFIGURATION_FILE, cfg, len)) < 0)
+        return false;
+    
+    cfg[(size_t)res] = '\0';
+    return true;
+}
+
+bool DeviceMemory::saveConfiguration(char *cfg)
+{
+    size_t len;
+    
+    len = strlen(cfg);
+    
+    resetConfiguration();
+    return (_mdm.writeFile(CONFIGURATION_FILE, cfg, len) == len);
+}
+
+bool DeviceMemory::resetConfiguration()
+{
+    return _mdm.delFile(CONFIGURATION_FILE);
+}
diff -r 713518ea5028 -r cac9b2960637 device/DeviceMemory.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/device/DeviceMemory.h	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <stddef.h>
+#include "MDM.h"
+
+/**
+ * Device Memory storage handler
+ */
+class DeviceMemory
+{
+public:
+    DeviceMemory(MDMSerial&);
+    
+    /** loads configuration from persistent memory */
+    bool loadConfiguration(char*, size_t);
+    
+    /** saves configuration to persistent memory */
+    bool saveConfiguration(char*);
+    
+    /** removes configuration from persistent memory */
+    bool resetConfiguration();
+
+private:
+    MDMSerial& _mdm;
+};
diff -r 713518ea5028 -r cac9b2960637 device/GPSTracker.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/device/GPSTracker.cpp	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,74 @@
+#include "GPSTracker.h"
+#include <stdlib.h>
+#include <string.h>
+
+GPSTracker::GPSTracker(GPSI2C& gps) :
+    _gps(gps),
+    _thread(GPSTracker::thread_func, this),
+    _positionSet(false)
+{
+}
+
+bool GPSTracker::position(GPSTracker::Position *position)
+{
+    bool result;
+    
+    _mutex.lock();
+    if (_positionSet) {
+        memcpy(position, &_position, sizeof(GPSTracker::Position));
+        _positionSet = false;
+        result = true;
+    } else {
+        result = false;
+    }
+    _mutex.unlock();
+    
+    return result;
+}
+
+void GPSTracker::thread()
+{
+    char buf[256], chr; // needs to be that big otherwise mdm isn't working
+    int ret, len, n;
+    double altitude, latitude, longitude;
+    
+    while (true) {
+        ret = _gps.getMessage(buf, sizeof(buf));
+        if (ret <= 0) {
+            Thread::wait(100);
+            continue;
+        }
+        
+        len = LENGTH(ret);
+        if ((PROTOCOL(ret) != GPSParser::NMEA) || (len <= 6))
+            continue;
+
+        // we're only interested in fixed GPS positions
+        // we are not interested in invalid data
+        if ((strncmp("$GPGGA", buf, 6) != 0) ||
+            (!_gps.getNmeaItem(6, buf, len, n, 10)) || (n == 0))
+            continue;
+        
+        // get altitude, latitude and longitude
+        if ((!_gps.getNmeaAngle(2, buf, len, latitude)) ||
+            (!_gps.getNmeaAngle(4, buf, len, longitude)) ||
+            (!_gps.getNmeaItem(9, buf, len, altitude)) ||
+            (!_gps.getNmeaItem(10, buf, len, chr)) ||
+            (chr != 'M'))
+            continue;
+
+        _mutex.lock();
+        _position.altitude = altitude;
+        _position.latitude = latitude;
+        _position.longitude = longitude;
+        _positionSet = true;
+        _mutex.unlock();
+    }
+}
+
+void GPSTracker::thread_func(void const *arg)
+{
+    GPSTracker *that;
+    that = (GPSTracker*)arg;
+    that->thread();
+}
diff -r 713518ea5028 -r cac9b2960637 device/GPSTracker.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/device/GPSTracker.h	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <stddef.h>
+#include "GPS.h"
+#include "rtos.h"
+
+/**
+ * A GPS tracker class providing access to the current position.
+ */
+class GPSTracker
+{
+public:
+    /**
+     * Initialize a new GPSTracker object.
+     * @param gps a previously initialized instance of the GPSI2C class
+     */
+    GPSTracker(GPSI2C&);
+    
+    typedef struct {
+        double altitude;  // altitude  meters
+        double latitude;  // latitude  degrees
+        double longitude; // longitude degrees
+    } Position;
+    
+    /**
+     * Retrieves and invalidates the current position.
+     * @param position a pointer of type Position where the current position is written to
+     * @return true on success, false otherwise
+     */
+    bool position(Position*);
+    
+protected:
+    void thread();
+    static void thread_func(void const*);
+
+private:
+    GPSI2C _gps;
+    Thread _thread;
+    Mutex _mutex;
+    Position _position;
+    bool _positionSet;
+};
diff -r 713518ea5028 -r cac9b2960637 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,130 @@
+#include "mbed.h"
+#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 <stdio.h>
+
+// ----------------------------------------------------------------
+// Cellular modem / SIM parameters
+// ----------------------------------------------------------------
+#include "MDM.h"
+#define SIMPIN      NULL                    //!< Set your secret SIM pin here (e.g. "1234"). Check your SIM manual.
+#define APN         "internet"              //!< The APN of your network operator SIM, sometimes it is "internet"
+#define USERNAME    NULL                    //!< Set the user name for your APN, or NULL if not needed
+#define PASSWORD    NULL                    //!< Set the password for your APN, or NULL if not needed
+
+// ----------------------------------------------------------------
+// PubNub Config
+// ----------------------------------------------------------------
+//#include "PubNub.h"
+//const char pubkey[] = "pub-c-e3a95948-182a-46fd-b5f3-52c184eb3c12";
+//const char subkey[] = "sub-c-0313f6b2-b2c0-11e4-ab0e-02ee2ddab7fe";
+//const char channel[] = "mbed";
+//const char channel_pub[] = "mbed_data";
+//const char channel_sub[] = "mbed_cmd";
+
+int main()
+{
+    MDMParser::DevStatus devStatus;
+    uint8_t status = 0;
+
+    MDMRtos<MDMSerial> mdm;
+    GPSI2C gps;
+    
+    //mdm.setDebug(4);
+
+    if (!mdm.init(SIMPIN, &devStatus))
+        status = 1;
+    else if (!gps.init())
+        status = 2;
+    
+    DeviceIO io(gps);
+
+    /** For debugging, you may find it useful to print memory usage
+     * stats. AvailableMemory may be flaky, but the following is nice.
+     * It will get printed to the USB serial port interface. 
+     */
+    //io.debugPrint("%d: ", __LINE__); __heapstats((__heapprt)fprintf, stdout);
+    
+    io.debugPrint("\r\nWiFi Scanner build " __DATE__ " " __TIME__ "\r\n");
+    //io.debugPrint("CPU SystemCoreClock is %d Hz\r\n", SystemCoreClock);  
+    
+    switch (status) {
+    case 1:
+        io.debugPrint("MODEM INIT FAILURE. CHECK SIM");
+        break;
+    case 2:
+        io.debugPrint("GPS INIT FAILURE");
+        break;
+    }
+    
+    if (status != 0)
+        goto error;
+    
+    io.debugPrint("DEVICE INIT");
+    
+    //io.debugPrint("REGISTER NETWORK. IMEI: %s", devStatus.imei);
+
+    if (!mdm.registerNet()) {
+        io.debugPrint("NETWORK REG ERROR");
+        goto error;
+    }
+
+    io.debugPrint("JOIN NETWORK");
+#ifdef SIM_APN
+    if (mdm.join(SIM_APN, SIM_USER, SIM_PASS) == NOIP) {
+#else
+    if (mdm.join() == NOIP) {
+#endif
+        io.debugPrint("NETWORK JOIN FAILURE");
+        goto error;
+    }
+    
+    {
+        uint8_t tries;
+        DeviceInfo deviceInfo(mdm, devStatus);
+        DeviceMemory deviceMemory(mdm);
+        
+        if (io.userButtonPressed()) {
+            if (deviceMemory.resetConfiguration())
+                io.deviceFeedback().showSuccess();
+            else
+                io.deviceFeedback().showFailure();
+            Thread::wait(1000);
+            return 0;
+        }
+
+        MbedAgent agent(io, mdm, deviceInfo, deviceMemory);
+    
+        io.debugPrint("AGENT INIT");
+        if (!agent.init()) {
+            io.debugPrint("AGENT INIT FAILURE");
+            goto error;
+        }
+        
+        tries = 3;
+        do {
+            io.debugPrint("AGENT RUN");
+            if (agent.run())
+                break;
+        } while (--tries > 0);
+
+        if (tries == 0) {
+            io.debugPrint("AGENT RUN FAILURE");
+            goto error;
+        }
+    }
+    
+    mdm.disconnect();
+    return 0;
+
+error:
+    mdm.disconnect();
+    return 1;
+}
diff -r 713518ea5028 -r cac9b2960637 mbed-rtos.lib
--- a/mbed-rtos.lib	Wed Oct 01 11:39:10 2014 +0000
+++ b/mbed-rtos.lib	Sun Feb 15 22:04:12 2015 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed-rtos/#631c0f1008c3
+http://mbed.org/users/mbed_official/code/mbed-rtos/#83e169389a69
diff -r 713518ea5028 -r cac9b2960637 mbed.bld
--- a/mbed.bld	Wed Oct 01 11:39:10 2014 +0000
+++ b/mbed.bld	Sun Feb 15 22:04:12 2015 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/552587b429a1
\ No newline at end of file
+http://mbed.org/users/mbed_official/code/mbed/builds/e188a91d3eaa
\ No newline at end of file
diff -r 713518ea5028 -r cac9b2960637 measurement/AnalogMeasurement.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/AnalogMeasurement.cpp	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,27 @@
+#include "AnalogMeasurement.h"
+
+AnalogMeasurement::AnalogMeasurement(AnalogIn& analog1, AnalogIn& analog2) :
+    _analog1(analog1),
+    _analog2(analog2)
+{
+    _init = false;
+}
+
+bool AnalogMeasurement::init()
+{
+    if (_init)
+        return false;
+    
+    _init = true;
+    return true;
+}
+
+bool AnalogMeasurement::run()
+{
+    float analog1 = _analog1.read();
+    float analog2 = _analog2.read();
+    
+    printf("A0: %.2f A1: %.2f", analog1, analog2);
+    
+    return true;
+}
diff -r 713518ea5028 -r cac9b2960637 measurement/AnalogMeasurement.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/AnalogMeasurement.h	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "mbed.h"
+
+class AnalogMeasurement
+{
+public:
+    AnalogMeasurement(AnalogIn&, AnalogIn&);
+    
+    bool init();
+    bool run();
+
+private:
+    bool _init;
+    AnalogIn& _analog1;
+    AnalogIn& _analog2;
+};
diff -r 713518ea5028 -r cac9b2960637 measurement/LocationUpdate.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/LocationUpdate.cpp	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,36 @@
+#include "LocationUpdate.h"
+
+LocationUpdate::LocationUpdate(GPSTracker& gpsTracker) :
+    _gpsTracker(gpsTracker)
+{
+    _init = false;
+}
+
+bool LocationUpdate::init()
+{
+    if (_init)
+        return false;
+    
+    _init = true;
+    return true;
+}
+
+bool LocationUpdate::run()
+{
+    GPSTracker::Position position;
+    
+    if (!_gpsTracker.position(&position)) {
+        puts("No GPS data available.");
+        return true;
+    }
+        
+    puts("Starting measurement sending.");
+
+    float altitude = position.altitude;
+    float latitude = position.latitude;
+    float longitude = position.longitude;
+    
+    printf("Lat: %9.7f Long: %9.7f Altitude %.2f", latitude, longitude, altitude);
+    
+    return true;
+}
diff -r 713518ea5028 -r cac9b2960637 measurement/LocationUpdate.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/LocationUpdate.h	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "GPSTracker.h"
+
+class LocationUpdate
+{
+public:
+    LocationUpdate(GPSTracker&);
+    
+    bool init();
+    bool run();
+
+private:
+    bool _init;
+    GPSTracker& _gpsTracker;
+};
diff -r 713518ea5028 -r cac9b2960637 measurement/SignalQualityMeasurement.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/SignalQualityMeasurement.cpp	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,31 @@
+#include "SignalQualityMeasurement.h"
+
+SignalQualityMeasurement::SignalQualityMeasurement(DeviceInfo& deviceInfo) :
+    _deviceInfo(deviceInfo)
+{
+    _init = false;
+}
+
+bool SignalQualityMeasurement::init()
+{
+    if (_init)
+        return false;
+    
+    _init = true;
+    return true;
+}
+
+bool SignalQualityMeasurement::run()
+{
+    DeviceInfo::SignalQuality *signalQuality;
+    
+    if ((signalQuality = _deviceInfo.signalQuality()) == NULL)
+        return false;
+        
+    int rssi = signalQuality->rssi;
+    int ber = signalQuality->ber;
+    
+    printf("RSSI: %d dBm BER: %d %", rssi, ber);
+    
+    return true;
+}
diff -r 713518ea5028 -r cac9b2960637 measurement/SignalQualityMeasurement.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/measurement/SignalQualityMeasurement.h	Sun Feb 15 22:04:12 2015 +0000
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "DeviceInfo.h"
+
+class SignalQualityMeasurement
+{
+public:
+    SignalQualityMeasurement(DeviceInfo&);
+    
+    bool init();
+    bool run();
+
+private:
+    bool _init;
+    DeviceInfo& _deviceInfo;
+};
diff -r 713518ea5028 -r cac9b2960637 pubnub_acc.html
--- a/pubnub_acc.html	Wed Oct 01 11:39:10 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,186 +0,0 @@
-<html>
-	<head>
-<!--		<script type="text/javascript" src="jscolor/jscolor.js"></script>-->
-		<script type="text/javascript" src="https://www.google.com/jsapi"></script>
-    <script type="text/javascript">
-	  var baseline = Math.round(new Date().getTime()/10); // current time as integer in 10ms resolution
-	  var temps = [['Time', 'Temp']];
-	  var accs = [['Time', 'X', 'Y', 'Z']];
-      google.load("visualization", "1", {packages:["corechart"]});
-      //google.setOnLoadCallback(drawChart);
-      function drawChart() {
-        /*var data = google.visualization.arrayToDataTable([
-          ['Year', 'Sales', 'Expenses'],
-          ['2004',  1000,      400],
-          ['2005',  1170,      460],
-          ['2006',  660,       1120],
-          ['2007',  1030,      540]
-        ]);*/
-		var data = google.visualization.arrayToDataTable(temps);
-
-        var options = {
-          title: 'Temperature over time',
-		  vAxis: { title: "Degrees C" },
-		  hAxis: { title: "Time since first message (in seconds)" },
-		  curveType: 'function',
-		  legend: { position: 'none' },
-        };
-
-        var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
-
-        chart.draw(data, options);
-
-		// Acc chart
-		var data = google.visualization.arrayToDataTable(accs);
-
-        var options = {
-          title: 'Acceleration over time',
-		  vAxis: { title: "Acc value", minValue: -60, maxValue: 60 },
-		  hAxis: { title: "Time since first message (in seconds)" },
-		  curveType: 'function',
-		  //legend: { position: 'none' },
-        };
-
-        var chart = new google.visualization.LineChart(document.getElementById('acc_chart_div'));
-
-        chart.draw(data, options);
-      }
-	  function addToChart(t, x, y, z) {
-	    var now = Math.round(new Date().getTime()/10); // current time as integer in 10ms resolution
-	    console.log(new Date().getTime()/10 + " " + (now - baseline) + " temp = " + t+ " acc {"+x+","+y+","+z+"}");
-	    temps[temps.length] = [ (now - baseline)/100, t ];
-	    accs[accs.length] = [ (now - baseline)/100, x, y, z];
-		drawChart();
-	  }
-    </script>
-   <script src=http://cdn.pubnub.com/pubnub.min.js ></script>
-   <script>
-	 var pubnub = PUBNUB.init({
-		publish_key: 'pub-c-e4a8b6d6-7be2-4ef9-85b9-f6dfbed23f7d',
-		subscribe_key: 'sub-c-83ad9d3a-3365-11e4-9846-02ee2ddab7fe'
-	 });
- 
-	function receiveMessage(message) {
-		//console.log(message);
-
-		var type = 0;
-		try {
-			var test = message.status.mx;
-			type = 1;
-		} catch (err) {
-			// not a measurement status message from HW
-		}
-		try {
-			var test = message.led.r;
-			type = 2;
-		} catch (err) {
-			// not a set RGB color request from us
-		}
-		
-		var messageLog = document.getElementById("messageLog");
-		if (type == 1) {			
-			var listItem = document.createElement("li");
-			var msg = "Acc X,Y,Z = {" + message.status.mx + ", " + message.status.my + ", " + message.status.mz + "} Temp = " + message.status.temp;
-			var text = document.createTextNode(msg);
-			listItem.appendChild(text);
-			document.getElementById("messageList").appendChild(listItem);
-			messageLog.scrollTop = messageLog.scrollHeight;			
-			addToChart(message.status.temp, message.status.mx, message.status.my, message.status.mz);
-		} else if (type == 2) {
-			var listItem = document.createElement("li");
-			var msg = "Set RGB LED: {" + message.led.r + ", " + message.led.g + ", " + message.led.b + "}";
-			var text = document.createTextNode(msg);
-			listItem.appendChild(text);
-			document.getElementById("messageList").appendChild(listItem);
-			messageLog.scrollTop = messageLog.scrollHeight;			
-			//addToChart(message.status.temp);
-		} else {
-			// got an error, probably because message is not from mbed
-			var listItem = document.createElement("li");
-			var msg = "Unknwon RAW message: " + message;
-			var text = document.createTextNode(msg);
-			listItem.appendChild(text);
-			document.getElementById("messageList").appendChild(listItem);
-			messageLog.scrollTop = messageLog.scrollHeight;			
-			//addToChart(message.status.temp);
-		}
-	}
-	
-	/*function sendMessage(newcolor) {
-		//var r = parseInt(newcolor.substr(0,2), 16)/255;
-		//var g = parseInt(newcolor.substr(2,2), 16)/255;
-		//var b = parseInt(newcolor.substr(4,2), 16)/255;
-		//var msg = '{ "led": {"r": ' + r + ', "g": ' + g + ', "b": ' + b + '} }';
-		//var msg = '{ "led": {"r": ' + newcolor.rgb[0] + ', "g": ' + newcolor.rgb[1] + ', "b": ' + newcolor.rgb[2] + '} }';
-		var msg = { "led": {"r": newcolor.rgb[0], "g": newcolor.rgb[1], "b": newcolor.rgb[2]} };
-		console.log("new color #" + newcolor + " => message " + msg.led.r+","+msg.led.g+","+msg.led.b);
-		pubnub.publish({
-			channel: 'mbed_cmd',//'hello_world',
-			message: msg
-		});
-	}*/
-	function sendColorMessage(r,g,b) {
-		var msg = { "led": {"r": r, "g": g, "b": b} };
-		console.log("message " + msg.led.r+","+msg.led.g+","+msg.led.b);
-		pubnub.publish({
-			channel: 'mbed_cmd',//'hello_world',
-			message: msg
-		});
-	}
- 
-	 pubnub.subscribe({
-		channel: 'mbed_data',//'hello_world',
-		message: receiveMessage
-	 });
- 
-/* pubnub.unsubscribe({
-    channel: 'a',
-    message: function(m){console.log(m)}
- });*/
-   </script>
-		<style>
-			li { font-style: monospace; }
-			table,tr {border: none; }
-		</style>
-	</head>
-   <body>
-   <!--<img src="http://www.pubnub.com/static/images/illustrations/cloud-red.png">-->
-   
-   <table>
-   <tr>
-	<td valign="top">
-		<table>
-			<tr valign="top">
-				<td><div id="chart_div" style="width: 800px; height: 400px;"></div></td>
-			</tr>
-			<tr valign="top">
-				<td><div id="acc_chart_div" style="width: 800px; height: 400px;"></div></td>
-			</tr>
-			<!--<tr valign="top">
-				<td>Change color on RGB LED to:&nbsp;&nbsp;&nbsp;<input class="color" onchange="sendMessage(this.color)"></td>
-			</tr>-->
-			<tr valign="top">
-				<td>
-					<input type="button" value="Set color to RED" onclick="sendColorMessage(1,0,0)">
-					<input type="button" value="Set color to GREEN" onclick="sendColorMessage(0,1,0)">
-					<input type="button" value="Set color to BLUE" onclick="sendColorMessage(0,0,1)">
-				</td>
-			</tr>
-		</table>
-	</td>
-	<td>
-	<p><b>Data from mbed:</b></p>
-    <div id="messageLog" style="height: 600px; width: 350px; overflow:auto;">
-        <ol id="messageList">
-            <!-- This will be populated dynamically. -->
-        </ol>
-    </div>
-	</td>
-	</tr>
-	<tr>
-	<td>
-		<!--<input class="color" onchange="sendMessage(this.color)">-->
-	</td>
-	</tr>
-	</body>
-</html>
\ No newline at end of file