Example node for Yodiwo's Plegma API

Dependencies:   EthernetInterface FXOS8700Q HTTPClient HTTPD MQTTS SDFileSystem YodiwoPlegma mbed-rpc mbed-rtos mbed wolfSSL

Files at this revision

API Documentation at this revision

Comitter:
mitsarionas
Date:
Mon Sep 28 08:55:29 2015 +0000
Parent:
4:cc4c5b6d9730
Child:
6:94a7e44a0679
Commit message:
publish?

Changed in this revision

HTTPClient.lib Show annotated file Show diff for this revision Revisions of this file
HTTPD.lib Show annotated file Show diff for this revision Revisions of this file
YodiwoPlegma.lib Show annotated file Show diff for this revision Revisions of this file
config.c Show annotated file Show diff for this revision Revisions of this file
config.cpp Show diff for this revision Revisions of this file
config.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
mqtt_helpers.cpp Show annotated file Show diff for this revision Revisions of this file
mqtt_helpers.h Show annotated file Show diff for this revision Revisions of this file
nodas.cpp Show diff for this revision Revisions of this file
nodas.h Show diff for this revision Revisions of this file
nodas_things.cpp Show annotated file Show diff for this revision Revisions of this file
nodas_things.h Show annotated file Show diff for this revision Revisions of this file
pairing_backend.c Show annotated file Show diff for this revision Revisions of this file
pairing_backend.cpp Show diff for this revision Revisions of this file
pairing_backend.h Show annotated file Show diff for this revision Revisions of this file
pairing_http_handler.cpp Show annotated file Show diff for this revision Revisions of this file
pairing_http_handler.h Show annotated file Show diff for this revision Revisions of this file
system.h Show annotated file Show diff for this revision Revisions of this file
system_mbed.cpp Show annotated file Show diff for this revision Revisions of this file
yodiwo.lib Show diff for this revision Revisions of this file
yodiwo_functions.c Show annotated file Show diff for this revision Revisions of this file
yodiwo_functions.h Show annotated file Show diff for this revision Revisions of this file
--- a/HTTPClient.lib	Mon Sep 21 06:56:11 2015 +0000
+++ b/HTTPClient.lib	Mon Sep 28 08:55:29 2015 +0000
@@ -1,1 +1,1 @@
-http://developer.mbed.org/users/wolfSSL/code/HTTPClient/#77082c88748a
+http://developer.mbed.org/users/wolfSSL/code/HTTPClient/#09abfb894400
--- a/HTTPD.lib	Mon Sep 21 06:56:11 2015 +0000
+++ b/HTTPD.lib	Mon Sep 28 08:55:29 2015 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/okini3939/code/HTTPD/#f30e7b210e53
+https://developer.mbed.org/teams/Yodiwo/code/HTTPD/#f30e7b210e53
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/YodiwoPlegma.lib	Mon Sep 28 08:55:29 2015 +0000
@@ -0,0 +1,1 @@
+YodiwoPlegma#710e7fa99666
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config.c	Mon Sep 28 08:55:29 2015 +0000
@@ -0,0 +1,62 @@
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdbool.h>
+#include "jsmn.h"
+#include "config.h"
+
+int read_config(Yodiwo_Tools_APIGenerator_CNodeYConfig_t *config, char *filename)
+{
+    FILE *f;
+    int size;
+    char *buf;
+    int r;
+    f = fopen(filename, "r");
+    if (f == NULL) {
+        return -1;    
+    }
+    fseek(f, 0L, SEEK_END);
+    size = ftell(f);
+    fseek(f, 0L, SEEK_SET);
+    
+    buf = (char *)malloc(sizeof(char) * (size + 10));
+    if (buf == NULL) {
+        r = -ENOMEM;
+        goto exit;
+    }
+    size = fread(buf, 1, size, f);
+    buf[size] = '\0';
+    fclose(f);
+    f = NULL;
+    r = Yodiwo_Tools_APIGenerator_CNodeYConfig_FromJson(buf, size, config);
+exit:
+    free(buf);
+    if (f != NULL)
+    	fclose(f);
+    return (r < 0) ? r : 0;
+}
+
+int write_config(Yodiwo_Tools_APIGenerator_CNodeYConfig_t *config, char *filename)
+{
+    FILE *f;
+    char *buf;
+    int r;
+    f = fopen(filename, "w");
+    if (f == NULL) {
+        return -1;    
+    }
+    buf = (char *)malloc(2048); //TODO: proper
+    if (buf == NULL) {
+        r = -ENOMEM;
+        goto exit;
+    }
+    r = Yodiwo_Tools_APIGenerator_CNodeYConfig_ToJson(buf, 2048, config);
+    if (r < 0) 
+        goto exit;
+    fwrite(buf, r - 1, 1, f);
+exit:
+    free(buf);
+    fclose(f);
+    return (r < 0) ? r : 0;
+}
+
--- a/config.cpp	Mon Sep 21 06:56:11 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-#include "jsmn.h"
-#include "config.h"
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-
-//Yodiwo_Plegma_Json_e Configuration_FromJson(char* json, size_t jsonSize, config_t *config)
-//{
-//    memset(config, 0, sizeof(config_t));
-//    ParseTable table[] = {
-//        { "uuid",                 4, Parse_String, NULL, (void **)&config->uuid },
-//        { "name",                 4, Parse_String, NULL, (void **)&config->name },
-//        { "nodeKey",              7, Parse_String, NULL, (void **)&config->nodeKey },
-//        { "nodeSecret",          10, Parse_String, NULL, (void **)&config->nodeSecret },
-//        { "pairingServerUrl",    16, Parse_String, NULL, (void **)&config->pairingServerUrl },
-//        { "ypchannelServer",     15, Parse_String, NULL, (void **)&config->ypchannelServer },
-//        { "ypchannelServerPort", 19, Parse_Int,    NULL, (void **)&config->ypchannelServerPort },
-//        { "webPort",              7, Parse_Int,    NULL, (void **)&config->webPort },
-//        { "mqttBrokerHostname",  18, Parse_String, NULL, (void **)&config->mqttBrokerHostname },
-//        { "mqttBrokerPort",      14, Parse_Int,    NULL, (void **)&config->mqttBrokerPort },
-//        { "mqttBrokerCertFile",  18, Parse_String, NULL, (void **)&config->mqttBrokerCertFile },
-//    };
-//    return HelperJsonParseExec(json, jsonSize, table, sizeof(table) / sizeof(table[0]));
-//}
-//
-//int Configuration_ToJson(char* jsonStart, size_t jsonSize, config_t *config)
-//{
-//    char *json = jsonStart, *jsonEnd = json + jsonSize;
-//    json += snprintf(json, jsonEnd - json, "{ \"uuid\" : \"%s\"", config->uuid); if (json >= jsonEnd) return -1;
-//    json += snprintf(json, jsonEnd - json, ", \"name\" : \"%s\"", config->name); if (json >= jsonEnd) return -1;
-//    json += snprintf(json, jsonEnd - json, ", \"nodeKey\" : \"%s\"", config->nodeKey); if (json >= jsonEnd) return -1;
-//    json += snprintf(json, jsonEnd - json, ", \"nodeSecret\" : \"%s\"", config->nodeSecret); if (json >= jsonEnd) return -1;
-//    json += snprintf(json, jsonEnd - json, ", \"pairingServerUrl\" : \"%s\"", config->pairingServerUrl); if (json >= jsonEnd) return -1;
-//    json += snprintf(json, jsonEnd - json, ", \"ypchannelServer\" : \"%s\"", config->ypchannelServer); if (json >= jsonEnd) return -1;
-//    json += snprintf(json, jsonEnd - json, ", \"ypchannelServerPort\" : %d", config->ypchannelServerPort); if (json >= jsonEnd) return -1;
-//    json += snprintf(json, jsonEnd - json, ", \"webPort\" : %d", config->webPort); if (json >= jsonEnd) return -1;
-//    json += snprintf(json, jsonEnd - json, ", \"mqttBrokerHostname\" : \"%s\"", config->mqttBrokerHostname); if (json >= jsonEnd) return -1;
-//    json += snprintf(json, jsonEnd - json, ", \"mqttBrokerPort\" : %d", config->mqttBrokerPort); if (json >= jsonEnd) return -1;
-//    json += snprintf(json, jsonEnd - json, ", \"mqttBrokerCertFile\" : \"%s\"", config->mqttBrokerCertFile); if (json >= jsonEnd) return -1;
-//    *json = '}'; json++;
-//    *json = '\0'; json++;
-//    return json - jsonStart;
-//}
-
-int read_config(Yodiwo_Tools_APIGenerator_CNodeYConfig_t *config, char *filename)
-{
-    FILE *f;
-    int size;
-    char *buf;
-    int r;
-    f = fopen(filename, "r");
-    if (f == NULL) {
-        return -1;    
-    }
-    fseek(f, 0L, SEEK_END);
-    size = ftell(f);
-    fseek(f, 0L, SEEK_SET);
-    
-    buf = (char *)malloc(sizeof(char) * (size + 10));
-    if (buf == NULL) {
-        r = -ENOMEM;
-        goto exit;
-    }
-    size = fread(buf, 1, size, f);
-    buf[size] = '\0';
-    fclose(f);
-    printf("config file size was %d\n", size);
-    printf("gonna convert from json...\n");
-    r = Yodiwo_Tools_APIGenerator_CNodeYConfig_FromJson(buf, size, config);
-exit:
-    free(buf);
-    fclose(f);
-    return (r < 0) ? r : 0;
-}
-
-int write_config(Yodiwo_Tools_APIGenerator_CNodeYConfig_t *config, char *filename)
-{
-    FILE *f;
-    char *buf;
-    int r;
-    f = fopen(filename, "w");
-    if (f == NULL) {
-        return -1;    
-    }
-    buf = (char *)malloc(2048); //TODO: proper
-    if (buf == NULL) {
-        r = -ENOMEM;
-        goto exit;
-    }
-    r = Yodiwo_Tools_APIGenerator_CNodeYConfig_ToJson(buf, 2048, config);
-    if (r < 0) 
-        goto exit;
-    fwrite(buf, r - 1, 1, f);
-exit:
-    free(buf);
-    fclose(f);
-    return (r < 0) ? r : 0;
-}
\ No newline at end of file
--- a/config.h	Mon Sep 21 06:56:11 2015 +0000
+++ b/config.h	Mon Sep 28 08:55:29 2015 +0000
@@ -9,22 +9,6 @@
 #include <stdlib.h>
 #include "yodiwo_helpers.h"
 
