Test version of BlueUSB stack. Includes SDP and RFCOMM. As Client it allows to connect to my fischertechnik TX Controller. As Server it echo\\\\\\\'s characters to Putty. PIN=1234
Dependencies: mbed myUSBHost AvailableMemory
Dependents: mbed_TANK_Kinect myBlueUSB_ros ftusbClass
Diff: hci.cpp
- Revision:
- 5:378c208637e3
- Parent:
- 2:0118da9e5169
diff -r b94984a20500 -r 378c208637e3 hci.cpp --- a/hci.cpp Sun May 08 18:30:10 2011 +0000 +++ b/hci.cpp Sat Jun 11 19:43:00 2011 +0000 @@ -31,6 +31,10 @@ #include "hci_private.h" #include "USBHost.h" //for USBLoop #include "HCITransportUSB.h" //for ACL/HCL buffer size +#include "neighbourhood.h" + +extern const char FtDevClass[]; +const char FtDevClass[3] = {0x00, 0x1F, 0x82 }; enum hci_callback_evt { NONE, @@ -51,8 +55,8 @@ MASK_CREATE_CONNECTION = 64 }; -static const u8 local_name[] = "MBED"; - +//static const u8 local_name[] = "MBED"; +static const u8 local_name[] = "ROBO TX-599"; int HCI::Open(HCITransport* transport, HCICallback callback) { _transport = transport; @@ -168,10 +172,12 @@ param[6] = 0; //0 Synchronous buffers SendCmd(HCI_OP_HOST_BUFFER_SIZE, param, 7); const unsigned char flow = 1;//ACL on, Synchonous off - SendCmd(HCI_OP_CONTR_TO_HOST_FLOW, &flow, 1); -#endif + SendCmd(HCI_OP_CONTR_TO_HOST_FLOW, &flow, 1); +#endif const unsigned char scan_enable = 3; SendCmd(HCI_OP_WRITE_SCAN_ENABLE, &scan_enable, 1); + SendCmd(HCI_OP_WRITE_CLASS_OF_DEV, (const u8*)FtDevClass, 3); + //SendCmd(HCI_OP_READ_LOCAL_VERSION, 0, 0); SendCmd(HCI_OP_WRITE_LOCAL_NAME, local_name, 248); } Callback(CALLBACK_READY,data,6); @@ -209,6 +215,9 @@ case HCI_OP_PIN_CODE_REPLY: printf("Got pin reply\n"); break; + case HCI_READ_STORED_LINK_KEY: + neighbors->set_cap(LE16(data), LE16(data+2)); + break; default: printf("Unrecognized Command Completion %04X\n",cmd); @@ -332,7 +341,9 @@ void HCI::ConnectComplete(const connection_info* info) { BTDevice* d = Find(&info->bdaddr); if (!d) { - printf("BT Device not known!?! "); printf(&info->bdaddr);printf("\n"); + printf("BT Device not known!?! "); + printf(&info->bdaddr); + printf("\n"); return; } if (info->status == 0) { @@ -350,7 +361,7 @@ memcpy(b, addr, 6); b[6] = slave; BTDevice* bt = Find(addr); - if (!bt){ + if (!bt) { printf("Received connection request from undiscovered device\n"); for (int i = 0; i < MAX_BTDEVICES; i++) { if (_devices[i]._state == 0) { @@ -431,7 +442,7 @@ case HCI_EV_CMD_COMPLETE://[2]=cmd-pkts, [3-4]=cmd, [5...]=pars if (data[5]) { //[5]=usually status - printf("HCIRecv error status: %s\n", HCIErrStr(data[5])); + printf("HCIRecv error status: %s\n", HCIErrStr(data[5])); } OnCommandComplete(data[3] | (data[4] << 8), data+6, data[1]-4); #ifdef COMMAND_FLOW @@ -444,9 +455,15 @@ //PinCodeReply(data+2); break; - case HCI_EV_LINK_KEY_REQ: - SendCmd(HCI_OP_LINK_KEY_NEG_REPLY,data+2,6); - break; + case HCI_EV_LINK_KEY_REQ: { + u8 param[22]; + if (neighbors->get((BD_ADDR*)(data+2), param+sizeof(BD_ADDR))){ + memcpy(param, data+2, sizeof(BD_ADDR)); + SendCmd(HCI_OP_LINK_KEY_REPLY,param,sizeof(param)); + } else + SendCmd(HCI_OP_LINK_KEY_NEG_REPLY,data+2,6); + } + break; #ifdef HOST_CONTR_FLOW case HCI_EV_NUM_COMP_PKTS: for (int k = 0; k < data[2]; k++) {//data[2] and 'c' are usually 1 @@ -454,22 +471,29 @@ u16 c = LE16(data+5+2*k); BTDevice *d = Find(h); if (!d) - continue;//skip no existing devices - if (d->pkts_sent >= c){ - d->pkts_sent -= c; - _transport->data_credits += c; - } - else - d->pkts_sent = 0; + continue;//skip no existing devices + if (d->pkts_sent >= c) { + d->pkts_sent -= c; + _transport->data_credits += c; + } else + d->pkts_sent = 0; //printf("%d Outstanding pkts for handle %03X (total credits=%d)\n", d->pkts_sent, h, _transport->data_credits); } break; #endif case HCI_EV_LINK_KEY_NOTIFY: + neighbors->add((BD_ADDR*)(data+2), data+8); + break; + case HCI_EV_RETURN_LINK_KEYS: + for (int i = 0; i < data[2]; i++) + neighbors->add((BD_ADDR*)(data+3+22*i), data+9+22*i, true); + break; case HCI_EV_ENCRYPT_CHANGE: //for(int k=0; k<1000000;k++) USBLoop(); break; - + case HCI_EV_VENDOR: + Callback(CALLBACK_VENDOR, data+2, data[1]); + break; default: printfBytes("HCIRecv:",data,data[1]+2); break; @@ -502,22 +526,22 @@ } int HCI::Send(SocketInternal* sock, const u8* data, int len) {//check here for appropriate buffersize on the device -/* these checks are HCI functions but this 'Send' does not catch all ACL traffic, so it is better done in L2CAP or transport -//assume acl packet -//FIXME: treatment of OFFSET is dubious, OFFSET is not defined?! -#if OFFSET==8 //sizeof ACL/L2CAP is include in data/len - if (len > _acl_mtu) -#else //OFFSET==0, data is bare application frame - if (len+8 > _acl_mtu) -#endif - { printf("Max outgoing packet(%d) size exceeded, segmenting necessary, pktlen = %d\n", _acl_mtu, len); - } - if (data_credits == 0) { - printf("Out of ACL data credits\n"); - return 0; - } - data_credits--; -*/ + /* these checks are HCI functions but this 'Send' does not catch all ACL traffic, so it is better done in L2CAP or transport + //assume acl packet + //FIXME: treatment of OFFSET is dubious, OFFSET is not defined?! + #if OFFSET==8 //sizeof ACL/L2CAP is include in data/len + if (len > _acl_mtu) + #else //OFFSET==0, data is bare application frame + if (len+8 > _acl_mtu) + #endif + { printf("Max outgoing packet(%d) size exceeded, segmenting necessary, pktlen = %d\n", _acl_mtu, len); + } + if (data_credits == 0) { + printf("Out of ACL data credits\n"); + return 0; + } + data_credits--; + */ L2CAPSocket* l2capsock = (L2CAPSocket*)sock; return l2capsock->btdevice->Send(sock,data,len); // Pointless double dispatch } @@ -539,17 +563,16 @@ int handle = LE16(data); BTDevice* d = Find(handle & 0x0FFF); int bufs = 1; - if (!d){ + if (!d) { printfBytes("unk. dest. HCI:ACLRecv ", data, len); - } - else - bufs = d->ACLRecv(data,len); + } else + bufs = d->ACLRecv(data,len); //controller to host flow control #ifdef CONTR_HOST_FLOW //the ACLRecv function returned so we assume that the buffer is free, and tell this to the controller if (bufs) { - Compl_pkts(handle, bufs);//this packet is completed - printf("%d ACL buffers completed\n", bufs); + Compl_pkts(handle, bufs);//this packet is completed + printf("%d ACL buffers completed\n", bufs); } #endif }