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

Committer:
networker
Date:
Mon Apr 04 16:47:10 2011 +0000
Revision:
1:0dde58e0cccf
initial revision

Who changed what in which revision?

UserRevisionLine numberNew contents of line
networker 1:0dde58e0cccf 1
networker 1:0dde58e0cccf 2 /*
networker 1:0dde58e0cccf 3 Copyright (c) 2010 Peter Barrett
networker 1:0dde58e0cccf 4
networker 1:0dde58e0cccf 5 Permission is hereby granted, free of charge, to any person obtaining a copy
networker 1:0dde58e0cccf 6 of this software and associated documentation files (the "Software"), to deal
networker 1:0dde58e0cccf 7 in the Software without restriction, including without limitation the rights
networker 1:0dde58e0cccf 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
networker 1:0dde58e0cccf 9 copies of the Software, and to permit persons to whom the Software is
networker 1:0dde58e0cccf 10 furnished to do so, subject to the following conditions:
networker 1:0dde58e0cccf 11
networker 1:0dde58e0cccf 12 The above copyright notice and this permission notice shall be included in
networker 1:0dde58e0cccf 13 all copies or substantial portions of the Software.
networker 1:0dde58e0cccf 14
networker 1:0dde58e0cccf 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
networker 1:0dde58e0cccf 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
networker 1:0dde58e0cccf 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
networker 1:0dde58e0cccf 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
networker 1:0dde58e0cccf 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
networker 1:0dde58e0cccf 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
networker 1:0dde58e0cccf 21 THE SOFTWARE.
networker 1:0dde58e0cccf 22 */
networker 1:0dde58e0cccf 23 #include "mbed.h"
networker 1:0dde58e0cccf 24 #include <vector>
networker 1:0dde58e0cccf 25 #include "Utils.h"
networker 1:0dde58e0cccf 26 #include "USBHost.h"
networker 1:0dde58e0cccf 27 #include "hci.h"
networker 1:0dde58e0cccf 28 #include "HCITransportUSB.h"
networker 1:0dde58e0cccf 29 #include "RFCOMM.h"
networker 1:0dde58e0cccf 30 #include "ftclasslibusbdevbt.h"
networker 1:0dde58e0cccf 31 #include "sdp_data.h"
networker 1:0dde58e0cccf 32 #include "sdp.h"
networker 1:0dde58e0cccf 33
networker 1:0dde58e0cccf 34 /************************************************
networker 1:0dde58e0cccf 35 TODO:
networker 1:0dde58e0cccf 36 mtu and credits are completely unhandled - in progress
networker 1:0dde58e0cccf 37 multiple rfcomm sessions should be possible - done
networker 1:0dde58e0cccf 38 SDP would be nice - beta
networker 1:0dde58e0cccf 39 multiple rfcomm channels are untested
networker 1:0dde58e0cccf 40 decoupling of rfcomm and application - much better
networker 1:0dde58e0cccf 41 packets are not reassembled - some are (HCI and ft application level)
networker 1:0dde58e0cccf 42 disconnect and timeouts
networker 1:0dde58e0cccf 43 ************************************************/
networker 1:0dde58e0cccf 44 #define DEBUG 1
networker 1:0dde58e0cccf 45 int state = 0;
networker 1:0dde58e0cccf 46
networker 1:0dde58e0cccf 47 void printf(const BD_ADDR* addr) {
networker 1:0dde58e0cccf 48 const u8* a = addr->addr;
networker 1:0dde58e0cccf 49 printf("%02X:%02X:%02X:%02X:%02X:%02X",a[5],a[4],a[3],a[2],a[1],a[0]);
networker 1:0dde58e0cccf 50 }
networker 1:0dde58e0cccf 51
networker 1:0dde58e0cccf 52 //int bulk = 0;
networker 1:0dde58e0cccf 53
networker 1:0dde58e0cccf 54 char FtDevClass[3] = {0x00, 0x1F, 0x82 };
networker 1:0dde58e0cccf 55
networker 1:0dde58e0cccf 56 // Instance
networker 1:0dde58e0cccf 57 RFCOMMManager rfcomm_manager;
networker 1:0dde58e0cccf 58
networker 1:0dde58e0cccf 59 class application : public HCI {
networker 1:0dde58e0cccf 60 BTDevice* devs[8];
networker 1:0dde58e0cccf 61 int count, i, pending;
networker 1:0dde58e0cccf 62 public:
networker 1:0dde58e0cccf 63 // We have connected to a device
networker 1:0dde58e0cccf 64 void ConnectionComplete(connection_info* info) {
networker 1:0dde58e0cccf 65 printf("ConnectionComplete ");
networker 1:0dde58e0cccf 66 BD_ADDR* a = &info->bdaddr;
networker 1:0dde58e0cccf 67 printf(a);
networker 1:0dde58e0cccf 68 printf("\n");
networker 1:0dde58e0cccf 69 RemoteNameRequest(a);
networker 1:0dde58e0cccf 70 for (i++; i < count; i++) {//find the next device to open
networker 1:0dde58e0cccf 71 printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
networker 1:0dde58e0cccf 72 if (devs[i]->_handle == 0 && memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0) {//or some other way to connect to RFCOMM devices
networker 1:0dde58e0cccf 73 BD_ADDR* bd = &devs[i]->_info.bdaddr;
networker 1:0dde58e0cccf 74 printf("Connecting to ");
networker 1:0dde58e0cccf 75 printf(bd);
networker 1:0dde58e0cccf 76 printf("\n");
networker 1:0dde58e0cccf 77 pending++;
networker 1:0dde58e0cccf 78 CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.)
networker 1:0dde58e0cccf 79 printf("connection cmd was sent\n");
networker 1:0dde58e0cccf 80 return;
networker 1:0dde58e0cccf 81 }
networker 1:0dde58e0cccf 82 }
networker 1:0dde58e0cccf 83 //state = 1; //start the real application
networker 1:0dde58e0cccf 84 }
networker 1:0dde58e0cccf 85
networker 1:0dde58e0cccf 86 void ConnectDevices() {
networker 1:0dde58e0cccf 87 count = GetDevices(devs,8);//get pointers to all bluetooth devices
networker 1:0dde58e0cccf 88 pending = 0;
networker 1:0dde58e0cccf 89 for (i = 0; i < count; i++) {
networker 1:0dde58e0cccf 90 printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
networker 1:0dde58e0cccf 91 if (devs[i]->_handle == 0 && memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0) {//or some other way to connect to RFCOMM devices
networker 1:0dde58e0cccf 92 BD_ADDR* bd = &devs[i]->_info.bdaddr;
networker 1:0dde58e0cccf 93 printf("Connecting to ");
networker 1:0dde58e0cccf 94 printf(bd);
networker 1:0dde58e0cccf 95 printf("\n");
networker 1:0dde58e0cccf 96 pending++;
networker 1:0dde58e0cccf 97 CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.)
networker 1:0dde58e0cccf 98 printf("connection cmd was sent\n");
networker 1:0dde58e0cccf 99 return;
networker 1:0dde58e0cccf 100 }
networker 1:0dde58e0cccf 101 }
networker 1:0dde58e0cccf 102 if (pending == 0) state = 1;//for the case when there are no ft devices
networker 1:0dde58e0cccf 103 }
networker 1:0dde58e0cccf 104 virtual void Callback(HCI_CALLBACK_EVENT c, const u8* data, int len);
networker 1:0dde58e0cccf 105 } App; //application instance
networker 1:0dde58e0cccf 106
networker 1:0dde58e0cccf 107
networker 1:0dde58e0cccf 108 void application::Callback(HCI_CALLBACK_EVENT evt, const u8* data, int len) {//these events are forwarded (in)directly from HCIRecv
networker 1:0dde58e0cccf 109 unsigned char pin[] = "1234";
networker 1:0dde58e0cccf 110 printf("\x1b[%dm", 33);
networker 1:0dde58e0cccf 111 switch (evt) {
networker 1:0dde58e0cccf 112 case CALLBACK_READY:
networker 1:0dde58e0cccf 113 printf("CALLBACK_READY\n");
networker 1:0dde58e0cccf 114 Inquiry();//start the second phase of the discovery
networker 1:0dde58e0cccf 115 break;
networker 1:0dde58e0cccf 116
networker 1:0dde58e0cccf 117 case CALLBACK_INQUIRY_RESULT: //optionally build the list of FT devices here
networker 1:0dde58e0cccf 118 printf("CALLBACK_INQUIRY_RESULT ");
networker 1:0dde58e0cccf 119 printf((BD_ADDR*)data);
networker 1:0dde58e0cccf 120 printf("\n");//data points to inquiry_info struct
networker 1:0dde58e0cccf 121 // RemoteNameRequest((BD_ADDR*)data);
networker 1:0dde58e0cccf 122 break;
networker 1:0dde58e0cccf 123
networker 1:0dde58e0cccf 124 case CALLBACK_INQUIRY_DONE:
networker 1:0dde58e0cccf 125 printf("CALLBACK_INQUIRY_DONE\n");
networker 1:0dde58e0cccf 126 ConnectDevices();
networker 1:0dde58e0cccf 127 break;
networker 1:0dde58e0cccf 128
networker 1:0dde58e0cccf 129 case CALLBACK_REMOTE_NAME: {
networker 1:0dde58e0cccf 130 BD_ADDR* addr = (BD_ADDR*)data;
networker 1:0dde58e0cccf 131 const char* name = (const char*)(data + 6);
networker 1:0dde58e0cccf 132 printf(addr);
networker 1:0dde58e0cccf 133 printf(" = % s\n",name);
networker 1:0dde58e0cccf 134 pending--;
networker 1:0dde58e0cccf 135 if (pending == 0) state = 1;
networker 1:0dde58e0cccf 136 }
networker 1:0dde58e0cccf 137 break;
networker 1:0dde58e0cccf 138
networker 1:0dde58e0cccf 139 case CALLBACK_CONNECTION_COMPLETE:
networker 1:0dde58e0cccf 140 ConnectionComplete((connection_info*)data);
networker 1:0dde58e0cccf 141 {
networker 1:0dde58e0cccf 142 printf("Going to open sdp socket\n");
networker 1:0dde58e0cccf 143 L2CAPAddr addr;
networker 1:0dde58e0cccf 144 connection_info *ci = (connection_info*)data;
networker 1:0dde58e0cccf 145 memcpy(&addr.bdaddr, &ci->bdaddr, 6);
networker 1:0dde58e0cccf 146 addr.psm = 1;//should not matter
networker 1:0dde58e0cccf 147 int s = Socket_Open(SOCKET_SDP, &addr.hdr, &SDP.OnSockCallback, &SDP);
networker 1:0dde58e0cccf 148 }
networker 1:0dde58e0cccf 149 break;
networker 1:0dde58e0cccf 150 case CALLBACK_PIN_REQ:
networker 1:0dde58e0cccf 151 printf("Enter PIN for ");
networker 1:0dde58e0cccf 152 printf((BD_ADDR*)data);
networker 1:0dde58e0cccf 153 printf(" : submitting %s\n", pin);
networker 1:0dde58e0cccf 154 PinCodeReply(data, pin);
networker 1:0dde58e0cccf 155 break;
networker 1:0dde58e0cccf 156 };
networker 1:0dde58e0cccf 157 printf("\x1b[%dm", 0);
networker 1:0dde58e0cccf 158 }
networker 1:0dde58e0cccf 159
networker 1:0dde58e0cccf 160 // these should be placed in the DMA SRAM
networker 1:0dde58e0cccf 161 typedef struct {
networker 1:0dde58e0cccf 162 u8 _hciBuffer[MAX_HCL_SIZE];
networker 1:0dde58e0cccf 163 u8 _aclBuffer[MAX_ACL_SIZE];
networker 1:0dde58e0cccf 164 } SRAMPlacement;
networker 1:0dde58e0cccf 165
networker 1:0dde58e0cccf 166 HCITransportUSB _HCITransportUSB; //use USB as the transport to the radio
networker 1:0dde58e0cccf 167
networker 1:0dde58e0cccf 168 int OnBluetoothInsert(int device) {//install the HCI and start discovery, user callbacks are made to HciCalback
networker 1:0dde58e0cccf 169 printf("Bluetooth inserted of %d\n",device);
networker 1:0dde58e0cccf 170 u32 sramLen;
networker 1:0dde58e0cccf 171 u8* sram = USBGetBuffer(&sramLen);
networker 1:0dde58e0cccf 172 sram = (u8*)(((u32)sram + 1023) & ~1023);
networker 1:0dde58e0cccf 173 SRAMPlacement* s = (SRAMPlacement*)sram;
networker 1:0dde58e0cccf 174 _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);//setup buffers for USB host, incoming data goes first to HCIRecv and ACLRecv
networker 1:0dde58e0cccf 175 RegisterSocketHandler(SOCKET_L2CAP,&App); //register the application::hci as handler for L2CAP events
networker 1:0dde58e0cccf 176 RegisterSocketHandler(SOCKET_RFCOM, &rfcomm_manager);//set the RFCOMMManager as the RFCOM socket handler
networker 1:0dde58e0cccf 177 if (RegisterSocketHandler(SOCKET_SDP, &SDP))
networker 1:0dde58e0cccf 178 printf("Could not register SDP socket type\n");
networker 1:0dde58e0cccf 179 App.Open(&_HCITransportUSB);
networker 1:0dde58e0cccf 180 App.Inquiry();//start discovery of BT devices phase 0
networker 1:0dde58e0cccf 181 return 0;
networker 1:0dde58e0cccf 182 }
networker 1:0dde58e0cccf 183
networker 1:0dde58e0cccf 184 DigitalOut led(LED1), loop(LED2);
networker 1:0dde58e0cccf 185
networker 1:0dde58e0cccf 186 void TestShell() {
networker 1:0dde58e0cccf 187 int n=0;
networker 1:0dde58e0cccf 188 USBInit();
networker 1:0dde58e0cccf 189 for (;;) {
networker 1:0dde58e0cccf 190 switch (state) {
networker 1:0dde58e0cccf 191 case 0: //inquiry and low-level connection
networker 1:0dde58e0cccf 192 break;
networker 1:0dde58e0cccf 193 case 1: {//initialisation
networker 1:0dde58e0cccf 194 printf("Ready to open ports\n");
networker 1:0dde58e0cccf 195 InitFtBtDeviceList();
networker 1:0dde58e0cccf 196 int n = GetNrOfFtBtDevices();
networker 1:0dde58e0cccf 197 printf("%d ft BT devices have been found\n", n);
networker 1:0dde58e0cccf 198 if (n > 0) {
networker 1:0dde58e0cccf 199 ftbtdev *d = GetFtUsbDeviceHandle(0);
networker 1:0dde58e0cccf 200 if (d==0) printf("could not get device handle\n");
networker 1:0dde58e0cccf 201 int sock = OpenFtBtDevice(d);
networker 1:0dde58e0cccf 202 }
networker 1:0dde58e0cccf 203 state = 2;
networker 1:0dde58e0cccf 204 }
networker 1:0dde58e0cccf 205 break;
networker 1:0dde58e0cccf 206 case 2://main loop
networker 1:0dde58e0cccf 207 break;
networker 1:0dde58e0cccf 208 default:
networker 1:0dde58e0cccf 209 break;
networker 1:0dde58e0cccf 210 }
networker 1:0dde58e0cccf 211 loop=1;
networker 1:0dde58e0cccf 212 USBLoop();
networker 1:0dde58e0cccf 213 loop=0;
networker 1:0dde58e0cccf 214 n++;
networker 1:0dde58e0cccf 215 if (n>=500000) {
networker 1:0dde58e0cccf 216 n=0;
networker 1:0dde58e0cccf 217 led = !led;
networker 1:0dde58e0cccf 218 }
networker 1:0dde58e0cccf 219 }
networker 1:0dde58e0cccf 220 //printf("Dropped out of main loop!\n");
networker 1:0dde58e0cccf 221 }
networker 1:0dde58e0cccf 222
networker 1:0dde58e0cccf 223 //********************************************************************************************************************************