-typedef struct
-{
-    char    *uuid;
-    char    *name;
-    char    *nodeKey;
-    char    *nodeSecret;
-    char    *pairingServerUrl;
-    char    *ypchannelServer;
-    int32_t  ypchannelServerPort;
-    int32_t  webPort;
-    char    *mqttBrokerHostname;
-    int32_t  mqttBrokerPort;
-    char    *mqttBrokerCertFile;
-} config_t;
-
-
 int read_config(Yodiwo_Tools_APIGenerator_CNodeYConfig_t *config, char *filename);
 int write_config(Yodiwo_Tools_APIGenerator_CNodeYConfig_t *config, char *filename);
 
@@ -32,4 +16,5 @@
 }
 #endif
 
-#endif /* __CONFIG_H__ */
\ No newline at end of file
+#endif /* __CONFIG_H__ */
+
--- a/main.cpp	Mon Sep 21 06:56:11 2015 +0000
+++ b/main.cpp	Mon Sep 28 08:55:29 2015 +0000
@@ -2,18 +2,16 @@
 #include "rtos.h"
 #include "EthernetInterface.h"
 #include "HTTPD.h"
-//#include "HTTPServer.h"
-//#include "LocalFileSystem.h"
+
 #include "SDFileSystem.h"                  // SD File System functions
 
-//#include "FsHandler.h"
-//#include "RpcHandler.h"
 #include "pairing_backend.h"
 #include "pairing_http_handler.h"
 #include "config.h"
 #include "yodiwo_functions.h"
-#include "nodas.h"
-#include "yodiwo_extra.h"
+#include "nodas_things.h"
+#include "mqtt_helpers.h"
+#include "yodiwo_helpers.h"
 
 #define DAT0 PTE3                          // MOSI
 #define CMD  PTE1                          // MISO
@@ -32,10 +30,8 @@
 InterruptIn sw2(SW2);
 uint32_t button_pressed;
 Thread *thread2;
-//HTTPServer server;
 extern HTTPD *httpd;
-//  Instantiate a local file system handler named 'local' which will be used later to access files on the mbed.
-//LocalFileSystem local("local");
+
  
  
 SDFileSystem sd(DAT0, CMD, CLK, CD, "sd"); // MOSI, MISO, SCLK, CS
@@ -50,13 +46,11 @@
 
 void sw2_press(void)
 {
-//    button_event(1, true);
     thread2->signal_set(0x1);
 }
 
 void sw2_release(void)
 {
-//    button_event(1, false);
     thread2->signal_set(0x2);    
 }
 
@@ -75,7 +69,6 @@
     blueled = 0;
     while (true) {
         osEvent evt = Thread::signal_wait(0x1 | 0x02);
-//        button_event(1, true);
         if (evt.value.signals & 0x01) {
             button_event(1, true);
         }
@@ -87,8 +80,6 @@
     }
 }
 
-//void callback_pairing (int id);
-
 int launch_mqtt();
 
 int main()
@@ -120,7 +111,6 @@
     sw2.rise(&sw2_release);
     while (true) {
         Thread::wait(5000);
-//        printf("SW2 was pressed (last 5 seconds): %d \n", button_pressed);
         fflush(stdout);
         button_pressed = 0;
     }
