Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed myUSBHost AvailableMemory
Dependents: mbed_TANK_Kinect myBlueUSB_ros ftusbClass
TestShell.cpp
00001 00002 /* 00003 Copyright (c) 2010 Peter Barrett 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy 00006 of this software and associated documentation files (the "Software"), to deal 00007 in the Software without restriction, including without limitation the rights 00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 copies of the Software, and to permit persons to whom the Software is 00010 furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in 00013 all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00021 THE SOFTWARE. 00022 */ 00023 #include "mbed.h" 00024 #include <vector> 00025 #include "Utils.h" 00026 #include "USBHost.h" 00027 #include "hci.h" 00028 #include "HCITransportUSB.h" 00029 #include "RFCOMM.h" 00030 #include "ftclasslibusbdevbt.h" 00031 #include "sdp_data.h" 00032 #include "sdp.h" 00033 #include "btserial.h" 00034 #include "neighbourhood.h" 00035 00036 /************************************************ 00037 TODO: 00038 mtu and credits are completely unhandled - in progress 00039 multiple rfcomm sessions should be possible - done 00040 SDP would be nice - beta 00041 multiple rfcomm channels are untested 00042 decoupling of rfcomm and application - much better 00043 packets are not reassembled - some are (HCI and ft application level) 00044 disconnect and timeouts 00045 ************************************************/ 00046 #define DEBUG 1 00047 int state = 0; 00048 00049 //int bulk = 0; 00050 void printf(const BD_ADDR* addr) { 00051 const u8* a = addr->addr; 00052 printf("%02X:%02X:%02X:%02X:%02X:%02X",a[5],a[4],a[3],a[2],a[1],a[0]); 00053 } 00054 00055 const char FtDevClass[3] = {0x00, 0x1F, 0x82 }; 00056 const char SerDevClass[3] = {4, 1, 0x00}; 00057 // Instance 00058 //RFCOMMManager rfcomm_manager; 00059 00060 class application : public HCI { 00061 BTDevice* devs[8]; 00062 int count, i, pending; 00063 public: 00064 // We have connected to a device 00065 void ConnectionComplete(connection_info* info) { 00066 printf("ConnectionComplete "); 00067 BD_ADDR* a = &info->bdaddr; 00068 printf(a); 00069 printf("\n"); 00070 RemoteNameRequest(a); 00071 for (i++; i < count; i++) {//find the next device to open 00072 printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3); 00073 if (devs[i]->_handle == 0 && memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0) {//or some other way to connect to RFCOMM devices 00074 BD_ADDR* bd = &devs[i]->_info.bdaddr; 00075 printf("Connecting to "); 00076 printf(bd); 00077 printf("\n"); 00078 pending++; 00079 CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.) 00080 printf("connection cmd was sent\n"); 00081 return; 00082 } 00083 } 00084 //state = 1; //start the real application 00085 } 00086 00087 void ConnectDevices() { 00088 count = GetDevices(devs,8);//get pointers to all bluetooth devices 00089 pending = 0; 00090 for (i = 0; i < count; i++) { 00091 printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3); 00092 if (devs[i]->_handle == 0 /*&& memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0*/) {//or some other way to connect to RFCOMM devices 00093 BD_ADDR* bd = &devs[i]->_info.bdaddr; 00094 printf("Connecting to "); 00095 printf(bd); 00096 printf("\n"); 00097 pending++; 00098 CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.) 00099 printf("connection cmd was sent\n"); 00100 return; 00101 } 00102 } 00103 if (pending == 0) state = 1;//for the case when there are no ft devices 00104 } 00105 virtual void Callback(HCI_CALLBACK_EVENT c, const u8* data, int len); 00106 int csr_write_bd_addr(BD_ADDR *bdaddr, bool transient=true); 00107 int csr_reset_device(bool transient=true); 00108 } App; //application instance 00109 00110 extern "C" void mbed_reset(); 00111 00112 00113 void application::Callback(HCI_CALLBACK_EVENT evt, const u8* data, int len) {//these events are forwarded (in)directly from HCIRecv 00114 unsigned char pin[] = "1234"; 00115 unsigned char newaddr[] = {0x2c, 0x07, 0x54, 0x7b, 0x13, 0x00};//possible ft TX address (ROBO TX-277) 00116 // unsigned char newaddr[] = {0x57, 0x0a, 0x3d, 0x83, 0x15, 0x00};//original address of the cheap round BT dongle 00117 printf("\x1b[%dm", 33); 00118 switch (evt) { 00119 case CALLBACK_READY: 00120 printf("CALLBACK_READY\n"); 00121 printf("my address = "); 00122 printf((BD_ADDR*)data); 00123 if (memcmp(newaddr, data, 6) != 0) { //csr_write_bd_addr((BD_ADDR*)newaddr, false); 00124 } 00125 Inquiry();//start the second phase of the discovery 00126 break; 00127 00128 case CALLBACK_INQUIRY_RESULT: //optionally build the list of FT devices here 00129 printf("CALLBACK_INQUIRY_RESULT "); 00130 printf((BD_ADDR*)data); 00131 printf("\n");//data points to inquiry_info struct 00132 // RemoteNameRequest((BD_ADDR*)data); 00133 break; 00134 00135 case CALLBACK_INQUIRY_DONE: 00136 printf("CALLBACK_INQUIRY_DONE\n"); 00137 neighbors = new neighbourhood(&App); 00138 neighbors->read(); 00139 ConnectDevices(); 00140 break; 00141 00142 case CALLBACK_REMOTE_NAME: { 00143 BD_ADDR* addr = (BD_ADDR*)data; 00144 const char* name = (const char*)(data + 6); 00145 printf(addr); 00146 printf(" = % s\n",name); 00147 pending--; 00148 if (pending == 0) state = 1; 00149 } 00150 break; 00151 00152 case CALLBACK_CONNECTION_COMPLETE: { 00153 connection_info *ci = (connection_info*)data; 00154 if (ci->status>0) { 00155 printf("Connection failed, status=0x%02X\n", ci->status); 00156 break; 00157 } 00158 ConnectionComplete(ci); 00159 printf("Going to open sdp socket\n"); 00160 L2CAPAddr addr; 00161 memcpy(&addr.bdaddr, &ci->bdaddr, 6); 00162 //int s = SDP.Open(&addr.hdr); 00163 } 00164 break; 00165 case CALLBACK_PIN_REQ: 00166 printf("Enter PIN for "); 00167 printf((BD_ADDR*)data); 00168 printf(" : submitting %s\n", pin); 00169 //USBLoop(); wait(1.0); USBLoop(); 00170 //for(int k=0; k<2000000;k++) USBLoop(); 00171 PinCodeReply(data, pin); 00172 break; 00173 case CALLBACK_VENDOR: 00174 printfBytes("Vendor Reply:", data, len); 00175 //mbed_reset(); 00176 if (data[0] == 0xc2) 00177 csr_reset_device(false); 00178 break; 00179 default: 00180 printf("Unhandled HCI Callback %d\n", evt); 00181 }; 00182 printf("\x1b[%dm", 0); 00183 } 00184 00185 #define CSR_WRITE 0xFC00 00186 00187 int application::csr_write_bd_addr(BD_ADDR *bdaddr, bool transient) { 00188 unsigned char cmd[] = { 0xc2, 00189 0x02, 0x00, 0x0c, 0x00, 0x11, 0x47, 0x03, 0x70, 00190 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 00191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00192 }; 00193 00194 if (transient) 00195 cmd[15] = 0x08; 00196 00197 cmd[17] = bdaddr->addr[2]; 00198 cmd[18] = 0x00; 00199 cmd[19] = bdaddr->addr[0]; 00200 cmd[20] = bdaddr->addr[1]; 00201 cmd[21] = bdaddr->addr[3]; 00202 cmd[22] = 0x00; 00203 cmd[23] = bdaddr->addr[4]; 00204 cmd[24] = bdaddr->addr[5]; 00205 00206 return SendCmd(CSR_WRITE, cmd, sizeof(cmd)); 00207 } 00208 00209 int application::csr_reset_device(bool transient) { 00210 unsigned char cmd[] = { 0xc2, 0x02, 0x00, 0x09, 0x00, 00211 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 00212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00213 }; 00214 00215 if (transient) 00216 cmd[7] = 0x02; 00217 00218 return SendCmd(CSR_WRITE, cmd, sizeof(cmd)); 00219 } 00220 00221 00222 // these should be placed in the DMA SRAM 00223 typedef struct { 00224 u8 _hciBuffer[MAX_HCL_SIZE]; 00225 u8 _aclBuffer[MAX_ACL_SIZE]; 00226 } SRAMPlacement; 00227 00228 HCITransportUSB _HCITransportUSB; //use USB as the transport to the radio 00229 00230 int OnBluetoothInsert(int device) {//install the HCI and start discovery, user callbacks are made to HciCalback 00231 printf("Bluetooth inserted of %d\n",device); 00232 u32 sramLen; 00233 u8* sram = USBGetBuffer(&sramLen); 00234 sram = (u8*)(((u32)sram + 1023) & ~1023); 00235 SRAMPlacement* s = (SRAMPlacement*)sram; 00236 _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);//setup buffers for USB host, incoming data goes first to HCIRecv and ACLRecv 00237 RegisterSocketHandler(SOCKET_L2CAP,&App); //register the application::hci as handler for L2CAP events 00238 RegisterSocketHandler(SOCKET_RFCOM, &rfcomm_manager);//set the RFCOMMManager as the RFCOM socket handler 00239 if (RegisterSocketHandler(SOCKET_SDP, &SDP)) 00240 printf("Could not register SDP socket type\n"); 00241 App.Open(&_HCITransportUSB);//the callback is virtual 00242 App.Inquiry();//start discovery of BT devices phase 0 00243 return 0; 00244 } 00245 00246 DigitalOut led(LED1), loop(LED2); 00247 00248 int comm = 0; 00249 btserial *incoming, *outgoing; 00250 00251 void echo(int socket, SocketState state, const u8* data, int len, void* userData) { 00252 const u8 connack[] = { 0xbe, 0xef, 8, 'C','O','N','N','_','A','C','K', 0x11}; 00253 printf("Echo: socket %d, state %d, len=%d\n", socket, state, len); 00254 if (state==SocketState_Open) { 00255 if (len == 0) { 00256 printf("Sending CONN_ACK\n"); 00257 Socket_Send(socket, connack, sizeof(connack)); 00258 } else { 00259 //Socket_Send(socket, data, len); 00260 printfBytes("echo:", data, len); 00261 } 00262 } 00263 } 00264 00265 void TestShell() { 00266 int n=0; 00267 USBInit(); 00268 for (;;) { 00269 switch (state) { 00270 case 0: //inquiry and low-level connection 00271 break; 00272 case 1: {//initialisation 00273 printf("Ready to open ports\n"); 00274 InitFtBtDeviceList(); 00275 int n = GetNrOfFtBtDevices(); 00276 printf("%d ft BT devices have been found\n", n); 00277 if (n > 0) { 00278 ftbtdev *d = GetFtUsbDeviceHandle(0); 00279 if (d==0) printf("could not get device handle\n"); 00280 int sock = OpenFtBtDevice(d); 00281 } 00282 state = 2; 00283 //comm = Socket_Listen(SOCKET_RFCOM, 1, echo, 0); 00284 //incoming = new btserial(1); 00285 } 00286 break; 00287 case 2://main loop 00288 /* if (incoming->readable()>0){ 00289 int c= incoming->getc(); 00290 putc(c, stderr); 00291 incoming->putc(c); 00292 } 00293 else if (incoming->readable()<0){ 00294 state = 3; 00295 printf("end of session"); 00296 delete incoming; 00297 }*/ 00298 break; 00299 default: 00300 break; 00301 } 00302 loop=1; 00303 USBLoop(); 00304 loop=0; 00305 n++; 00306 if (n>=500000) { 00307 n=0; 00308 led = !led; 00309 } 00310 } 00311 //printf("Dropped out of main loop!\n"); 00312 } 00313 00314 //********************************************************************************************************************************
Generated on Wed Jul 13 2022 01:10:48 by
1.7.2