local fix version of myBlueUSB (http://mbed.org/users/networker/code/myBlueUSB/). - merge deleted files which are required to compile. - enable echo back of received data via RFCOMM.
Dependencies: AvailableMemory FatFileSystem mbed myUSBHost
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 if (devs[i]->_handle == 0) { // 00075 BD_ADDR* bd = &devs[i]->_info.bdaddr; 00076 printf("Connecting to "); 00077 printf(bd); 00078 printf("\n"); 00079 pending++; 00080 CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.) 00081 printf("connection cmd was sent\n"); 00082 return; 00083 } 00084 } 00085 //state = 1; //start the real application 00086 } 00087 00088 void ConnectDevices() { 00089 count = GetDevices(devs,8);//get pointers to all bluetooth devices 00090 pending = 0; 00091 for (i = 0; i < count; i++) { 00092 printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3); 00093 if (devs[i]->_handle == 0 /*&& memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0*/) {//or some other way to connect to RFCOMM devices 00094 BD_ADDR* bd = &devs[i]->_info.bdaddr; 00095 printf("Connecting to "); 00096 printf(bd); 00097 printf("\n"); 00098 pending++; 00099 CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.) 00100 printf("connection cmd was sent\n"); 00101 return; 00102 } 00103 } 00104 if (pending == 0) state = 1;//for the case when there are no ft devices 00105 } 00106 virtual void Callback(HCI_CALLBACK_EVENT c, const u8* data, int len); 00107 int csr_write_bd_addr(BD_ADDR *bdaddr, bool transient=true); 00108 int csr_reset_device(bool transient=true); 00109 } App; //application instance 00110 00111 extern "C" void mbed_reset(); 00112 00113 00114 void application::Callback(HCI_CALLBACK_EVENT evt, const u8* data, int len) {//these events are forwarded (in)directly from HCIRecv 00115 unsigned char pin[] = "1234"; 00116 unsigned char newaddr[] = {0x2c, 0x07, 0x54, 0x7b, 0x13, 0x00};//possible ft TX address (ROBO TX-277) 00117 // unsigned char newaddr[] = {0x57, 0x0a, 0x3d, 0x83, 0x15, 0x00};//original address of the cheap round BT dongle 00118 printf("\x1b[%dm", 33); 00119 switch (evt) { 00120 case CALLBACK_READY: 00121 printf("CALLBACK_READY\n"); 00122 printf("my address = "); 00123 printf((BD_ADDR*)data); 00124 if (memcmp(newaddr, data, 6) != 0) { //csr_write_bd_addr((BD_ADDR*)newaddr, false); 00125 } 00126 Inquiry();//start the second phase of the discovery 00127 break; 00128 00129 case CALLBACK_INQUIRY_RESULT: //optionally build the list of FT devices here 00130 printf("CALLBACK_INQUIRY_RESULT "); 00131 printf((BD_ADDR*)data); 00132 printf("\n");//data points to inquiry_info struct 00133 // RemoteNameRequest((BD_ADDR*)data); 00134 break; 00135 00136 case CALLBACK_INQUIRY_DONE: 00137 printf("CALLBACK_INQUIRY_DONE\n"); 00138 neighbors = new neighbourhood(&App); 00139 neighbors->read(); 00140 ConnectDevices(); 00141 break; 00142 00143 case CALLBACK_REMOTE_NAME: { 00144 BD_ADDR* addr = (BD_ADDR*)data; 00145 const char* name = (const char*)(data + 6); 00146 printf(addr); 00147 printf(" = % s\n",name); 00148 pending--; 00149 if (pending == 0) state = 1; 00150 } 00151 break; 00152 00153 case CALLBACK_CONNECTION_COMPLETE: { 00154 connection_info *ci = (connection_info*)data; 00155 if (ci->status>0) { 00156 printf("Connection failed, status=0x%02X\n", ci->status); 00157 break; 00158 } 00159 ConnectionComplete(ci); 00160 printf("Going to open sdp socket\n"); 00161 L2CAPAddr addr; 00162 memcpy(&addr.bdaddr, &ci->bdaddr, 6); 00163 //int s = SDP.Open(&addr.hdr); 00164 } 00165 break; 00166 case CALLBACK_PIN_REQ: 00167 printf("Enter PIN for "); 00168 printf((BD_ADDR*)data); 00169 printf(" : submitting %s\n", pin); 00170 //USBLoop(); wait(1.0); USBLoop(); 00171 //for(int k=0; k<2000000;k++) USBLoop(); 00172 PinCodeReply(data, pin); 00173 break; 00174 case CALLBACK_VENDOR: 00175 printfBytes("Vendor Reply:", data, len); 00176 //mbed_reset(); 00177 if (data[0] == 0xc2) 00178 csr_reset_device(false); 00179 break; 00180 default: 00181 printf("Unhandled HCI Callback %d\n", evt); 00182 }; 00183 printf("\x1b[%dm", 0); 00184 } 00185 00186 #define CSR_WRITE 0xFC00 00187 00188 int application::csr_write_bd_addr(BD_ADDR *bdaddr, bool transient) { 00189 unsigned char cmd[] = { 0xc2, 00190 0x02, 0x00, 0x0c, 0x00, 0x11, 0x47, 0x03, 0x70, 00191 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 00192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00193 }; 00194 00195 if (transient) 00196 cmd[15] = 0x08; 00197 00198 cmd[17] = bdaddr->addr[2]; 00199 cmd[18] = 0x00; 00200 cmd[19] = bdaddr->addr[0]; 00201 cmd[20] = bdaddr->addr[1]; 00202 cmd[21] = bdaddr->addr[3]; 00203 cmd[22] = 0x00; 00204 cmd[23] = bdaddr->addr[4]; 00205 cmd[24] = bdaddr->addr[5]; 00206 00207 return SendCmd(CSR_WRITE, cmd, sizeof(cmd)); 00208 } 00209 00210 int application::csr_reset_device(bool transient) { 00211 unsigned char cmd[] = { 0xc2, 0x02, 0x00, 0x09, 0x00, 00212 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 00213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00214 }; 00215 00216 if (transient) 00217 cmd[7] = 0x02; 00218 00219 return SendCmd(CSR_WRITE, cmd, sizeof(cmd)); 00220 } 00221 00222 00223 // these should be placed in the DMA SRAM 00224 typedef struct { 00225 u8 _hciBuffer[MAX_HCL_SIZE]; 00226 u8 _aclBuffer[MAX_ACL_SIZE]; 00227 } SRAMPlacement; 00228 00229 HCITransportUSB _HCITransportUSB; //use USB as the transport to the radio 00230 00231 int OnBluetoothInsert(int device) {//install the HCI and start discovery, user callbacks are made to HciCalback 00232 printf("Bluetooth inserted of %d\n",device); 00233 u32 sramLen; 00234 u8* sram = USBGetBuffer(&sramLen); 00235 sram = (u8*)(((u32)sram + 1023) & ~1023); 00236 SRAMPlacement* s = (SRAMPlacement*)sram; 00237 _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);//setup buffers for USB host, incoming data goes first to HCIRecv and ACLRecv 00238 RegisterSocketHandler(SOCKET_L2CAP,&App); //register the application::hci as handler for L2CAP events 00239 RegisterSocketHandler(SOCKET_RFCOM, &rfcomm_manager);//set the RFCOMMManager as the RFCOM socket handler 00240 if (RegisterSocketHandler(SOCKET_SDP, &SDP)) 00241 printf("Could not register SDP socket type\n"); 00242 App.Open(&_HCITransportUSB);//the callback is virtual 00243 App.Inquiry();//start discovery of BT devices phase 0 00244 return 0; 00245 } 00246 00247 DigitalOut led(LED1), loop(LED2); 00248 00249 int comm = 0; 00250 btserial *incoming, *outgoing; 00251 00252 void echo(int socket, SocketState state, const u8* data, int len, void* userData) { 00253 const u8 connack[] = { 0xbe, 0xef, 8, 'C','O','N','N','_','A','C','K', 0x11}; 00254 printf("Echo: socket %d, state %d, len=%d\n", socket, state, len); 00255 if (state==SocketState_Open) { 00256 if (len == 0) { 00257 printf("Sending CONN_ACK\n"); 00258 Socket_Send(socket, connack, sizeof(connack)); 00259 } else { 00260 printf("echo back: len=%d, data[0]=%x\n", len, data[0]); 00261 Socket_Send(socket, data, len); // uncomment 00262 printfBytes("echo:", data, len); 00263 } 00264 } 00265 } 00266 00267 void TestShell() { 00268 int n=0; 00269 USBInit(); 00270 for (;;) { 00271 switch (state) { 00272 case 0: //inquiry and low-level connection 00273 break; 00274 case 1: {//initialisation 00275 printf("Ready to open ports\n"); 00276 InitFtBtDeviceList(); 00277 int n = GetNrOfFtBtDevices(); 00278 printf("%d ft BT devices have been found\n", n); 00279 if (n > 0) { 00280 ftbtdev *d = GetFtUsbDeviceHandle(0); 00281 if (d==0) printf("could not get device handle\n"); 00282 int sock = OpenFtBtDevice(d); 00283 } 00284 state = 2; 00285 comm = Socket_Listen(SOCKET_RFCOM, 1, echo, 0); // uncomment 00286 //incoming = new btserial(1); 00287 } 00288 break; 00289 case 2://main loop 00290 /*if (incoming->readable()>0){ 00291 int c= incoming->getc(); 00292 putc(c, stderr); 00293 incoming->putc(c); 00294 } 00295 else if (incoming->readable()<0){ 00296 state = 3; 00297 printf("end of session"); 00298 delete incoming; 00299 }*/ 00300 break; 00301 default: 00302 break; 00303 } 00304 loop=1; 00305 USBLoop(); 00306 loop=0; 00307 n++; 00308 if (n>=500000) { 00309 n=0; 00310 led = !led; 00311 } 00312 } 00313 //printf("Dropped out of main loop!\n"); 00314 } 00315 00316 //********************************************************************************************************************************
Generated on Tue Jul 12 2022 18:48:53 by 1.7.2