--- a/mbed-rtos.lib	Mon Sep 21 06:56:11 2015 +0000
+++ b/mbed-rtos.lib	Mon Sep 28 08:55:29 2015 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed-rtos/#21b438192b0f
+http://mbed.org/users/mbed_official/code/mbed-rtos/#9d001ed5feec
--- a/mbed.bld	Mon Sep 21 06:56:11 2015 +0000
+++ b/mbed.bld	Mon Sep 28 08:55:29 2015 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/8ed44a420e5c
\ No newline at end of file
+http://mbed.org/users/mbed_official/code/mbed/builds/4f6c30876dfa
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mqtt_helpers.cpp	Mon Sep 28 08:55:29 2015 +0000
@@ -0,0 +1,102 @@
+#include "mbed.h"
+#include "rtos.h"
+
+#include <stdint.h>
+
+#include "MQTTClient.h"
+#include "MQTTSocket.h"
+
+#include "mqtt_helpers.h"
+#include "yodiwo_functions.h"
+#include "jsmn.h"
+#include "yodiwo_helpers.h"
+
+///////////////////////////////// NETWORK
+//MQTTEthernet ipstack;
+MQTTSocket ipstack;
+MQTT::Client<MQTTSocket, Countdown, MAX_MSG_LEN> *client;
+
+///////////////////////////////// MQTT
+Thread *mqtt_thread;
+void mqtt_thread_func(void const *args);
+
+char mqtt_topic_sub[MAX_TOPIC_LEN];
+char mqtt_topic_pub[MAX_TOPIC_LEN];
+
+
+int mqtt_init(char *hostname, int port, char *certfile, char *nodeKeyS, char *nodeSecret)
+{   
+//    initialize_things(nodeKeyS); 
+    Yodiwo_Plegma_NodeKey_t nodeKey;
+    NodeKey_FromString(&nodeKey, nodeKeyS);
+    sprintf(mqtt_topic_sub, "/api/out/" YODIWO_API_VERSION_STR "/%s/#", nodeKeyS);
+    sprintf(mqtt_topic_pub, "/api/in/" YODIWO_API_VERSION_STR "/%s/%s/", nodeKey.UserKey.UserID, nodeKeyS);
+    printf("topic to subscribe: %s\n", mqtt_topic_sub);
+    
+    client = new MQTT::Client<MQTTSocket, Countdown, MAX_MSG_LEN>(ipstack);
+    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
+    data.MQTTVersion = 4;
+    data.clientID.cstring = nodeKeyS;
+    data.username.cstring = nodeKeyS;
+    data.password.cstring = nodeSecret;
+    ipstack = MQTTSocket();  
+    
+    printf("connecting to MQTT broker: %s:%d\n", hostname, port);    
+    
+    int rc = ipstack.connect(hostname, port, port > 8000 ? certfile : NULL);
+    if (rc != 0)
+        printf("rc from TCP connect is %d\n", rc);
+ 
+    if ((rc = client->connect(data)) != 0)
+        printf("rc from MQTT connect is %d\n", rc);
+    printf("MQTT connected\n") ;
+    if ((rc = client->subscribe(mqtt_topic_sub, MQTT::QOS0, on_mqtt_message)) != 0)
+        printf("rc from MQTT subscribe is %d\n", rc);
+    printf("Subscribed\n") ;
+    if (rc != 0) {
+        printf("MQTT init failed: %d\n", rc);
+        return rc;
+    }
+    mqtt_thread = new Thread(mqtt_thread_func, (void *)client, osPriorityNormal, 10000);
+    return 0;
+}
+
+void mqtt_thread_func(void const *args)
+{
+    MQTT::Client<MQTTSocket, Countdown, MAX_MSG_LEN> *client = (MQTT::Client<MQTTSocket, Countdown, MAX_MSG_LEN>*)args;
+    while(1)
+        client->yield(100);
+}
+
+
+void on_mqtt_message(MQTT::MessageData &md)
+{
+    MQTT::Message &message = md.message;
+
+    printf("%.*s\n", md.topicName.lenstring.len, md.topicName.lenstring.data);
+    printf("Message arrived: qos %d, retained %d, dup %d, packetid %d\n", message.qos, message.retained, message.dup, message.id);
+    printf("Payload %.*s\n", message.payloadlen, (char*)message.payload);
+    
+    yodiwo_handle_message((char *)message.payload, message.payloadlen, md.topicName.lenstring.data, md.topicName.lenstring.len);
+}
+
+int publisher(char *msg, int msg_len, char *msg_type)
+{
+    int r;
+    char topic[MAX_TOPIC_LEN];
+    MQTT::Message message;
+    message.retained = false;
+    message.dup = false;
+    message.payload = (void*)msg;
+    message.qos = MQTT::QOS0;
+    message.payloadlen = msg_len - 1;
+    
+    strcpy(topic, mqtt_topic_pub);
+    strcat(topic, msg_type);
+    printf("publishing to %s\n", topic);
+    printf("content: %.*s\n", msg_len, msg);
+    printf("length: %d\n", msg_len);
+    r = client->publish(topic, message);
+    printf("publish returned %d\n", r);
+    return r;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mqtt_helpers.h	Mon Sep 28 08:55:29 2015 +0000
@@ -0,0 +1,21 @@
+#ifndef __MQTT_HELPERS_H__
+#define __MQTT_HELPERS_H__
+
+#include "MQTTClient.h"
+#include "MQTTSocket.h"
+
+//#include "yodiwo_api.h"
+#include <stdlib.h>
+
+#define MAX_MSG_LEN 2500
+#define MAX_TOPIC_LEN 150
+
+
+int mqtt_init(char *hostname, int port, char *certfile, char *nodeKey, char *nodeSecret);
+void on_mqtt_message(MQTT::MessageData &msg);
+
+//typedef int (*portevent_handler_func)(Yodiwo_Plegma_PortEvent_t *event);
+
+int publisher(char *msg, int msg_len, char *msg_type);
+
+#endif /* __MQTT_HELPERS_H__ */
--- a/nodas.cpp	Mon Sep 21 06:56:11 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,360 +0,0 @@
-#include "mbed.h"
-#include "rtos.h"
-
-#include <stdint.h>
-
-#include "MQTTClient.h"
-#include "MQTTSocket.h"
-
-#include "jsmn.h"
-#include "config.h"
-#include "nodas.h"
-#include "yodiwo_api.h"
-#include "yodiwo_functions.h"
-#include "yodiwo_extra.h"
-
-///////////////////////////////// LEDS
-DigitalOut redled(LED1);
-DigitalOut greenled(LED2);
-DigitalOut blueled(LED3);
-
-///////////////////////////////// NETWORK
-//MQTTEthernet ipstack;
-MQTTSocket ipstack;
-MQTT::Client<MQTTSocket, Countdown, MAX_MSG_LEN> *client;
-
-///////////////////////////////// MQTT
-Thread *mqtt_thread;
-void mqtt_thread_func(void const *args);
-
-char mqtt_topic_sub[MAX_TOPIC_LEN];
-char mqtt_topic_pub[MAX_TOPIC_LEN];
-
-///////////////////////////////// CONFIG
-extern Yodiwo_Tools_APIGenerator_CNodeConfig_t *activeConfig;
-
-
-///////////////////////////////// THINGS
-Yodiwo_Plegma_Port_t button_port;
-Yodiwo_Plegma_Port_t axel_port;
-Yodiwo_Plegma_Port_t _led_ports[3];
-
-Yodiwo_Plegma_Thing_t *button;
-Yodiwo_Plegma_Thing_t *axel;
-Yodiwo_Plegma_Thing_t *led;
-
-Yodiwo_Plegma_Thing_t _things[3];
-Array_Yodiwo_Plegma_Thing_t things;
-
-
-
-int mqtt_init(char *hostname, int port, char *certfile, char *nodeKeyS, char *nodeSecret)
-{   
-//    initialize_things(nodeKeyS); 
-    Yodiwo_Plegma_NodeKey_t nodeKey;
-    NodeKey_FromString(&nodeKey, nodeKeyS);
-    sprintf(mqtt_topic_sub, "/api/out/" YODIWO_API_VERSION_STR "/%s/#", nodeKeyS);
-    sprintf(mqtt_topic_pub, "/api/in/" YODIWO_API_VERSION_STR "/%s/%s/", nodeKey.UserKey.UserID, nodeKeyS);
-    printf("topic to subscribe: %s\n", mqtt_topic_sub);
-    
-    client = new MQTT::Client<MQTTSocket, Countdown, MAX_MSG_LEN>(ipstack);
-    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
-    data.MQTTVersion = 4;
-    data.clientID.cstring = nodeKeyS;
-    data.username.cstring = nodeKeyS;
-    data.password.cstring = nodeSecret;
-    ipstack = MQTTSocket();  
-    
-    printf("connecting to MQTT broker: %s:%d\n", hostname, port);    
-    
-    int rc = ipstack.connect(hostname, port, port > 8000 ? certfile : NULL);
-    if (rc != 0)
-        printf("rc from TCP connect is %d\n", rc);
- 
-    if ((rc = client->connect(data)) != 0)
-        printf("rc from MQTT connect is %d\n", rc);
-    printf("MQTT connected\n") ;
-    if ((rc = client->subscribe(mqtt_topic_sub, MQTT::QOS0, on_mqtt_message)) != 0)
-        printf("rc from MQTT subscribe is %d\n", rc);
-    printf("Subscribed\n") ;
-    if (rc != 0) {
-        printf("MQTT init failed: %d\n", rc);
-        return rc;
-    }
-    mqtt_thread = new Thread(mqtt_thread_func, (void *)client, osPriorityNormal, 10000);
-    return 0;
-}
-
-void mqtt_thread_func(void const *args)
-{
-    MQTT::Client<MQTTSocket, Countdown, MAX_MSG_LEN> *client = (MQTT::Client<MQTTSocket, Countdown, MAX_MSG_LEN>*)args;
-    while(1)
-        client->yield(100);
-}
-
-
-void on_mqtt_message(MQTT::MessageData &md)
-{
-    MQTT::Message &message = md.message;
-
-    printf("%.*s\n", md.topicName.lenstring.len, md.topicName.lenstring.data);
-    printf("Message arrived: qos %d, retained %d, dup %d, packetid %d\n", message.qos, message.retained, message.dup, message.id);
-    printf("Payload %.*s\n", message.payloadlen, (char*)message.payload);
-    
-    yodiwo_handle_message((char *)message.payload, message.payloadlen, md.topicName.lenstring.data, md.topicName.lenstring.len);
-}
-
-int publisher(char *msg, int msg_len, char *msg_type)
-{
-    int r;
-    char topic[MAX_TOPIC_LEN];
-    MQTT::Message message;
-    message.retained = false;
-    message.dup = false;
-    message.payload = (void*)msg;
-    message.qos = MQTT::QOS0;
-    message.payloadlen = msg_len - 1;
-    
-    strcpy(topic, mqtt_topic_pub);
-    strcat(topic, msg_type);
-    printf("publishing to %s\n", topic);
-    printf("content: %.*s\n", msg_len, msg);
-    printf("length: %d\n", msg_len);
-    r = client->publish(topic, message);
-    printf("publish returned %d\n", r);
-    return r;
-}
-
-int shaken_event()
-{
-    Yodiwo_Plegma_PortEvent_t event;
-    Array_Yodiwo_Plegma_PortEvent_t array_events;
-    
-    event.PortKey = axel->Ports.elems[0].PortKey;
-    event.State = "True";
-    event.RevNum = 1;
-    
-    array_events.num = 1;
-    array_events.elems = &event;
-    
-    return portevents(&array_events);    
-}
-
-int button_event(int buttonId, bool pressed)
-{
-    printf("button %d: %s\n", buttonId, (pressed) ? "pressed" : "released");
-    
-    Yodiwo_Plegma_PortEvent_t event;
-    Array_Yodiwo_Plegma_PortEvent_t array_events;
-    
-    event.PortKey = button->Ports.elems[0].PortKey;
-    event.State = (char *)((pressed) ? "True" : "False");
-    event.RevNum = 1;
-    
-    array_events.num = 1;
-    array_events.elems = &event;
-    
-    return portevents(&array_events);
-}
-
-void led_event(DigitalOut &led, Yodiwo_Plegma_PortEvent_t *event)
-{
-    if (!strcmp(event->State, "on") || !strcmp(event->State, "1")  || !strcmp(event->State, "true")
-    || !strcmp(event->State, "True")  || !strcmp(event->State, "On")) {
-        printf("ON\n");
-        led = 0;
-    } else {
-        printf("OFF\n");
-        led = 1;
-    }
-}
-
-int handle_red_led(Yodiwo_Plegma_PortEvent_t *event)
-{
-    printf("event for red led\n");
-    led_event(redled, event);
-    return 0;
-}
-
-int handle_green_led(Yodiwo_Plegma_PortEvent_t *event)
-{
-    printf("event for green led\n");
-    led_event(greenled, event);
-    return 0;
-}
-
-int handle_blue_led(Yodiwo_Plegma_PortEvent_t *event)
-{
-    printf("event for blue led\n");
-    led_event(blueled, event);
-    return 0;
-}
-
-void initialize_things(char *nodeKey)
-{
-    // init thing pointers
-    button = &_things[0];
-    axel   = &_things[1];
-    led    = &_things[2];
-    
-    //BUTTON
-    button_port.ConfFlags = Yodiwo_ePortConf_None; //why not
-    button_port.Description = "the state of the freedom button";
-    button_port.Name = "BTN State";
-    button_port.Type = Yodiwo_ePortType_Boolean;
-    button_port.State = "False";
-    button_port.RevNum = 1;
-    button_port.ioDirection = Yodiwo_ioPortDirection_Output;
-    button_port.PortKey = "";
-
-    button->ThingKey = "";
-    button->Name = "FRDM Button";
-    button->Config.num = 0;
-    button->Config.elems = NULL;
-    button->Ports.num = 1;
-    button->Ports.elems = &button_port;
-    button->Type = "";
-    button->BlockType = "";
-    button->UIHints.Description = "";
-    button->UIHints.IconURI = "/Content/VirtualGateway/img/icon-thing-genericbutton.png";
-
-    //AXEL
-    axel_port.ConfFlags = Yodiwo_ePortConf_IsTrigger; //why not
-    axel_port.Description = "triggered when the shaker is shaked";
-    axel_port.Name = "SHAKER SHAKED";
-    axel_port.Type = Yodiwo_ePortType_Boolean;
-    axel_port.State = "";
-    axel_port.RevNum = 1;
-    axel_port.ioDirection = Yodiwo_ioPortDirection_Output;
-    axel_port.PortKey = "";
-
-    axel->ThingKey = "";
-    axel->Name = "FRDM SHAKER";
-    axel->Config.num = 0;
-    axel->Config.elems = NULL;
-    axel->Ports.num = 1;
-    axel->Ports.elems = &axel_port;
-    axel->Type = "";
-    axel->BlockType = "";
-    axel->UIHints.Description = "";
-    axel->UIHints.IconURI = "/Content/VirtualGateway/img/accelerometer.jpg";
-    
-    //LED
-    _led_ports[0].ConfFlags = Yodiwo_ePortConf_None; //why not
-    _led_ports[0].Description = "RED LED";
-    _led_ports[0].Name = "RED LED";
-    _led_ports[0].Type = Yodiwo_ePortType_Boolean;    
-    _led_ports[0].State = "False";
-    _led_ports[0].RevNum = 1;
-    _led_ports[0].ioDirection = Yodiwo_ioPortDirection_Input;
-    _led_ports[0].PortKey = "";
-
-    _led_ports[1].ConfFlags = Yodiwo_ePortConf_None; //why not
-    _led_ports[1].Description = "GREEN LED";
-    _led_ports[1].Name = "GREEN LED";
-    _led_ports[0].Type = Yodiwo_ePortType_Boolean;    
-    _led_ports[1].State = "off";
-    _led_ports[1].RevNum = 1;
-    _led_ports[1].ioDirection = Yodiwo_ioPortDirection_Input;
-    _led_ports[1].PortKey = "";
-    
-    _led_ports[2].ConfFlags = Yodiwo_ePortConf_None; //why not
-    _led_ports[2].Description = "BLUE LED";
-    _led_ports[2].Name = "BLUE LED";
-    _led_ports[0].Type = Yodiwo_ePortType_Boolean;    
-    _led_ports[2].State = "off";
-    _led_ports[2].RevNum = 1;
-    _led_ports[2].ioDirection = Yodiwo_ioPortDirection_Input;
-    _led_ports[2].PortKey = "";
-    
-    led->ThingKey = "";
-    led->Name = "FRDM LED";
-    led->Config.num = 0;
-    led->Config.elems = NULL;
-    led->Ports.num = 3;
-    led->Ports.elems = _led_ports;
-    led->Type = "";
-    led->BlockType = "";
-    led->UIHints.Description = "";
-    led->UIHints.IconURI = "/Content/VirtualGateway/img/icon-thing-genericlight.png";    
-
-    things.num = 3;
-    things.elems = _things;
-    
-    if (activeConfig->NodeKey != NULL) {
-        int r;
-        r = fill_Thing_Keys(&things.elems[0], activeConfig->NodeKey, 1);
-        r = fill_Thing_Keys(&things.elems[1], activeConfig->NodeKey, 2);
-        r = fill_Thing_Keys(&things.elems[2], activeConfig->NodeKey, 3);
-        
-        printf("fill keys returned: %d\n", r);
-    }
-}
-
-void register_led_handlers()
-{
-    redled = 1;
-    greenled = 1;
-    blueled = 1;
-    register_portevent_handler(things.elems[2].Ports.elems[0].PortKey, handle_red_led);
-    register_portevent_handler(things.elems[2].Ports.elems[1].PortKey, handle_green_led);
-    register_portevent_handler(things.elems[2].Ports.elems[2].PortKey, handle_blue_led);
-}
-
-
-#include "FXOS8700Q.h"
-//FXOS8700Q acc( A4, A5, FXOS8700CQ_SLAVE_ADDR0); // Proper Ports and I2C address for Freescale Multi Axis shield
-//FXOS8700Q mag( A4, A5, FXOS8700CQ_SLAVE_ADDR0); // Proper Ports and I2C address for Freescale Multi Axis shield
-FXOS8700Q_acc acc( PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); // Proper Ports and I2C Address for K64F Freedom board
-FXOS8700Q_mag mag( PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); // Proper Ports and I2C Address for K64F Freedom board
- 
-//MotionSensorDataUnits mag_data;
-MotionSensorDataUnits acc_data;
-// 
-//MotionSensorDataCounts mag_raw;
-//MotionSensorDataCounts acc_raw;
- 
-#define DOWNSAMPLING 50
-
-void axel_thread(const void *args)
-{
-//    float faX, faY, faZ;
-//    float fmX, fmY, fmZ;
-//    int16_t raX, raY, raZ;
-//    int16_t rmX, rmY, rmZ;
-    acc.enable();
-    printf("\r\n\nFXOS8700Q Who Am I= %X\r\n", acc.whoAmI());
-    int count = 0;
-    int shaken_cd = 0;
-    while (true) {
-//        if (client->isConnected())
-        {
-            acc.getAxis(acc_data);
-            ++count %= DOWNSAMPLING;
-            if (shaken_cd) shaken_cd--;
-            if ((acc_data.x > 1.5f || acc_data.y > 1.5f || acc_data.z > 1.5f) && !shaken_cd) {
-                printf("shaken, not stirred\n");
-                shaken_cd = DOWNSAMPLING;
-                shaken_event();
-            }
-            if (!count) {
-        //        mag.getAxis(mag_data);
-
-        
-//                printf("FXOS8700Q ACC: X=%1.4f Y=%1.4f Z=%1.4f  \n", acc_data.x, acc_data.y, acc_data.z);
-
-
-        //        printf("    MAG: X=%4.1f Y=%4.1f Z=%4.1f\r\n", mag_data.x, mag_data.y, mag_data.z);
-        //        acc.getX(&faX);
-        //        acc.getY(&faY);
-        //        acc.getZ(&faZ);
-        //        mag.getX(&fmX);
-        //        mag.getY(&fmY);
-        //        mag.getZ(&fmZ);
-        //        printf("FXOS8700Q ACC: X=%1.4f Y=%1.4f Z=%1.4f  ", faX, faY, faZ);
-        //        printf("    MAG: X=%4.1f Y=%4.1f Z=%4.1f\r\n", fmX, fmY, fmZ);
-            }
-        }
-        Thread::wait(20);
-    }
-}
\ No newline at end of file
--- a/nodas.h	Mon Sep 21 06:56:11 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-#ifndef __NODAS_H__
-#define __NODAS_H__
-
-#include "MQTTClient.h"
-#include "MQTTSocket.h"
-
-#include "yodiwo_api.h"
-#include <stdlib.h>
-
-#define MAX_MSG_LEN 2500
-#define MAX_TOPIC_LEN 150
-
-
-typedef int (func_ToJson)(char *, size_t, void *);
-typedef Yodiwo_Plegma_Json_e (func_FromJson)(char *, size_t, void *);
-
-int mqtt_init(char *hostname, int port, char *certfile, char *nodeKey, char *nodeSecret);
-void on_mqtt_message(MQTT::MessageData &msg);
-
-int button_event(int buttonId, bool pressed);
-
-typedef int (*portevent_handler_func)(Yodiwo_Plegma_PortEvent_t *event);
-
-void initialize_things(char *nodeKey);
-int publisher(char *msg, int msg_len, char *msg_type);
-
-
-int handle_red_led(Yodiwo_Plegma_PortEvent_t *event);
-int handle_green_led(Yodiwo_Plegma_PortEvent_t *event);
-int handle_blue_led(Yodiwo_Plegma_PortEvent_t *event);
-
-extern Array_Yodiwo_Plegma_Thing_t things;
-
-void register_led_handlers();
-
-void axel_thread(const void *args);
-
-#endif /* __NODAS_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nodas_things.cpp	Mon Sep 28 08:55:29 2015 +0000
@@ -0,0 +1,262 @@
+#include "mbed.h"
+#include "rtos.h"
+
+#include <stdint.h>
+
+#include "nodas_things.h"
+#include "yodiwo_functions.h"
+#include "jsmn.h"
+#include "yodiwo_api.h"
+#include "yodiwo_helpers.h"
+
+///////////////////////////////// LEDS
+DigitalOut redled(LED1);
+DigitalOut greenled(LED2);
+DigitalOut blueled(LED3);
+
+///////////////////////////////// THINGS
+Yodiwo_Plegma_Port_t button_port;
+Yodiwo_Plegma_Port_t axel_port;
+Yodiwo_Plegma_Port_t _led_ports[3];
+
+Yodiwo_Plegma_Thing_t *button;
+Yodiwo_Plegma_Thing_t *axel;
+Yodiwo_Plegma_Thing_t *led;
+
+Yodiwo_Plegma_Thing_t _things[3];
+Array_Yodiwo_Plegma_Thing_t things;
+
+
+int shaken_event()
+{
+    Yodiwo_Plegma_PortEvent_t event;
+    Array_Yodiwo_Plegma_PortEvent_t array_events;
+    
+    event.PortKey = axel->Ports.elems[0].PortKey;
+    event.State = "True";
+    event.RevNum = 1;
+    
+    array_events.num = 1;
+    array_events.elems = &event;
+    
+    return portevents(&array_events);    
+}
+
+int button_event(int buttonId, bool pressed)
+{
+    printf("button %d: %s\n", buttonId, (pressed) ? "pressed" : "released");
+    
+    Yodiwo_Plegma_PortEvent_t event;
+    Array_Yodiwo_Plegma_PortEvent_t array_events;
+    
+    event.PortKey = button->Ports.elems[0].PortKey;
+    event.State = (char *)((pressed) ? "True" : "False");
+    event.RevNum = 1;
+    
+    array_events.num = 1;
+    array_events.elems = &event;
+    
+    return portevents(&array_events);
+}
+
+void led_event(DigitalOut &led, Yodiwo_Plegma_PortEvent_t *event)
+{
+    if (!strcmp(event->State, "on") || !strcmp(event->State, "1")  || !strcmp(event->State, "true")
+    || !strcmp(event->State, "True")  || !strcmp(event->State, "On")) {
+        printf("ON\n");
+        led = 0;
+    } else {
+        printf("OFF\n");
+        led = 1;
+    }
+}
+
+int handle_red_led(Yodiwo_Plegma_PortEvent_t *event)
+{
+    printf("event for red led\n");
+    led_event(redled, event);
+    return 0;
+}
+
+int handle_green_led(Yodiwo_Plegma_PortEvent_t *event)
+{
+    printf("event for green led\n");
+    led_event(greenled, event);
+    return 0;
+}
+
+int handle_blue_led(Yodiwo_Plegma_PortEvent_t *event)
+{
+    printf("event for blue led\n");
+    led_event(blueled, event);
+    return 0;
+}
+
+void initialize_things(char *nodeKey)
+{
+    // init thing pointers
+    button = &_things[0];
+    axel   = &_things[1];
+    led    = &_things[2];
+    
+    //BUTTON
+    button_port.ConfFlags = Yodiwo_ePortConf_None; //why not
+    button_port.Description = "the state of the freedom button";
+    button_port.Name = "BTN State";
+    button_port.Type = Yodiwo_ePortType_Boolean;
+    button_port.State = "False";
+    button_port.RevNum = 1;
+    button_port.ioDirection = Yodiwo_ioPortDirection_Output;
+    button_port.PortKey = "";
+
+    button->ThingKey = "";
+    button->Name = "FRDM Button";
+    button->Config.num = 0;
+    button->Config.elems = NULL;
+    button->Ports.num = 1;
+    button->Ports.elems = &button_port;
+    button->Type = "";
+    button->BlockType = "";
+    button->UIHints.Description = "";
+    button->UIHints.IconURI = "/Content/VirtualGateway/img/icon-thing-genericbutton.png";
+
+    //AXEL
+    axel_port.ConfFlags = Yodiwo_ePortConf_IsTrigger; //why not
+    axel_port.Description = "triggered when the shaker is shaked";
+    axel_port.Name = "SHAKER SHAKED";
+    axel_port.Type = Yodiwo_ePortType_Boolean;
+    axel_port.State = "";
+    axel_port.RevNum = 1;
+    axel_port.ioDirection = Yodiwo_ioPortDirection_Output;
+    axel_port.PortKey = "";
+
+    axel->ThingKey = "";
+    axel->Name = "FRDM SHAKER";
+    axel->Config.num = 0;
+    axel->Config.elems = NULL;
+    axel->Ports.num = 1;
+    axel->Ports.elems = &axel_port;
+    axel->Type = "";
+    axel->BlockType = "";
+    axel->UIHints.Description = "";
+    axel->UIHints.IconURI = "/Content/VirtualGateway/img/accelerometer.jpg";
+    
+    //LED
+    _led_ports[0].ConfFlags = Yodiwo_ePortConf_None; //why not
+    _led_ports[0].Description = "RED LED";
+    _led_ports[0].Name = "RED LED";
+    _led_ports[0].Type = Yodiwo_ePortType_Boolean;    
+    _led_ports[0].State = "False";
+    _led_ports[0].RevNum = 1;
+    _led_ports[0].ioDirection = Yodiwo_ioPortDirection_Input;
+    _led_ports[0].PortKey = "";
+
+    _led_ports[1].ConfFlags = Yodiwo_ePortConf_None; //why not
+    _led_ports[1].Description = "GREEN LED";
+    _led_ports[1].Name = "GREEN LED";
+    _led_ports[0].Type = Yodiwo_ePortType_Boolean;    
+    _led_ports[1].State = "off";
+    _led_ports[1].RevNum = 1;
+    _led_ports[1].ioDirection = Yodiwo_ioPortDirection_Input;
+    _led_ports[1].PortKey = "";
+    
+    _led_ports[2].ConfFlags = Yodiwo_ePortConf_None; //why not
+    _led_ports[2].Description = "BLUE LED";
+    _led_ports[2].Name = "BLUE LED";
+    _led_ports[0].Type = Yodiwo_ePortType_Boolean;    
+    _led_ports[2].State = "off";
+    _led_ports[2].RevNum = 1;
+    _led_ports[2].ioDirection = Yodiwo_ioPortDirection_Input;
+    _led_ports[2].PortKey = "";
+    
+    led->ThingKey = "";
+    led->Name = "FRDM LED";
+    led->Config.num = 0;
+    led->Config.elems = NULL;
+    led->Ports.num = 3;
+    led->Ports.elems = _led_ports;
+    led->Type = "";
+    led->BlockType = "";
+    led->UIHints.Description = "";
+    led->UIHints.IconURI = "/Content/VirtualGateway/img/icon-thing-genericlight.png";    
+
+    things.num = 3;
+    things.elems = _things;
+    
+    if (nodeKey != NULL) {
+        int r;
+        r = fill_Thing_Keys(&things.elems[0], nodeKey, 1);
+        r = fill_Thing_Keys(&things.elems[1], nodeKey, 2);
+        r = fill_Thing_Keys(&things.elems[2], nodeKey, 3);
+        
+        printf("fill keys returned: %d\n", r);
+    }
+}
+
+void register_led_handlers()
+{
+    redled = 1;
+    greenled = 1;
+    blueled = 1;
+    register_portevent_handler(things.elems[2].Ports.elems[0].PortKey, handle_red_led);
+    register_portevent_handler(things.elems[2].Ports.elems[1].PortKey, handle_green_led);
+    register_portevent_handler(things.elems[2].Ports.elems[2].PortKey, handle_blue_led);
+}
+
+
+#include "FXOS8700Q.h"
+//FXOS8700Q acc( A4, A5, FXOS8700CQ_SLAVE_ADDR0); // Proper Ports and I2C address for Freescale Multi Axis shield
+//FXOS8700Q mag( A4, A5, FXOS8700CQ_SLAVE_ADDR0); // Proper Ports and I2C address for Freescale Multi Axis shield
+FXOS8700Q_acc acc( PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); // Proper Ports and I2C Address for K64F Freedom board
+FXOS8700Q_mag mag( PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); // Proper Ports and I2C Address for K64F Freedom board
+ 
+//MotionSensorDataUnits mag_data;
+MotionSensorDataUnits acc_data;
+// 
+//MotionSensorDataCounts mag_raw;
+//MotionSensorDataCounts acc_raw;
+ 
+#define DOWNSAMPLING 50
+
+void axel_thread(const void *args)
+{
+//    float faX, faY, faZ;
+//    float fmX, fmY, fmZ;
+//    int16_t raX, raY, raZ;
+//    int16_t rmX, rmY, rmZ;
+    acc.enable();
+    printf("\r\n\nFXOS8700Q Who Am I= %X\r\n", acc.whoAmI());
+    int count = 0;
+    int shaken_cd = 0;
+    while (true) {
+//        if (client->isConnected())
+        {
+            acc.getAxis(acc_data);
+            ++count %= DOWNSAMPLING;
+            if (shaken_cd) shaken_cd--;
+            if ((acc_data.x > 1.5f || acc_data.y > 1.5f || acc_data.z > 1.5f) && !shaken_cd) {
+                printf("shaken, not stirred\n");
+                shaken_cd = DOWNSAMPLING;
+                shaken_event();
+            }
+            if (!count) {
+        //        mag.getAxis(mag_data);
+
+        
+//                printf("FXOS8700Q ACC: X=%1.4f Y=%1.4f Z=%1.4f  \n", acc_data.x, acc_data.y, acc_data.z);
+
+
+        //        printf("    MAG: X=%4.1f Y=%4.1f Z=%4.1f\r\n", mag_data.x, mag_data.y, mag_data.z);
+        //        acc.getX(&faX);
+        //        acc.getY(&faY);
+        //        acc.getZ(&faZ);
+        //        mag.getX(&fmX);
+        //        mag.getY(&fmY);
+        //        mag.getZ(&fmZ);
+        //        printf("FXOS8700Q ACC: X=%1.4f Y=%1.4f Z=%1.4f  ", faX, faY, faZ);
+        //        printf("    MAG: X=%4.1f Y=%4.1f Z=%4.1f\r\n", fmX, fmY, fmZ);
+            }
+        }
+        Thread::wait(20);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nodas_things.h	Mon Sep 28 08:55:29 2015 +0000
@@ -0,0 +1,38 @@
+#ifndef __NODAS_THINGS_H__
+#define __NODAS_THINGS_H__
+
+#include "MQTTClient.h"
+#include "MQTTSocket.h"
+
+#include "yodiwo_api.h"
+#include <stdlib.h>
+
+#define MAX_MSG_LEN 2500
+#define MAX_TOPIC_LEN 150
+
+
+typedef int (func_ToJson)(char *, size_t, void *);
+typedef Yodiwo_Plegma_Json_e (func_FromJson)(char *, size_t, void *);
+
+int mqtt_init(char *hostname, int port, char *certfile, char *nodeKey, char *nodeSecret);
+void on_mqtt_message(MQTT::MessageData &msg);
+
+int button_event(int buttonId, bool pressed);
+
+typedef int (*portevent_handler_func)(Yodiwo_Plegma_PortEvent_t *event);
+
+void initialize_things(char *nodeKey);
+int publisher(char *msg, int msg_len, char *msg_type);
+
+
+int handle_red_led(Yodiwo_Plegma_PortEvent_t *event);
+int handle_green_led(Yodiwo_Plegma_PortEvent_t *event);
+int handle_blue_led(Yodiwo_Plegma_PortEvent_t *event);
+
+extern Array_Yodiwo_Plegma_Thing_t things;
+
+void register_led_handlers();
+
+void axel_thread(const void *args);
+
+#endif /* __NODAS_THINGS_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pairing_backend.c	Mon Sep 28 08:55:29 2015 +0000
@@ -0,0 +1,153 @@
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include "jsmn.h"
+#include "yodiwo_helpers.h"
+#include "config.h"
+#include "system.h"
+#include "pairing_backend.h"
+
+char recvBuff[1024*20];
+void *__get_tokens(pairing_context *ctx);
+void *__get_keys(pairing_context *ctx);
+
+void *do_on_thread(thread_func func, void *args, unsigned int stack_size);
+
+#define PAGE_SERVER_PHASE2 "userconfirm"
+
+int pairing_context_init_with_defaults(pairing_context *ctx, onPaired_callback callback)
+{
+    ctx->postUrl = "http://10.30.254.199:3334/pairing/";
+    ctx->uuid = "1337CNode";
+    ctx->name = "Nodas";
+    ctx->onPaired = callback;
+    return 0;
+}
+
+extern Yodiwo_Tools_APIGenerator_CNodeConfig_t *activeConfig;
+
+int pairing_context_init_from_config(pairing_context *ctx, onPaired_callback callback)
+{
+    printf("server url: %s\n", activeConfig->PairingServerUrl);
+    printf("uuid: %s\n", activeConfig->Uuid);
+    printf("name: %s\n", activeConfig->Name);
+    ctx->postUrl = activeConfig->PairingServerUrl;
+    ctx->uuid = activeConfig->Uuid;
+    ctx->name = activeConfig->Name;
+    ctx->onPaired = callback;
+    return 0;    
+}
+
+#define STACK_SIZE 24000
+
+
+int pairing_get_tokens(pairing_context *ctx)
+{
+    printf("getting tokens from server\n");
+    return (int)do_on_thread((thread_func)__get_tokens, ctx, STACK_SIZE);
+}
+
+char* get_server_phase2_url(pairing_context *ctx, char *hostname, int port, char *urlBase)
+{
+        int len = 200; //TODO: proper calculation
+        char* result = (char *)malloc(sizeof(char) * len);
+        if (!result)
+            return NULL;
+        sprintf(result, "%s" "1/" PAGE_SERVER_PHASE2 "?token2=%s&noderedirect=http://%s:%d%snext",
+        		ctx->postUrl, ctx->token2, hostname, (port == 0) ? 80 : port, urlBase);
+        return result;        
+}
+
+int pairing_get_keys(pairing_context *ctx)
+{
+    printf("getting keys from server\n");
+    return (int)do_on_thread((thread_func)__get_keys, ctx, STACK_SIZE);
+}
+
+void *do_on_thread(thread_func func, void *args, unsigned int stack_size)
+{
+	int r;
+    thread_t t;
+    r = thread_run(&t, func, args, 0, stack_size);
+    printf("run: %d\n", r);
+    if (r < 0)
+    	return (void *)-1;
+    return thread_join(&t);  
+}
+    
+void *__get_tokens(pairing_context *ctx)
+{
+	char url[100];
+    char postfields[100];
+    char response[512];
+    int ret;
+    strcpy(url, ctx->postUrl);
+    strcat(url, "/1/gettokensreq");
+
+    //POST data
+    sprintf(postfields, "name=%s&uuid=%s", ctx->name, ctx->uuid);
+    printf("\nTrying to post data...\n");
+    ret = http_post(url, postfields, response, 512);
+    Yodiwo_Plegma_NodePairing_PairingServerTokensResponse_t tokens;
+    if (ret > 0)
+    {
+        printf("Executed POST successfully - read %zu characters\n", strlen(response));
+        printf("Result: %s\n", response);
+        int jret = Yodiwo_Plegma_NodePairing_PairingServerTokensResponse_FromJson(response, strlen(response), &tokens);
+        if (jret == Yodiwo_JsonSuccessParse) {
+            ctx->token1 = tokens.token1;
+            ctx->token2 = tokens.token2;
+            return (void *)0;
+        } else {
+            printf("error parsing response");
+            return (void *)-2;
+        }
+    }
+    else
+    {
+      printf("Error HTTP Post return code = %d\n", ret);
+    }
+    return (void *)ret;
+    
+}
+
+
+void *__get_keys(pairing_context *ctx)
+{
+	char url[100];
+    char postfields[100];
+    char response[512];
+
+    strcpy(url, ctx->postUrl);
+    strcat(url, "/1/getkeysreq");
+    int ret;
+
+    //POST data
+    sprintf(postfields, "uuid=%s&token1=%s", ctx->uuid, ctx->token1);
+
+    printf("\nTrying to post data...\n");
+    ret = http_post(url, postfields, response, 512);
+    Yodiwo_Plegma_NodePairing_PairingServerKeysResponse_t keys;
+    if (ret > 0)
+    {
+        printf("Executed POST successfully - read %zu characters\n", strlen(response));
+        printf("Result: %s\n", response);
+        int jret = Yodiwo_Plegma_NodePairing_PairingServerKeysResponse_FromJson(response, strlen(response), &keys);
+        if (jret == Yodiwo_JsonSuccessParse) {
+            ctx->nodeKey = keys.nodeKey;
+            ctx->secretKey = keys.secretKey;
+            return (void *)0;
+        } else {
+            printf("error parsing response");
+            return (void *)-2;
+        }
+    }
+    else
+    {
+        printf("Error HTTP Post return code = %d\n", ret);
+    }
+    return (void *)ret;
+    
+}
+
--- a/pairing_backend.cpp	Mon Sep 21 06:56:11 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,185 +0,0 @@
-#include "pairing_backend.h"
-#include "HTTPClient.h"
-#include "mbed.h"
-#include "rtos.h"
-#include "yodiwo_helpers.h"
-#include "jsmn.h"
-#include "config.h"
-
-HTTPClient http;
-char recvBuff[1024*20];
-int __get_tokens(pairing_context *ctx);
-int __get_keys(pairing_context *ctx);
-
-int do_on_thread(function_with_result func, void *args, unsigned int stack_size);
-void __thread_wrapper(void const *arg);
-
-#define PAGE_SERVER_PHASE2 "userconfirm"
-
-int pairing_context_init_with_defaults(pairing_context *ctx, onPaired_callback callback)
-{
-    ctx->postUrl = "http://10.30.254.199:3334/pairing/";
-    ctx->uuid = "1337CNode";
-    ctx->name = "Nodas";
-    ctx->onPaired = callback;
-    return 0;
-}
-
-extern Yodiwo_Tools_APIGenerator_CNodeConfig_t *activeConfig;
-
-int pairing_context_init_from_config(pairing_context *ctx, onPaired_callback callback)
-{
-    printf("server url: %s\n", activeConfig->PairingServerUrl);
-    printf("uuid: %s\n", activeConfig->Uuid);
-    printf("name: %s\n", activeConfig->Name);
-    ctx->postUrl = activeConfig->PairingServerUrl;
-    ctx->uuid = activeConfig->Uuid;
-    ctx->name = activeConfig->Name;
-    ctx->onPaired = callback;
-    return 0;    
-}
-
-#define STACK_SIZE 24000
-
-
-int pairing_get_tokens(pairing_context *ctx)
-{
-    printf("getting tokens from server\n");
-    return do_on_thread((function_with_result)__get_tokens, ctx, STACK_SIZE);
-}
-
-char* get_server_phase2_url(pairing_context *ctx, char *nodeUrlBase)
-{
-        int len = 200; //TODO: proper calculation
-        char* result = (char *)malloc(sizeof(char) * len);
-        if (!result)
-            return NULL;
-        sprintf(result, "%s" "1/" PAGE_SERVER_PHASE2 "?token2=%s&noderedirect=%snext", ctx->postUrl, ctx->token2, nodeUrlBase);
-        return result;        
-}
-
-int pairing_get_keys(pairing_context *ctx)
-{
-    printf("getting keys from server\n");
-    return do_on_thread((function_with_result)__get_keys, ctx, STACK_SIZE);
-}
-
-char str[512];
-char url[100];
-
-struct thread_info
-{
-    function_with_result func;
-    void * args;
-    int result;
-};
-
-void __thread_wrapper(void const *arg)
-{
-    struct thread_info *info = (struct thread_info *)arg;
-    info->result = info->func(info->args);
-}
-
-int do_on_thread(function_with_result func, void *args, unsigned int stack_size)
-{
-    struct thread_info info;
-    info.func = func;
-    info.args = args;
-    Thread t(__thread_wrapper, &info, osPriorityNormal, stack_size);
-    while (t.get_state() != Thread::Inactive) {
-//        printf("yielding... %d\n", t.get_state());
-//        Thread::yield();
-//        Thread::wait(1000);
-    }
-    return info.result;    
-}
-    
-int __get_tokens(pairing_context *ctx)
-{
-    strcpy(url, ctx->postUrl);
-    strcat(url, "/1/gettokensreq");
-    http.dumpReqHeader(true);
-    http.dumpResHeader(true);
-    int ret;
-    
-    //GET data
-//    printf("\nTrying to fetch page...\n");
-//    ret = http.get("http://mbed.org/media/uploads/donatien/hello.txt", str, 128);
-//    if (!ret)
-//    {
-//      printf("Page fetched successfully - read %d characters\n", strlen(str));
-//      printf("Result: %s\n", str);
-//    }
-//    else
-//    {
-//      printf("Error - ret = %d - HTTP return code = %d\n", ret, http.getHTTPResponseCode());
-//    }    
-        
-    //POST data
-    HTTPMap map;
-    HTTPText inText(str, 512);
-    map.put("name", ctx->name);
-    map.put("uuid", ctx->uuid);
-    printf("\nTrying to post data...\n");
-    ret = http.post(url, map, &inText);
-    Yodiwo_Plegma_NodePairing_PairingServerTokensResponse_t tokens;
-    if (!ret)
-    {
-        printf("Executed POST successfully - read %d characters\n", strlen(str));
-        printf("Result: %s\n", str);
-        int jret = Yodiwo_Plegma_NodePairing_PairingServerTokensResponse_FromJson(str, strlen(str), &tokens);
-        if (jret == Yodiwo_JsonSuccessParse) {
-            ctx->token1 = tokens.token1;
-            ctx->token2 = tokens.token2;
-            return 0;
-        } else {
-            printf("error parsing response");
-            return -2;
-        }
-    }
-    else
-    {
-      printf("Error - ret = %d - HTTP return code = %d\n", ret, http.getHTTPResponseCode());
-    }
-    return ret;
-    
-}
-
-
-int __get_keys(pairing_context *ctx)
-{
-    strcpy(url, ctx->postUrl);
-    strcat(url, "/1/getkeysreq");
-    http.dumpReqHeader(true);
-    http.dumpResHeader(true);
-    int ret;
-
-    //POST data
-    HTTPMap map;
-    HTTPText inText(str, 512);
-    map.put("uuid", ctx->uuid);
-    map.put("token1", ctx->token1);
-    printf("\nTrying to post data...\n");
-    ret = http.post(url, map, &inText);
-    Yodiwo_Plegma_NodePairing_PairingServerKeysResponse_t keys;
-    if (!ret)
-    {
-        printf("Executed POST successfully - read %d characters\n", strlen(str));
-        printf("Result: %s\n", str);
-        int jret = Yodiwo_Plegma_NodePairing_PairingServerKeysResponse_FromJson(str, strlen(str), &keys);
-        if (jret == Yodiwo_JsonSuccessParse) {
-            ctx->nodeKey = keys.nodeKey;
-            ctx->secretKey = keys.secretKey;
-            return 0;
-        } else {
-            printf("error parsing response");
-            return -2;
-        }
-    }
-    else
-    {
-      printf("Error - ret = %d - HTTP return code = %d\n", ret, http.getHTTPResponseCode());
-    }
-    return ret;
-    
-}
--- a/pairing_backend.h	Mon Sep 21 06:56:11 2015 +0000
+++ b/pairing_backend.h	Mon Sep 28 08:55:29 2015 +0000
@@ -38,10 +38,11 @@
 int pairing_get_tokens(pairing_context *ctx);
 int pairing_get_keys(pairing_context *ctx);
 
-char* get_server_phase2_url(pairing_context *ctx, char *nodeUrlBase);
+char* get_server_phase2_url(pairing_context *ctx, char *hostname, int port, char *urlBase);
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* __PAIRING_BACKEND_H__ */
\ No newline at end of file
+#endif /* __PAIRING_BACKEND_H__ */
+
--- a/pairing_http_handler.cpp	Mon Sep 21 06:56:11 2015 +0000
+++ b/pairing_http_handler.cpp	Mon Sep 28 08:55:29 2015 +0000
@@ -9,11 +9,16 @@
 onPaired_callback pairing_done_cb;
 EthernetInterface *interface;
 void pairing_handler (int id);
+int server_port; //TODO: get this from HTTPD?
 
-int start_pairing_http_server(EthernetInterface *eth, int port, onPaired_callback onPaired)
+
+int startpairing(int id);
+int next(int id);
+
+int start_pairing_http_server(void *ifdata, int port, onPaired_callback onPaired)
 {
+    interface = (EthernetInterface *)ifdata;
     pairing_done_cb = onPaired;
-    interface = eth;
     httpd = new HTTPD;
 //    httpd->attach("/cgi-bin/", &callback_cgi);
 //    httpd->attach("/ws/", &callback_ws);
@@ -24,56 +29,60 @@
 
 void pairing_handler (int id)
 {
-    int i, n;
-    int ret;
-    char buf[256];
-    char backUrl[100];
-    
     if (!strcmp(httpd->getFilename(id), "startpairing")) {
-        printf("starting pairing...\n");
-        pairing_context_init_from_config(&pairing_state, pairing_done_cb);
-        pairing_get_tokens(&pairing_state);
-        
-        int idx = 0;
-        i = 0;
-        sprintf(backUrl, "http://%s", interface->getIPAddress());
-        char *uri = httpd->getUri(id);
-        printf("1st url part: %s\n",backUrl);
-        while (uri[i] != '\0') {
-            if (uri[i] == '/') {
-                idx = i;
-            }
-            i++;
+        if (!startpairing(id)) {
+            return;
         }
-        strncat(backUrl, uri, idx + 1);
-        printf("more of url: %s\n", backUrl);
-        char *redirect = get_server_phase2_url(&pairing_state, backUrl);
-        printf("redirect url: %s\n", redirect);
-        if (redirect) {
-            httpd->redirect(id, 302, redirect, NULL, 0, NULL);
-//            free(redirect);
+    } else if (!strcmp(httpd->getFilename(id), "next")) {
+        if (!next(id)) {
             return;
         }
 
-    } else if (!strcmp(httpd->getFilename(id), "next")) {
-        ret = pairing_get_keys(&pairing_state);
-        pairing_done_cb(pairing_state.nodeKey, pairing_state.secretKey);
-        sprintf(buf, "OK\r\nnodeKey: %s\r\nsecretKey: %s\r\n", pairing_state.nodeKey, pairing_state.secretKey);
-        httpd->send(id, buf, strlen(buf), "Content-Type: text/plain\r\n");
     } else {
         httpd->httpdError(id, 404);
     }
-    strcpy(buf, httpd->getFilename(id));
-    strcat(buf, "\r\n");
-    strcat(buf, httpd->getQueryString(id));
-    strcat(buf, "\r\n");
-    n = strlen(buf);
- 
-    i = httpd->receive(id, &buf[n], sizeof(buf) - n);
-    if (i < 0) return;
-    i += n;
-    buf[i] = 0;
- 
-    printf("CGI %d %s\r\n", id, buf);
-//    httpd->send(id, buf, i, "Content-Type: text/plain\r\n");
-}
\ No newline at end of file
+    httpd->httpdError(id, 400);
+}
+
+int startpairing(int id)
+{
+    char urlBase[100];
+    int i;
+    printf("starting pairing...\n");
+    pairing_context_init_from_config(&pairing_state, pairing_done_cb);
+    pairing_get_tokens(&pairing_state);
+    
+    int idx = 0;
+    i = 0;
+    char *uri = httpd->getUri(id);
+    while (uri[i] != '\0') {
+        if (uri[i] == '/') {
+            idx = i;
+        }
+        i++;
+    }
+    urlBase[0] = '\0';
+    strncat(urlBase, uri, idx + 1);
+    char *redirect = get_server_phase2_url(&pairing_state, interface->getIPAddress(), server_port, urlBase);
+    printf("redirect url: %s\n", redirect);
+    if (redirect) {
+        httpd->redirect(id, 302, redirect, NULL, 0, NULL);
+        free(redirect);
+        return 0;
+    }
+    return -1;
+}
+
+int next(int id)
+{
+    char buf[300];
+    int ret;
+    ret = pairing_get_keys(&pairing_state);
+    if (ret) {
+        return ret;
+    }
+    pairing_done_cb(pairing_state.nodeKey, pairing_state.secretKey);
+    sprintf(buf, "OK\r\nnodeKey: %s\r\nsecretKey: %s\r\n", pairing_state.nodeKey, pairing_state.secretKey);
+    httpd->send(id, buf, strlen(buf), "Content-Type: text/plain\r\n");
+    return 0;
+}
--- a/pairing_http_handler.h	Mon Sep 21 06:56:11 2015 +0000
+++ b/pairing_http_handler.h	Mon Sep 28 08:55:29 2015 +0000
@@ -8,7 +8,7 @@
 
 #include "pairing_backend.h"
 
-int start_pairing_http_server(EthernetInterface *eth, int port, onPaired_callback onPaired);
+int start_pairing_http_server(void *ifdata, int port, onPaired_callback onPaired);
 
 void pairing_handler(int id);
 
@@ -17,4 +17,4 @@
 }
 #endif
 
-#endif /* __PAIRING_HTTP_HANDLER_H__ */
\ No newline at end of file
+#endif /* __PAIRING_HTTP_HANDLER_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/system.h	Mon Sep 28 08:55:29 2015 +0000
@@ -0,0 +1,52 @@
+#ifndef SYSTEM_H_
+#define SYSTEM_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void * (*thread_func)(void *);
+
+
+#ifdef linux
+
+#include <pthread.h>
+typedef pthread_t thread_t;
+
+#elif defined(__MBED__)
+
+
+//
+//#ifdef __cplusplus
+//#include "rtos.h"
+//#else
+//struct Thread;
+//#endif
+//
+////#include "mbed.h"
+////struct thread_s;
+typedef struct thread_info_s* thread_t;
+#endif
+
+
+/*
+ * These functions must be implemented for the node platform
+ * for linux, thread_* functions are wrappers for pthead functions
+ * and http_post uses curl to do an http post and return the response code and body to the caller
+ * implementation is in system_linux.c
+ */
+
+int thread_run(thread_t *ctx, thread_func func, void * args, int priority, int stack_size);
+void thread_wait(int ms);
+void *thread_join(thread_t *ctx);
+
+int http_post(char *url, char *post_fields, char *response, size_t max_size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SYSTEM_H_ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/system_mbed.cpp	Mon Sep 28 08:55:29 2015 +0000
@@ -0,0 +1,84 @@
+#include <string.h>
+#include <stdlib.h>
+#include "rtos.h"
+#include "HTTPClient.h"
+
+#include "system.h"
+#include "yodiwo_api.h"
+
+
+
+
+typedef void * (*thread_func)(void *);
+
+typedef struct thread_info_s
+{
+    Thread *t;
+    thread_func func;
+    void *args;
+    void *result;
+} thread_info;
+
+void __thread_wrapper(void const *args);
+
+HTTPClient http;
+
+int thread_run(thread_t *ctx, thread_func func, void * args, int priority, int stack_size)
+{
+    thread_info *info = (thread_info *)malloc(sizeof(thread_info));
+    if (info == NULL) {
+        return -1;
+    }    
+    *ctx = info;
+    info->func = func;
+    info->args = args;
+    info->result = NULL;
+
+    if (stack_size) {
+        (*ctx)->t = new Thread(__thread_wrapper, *ctx, (osPriority)priority, stack_size);
+    } else {
+        (*ctx)->t = new Thread(__thread_wrapper, *ctx, (osPriority)priority);
+    }
+    return 0;
+}
+
+void __thread_wrapper(void const *args)
+{
+    thread_info *info = (thread_info *)args;
+    info->result = info->func(info->args);
+    return;
+}
+
+void thread_wait(int ms)
+{
+    Thread::wait(ms);
+}
+
+void *thread_join(thread_t *ctx)
+{
+    while ((*ctx)->t->get_state() != Thread::Inactive) {
+//        printf("yielding... %d\n", t.get_state());
+//        Thread::yield();
+//        Thread::wait(1000);
+    }
+    return (*ctx)->result;
+}
+
+int http_post(char *url, char *post_fields, char *response, size_t max_size)
+{
+    http.dumpReqHeader(true);
+    http.dumpResHeader(true);
+    int ret;
+        //POST data
+    HTTPText params(post_fields, strlen(post_fields) + 1);
+    params.setDataType("application/x-www-form-urlencoded");
+    HTTPText inText(response, max_size);
+    printf("\nTrying to post data...\n");
+    printf("post url: %s\n", url);
+    ret = http.post(url, params, &inText);
+    if (!ret) {
+        ret = http.getHTTPResponseCode();
+    }
+    return ret;
+}
+
--- a/yodiwo.lib	Mon Sep 21 06:56:11 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-yodiwo#7358822a587a
--- a/yodiwo_functions.c	Mon Sep 21 06:56:11 2015 +0000
+++ b/yodiwo_functions.c	Mon Sep 28 08:55:29 2015 +0000
@@ -7,8 +7,7 @@
 
 #include "yodiwo_functions.h"
 #include "jsmn.h"
-#include "yodiwo_api.h"
-#include "yodiwo_extra.h"
+#include "yodiwo_helpers.h"
 
 #define MAX_TOPIC_LEN 100
 #define MAX_PORTEVENT_HANDLERS 5
@@ -164,10 +163,15 @@
     printf("fromjson: %d\n", r);
     if (r)
         goto exit;
+    printf("%p\n", &msg);
+    printf("%p\n", &msg.SeqNo);
+    printf("%p\n", &msg.Operation);
+    printf("%p\n", &msg.ThingKey);
+    printf("%p\n", &msg.Data);
     
     rsp.SeqNo = msg.SeqNo;
     rsp.Operation = msg.Operation;
-    printf("thingsrep operation: %d\n", msg.Operation);
+    printf("thingsreq operation: %d\n", msg.Operation);
     if (msg.Operation == Yodiwo_eThingsOperation_Get) {
         rsp.Data = *array_things;
         rsp.Status = 1;
@@ -194,48 +198,6 @@
     return r;
 }
 
-//int handle_thingsreq2(char *json, size_t len)
-//{
-//    int r;
-//    Yodiwo_Plegma_ThingsReq_t msg;
-//    Yodiwo_Plegma_ThingsRsp_t rsp;
-//    char *sendbuf = NULL;
-//    r = Yodiwo_Plegma_ThingsReq_FromJson(json, len, &msg);
-//    printf("thingsreq json: %s\n", json);
-//    printf("fromjson: %d\n", r);
-//    if (r)
-//        goto exit;
-//    
-//    rsp.SeqNo = msg.SeqNo;
-//    rsp.Operation = msg.Operation;
-//    printf("thingsrep operation: %d\n", msg.Operation);
-//    if (msg.Operation == Yodiwo_eThingsOperation_Get) {
-//        rsp.Data.num = 0;
-//        rsp.Data.elems = 0;
-//        rsp.Status = 1;
-//    } else {
-//        rsp.Data.num = 0;
-//        rsp.Data.elems = NULL;
-//        rsp.Status = 0;
-//    }
-//    
-//    sendbuf = (char *)malloc(1200 * sizeof(char));
-//    if (sendbuf == NULL) {
-//        r = -ENOMEM;
-//        goto exit;
-//    }
-//    r = Yodiwo_Plegma_ThingsRsp_ToJson(sendbuf, 1200, &rsp);
-//    printf("thingsrsp json: %s\n", sendbuf);
-//    printf("tojson: %d\n", r);    
-//    if (r < 0)
-//        goto exit;
-//    r = publish_helper(sendbuf, r, "thingsrsp", msg.SeqNo);
-//exit:
-//    free(sendbuf);
-//    //free thingsreq internals
-//    return r;
-//}
-
 int portevents(Array_Yodiwo_Plegma_PortEvent_t *events)
 {
     Yodiwo_Plegma_PortEventMsg_t msg;
@@ -317,3 +279,4 @@
     //TODO: free msg internals
     return r;
 }
+
--- a/yodiwo_functions.h	Mon Sep 21 06:56:11 2015 +0000
+++ b/yodiwo_functions.h	Mon Sep 28 08:55:29 2015 +0000
@@ -36,3 +36,4 @@
 #endif
 
 #endif /* __YODIWO_FUNCTIONS_H__ */
+