BTstack Bluetooth stack

Dependencies:   mbed USBHost

USBホストライブラリを変更しました。

  • Bluetoothマウス(VGP-BMS33)での動作を確認しました。mouse_demo.cpp
Committer:
va009039
Date:
Fri Mar 22 22:35:57 2013 +0000
Revision:
2:871b41f4789e
Parent:
1:b657594559be
change to single thread

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 2:871b41f4789e 1 // USBHostBTstack.cpp
va009039 1:b657594559be 2 #include "USBHostBTstack.h"
va009039 1:b657594559be 3 #include "dbg.h"
va009039 1:b657594559be 4
va009039 2:871b41f4789e 5 //#define BTSTACK_DEBUG
va009039 1:b657594559be 6
va009039 1:b657594559be 7 #ifdef BTSTACK_DEBUG
va009039 1:b657594559be 8 #define BT_DBG(x, ...) std::printf("[%s:%d]"x"\r\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
va009039 2:871b41f4789e 9 #define BT_DBG_BYTES(STR,BUF,LEN) _debug_bytes(__PRETTY_FUNCTION__,__LINE__,STR,BUF,LEN)
va009039 1:b657594559be 10 #else
va009039 1:b657594559be 11 #define BT_DBG(...) while(0);
va009039 2:871b41f4789e 12 #define BT_DBG_BYTES(S,BUF,LEN) while(0);
va009039 1:b657594559be 13 #endif
va009039 1:b657594559be 14
va009039 1:b657594559be 15 #define HCI_COMMAND_DATA_PACKET 0x01
va009039 1:b657594559be 16 #define HCI_ACL_DATA_PACKET 0x02
va009039 1:b657594559be 17 #define HCI_SCO_DATA_PACKET 0x03
va009039 1:b657594559be 18 #define HCI_EVENT_PACKET 0x04
va009039 1:b657594559be 19
va009039 1:b657594559be 20 USBHostBTstack::USBHostBTstack()
va009039 1:b657594559be 21 {
va009039 1:b657594559be 22 host = USBHost::getHostInst();
va009039 1:b657594559be 23 init();
va009039 1:b657594559be 24 m_pCb = NULL;
va009039 1:b657594559be 25 }
va009039 1:b657594559be 26
va009039 1:b657594559be 27 void USBHostBTstack::init()
va009039 1:b657594559be 28 {
va009039 1:b657594559be 29 BT_DBG("");
va009039 1:b657594559be 30 dev = NULL;
va009039 1:b657594559be 31 int_in = NULL;
va009039 1:b657594559be 32 bulk_in = NULL;
va009039 1:b657594559be 33 bulk_out = NULL;
va009039 1:b657594559be 34 btstack_intf = -1;
va009039 1:b657594559be 35 btstack_device_found = false;
va009039 1:b657594559be 36 dev_connected = false;
va009039 1:b657594559be 37 ep_int_in = false;
va009039 1:b657594559be 38 ep_bulk_in = false;
va009039 1:b657594559be 39 ep_bulk_out = false;
va009039 1:b657594559be 40 }
va009039 1:b657594559be 41
va009039 1:b657594559be 42 bool USBHostBTstack::connected()
va009039 1:b657594559be 43 {
va009039 1:b657594559be 44 return dev_connected;
va009039 1:b657594559be 45 }
va009039 1:b657594559be 46
va009039 1:b657594559be 47 bool USBHostBTstack::connect()
va009039 1:b657594559be 48 {
va009039 1:b657594559be 49 if (dev_connected) {
va009039 1:b657594559be 50 return true;
va009039 1:b657594559be 51 }
va009039 1:b657594559be 52
va009039 1:b657594559be 53 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
va009039 1:b657594559be 54 if ((dev = host->getDevice(i)) != NULL) {
va009039 1:b657594559be 55
va009039 1:b657594559be 56 BT_DBG("Trying to connect BTstack device\r\n");
va009039 1:b657594559be 57
va009039 1:b657594559be 58 if(host->enumerate(dev, this)) {
va009039 1:b657594559be 59 break;
va009039 1:b657594559be 60 }
va009039 1:b657594559be 61 if (btstack_device_found) {
va009039 1:b657594559be 62 int_in = dev->getEndpoint(btstack_intf, INTERRUPT_ENDPOINT, IN);
va009039 1:b657594559be 63 bulk_in = dev->getEndpoint(btstack_intf, BULK_ENDPOINT, IN);
va009039 1:b657594559be 64 bulk_out = dev->getEndpoint(btstack_intf, BULK_ENDPOINT, OUT);
va009039 1:b657594559be 65 if (!int_in || !bulk_in || !bulk_out) {
va009039 1:b657594559be 66 continue;
va009039 1:b657594559be 67 }
va009039 1:b657594559be 68 USB_INFO("New BTstack device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, btstack_intf);
va009039 1:b657594559be 69 dev->setName("BTstack", btstack_intf);
va009039 1:b657594559be 70 host->registerDriver(dev, btstack_intf, this, &USBHostBTstack::init);
va009039 1:b657594559be 71
va009039 1:b657594559be 72 int_in->attach(this, &USBHostBTstack::int_rxHandler);
va009039 1:b657594559be 73 host->interruptRead(dev, int_in, int_report, int_in->getSize(), false);
va009039 1:b657594559be 74
va009039 1:b657594559be 75 bulk_in->attach(this, &USBHostBTstack::bulk_rxHandler);
va009039 1:b657594559be 76 host->bulkRead(dev, bulk_in, bulk_report, bulk_in->getSize(), false);
va009039 1:b657594559be 77
va009039 1:b657594559be 78 dev_connected = true;
va009039 1:b657594559be 79 return true;
va009039 1:b657594559be 80 }
va009039 1:b657594559be 81 }
va009039 1:b657594559be 82 }
va009039 1:b657594559be 83 init();
va009039 1:b657594559be 84 return false;
va009039 1:b657594559be 85 }
va009039 1:b657594559be 86
va009039 2:871b41f4789e 87 void USBHostBTstack::int_rxHandler()
va009039 2:871b41f4789e 88 {
va009039 1:b657594559be 89 int len = int_in->getLengthTransferred();
va009039 2:871b41f4789e 90 BT_DBG_BYTES("HCI_EVT:", int_report, len);
va009039 2:871b41f4789e 91 Packet* pkt = mail_box.alloc();
va009039 2:871b41f4789e 92 TEST_ASSERT(pkt);
va009039 2:871b41f4789e 93 pkt->type = HCI_EVENT_PACKET;
va009039 2:871b41f4789e 94 pkt->buf = int_report;
va009039 2:871b41f4789e 95 pkt->len = len;
va009039 2:871b41f4789e 96 mail_box.put(pkt);
va009039 1:b657594559be 97 }
va009039 1:b657594559be 98
va009039 2:871b41f4789e 99 void USBHostBTstack::bulk_rxHandler()
va009039 2:871b41f4789e 100 {
va009039 1:b657594559be 101 int len = bulk_in->getLengthTransferred();
va009039 2:871b41f4789e 102 BT_DBG_BYTES("ACL_RCV:", bulk_report, len);
va009039 2:871b41f4789e 103 Packet* pkt = mail_box.alloc();
va009039 2:871b41f4789e 104 TEST_ASSERT(pkt);
va009039 2:871b41f4789e 105 pkt->type = HCI_ACL_DATA_PACKET;
va009039 2:871b41f4789e 106 pkt->buf = bulk_report;
va009039 2:871b41f4789e 107 pkt->len = len;
va009039 2:871b41f4789e 108 mail_box.put(pkt);
va009039 1:b657594559be 109 }
va009039 1:b657594559be 110
va009039 1:b657594559be 111 /*virtual*/ void USBHostBTstack::setVidPid(uint16_t vid, uint16_t pid)
va009039 1:b657594559be 112 {
va009039 1:b657594559be 113 BT_DBG("vid:%04x,pid:%04x", vid, pid);
va009039 1:b657594559be 114 }
va009039 1:b657594559be 115
va009039 1:b657594559be 116 /*virtual*/ bool USBHostBTstack::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
va009039 1:b657594559be 117 {
va009039 1:b657594559be 118 BT_DBG("intf_nb=%d,intf_class=%02X,intf_subclass=%d,intf_protocol=%d", intf_nb, intf_class, intf_subclass, intf_protocol);
va009039 1:b657594559be 119 if ((btstack_intf == -1) && intf_class == 0xe0) {
va009039 1:b657594559be 120 btstack_intf = intf_nb;
va009039 1:b657594559be 121 return true;
va009039 1:b657594559be 122 }
va009039 1:b657594559be 123 return false;
va009039 1:b657594559be 124 }
va009039 1:b657594559be 125
va009039 1:b657594559be 126 /*virtual*/ bool USBHostBTstack::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
va009039 1:b657594559be 127 {
va009039 1:b657594559be 128 BT_DBG("intf_nb:%d,type:%d,dir:%d",intf_nb, type, dir);
va009039 1:b657594559be 129 if (intf_nb == btstack_intf) {
va009039 1:b657594559be 130 if (ep_int_in == false && type == INTERRUPT_ENDPOINT && dir == IN) {
va009039 1:b657594559be 131 ep_int_in = true;
va009039 1:b657594559be 132 } else if (ep_bulk_in == false && type == BULK_ENDPOINT && dir == IN) {
va009039 1:b657594559be 133 ep_bulk_in = true;
va009039 1:b657594559be 134 } else if (ep_bulk_out == false && type == BULK_ENDPOINT && dir == OUT) {
va009039 1:b657594559be 135 ep_bulk_out = true;
va009039 1:b657594559be 136 } else {
va009039 1:b657594559be 137 return false;
va009039 1:b657594559be 138 }
va009039 1:b657594559be 139 if (ep_int_in && ep_bulk_in && ep_bulk_out) {
va009039 1:b657594559be 140 btstack_device_found = true;
va009039 1:b657594559be 141 }
va009039 1:b657594559be 142 return true;
va009039 1:b657594559be 143 }
va009039 1:b657594559be 144 return false;
va009039 1:b657594559be 145 }
va009039 1:b657594559be 146
va009039 1:b657594559be 147 int USBHostBTstack::open()
va009039 1:b657594559be 148 {
va009039 1:b657594559be 149 BT_DBG("%p", this);
va009039 1:b657594559be 150 while(!connected()) {
va009039 1:b657594559be 151 if (connect()) {
va009039 1:b657594559be 152 break;
va009039 1:b657594559be 153 }
va009039 1:b657594559be 154 Thread::wait(500);
va009039 1:b657594559be 155 }
va009039 1:b657594559be 156 return 0;
va009039 1:b657594559be 157 }
va009039 1:b657594559be 158
va009039 1:b657594559be 159 int USBHostBTstack::send_packet(uint8_t packet_type, uint8_t* packet, int size)
va009039 1:b657594559be 160 {
va009039 1:b657594559be 161 USB_TYPE res;
va009039 1:b657594559be 162 switch(packet_type){
va009039 1:b657594559be 163 case HCI_COMMAND_DATA_PACKET:
va009039 2:871b41f4789e 164 BT_DBG_BYTES("HCI_CMD:", packet, size);
va009039 1:b657594559be 165 res = host->controlWrite(dev,
va009039 1:b657594559be 166 USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_DEVICE,
va009039 1:b657594559be 167 0, 0, 0, packet, size);
va009039 1:b657594559be 168 TEST_ASSERT(res == USB_TYPE_OK);
va009039 1:b657594559be 169 break;
va009039 1:b657594559be 170 case HCI_ACL_DATA_PACKET:
va009039 2:871b41f4789e 171 BT_DBG_BYTES("ACL_SND:", packet, size);
va009039 1:b657594559be 172 res = host->bulkWrite(dev, bulk_out, packet, size);
va009039 1:b657594559be 173 TEST_ASSERT(res == USB_TYPE_OK);
va009039 1:b657594559be 174 break;
va009039 1:b657594559be 175 default:
va009039 1:b657594559be 176 TEST_ASSERT(0);
va009039 1:b657594559be 177 }
va009039 1:b657594559be 178 return 0;
va009039 1:b657594559be 179 }
va009039 1:b657594559be 180
va009039 1:b657594559be 181 void USBHostBTstack::register_packet_handler(void (*pMethod)(uint8_t, uint8_t*, uint16_t) )
va009039 1:b657594559be 182 {
va009039 1:b657594559be 183 BT_DBG("pMethod: %p", pMethod);
va009039 1:b657594559be 184 m_pCb = pMethod;
va009039 1:b657594559be 185 }
va009039 1:b657594559be 186
va009039 2:871b41f4789e 187 void USBHostBTstack::poll()
va009039 2:871b41f4789e 188 {
va009039 2:871b41f4789e 189 osEvent evt = mail_box.get(0); // non-blocking
va009039 2:871b41f4789e 190 if (evt.status == osEventMail) {
va009039 2:871b41f4789e 191 Packet* pkt = reinterpret_cast<Packet*>(evt.value.p);
va009039 2:871b41f4789e 192 TEST_ASSERT(pkt);
va009039 2:871b41f4789e 193 //BT_DBG("type: %d, buf: %p, len: %d", pkt->type, pkt->buf, pkt->len);
va009039 2:871b41f4789e 194 if (m_pCb) {
va009039 2:871b41f4789e 195 m_pCb(pkt->type, pkt->buf, pkt->len);
va009039 2:871b41f4789e 196 }
va009039 2:871b41f4789e 197 if (dev) {
va009039 2:871b41f4789e 198 if (pkt->type == HCI_EVENT_PACKET) {
va009039 2:871b41f4789e 199 host->interruptRead(dev, int_in, int_report, int_in->getSize(), false);
va009039 2:871b41f4789e 200 } else { // HCI_ACL_DATA_PACKET
va009039 2:871b41f4789e 201 host->bulkRead(dev, bulk_in, bulk_report, bulk_in->getSize(), false);
va009039 2:871b41f4789e 202 }
va009039 2:871b41f4789e 203 }
va009039 2:871b41f4789e 204 mail_box.free(pkt);
va009039 2:871b41f4789e 205 }
va009039 2:871b41f4789e 206 }
va009039 2:871b41f4789e 207
va009039 2:871b41f4789e 208 void _debug_bytes(const char* pretty, int line, const char* s, uint8_t* buf, int len)
va009039 2:871b41f4789e 209 {
va009039 2:871b41f4789e 210 printf("[%s:%d]\n%s", pretty, line, s);
va009039 2:871b41f4789e 211 for(int i = 0; i < len; i++) {
va009039 2:871b41f4789e 212 printf(" %02x", buf[i]);
va009039 2:871b41f4789e 213 }
va009039 2:871b41f4789e 214 printf("\n");
va009039 2:871b41f4789e 215 }