watch using the RSSI of Bluetooth

Dependencies:   BaseUsbHost ConfigFile EthernetInterface HTTPClient-long mbed-rtos mbed

Files at this revision

API Documentation at this revision

Comitter:
va009039
Date:
Sun Jan 20 09:22:31 2013 +0000
Commit message:
first commit

Changed in this revision

BaseUsbHost.lib Show annotated file Show diff for this revision Revisions of this file
ConfigFile.lib Show annotated file Show diff for this revision Revisions of this file
CosmClient/CosmClient.cpp Show annotated file Show diff for this revision Revisions of this file
CosmClient/CosmClient.h Show annotated file Show diff for this revision Revisions of this file
EthernetInterface.lib Show annotated file Show diff for this revision Revisions of this file
HTTPClient-long.lib Show annotated file Show diff for this revision Revisions of this file
MyThread/MyThread.h Show annotated file Show diff for this revision Revisions of this file
UsbBt2/UsbBt2.cpp Show annotated file Show diff for this revision Revisions of this file
UsbBt2/UsbBt2.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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BaseUsbHost.lib	Sun Jan 20 09:22:31 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/va009039/code/BaseUsbHost/#ae77d63a1eda
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ConfigFile.lib	Sun Jan 20 09:22:31 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/shintamainjp/code/ConfigFile/#f6ceafabe9f8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CosmClient/CosmClient.cpp	Sun Jan 20 09:22:31 2013 +0000
@@ -0,0 +1,51 @@
+#include "CosmClient.h"
+
+CosmClient::CosmClient(const char* apiKey, const char* feedID)
+{
+    if (apiKey) {
+        m_apiKey = apiKey;
+    }
+    if (feedID) {
+        m_feedID = feedID;
+    }
+}
+
+void CosmClient::clear()
+{
+    m_buf.clear();
+}
+
+void CosmClient::add(const char* id, int value, const char* format)
+{
+    char buf[16];
+    snprintf(buf, sizeof(buf), format, value);
+    m_buf += string(id) + "," + buf + "\n";
+}
+
+void CosmClient::add(const char* id, float value, const char* format)
+{
+    char buf[16];
+    snprintf(buf, sizeof(buf), format, value);
+    m_buf += string(id) + "," + buf + "\n";
+}
+
+void CosmClient::add(int id, float value, const char* format)
+{
+    char buf[16];
+    snprintf(buf, sizeof(buf), "%d", id);
+    m_buf += buf;
+    snprintf(buf, sizeof(buf), format, value);
+    m_buf += string(",") + buf + "\n";
+}
+
+int CosmClient::update()
+{
+    HTTPClient http;
+    char str[16];
+    HTTPText inText(str, sizeof(str));
+    HTTPText outText(const_cast<char*>(m_buf.c_str()));
+    string url = "http://api.cosm.com/v2/feeds/" + m_feedID + ".csv?key=" + m_apiKey;
+    //string url = "http://api.cosm.com/v2/feeds/" + m_feedID + "?_method=put&key=" + m_apiKey;
+    int ret = http.put(url.c_str(), outText, &inText);
+    return ret;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CosmClient/CosmClient.h	Sun Jan 20 09:22:31 2013 +0000
@@ -0,0 +1,27 @@
+#ifndef COSM_CLIENT_H
+#define COSM_CLIENT_H
+#include "HTTPClient.h"
+#include <string>
+
+class CosmClient {
+public:
+    CosmClient(const char* apiKey = NULL, const char* feedID = NULL);
+    void setApikey(const char* apiKey) {
+        m_apiKey = apiKey;
+    }
+    void setFeedID(const char* feedID) {
+        m_feedID = feedID;
+    }
+    void putCsv(const char* feedID, ...);
+    void clear();
+    void add(const char* id, int value, const char* format="%d");
+    void add(const char* id, float value, const char* format="%f");
+    void add(int id, float value, const char* format="%f");
+    int update();
+private:
+    string m_buf;
+    string m_apiKey;
+    string m_feedID;
+};
+
+#endif //COSM_CLIENT_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EthernetInterface.lib	Sun Jan 20 09:22:31 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/EthernetInterface/#a0ee3ae75cfa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPClient-long.lib	Sun Jan 20 09:22:31 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/liviur2/code/HTTPClient-long/#4618a8948808
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MyThread/MyThread.h	Sun Jan 20 09:22:31 2013 +0000
@@ -0,0 +1,52 @@
+// MyThread.h 2012/12/16
+#ifndef MY_THREAD_H
+#define MY_THREAD_H
+
+#define MAGIC_WORD 0xE25A2EA5
+static void thread_handler(void const *argument);
+
+class MyThread {
+public:
+    MyThread() {
+        m_stack_size = DEFAULT_STACK_SIZE;
+        m_stack_pointer = NULL;
+    }
+    virtual void run() = 0;
+    void set_stack(uint32_t stack_size=DEFAULT_STACK_SIZE, uint8_t* stack_pointer = NULL) {
+        m_stack_size = stack_size;
+        m_stack_pointer = stack_pointer;
+    }
+    Thread* start(osPriority priority=osPriorityNormal) {
+        if (m_stack_pointer == NULL) {
+            m_stack_pointer = reinterpret_cast<uint8_t*>(malloc(m_stack_size));
+        }
+        for(int i = 0; i < m_stack_size-64; i += 4) {
+            *reinterpret_cast<uint32_t*>(m_stack_pointer+i) = MAGIC_WORD;
+        }
+        return th = new Thread(thread_handler, this, priority, m_stack_size, m_stack_pointer);
+    }
+
+    int stack_used() {
+        int i;
+        for(i = 0; i < m_stack_size; i += 4) {
+            if(*reinterpret_cast<uint32_t*>(m_stack_pointer+i) != MAGIC_WORD) {
+                break;
+            }
+        }
+        return m_stack_size - i;       
+    }
+
+    int stack_size() { return m_stack_size; }
+private:
+    Thread* th;
+    uint32_t m_stack_size;
+    uint8_t* m_stack_pointer;
+};
+static void thread_handler(void const *argument) {
+    MyThread* th = (MyThread*)argument;
+    if (th) {
+        th->run();
+    }    
+}
+
+#endif //MY_THREAD_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UsbBt2/UsbBt2.cpp	Sun Jan 20 09:22:31 2013 +0000
@@ -0,0 +1,219 @@
+// UsbBt2.cpp 2012/12/18
+#include "mbed.h"
+#include "rtos.h"
+#include "BaseUsbHost.h"
+#define DEBUG
+#include "BaseUsbHostDebug.h"
+#define TEST
+#include "BaseUsbHostTest.h"
+#include "UsbBt2.h"
+
+static int LE16(const uint8_t* d)
+{
+    return d[0] | (d[1] << 8);
+}
+
+bthci::bthci(ControlEp* ctlEp):m_pEpIntIn(NULL),m_pEpBulkIn(NULL),m_pEpBulkOut(NULL)
+{
+    if (ctlEp == NULL) { // root hub
+        DBG_OHCI(LPC_USB->HcRhPortStatus1);
+        TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200);
+        ctlEp = new ControlEp();
+        TEST_ASSERT_TRUE(ctlEp);
+    }
+    m_ctlEp = ctlEp;
+    bool r = check(ctlEp);
+    TEST_ASSERT(r);
+    ParseConfiguration(ctlEp);
+    int rc = ctlEp->SetConfiguration(1);
+    TEST_ASSERT_EQUAL(rc, USB_OK);
+}
+
+bool bthci::check(ControlEp* ctlEp)
+{
+    if (ctlEp == NULL) {
+        return false;
+    }
+    uint8_t buf[18];
+    int r = ctlEp->GetDescriptor(1, 0, buf, 8);
+    if (r != USB_OK) {
+        return false;
+    }
+    DBG_HEX(buf, 8);
+    r = ctlEp->GetDescriptor(1, 0, buf, 18);
+    if (r != USB_OK) {
+        return false;
+    }
+    DBG_HEX(buf, 18);
+    uint16_t vid = *reinterpret_cast<uint16_t*>(buf+8);
+    uint16_t pid = *reinterpret_cast<uint16_t*>(buf+10);
+    DBG("VID PID: %04X %04X\n", vid, pid);
+    if (buf[4] == 0xe0 && buf[5] == 0x01 && buf[6] == 0x01) {
+        return true;
+    }
+    return false;
+}
+
+int bthci::cmdSend(uint16_t op)
+{
+   return cmdSend(op, NULL, 0);
+}
+
+int bthci::cmdSend(uint16_t op, const uint8_t* data, int size)
+{
+    uint8_t* buf = new uint8_t[size+3];
+    TEST_ASSERT(buf);
+    if (buf == NULL) {
+        return USB_ERROR;
+    }
+    buf[0] = op;
+    buf[1] = op>>8;
+    buf[2] = size;
+    if (data) {
+        memcpy(buf+3, data, size);
+    }
+    int rc = m_ctlEp->controlSend(USB_REQUEST_TYPE_CLASS, 0, 0, 0, buf, size+3);
+    TEST_ASSERT(rc == USB_OK);
+    delete[] buf;
+    return rc;
+}
+
+int bthci::cmdSend(uint16_t op, const char* fmt, ...) 
+{   
+    va_list vl;
+    va_start(vl, fmt);
+    uint8_t* buf = new uint8_t[255];
+    TEST_ASSERT(buf);
+    if (buf == NULL) {
+        return USB_ERROR;
+    }
+    buf[0] = op;
+    buf[1] = op>>8;
+    int pos = 3;
+    char* name;
+    int name_len;
+    uint16_t h;
+    BD_ADDR* bdaddr;
+    for(int i = 0; fmt[i]; i++) {
+        switch(fmt[i]) {
+            case 's':
+                name = va_arg(vl, char*);
+                name_len = strlen(name)+1;
+                memcpy(buf+pos, name, name_len);
+                pos += name_len;
+                break;
+            case 'B':
+                buf[pos++] = va_arg(vl, int);
+                break;
+            case 'H':
+                h = va_arg(vl, int);
+                buf[pos++] = h;
+                buf[pos++] = h>>8;
+                break;
+            case 'A':
+                bdaddr = va_arg(vl, BD_ADDR*);
+                memcpy(buf+pos, bdaddr, 6);
+                pos += 6;
+                break;
+            default:
+                DBG("op=%04X fmt=%s i=%d", op, fmt, i);
+                TEST_ASSERT(0);
+                //break;
+        }
+    }
+    buf[2] = pos-3;
+    int rc = m_ctlEp->controlSend(USB_REQUEST_TYPE_CLASS, 0, 0, 0, buf, pos);
+    TEST_ASSERT(rc == USB_OK);
+    delete[] buf;
+    return rc;
+}
+
+int bthci::eventReceive(uint8_t* buf, int size, int millisec)
+{
+    //DBG("%p buf=%p size=%d millisec=%d\n", this, buf, size, millisec);
+    TEST_ASSERT(m_pEpIntIn);
+    return m_pEpIntIn->interruptReceive(buf, size, millisec);
+}
+
+int bthci::AclSend(uint8_t* buf, int size, int millisec)
+{
+    TEST_ASSERT(m_pEpBulkOut);
+    return m_pEpBulkOut->bulkSend(buf, size, millisec);
+}
+
+int bthci::AclReceive(uint8_t* buf, int size, int millisec)
+{
+    TEST_ASSERT(m_pEpBulkIn);
+    return m_pEpBulkIn->bulkReceive(buf, size, millisec);
+}
+
+int bthci::ParseConfiguration(ControlEp* ctlEp)
+{
+    int rc;
+    uint8_t ConfigDesc[9];
+    int index = 0;
+    rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc));
+    TEST_ASSERT(rc == USB_OK);
+    DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc));
+    TEST_ASSERT(ConfigDesc[0] == 9);
+    TEST_ASSERT(ConfigDesc[1] == 0x02);
+    int wTotalLength = *((uint16_t*)&ConfigDesc[2]);
+    DBG("TotalLength: %d\n", wTotalLength);
+    int bConfigValue = ConfigDesc[5];
+    TEST_ASSERT(bConfigValue == 1);
+    DBG("ConfigValue: %d\n", bConfigValue);
+    VERBOSE("MaxPower: %d mA\n", ConfigDesc[8]*2);   
+
+    uint8_t* buf = new uint8_t[wTotalLength];
+    TEST_ASSERT(buf);
+    rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength);
+    TEST_ASSERT(rc == USB_OK);
+    TEST_ASSERT(ConfigDesc[1] == 0x02);
+    for (int pos = 0; pos < wTotalLength; pos += buf[pos]) {
+        DBG_BYTES("CFG", buf+pos, buf[pos]);
+        int type = buf[pos+1];
+        if (USB_DESCRIPTOR_TYPE_INTERFACE == type) { // 0x04
+            DBG("InterfaceNumber: %d\n", buf[pos+2]);
+            DBG("AlternateSetting: %d\n", buf[pos+3]);
+            DBG("NumEndpoint: %d\n", buf[pos+4]);
+            VERBOSE("InterfaceClass: %02X\n", buf[pos+5]);
+            VERBOSE("InterfaceSubClass: %02X\n", buf[pos+6]);
+            VERBOSE("InterfaceProtocol: %02X\n", buf[pos+7]);
+            TEST_ASSERT(buf[pos+6] == 0x01);
+            TEST_ASSERT(buf[pos+7] == 0x01);
+        } 
+        if (USB_DESCRIPTOR_TYPE_ENDPOINT == type) {
+            TEST_ASSERT(buf[pos] == 7);
+            uint8_t att = buf[pos+3];
+            uint8_t ep = buf[pos+2];
+            uint16_t size = LE16(buf+pos+4);
+            DBG("EndpointAddress: %02X\n", ep);
+            DBG("Attribute: %02X\n", att);
+            DBG("MaxPacketSize: %d\n", size);
+            int addr = ctlEp->GetAddr(); 
+            if (att == 3) { // interrupt
+                if (m_pEpIntIn == NULL) {
+                    m_pEpIntIn = new InterruptEp(addr, ep, size);
+                }
+            } else if (att == 2) { // bulk
+                if (ep & 0x80) { // IN
+                  if (m_pEpBulkIn == NULL) {
+                      m_pEpBulkIn = new BulkEp(addr, ep, size);
+                  }
+              } else { // OUT
+                  if (m_pEpBulkOut == NULL) {
+                      m_pEpBulkOut = new BulkEp(addr, ep, size);
+                  }
+              } 
+          }
+      }
+      if (m_pEpIntIn && m_pEpBulkIn && m_pEpBulkOut) { // cut off
+          break;
+      }
+  }
+  delete[] buf;
+  TEST_ASSERT(m_pEpIntIn);
+  TEST_ASSERT(m_pEpBulkIn);
+  TEST_ASSERT(m_pEpBulkOut);
+  return 0;   
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UsbBt2/UsbBt2.h	Sun Jan 20 09:22:31 2013 +0000
@@ -0,0 +1,106 @@
+// UsbBt2.cpp 2013/1/19
+#ifndef USB_BT2_H
+#define USB_BT2_H
+#include <stdarg.h>
+
+#define HCI_OP_INQUIRY               0x0401
+#define HCI_OP_INQUIRY_CANCEL        0x0402
+#define HCI_OP_PERIODIC_INQUIRY      0x0403
+#define HCI_OP_EXIT_PERIODIC_INQUIRY 0x0404
+#define HCI_OP_REMOTE_NAME_REQ       0x0419
+#define HCI_OP_RESET                 0x0c03
+#define HCI_OP_WRITE_LOCAL_NAME      0x0c13
+#define HCI_OP_WRITE_SCAN_ENABLE     0x0c1a
+#define HCI_OP_WRITE_CLASS_OF_DEV    0x0c24
+#define HCI_OP_WRITE_INQUIRY_MODE    0x0c45
+#define HCI_OP_READ_EXTENDED_INQUIRY_RESPONSE  0x0c51
+#define HCI_OP_WRITE_EXTENDED_INQUIRY_RESPONSE 0x0c52
+#define HCI_OP_READ_BD_ADDR          0x1009
+
+#define HCI_EV_INQUIRY_COMPLETE         0x01
+#define HCI_EV_INQUIRY_RESULT           0x02
+#define HCI_EV_REMOTE_NAME              0x07
+#define HCI_EV_CMD_COMPLETE             0x0e
+#define HCI_EV_CMD_STATUS               0x0f
+#define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22
+#define HCI_EV_EXTENDED_INQUIRY_RESULT  0x2f
+
+
+#define VERBOSE(...) do{printf(__VA_ARGS__);} while(0);
+
+#pragma push
+#pragma pack(1)
+struct BD_ADDR {
+    uint8_t addr[6];
+    void set(char* s) {
+        char* p = s;
+        for(int i = 5; i >= 0; i--) {
+            addr[i] =  strtol(p, &p, 16);
+            if (*p == ':') {
+                p++;
+            }
+        }
+    }
+    void str(char* buf, size_t size) {
+        snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X", addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
+    }
+};
+
+typedef struct {
+    BD_ADDR bdaddr;
+    uint8_t page_scan_repetition_mode;
+    uint8_t reserved[2];
+    uint8_t dev_class[3];
+    uint16_t clock_offset;
+} inquiry_info;
+
+typedef struct {
+    BD_ADDR bdaddr;
+    uint8_t page_scan_repetition_mode;
+    uint8_t reserved[1];
+    uint8_t class_of_device[3];
+    uint16_t clock_offset;
+    int8_t rssi;
+} inquiry_with_rssi_info;
+
+typedef struct {
+    BD_ADDR bdaddr;
+    uint8_t page_scan_repetition_mode;
+    uint8_t reserved[1];
+    uint8_t class_of_device[3];
+    uint16_t clock_offset;
+    int8_t rssi;
+    uint8_t extended_inquiry_response[240];
+} extended_inquiry_info;
+
+typedef struct {
+    uint8_t evt;
+    uint8_t len;
+    uint8_t status;
+    union {
+        uint16_t op;
+        uint8_t data[];
+    } c;
+} hci_event;
+#pragma pop
+
+class bthci {
+public:
+    bthci(ControlEp* ctlEp = NULL);
+    static bool check(ControlEp* ctlEp);
+    int cmdSend(uint16_t op);
+    int cmdSend(uint16_t op, const char* fmt, ...);
+    int cmdSend(uint16_t op, const uint8_t* data, int size);
+    int eventReceive(uint8_t* buf, int size, int millisec=osWaitForever);
+    int AclSend(uint8_t* buf, int size, int millisec=osWaitForever);
+    int AclReceive(uint8_t* buf, int size, int millisec=osWaitForever);
+private:
+    int ParseConfiguration(ControlEp* ctlEp);
+    ControlEp* m_ctlEp;
+    InterruptEp* m_pEpIntIn;
+    BulkEp* m_pEpBulkIn;
+    BulkEp* m_pEpBulkOut;
+    uint8_t m_buf[255];
+};
+
+#endif //USB_BT2_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Jan 20 09:22:31 2013 +0000
@@ -0,0 +1,142 @@
+#include "mbed.h"
+#include "EthernetInterface.h"
+#include "BaseUsbHost.h"
+//#define DEBUG
+#include "BaseUsbHostDebug.h"
+#define TEST
+#include "BaseUsbHostTest.h"
+#include "UsbBt2.h"
+#include "CosmClient.h"
+#include "MyThread.h"
+#include "ConfigFile.h"
+
+#define CFG_FILE "/local/mimamori.cfg"
+
+LocalFileSystem local("local");
+Serial pc(USBTX, USBRX);
+EthernetInterface eth;
+ConfigFile cfg;
+CosmClient client;
+
+BD_ADDR addr;
+#define RSSI_NONE (-129)
+int rssi = RSSI_NONE;
+
+class bt_client : public MyThread {
+public:
+    bt_client(bthci* hci):m_hci(hci) {
+    }
+private:
+    virtual void run() {
+        inquiry_with_rssi_info rssi_info;
+        hci_event* event;
+        int max_period_length = 25;
+        int min_period_length = 20;
+        int inquiry_length = 15;
+        int rc = m_hci->cmdSend(HCI_OP_RESET);
+        TEST_ASSERT(rc == USB_OK);
+        for(int n = 0; ; n++) {
+            int r = m_hci->eventReceive(m_buf_int, sizeof(m_buf_int));
+            if (r > 0) {
+                //DBG("%p eventReceive %d\n", this, r);
+                //DBG_HEX(m_buf_int, r);
+                event = reinterpret_cast<hci_event*>(m_buf_int);
+                switch(event->evt) {
+                    case HCI_EV_CMD_COMPLETE:
+                        DBG("\nHCI_EV_CMD_COMPLETE\n");
+                        switch(event->c.op) {
+                            case HCI_OP_RESET:
+                                rc = m_hci->cmdSend(HCI_OP_WRITE_INQUIRY_MODE, "B", 0x01); // with RSSI
+                                TEST_ASSERT(rc == USB_OK);
+                                break;
+                            case HCI_OP_WRITE_INQUIRY_MODE:
+                                rc = m_hci->cmdSend(HCI_OP_PERIODIC_INQUIRY, "HHBBBBB", 
+                                                    max_period_length, min_period_length, 0x33, 0x8B, 0x9E, inquiry_length, 0);
+                                TEST_ASSERT(rc == USB_OK);
+                                break;
+                            default:
+                                DBG_HEX(m_buf_int, r);
+                                break;
+                        }
+                        break;
+                    case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
+                        //DBG("\nHCI_EV_INQUIRY_RESULT_WITH_RSSI\n");
+                        rssi_info = *reinterpret_cast<inquiry_with_rssi_info*>(event->c.data);
+                        DBG_HEX((uint8_t*)&rssi_info, sizeof(inquiry_with_rssi_info));
+                        if (memcmp(&rssi_info.bdaddr, &addr, 6) == 0) {
+                            rssi = rssi_info.rssi;
+                            DBG("rssi=%d\n", rssi);
+                        }
+                        break;
+                    default:
+                        DBG_HEX(m_buf_int, r);
+                        break;
+                }
+            }
+        }
+    }
+    bthci* m_hci;
+    uint8_t m_buf_int[250];
+};
+
+void no_memory () {
+  error("Failed to allocate memory!\n");
+}
+
+int main() {
+    pc.baud(921600);
+    printf("%s\n", __FILE__);
+    set_new_handler(no_memory);
+    
+    if(!cfg.read(CFG_FILE)) {
+        error("can not read %s\n", CFG_FILE);
+    }
+    char buf[128];
+    if (!cfg.getValue("apikey", buf, sizeof(buf))) {
+        error("apikey?\n");
+    }
+    client.setApikey(buf);
+    if (!cfg.getValue("feedid", buf, sizeof(buf))) {
+        error("feedid?\n");
+    }
+    client.setFeedID(buf);
+
+    if (!cfg.getValue("bdaddr", buf, sizeof(buf))) {
+        error("bdaddr?\n");
+    }
+    addr.set(buf);
+
+    eth.init(); //Use DHCP
+    eth.connect();
+
+    BaseUsbHost* usbHost = new BaseUsbHost();
+    ControlEp* ctlEp = new ControlEp; // root hub
+    bthci* bt_dongle1 = NULL;
+    if (bthci::check(ctlEp)) {
+        bt_dongle1 = new bthci(ctlEp);
+    } else if (UsbHub::check(ctlEp)) {
+        UsbHub* hub = new UsbHub(ctlEp);
+        for(vector<ControlEp*>::iterator it = hub->PortEp.begin(); it != hub->PortEp.end(); ++it) {
+            if (bthci::check(*it)) {
+                bt_dongle1 = new bthci(*it);
+                break;
+            }
+        }
+    }
+    if (bt_dongle1 == NULL) {
+        error("USB Bluetooth not found\n");
+    }
+    bt_client* bt_th = new bt_client(bt_dongle1);
+    bt_th->set_stack(DEFAULT_STACK_SIZE);
+    bt_th->start();
+    for(int n = 0; ; n++) {
+        printf("%d Bluetooth rssi: %d stack used: %d/%d bytes\n", n, rssi, bt_th->stack_used(), bt_th->stack_size());
+
+        client.clear();
+        client.add("0", rssi);
+        client.update();
+        rssi = RSSI_NONE;
+    
+        Thread::wait(40*1000);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Sun Jan 20 09:22:31 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#88a1a9c26ae3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Jan 20 09:22:31 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/0480438fc29c
\ No newline at end of file