Ad van der Weiden / Mbed 2 deprecated myBlueUSB

Dependencies:   mbed myUSBHost AvailableMemory

Dependents:   mbed_TANK_Kinect myBlueUSB_ros ftusbClass

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TestShell.cpp Source File

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 //********************************************************************************************************************************