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:
13:327622e38551
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TestShell.cpp	Fri Jul 01 09:16:00 2011 +0000
@@ -0,0 +1,314 @@
+
+/*
+Copyright (c) 2010 Peter Barrett
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#include "mbed.h"
+#include <vector>
+#include "Utils.h"
+#include "USBHost.h"
+#include "hci.h"
+#include "HCITransportUSB.h"
+#include "RFCOMM.h"
+#include "ftclasslibusbdevbt.h"
+#include "sdp_data.h"
+#include "sdp.h"
+#include "btserial.h"
+#include "neighbourhood.h"
+
+/************************************************
+TODO:
+mtu and credits are completely unhandled - in progress
+multiple rfcomm sessions should be possible - done
+SDP would be nice - beta
+multiple rfcomm channels are untested
+decoupling of rfcomm and application - much better
+packets are not reassembled - some are (HCI and ft application level)
+disconnect and timeouts
+************************************************/
+#define DEBUG   1
+int state = 0;
+
+//int bulk = 0;
+void printf(const BD_ADDR* addr) {
+    const u8* a = addr->addr;
+    printf("%02X:%02X:%02X:%02X:%02X:%02X",a[5],a[4],a[3],a[2],a[1],a[0]);
+}
+
+const char FtDevClass[3] = {0x00, 0x1F, 0x82 };
+const char SerDevClass[3] = {4, 1, 0x00};
+//  Instance
+//RFCOMMManager rfcomm_manager;
+
+class application : public HCI {
+    BTDevice* devs[8];
+    int count, i, pending;
+public:
+    //  We have connected to a device
+    void ConnectionComplete(connection_info* info) {
+        printf("ConnectionComplete ");
+        BD_ADDR* a = &info->bdaddr;
+        printf(a);
+        printf("\n");
+        RemoteNameRequest(a);
+        for (i++; i < count; i++) {//find the next device to open
+            printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
+            if (devs[i]->_handle == 0 && memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0) {//or some other way to connect to RFCOMM devices
+                BD_ADDR* bd = &devs[i]->_info.bdaddr;
+                printf("Connecting to ");
+                printf(bd);
+                printf("\n");
+                pending++;
+                CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.)
+                printf("connection cmd was sent\n");
+                return;
+            }
+        }
+        //state = 1; //start the real application
+    }
+
+    void ConnectDevices() {
+        count = GetDevices(devs,8);//get pointers to all bluetooth devices
+        pending = 0;
+        for (i = 0; i < count; i++) {
+            printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
+            if (devs[i]->_handle == 0 /*&& memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0*/) {//or some other way to connect to RFCOMM devices
+                BD_ADDR* bd = &devs[i]->_info.bdaddr;
+                printf("Connecting to ");
+                printf(bd);
+                printf("\n");
+                pending++;
+                CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.)
+                printf("connection cmd was sent\n");
+                return;
+            }
+        }
+        if (pending == 0) state = 1;//for the case when there are no ft devices
+    }
+    virtual void Callback(HCI_CALLBACK_EVENT c, const u8* data, int len);
+    int csr_write_bd_addr(BD_ADDR *bdaddr, bool transient=true);
+    int csr_reset_device(bool transient=true);
+} App; //application instance
+
+extern "C" void mbed_reset();
+
+
+void application::Callback(HCI_CALLBACK_EVENT evt, const u8* data, int len) {//these events are forwarded (in)directly from HCIRecv
+    unsigned char pin[] = "1234";
+    unsigned char newaddr[] = {0x2c, 0x07, 0x54, 0x7b, 0x13, 0x00};//possible ft TX address (ROBO TX-277)
+//    unsigned char newaddr[] = {0x57, 0x0a, 0x3d, 0x83, 0x15, 0x00};//original address of the cheap round BT dongle
+    printf("\x1b[%dm", 33);
+    switch (evt) {
+        case CALLBACK_READY:
+            printf("CALLBACK_READY\n");
+            printf("my address = ");
+            printf((BD_ADDR*)data);
+            if (memcmp(newaddr, data, 6) != 0) { //csr_write_bd_addr((BD_ADDR*)newaddr, false);
+            }
+            Inquiry();//start the second phase of the discovery
+            break;
+
+        case CALLBACK_INQUIRY_RESULT: //optionally build the list of FT devices here
+            printf("CALLBACK_INQUIRY_RESULT ");
+            printf((BD_ADDR*)data);
+            printf("\n");//data points to inquiry_info struct
+//          RemoteNameRequest((BD_ADDR*)data);
+            break;
+
+        case CALLBACK_INQUIRY_DONE:
+            printf("CALLBACK_INQUIRY_DONE\n");
+            neighbors = new neighbourhood(&App);
+            neighbors->read();
+            ConnectDevices();
+            break;
+
+        case CALLBACK_REMOTE_NAME: {
+            BD_ADDR* addr = (BD_ADDR*)data;
+            const char* name = (const char*)(data + 6);
+            printf(addr);
+            printf(" = % s\n",name);
+            pending--;
+            if (pending == 0) state = 1;
+        }
+        break;
+
+        case CALLBACK_CONNECTION_COMPLETE: {
+            connection_info *ci = (connection_info*)data;
+            if (ci->status>0) {
+                printf("Connection failed, status=0x%02X\n", ci->status);
+                break;
+            }
+            ConnectionComplete(ci);
+            printf("Going to open sdp socket\n");
+            L2CAPAddr addr;
+            memcpy(&addr.bdaddr, &ci->bdaddr, 6);
+            //int s = SDP.Open(&addr.hdr);
+        }
+        break;
+        case CALLBACK_PIN_REQ:
+            printf("Enter PIN for ");
+            printf((BD_ADDR*)data);
+            printf(" :  submitting %s\n", pin);
+            //USBLoop(); wait(1.0); USBLoop();
+            //for(int k=0; k<2000000;k++) USBLoop();
+            PinCodeReply(data, pin);
+            break;
+        case CALLBACK_VENDOR:
+            printfBytes("Vendor Reply:", data, len);
+            //mbed_reset();
+            if (data[0] == 0xc2)
+                csr_reset_device(false);
+            break;
+        default:
+            printf("Unhandled HCI Callback %d\n", evt);
+    };
+    printf("\x1b[%dm", 0);
+}
+
+#define CSR_WRITE        0xFC00
+
+int application::csr_write_bd_addr(BD_ADDR *bdaddr, bool transient) {
+    unsigned char cmd[] = { 0xc2,
+                            0x02, 0x00, 0x0c, 0x00, 0x11, 0x47, 0x03, 0x70,
+                            0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
+                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+                          };
+
+    if (transient)
+        cmd[15] = 0x08;
+
+    cmd[17] = bdaddr->addr[2];
+    cmd[18] = 0x00;
+    cmd[19] = bdaddr->addr[0];
+    cmd[20] = bdaddr->addr[1];
+    cmd[21] = bdaddr->addr[3];
+    cmd[22] = 0x00;
+    cmd[23] = bdaddr->addr[4];
+    cmd[24] = bdaddr->addr[5];
+
+    return SendCmd(CSR_WRITE, cmd, sizeof(cmd));
+}
+
+int application::csr_reset_device(bool transient) {
+    unsigned char cmd[] = { 0xc2, 0x02, 0x00, 0x09, 0x00,
+                            0x00, 0x00, 0x01, 0x40, 0x00, 0x00,
+                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+                          };
+
+    if (transient)
+        cmd[7] = 0x02;
+
+    return SendCmd(CSR_WRITE, cmd, sizeof(cmd));
+}
+
+
+//  these should be placed in the DMA SRAM
+typedef struct {
+    u8 _hciBuffer[MAX_HCL_SIZE];
+    u8 _aclBuffer[MAX_ACL_SIZE];
+} SRAMPlacement;
+
+HCITransportUSB _HCITransportUSB;  //use USB as the transport to the radio
+
+int OnBluetoothInsert(int device) {//install the HCI and start discovery, user callbacks are made to HciCalback
+    printf("Bluetooth inserted of %d\n",device);
+    u32 sramLen;
+    u8* sram =  USBGetBuffer(&sramLen);
+    sram = (u8*)(((u32)sram + 1023) & ~1023);
+    SRAMPlacement* s = (SRAMPlacement*)sram;
+    _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);//setup buffers for USB host, incoming data goes first to HCIRecv and ACLRecv
+    RegisterSocketHandler(SOCKET_L2CAP,&App); //register the application::hci as handler for L2CAP events
+    RegisterSocketHandler(SOCKET_RFCOM, &rfcomm_manager);//set the RFCOMMManager as the RFCOM socket handler
+    if (RegisterSocketHandler(SOCKET_SDP, &SDP))
+        printf("Could not register SDP socket type\n");
+    App.Open(&_HCITransportUSB);//the callback is virtual
+    App.Inquiry();//start discovery of BT devices phase 0
+    return 0;
+}
+
+DigitalOut led(LED1), loop(LED2);
+
+int comm = 0;
+btserial *incoming, *outgoing;
+
+void echo(int socket, SocketState state, const u8* data, int len, void* userData) {
+    const u8 connack[] = { 0xbe, 0xef, 8, 'C','O','N','N','_','A','C','K', 0x11};
+    printf("Echo: socket %d, state %d, len=%d\n", socket, state, len);
+    if (state==SocketState_Open) {
+        if (len == 0) {
+            printf("Sending CONN_ACK\n");
+            Socket_Send(socket, connack, sizeof(connack));
+        } else {
+            //Socket_Send(socket, data, len);
+            printfBytes("echo:", data, len);
+        }
+    }
+}
+
+void TestShell() {
+    int n=0;
+    USBInit();
+    for (;;) {
+        switch (state) {
+            case 0: //inquiry and low-level connection
+                break;
+            case 1: {//initialisation
+                printf("Ready to open ports\n");
+                InitFtBtDeviceList();
+                int n = GetNrOfFtBtDevices();
+                printf("%d ft BT devices have been found\n", n);
+                if (n > 0) {
+                    ftbtdev *d = GetFtUsbDeviceHandle(0);
+                    if (d==0) printf("could not get device handle\n");
+                    int sock = OpenFtBtDevice(d);
+                }
+                state = 2;
+                //comm = Socket_Listen(SOCKET_RFCOM, 1, echo, 0);
+                //incoming = new btserial(1);
+            }
+            break;
+            case 2://main loop
+                /*   if (incoming->readable()>0){
+                     int c= incoming->getc();
+                     putc(c, stderr);
+                     incoming->putc(c);
+                     }
+                     else if (incoming->readable()<0){
+                       state = 3;
+                       printf("end of session");
+                       delete incoming;
+                     }*/
+                break;
+            default:
+                break;
+        }
+        loop=1;
+        USBLoop();
+        loop=0;
+        n++;
+        if (n>=500000) {
+            n=0;
+            led = !led;
+        }
+    }
+    //printf("Dropped out of main loop!\n");
+}
+
+//********************************************************************************************************************************