watch using the RSSI of Bluetooth
Dependencies: BaseUsbHost ConfigFile EthernetInterface HTTPClient-long mbed-rtos mbed
Revision 0:600fe65e7c88, committed 2013-01-20
- Comitter:
- va009039
- Date:
- Sun Jan 20 09:22:31 2013 +0000
- Commit message:
- first commit
Changed in this revision
diff -r 000000000000 -r 600fe65e7c88 BaseUsbHost.lib --- /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
diff -r 000000000000 -r 600fe65e7c88 ConfigFile.lib --- /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
diff -r 000000000000 -r 600fe65e7c88 CosmClient/CosmClient.cpp --- /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; +}
diff -r 000000000000 -r 600fe65e7c88 CosmClient/CosmClient.h --- /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
diff -r 000000000000 -r 600fe65e7c88 EthernetInterface.lib --- /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
diff -r 000000000000 -r 600fe65e7c88 HTTPClient-long.lib --- /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
diff -r 000000000000 -r 600fe65e7c88 MyThread/MyThread.h --- /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
diff -r 000000000000 -r 600fe65e7c88 UsbBt2/UsbBt2.cpp --- /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; +}
diff -r 000000000000 -r 600fe65e7c88 UsbBt2/UsbBt2.h --- /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
diff -r 000000000000 -r 600fe65e7c88 main.cpp --- /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); + } +}
diff -r 000000000000 -r 600fe65e7c88 mbed-rtos.lib --- /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
diff -r 000000000000 -r 600fe65e7c88 mbed.bld --- /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