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:
Wed May 04 09:31:15 2011 +0000
Revision:
3:50196dce45f8

        

Who changed what in which revision?

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