J&W / Mbed 2 deprecated Rejestrator

Dependencies:   mbed Rejestrator

Dependents:   Rejestrator

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBHostRSSI.cpp Source File

USBHostRSSI.cpp

00001 #include "USBHostRSSI.h"
00002 
00003 USBHostRSSI::USBHostRSSI()
00004 {
00005     host = USBHost::getHostInst();
00006     init();
00007 }
00008 
00009 void USBHostRSSI::init()
00010 {
00011     dev = NULL;
00012     int_in = NULL;
00013     onUpdate = NULL;
00014     dev_connected = false;
00015     bluetooth_device_found = false;
00016     bluetooth_intf = -1;
00017     seq = 0;
00018     
00019 }
00020 
00021 bool USBHostRSSI::connected() {
00022     return dev_connected;
00023 }
00024 
00025 bool USBHostRSSI::connect() {
00026 
00027     if (dev_connected) {
00028         return true;
00029     }
00030     
00031     for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
00032         if ((dev = host->getDevice(i)) != NULL) {
00033             if(host->enumerate(dev, this)) {
00034                 break;
00035             }
00036             if (bluetooth_device_found) {
00037                 int_in = dev->getEndpoint(bluetooth_intf, INTERRUPT_ENDPOINT, IN);
00038                 USB_DBG("int_in=%p", int_in);
00039                 if (!int_in) {
00040                     break;
00041                 }
00042                 USB_INFO("New Bluetooth device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, bluetooth_intf);
00043                 int_in->attach(this, &USBHostRSSI::rxHandler);
00044                 int rc = host->interruptRead(dev, int_in, int_buf, sizeof(int_buf), false);
00045                 USB_TEST_ASSERT(rc != USB_TYPE_ERROR);
00046                 rc = cmdSend(HCI_OP_RESET);
00047                 USB_TEST_ASSERT(rc == USB_TYPE_OK);
00048                 dev_connected = true;
00049                 return true;
00050             }
00051         }
00052     }
00053     init();
00054     return false;
00055 }
00056 
00057 void USBHostRSSI::rxHandler() {
00058     event(int_buf, int_in->getLengthTransferred());
00059     if (dev) {
00060         host->interruptRead(dev, int_in, int_buf, sizeof(int_buf), false);
00061     }
00062 }
00063 
00064 /*virtual*/ void USBHostRSSI::setVidPid(uint16_t vid, uint16_t pid)
00065 {
00066     USB_DBG("vid:%04x pid:%04x", vid, pid);
00067     // we don't check VID/PID for mouse driver
00068 }
00069 
00070 /*virtual*/ bool USBHostRSSI::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
00071 {
00072     USB_DBG("intf: %d class: %02x %02x %02x", intf_nb, intf_class, intf_subclass, intf_protocol);
00073     if (bluetooth_intf == -1 && intf_class == 0xe0) {
00074         bluetooth_intf = intf_nb;
00075         return true;
00076     }
00077     return false;
00078 }
00079 
00080 /*virtual*/ bool USBHostRSSI::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
00081 {
00082     USB_DBG("intf_nb=%d type=%d dir=%d", intf_nb, type, dir);
00083 
00084     if (intf_nb == bluetooth_intf) {
00085         if (type == INTERRUPT_ENDPOINT && dir == IN) {
00086             bluetooth_device_found = true;
00087             return true;
00088         }
00089     }
00090     return false;
00091 }
00092 
00093 void USBHostRSSI::event(uint8_t* data, int len) {
00094     CTASSERT(sizeof(BD_ADDR) == 6);
00095     CTASSERT(sizeof(inquiry_with_rssi_info) == 14);
00096     inquiry_with_rssi_info* info;
00097     int max_period_length = 25;
00098     int min_period_length = 20;
00099     int inquiry_length = 15;
00100     USB_TYPE rc;
00101     if (len > 0) {
00102         USB_DBG_HEX(data, len);
00103         hci_event* event = reinterpret_cast<hci_event*>(data);
00104         switch(event->evt) {
00105             case HCI_EV_CMD_COMPLETE:
00106                 switch(event->c.op) {
00107                     case HCI_OP_RESET:
00108                         wait_ms(500);
00109                         rc = cmdSend(HCI_OP_WRITE_INQUIRY_MODE, "B", 0x01); // with RSSI
00110                         USB_TEST_ASSERT(rc == USB_TYPE_OK);
00111                         break;
00112                     case HCI_OP_WRITE_INQUIRY_MODE:
00113                         rc = cmdSend(HCI_OP_PERIODIC_INQUIRY, "HHBBBBB", 
00114                                             max_period_length, min_period_length, 0x33, 0x8B, 0x9E, inquiry_length, 0);
00115                         USB_TEST_ASSERT(rc == USB_TYPE_OK);
00116                         break;
00117                     default:
00118                         break;
00119                 }
00120                 break;
00121             case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
00122                 //USB_DBG_HEX(buf, r);
00123                 info = reinterpret_cast<inquiry_with_rssi_info*>(event->c.data);
00124                 if (onUpdate) {
00125                     (*onUpdate)(info);
00126                 }
00127                 break;
00128             default:
00129                 break;
00130         }        
00131     }
00132 }
00133 
00134 USB_TYPE USBHostRSSI::cmdSend(uint16_t op)
00135 {
00136    return cmdSendSub(op, NULL, 0);
00137 }
00138 
00139 USB_TYPE USBHostRSSI::cmdSend(uint16_t op, const char* fmt, ...) 
00140 {   
00141     va_list vl;
00142     va_start(vl, fmt);
00143     uint8_t buf[255];
00144     int pos = 0;
00145     char* name;
00146     int name_len;
00147     uint16_t h;
00148     BD_ADDR* bdaddr;
00149     for(int i = 0; fmt[i]; i++) {
00150         switch(fmt[i]) {
00151             case 's':
00152                 name = va_arg(vl, char*);
00153                 name_len = strlen(name)+1;
00154                 memcpy(buf+pos, name, name_len);
00155                 pos += name_len;
00156                 break;
00157             case 'B':
00158                 buf[pos++] = va_arg(vl, int);
00159                 break;
00160             case 'H':
00161                 h = va_arg(vl, int);
00162                 buf[pos++] = h;
00163                 buf[pos++] = h>>8;
00164                 break;
00165             case 'A':
00166                 bdaddr = va_arg(vl, BD_ADDR*);
00167                 memcpy(buf+pos, bdaddr, 6);
00168                 pos += 6;
00169                 break;
00170             default:
00171                 USB_DBG("op=%04X fmt=%s i=%d", op, fmt, i);
00172                 break;
00173         }
00174     }
00175     return cmdSendSub(op, buf, pos);
00176 }
00177 
00178 USB_TYPE USBHostRSSI::cmdSendSub(uint16_t op, const uint8_t* data, int size)
00179 {
00180     uint8_t* buf = new uint8_t[size+3];
00181     buf[0] = op;
00182     buf[1] = op>>8;
00183     buf[2] = size;
00184     if (data) {
00185         memcpy(buf+3, data, size);
00186     }
00187     USB_TYPE rc = host->controlWrite(dev, USB_REQUEST_TYPE_CLASS, 0, 0, 0, buf, size+3);
00188     USB_TEST_ASSERT(rc == USB_TYPE_OK);
00189     delete[] buf;
00190     return rc;
00191 }