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

Revision:
5:378c208637e3
Parent:
2:0118da9e5169
--- 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
 }