BTstack for Nucleo F401RE/FRDM-KL46Z example program

Dependencies:   F401RE-USBHost mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBHostBTstack.cpp Source File

USBHostBTstack.cpp

00001 // USBHostBTstack.cpp
00002 #include "USBHostBTstack.h"
00003 
00004 //#define BTSTACK_DEBUG
00005 
00006 #ifdef BTSTACK_DEBUG
00007 #define BT_DBG(x, ...) std::printf("[%s:%d]"x"\r\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
00008 #define BT_DBG_BYTES(STR,BUF,LEN) _debug_bytes(__PRETTY_FUNCTION__,__LINE__,STR,BUF,LEN)
00009 #else
00010 #define BT_DBG(...)  while(0);
00011 #define BT_DBG_BYTES(S,BUF,LEN) while(0);
00012 #endif
00013 #define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");}while(0);
00014 
00015 #define HCI_COMMAND_DATA_PACKET 0x01
00016 #define HCI_ACL_DATA_PACKET     0x02
00017 #define HCI_SCO_DATA_PACKET     0x03
00018 #define HCI_EVENT_PACKET        0x04
00019 
00020 USBHostBTstack::USBHostBTstack()
00021 {
00022     host = USBHost::getHostInst();
00023     init();
00024     m_pCb = NULL;
00025 }
00026 
00027 void USBHostBTstack::init()
00028 {
00029     BT_DBG("");
00030     dev = NULL;
00031     int_in = NULL;
00032     bulk_in = NULL;
00033     bulk_out = NULL;
00034     btstack_intf = -1;
00035     btstack_device_found = false;
00036     dev_connected = false;
00037     ep_int_in = false;
00038     ep_bulk_in = false;
00039     ep_bulk_out = false;
00040 }
00041 
00042 bool USBHostBTstack::connected()
00043 {
00044     return dev_connected;
00045 }
00046 
00047 bool USBHostBTstack::connect()
00048 {
00049     if (dev_connected) {
00050         return true;
00051     }
00052  
00053     for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
00054         if ((dev = host->getDevice(i)) != NULL) {
00055             
00056             BT_DBG("Trying to connect BTstack device\r\n");
00057             
00058             if(host->enumerate(dev, this)) {
00059                 break;
00060             }
00061             if (btstack_device_found) {
00062                 int_in = dev->getEndpoint(btstack_intf, INTERRUPT_ENDPOINT, IN);
00063                 bulk_in = dev->getEndpoint(btstack_intf, BULK_ENDPOINT, IN);
00064                 bulk_out = dev->getEndpoint(btstack_intf, BULK_ENDPOINT, OUT);
00065                 if (!int_in || !bulk_in || !bulk_out) {
00066                     continue;
00067                 }
00068                 USB_INFO("New BTstack device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, btstack_intf);
00069                 //dev->setName("BTstack", btstack_intf);
00070                 //host->registerDriver(dev, btstack_intf, this, &USBHostBTstack::init);
00071  
00072                 //int_in->attach(this, &USBHostBTstack::int_rxHandler);
00073                 //host->interruptRead(dev, int_in, int_report, int_in->getSize(), false);
00074  
00075                 //bulk_in->attach(this, &USBHostBTstack::bulk_rxHandler);
00076                 //host->bulkRead(dev, bulk_in, bulk_report, bulk_in->getSize(), false);
00077  
00078                 dev_connected = true;
00079                 return true;
00080             }
00081         }
00082     }
00083     init();
00084     return false;
00085 }
00086 
00087 /*virtual*/ void USBHostBTstack::setVidPid(uint16_t vid, uint16_t pid)
00088 {
00089     BT_DBG("vid:%04x,pid:%04x", vid, pid);
00090 }
00091  
00092 /*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
00093 {
00094     BT_DBG("intf_nb=%d,intf_class=%02X,intf_subclass=%d,intf_protocol=%d", intf_nb, intf_class, intf_subclass, intf_protocol);
00095     if ((btstack_intf == -1) && intf_class == 0xe0) {
00096         btstack_intf = intf_nb;
00097         return true;
00098     }
00099     return false;
00100 }
00101  
00102 /*virtual*/ bool USBHostBTstack::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
00103 {
00104     BT_DBG("intf_nb:%d,type:%d,dir:%d",intf_nb, type, dir);
00105     if (intf_nb == btstack_intf) {
00106         if (ep_int_in == false && type == INTERRUPT_ENDPOINT && dir == IN) {
00107             ep_int_in = true;
00108         } else if (ep_bulk_in == false && type == BULK_ENDPOINT && dir == IN) {
00109             ep_bulk_in = true;
00110         } else if (ep_bulk_out == false && type == BULK_ENDPOINT && dir == OUT) {
00111             ep_bulk_out = true;
00112         } else {
00113             return false;
00114         }
00115         if (ep_int_in && ep_bulk_in && ep_bulk_out) {
00116             btstack_device_found = true;
00117         }
00118         return true;
00119     }
00120     return false;
00121 }
00122  
00123 int USBHostBTstack::open()
00124 {
00125     BT_DBG("%p", this);
00126     if (!connect()) {
00127         error("Bluetooth not found.\n");
00128     }
00129     return 0;
00130 }
00131 
00132 int USBHostBTstack::send_packet(uint8_t packet_type, uint8_t* packet, int size)
00133 {
00134     USB_TYPE res;
00135     switch(packet_type){
00136         case HCI_COMMAND_DATA_PACKET:
00137             BT_DBG_BYTES("HCI_CMD:", packet, size);
00138             res = host->controlWrite(dev,
00139                     USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_DEVICE, 
00140                     0, 0, 0, packet, size);
00141             TEST_ASSERT(res == USB_TYPE_OK);
00142             break;
00143         case HCI_ACL_DATA_PACKET:
00144             BT_DBG_BYTES("ACL_SND:", packet, size);
00145             res = host->bulkWrite(dev, bulk_out, packet, size);
00146             TEST_ASSERT(res == USB_TYPE_OK);
00147             break;
00148         default:
00149             TEST_ASSERT(0);
00150     }
00151     return 0;
00152 }
00153 
00154 void USBHostBTstack::register_packet_handler(void (*pMethod)(uint8_t, uint8_t*, uint16_t) )
00155 {
00156     BT_DBG("pMethod: %p", pMethod);
00157     m_pCb = pMethod;
00158 }
00159 
00160 void USBHostBTstack::poll()
00161 {
00162     int result = host->interruptReadNB(int_in, int_report, sizeof(int_report));
00163     if (result >= 0) {
00164         int len = int_in->getLengthTransferred();
00165         BT_DBG_BYTES("HCI_EVT:", int_report, len);
00166         if (m_pCb) {
00167             m_pCb(HCI_EVENT_PACKET, int_report, len);
00168         }    
00169     }
00170     result = host->bulkReadNB(bulk_in, bulk_report, sizeof(bulk_report));
00171     if (result >= 0) {
00172         int len = bulk_in->getLengthTransferred();
00173         BT_DBG_BYTES("HCI_ACL_RECV:", bulk_report, len);
00174         if (m_pCb) {
00175             m_pCb(HCI_ACL_DATA_PACKET, bulk_report, len);
00176         }    
00177     }
00178 }
00179 
00180 void _debug_bytes(const char* pretty, int line, const char* s, uint8_t* buf, int len)
00181 {
00182     printf("[%s:%d]\n%s", pretty, line, s);
00183     for(int i = 0; i < len; i++) {
00184         printf(" %02x", buf[i]);
00185     }
00186     printf("\n");
00187 }