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
- Committer:
- nobukuma
- Date:
- 2013-12-07
- Revision:
- 0:003889bc474f
- Child:
- 2:9f25a7fa1a54
File content as of revision 0:003889bc474f:
/* Copyright (c) 2010 Peter Barrett Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "mbed.h" #include <vector> #include "Utils.h" #include "USBHost.h" #include "hci.h" #include "HCITransportUSB.h" #include "RFCOMM.h" #include "ftclasslibusbdevbt.h" #include "sdp_data.h" #include "sdp.h" #include "btserial.h" #include "neighbourhood.h" /************************************************ TODO: mtu and credits are completely unhandled - in progress multiple rfcomm sessions should be possible - done SDP would be nice - beta multiple rfcomm channels are untested decoupling of rfcomm and application - much better packets are not reassembled - some are (HCI and ft application level) disconnect and timeouts ************************************************/ #define DEBUG 1 int state = 0; //int bulk = 0; void printf(const BD_ADDR* addr) { const u8* a = addr->addr; printf("%02X:%02X:%02X:%02X:%02X:%02X",a[5],a[4],a[3],a[2],a[1],a[0]); } const char FtDevClass[3] = {0x00, 0x1F, 0x82 }; const char SerDevClass[3] = {4, 1, 0x00}; // Instance //RFCOMMManager rfcomm_manager; class application : public HCI { BTDevice* devs[8]; int count, i, pending; public: // We have connected to a device void ConnectionComplete(connection_info* info) { printf("ConnectionComplete "); BD_ADDR* a = &info->bdaddr; printf(a); printf("\n"); RemoteNameRequest(a); for (i++; i < count; i++) {//find the next device to open printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3); if (devs[i]->_handle == 0 && memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0) {//or some other way to connect to RFCOMM devices BD_ADDR* bd = &devs[i]->_info.bdaddr; printf("Connecting to "); printf(bd); printf("\n"); pending++; CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.) printf("connection cmd was sent\n"); return; } } //state = 1; //start the real application } void ConnectDevices() { count = GetDevices(devs,8);//get pointers to all bluetooth devices pending = 0; for (i = 0; i < count; i++) { printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3); if (devs[i]->_handle == 0 /*&& memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0*/) {//or some other way to connect to RFCOMM devices BD_ADDR* bd = &devs[i]->_info.bdaddr; printf("Connecting to "); printf(bd); printf("\n"); pending++; CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.) printf("connection cmd was sent\n"); return; } } if (pending == 0) state = 1;//for the case when there are no ft devices } virtual void Callback(HCI_CALLBACK_EVENT c, const u8* data, int len); int csr_write_bd_addr(BD_ADDR *bdaddr, bool transient=true); int csr_reset_device(bool transient=true); } App; //application instance extern "C" void mbed_reset(); void application::Callback(HCI_CALLBACK_EVENT evt, const u8* data, int len) {//these events are forwarded (in)directly from HCIRecv unsigned char pin[] = "1234"; unsigned char newaddr[] = {0x2c, 0x07, 0x54, 0x7b, 0x13, 0x00};//possible ft TX address (ROBO TX-277) // unsigned char newaddr[] = {0x57, 0x0a, 0x3d, 0x83, 0x15, 0x00};//original address of the cheap round BT dongle printf("\x1b[%dm", 33); switch (evt) { case CALLBACK_READY: printf("CALLBACK_READY\n"); printf("my address = "); printf((BD_ADDR*)data); if (memcmp(newaddr, data, 6) != 0) { //csr_write_bd_addr((BD_ADDR*)newaddr, false); } Inquiry();//start the second phase of the discovery break; case CALLBACK_INQUIRY_RESULT: //optionally build the list of FT devices here printf("CALLBACK_INQUIRY_RESULT "); printf((BD_ADDR*)data); printf("\n");//data points to inquiry_info struct // RemoteNameRequest((BD_ADDR*)data); break; case CALLBACK_INQUIRY_DONE: printf("CALLBACK_INQUIRY_DONE\n"); neighbors = new neighbourhood(&App); neighbors->read(); ConnectDevices(); break; case CALLBACK_REMOTE_NAME: { BD_ADDR* addr = (BD_ADDR*)data; const char* name = (const char*)(data + 6); printf(addr); printf(" = % s\n",name); pending--; if (pending == 0) state = 1; } break; case CALLBACK_CONNECTION_COMPLETE: { connection_info *ci = (connection_info*)data; if (ci->status>0) { printf("Connection failed, status=0x%02X\n", ci->status); break; } ConnectionComplete(ci); printf("Going to open sdp socket\n"); L2CAPAddr addr; memcpy(&addr.bdaddr, &ci->bdaddr, 6); //int s = SDP.Open(&addr.hdr); } break; case CALLBACK_PIN_REQ: printf("Enter PIN for "); printf((BD_ADDR*)data); printf(" : submitting %s\n", pin); //USBLoop(); wait(1.0); USBLoop(); //for(int k=0; k<2000000;k++) USBLoop(); PinCodeReply(data, pin); break; case CALLBACK_VENDOR: printfBytes("Vendor Reply:", data, len); //mbed_reset(); if (data[0] == 0xc2) csr_reset_device(false); break; default: printf("Unhandled HCI Callback %d\n", evt); }; printf("\x1b[%dm", 0); } #define CSR_WRITE 0xFC00 int application::csr_write_bd_addr(BD_ADDR *bdaddr, bool transient) { unsigned char cmd[] = { 0xc2, 0x02, 0x00, 0x0c, 0x00, 0x11, 0x47, 0x03, 0x70, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; if (transient) cmd[15] = 0x08; cmd[17] = bdaddr->addr[2]; cmd[18] = 0x00; cmd[19] = bdaddr->addr[0]; cmd[20] = bdaddr->addr[1]; cmd[21] = bdaddr->addr[3]; cmd[22] = 0x00; cmd[23] = bdaddr->addr[4]; cmd[24] = bdaddr->addr[5]; return SendCmd(CSR_WRITE, cmd, sizeof(cmd)); } int application::csr_reset_device(bool transient) { unsigned char cmd[] = { 0xc2, 0x02, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; if (transient) cmd[7] = 0x02; return SendCmd(CSR_WRITE, cmd, sizeof(cmd)); } // these should be placed in the DMA SRAM typedef struct { u8 _hciBuffer[MAX_HCL_SIZE]; u8 _aclBuffer[MAX_ACL_SIZE]; } SRAMPlacement; HCITransportUSB _HCITransportUSB; //use USB as the transport to the radio int OnBluetoothInsert(int device) {//install the HCI and start discovery, user callbacks are made to HciCalback printf("Bluetooth inserted of %d\n",device); u32 sramLen; u8* sram = USBGetBuffer(&sramLen); sram = (u8*)(((u32)sram + 1023) & ~1023); SRAMPlacement* s = (SRAMPlacement*)sram; _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);//setup buffers for USB host, incoming data goes first to HCIRecv and ACLRecv RegisterSocketHandler(SOCKET_L2CAP,&App); //register the application::hci as handler for L2CAP events RegisterSocketHandler(SOCKET_RFCOM, &rfcomm_manager);//set the RFCOMMManager as the RFCOM socket handler if (RegisterSocketHandler(SOCKET_SDP, &SDP)) printf("Could not register SDP socket type\n"); App.Open(&_HCITransportUSB);//the callback is virtual App.Inquiry();//start discovery of BT devices phase 0 return 0; } DigitalOut led(LED1), loop(LED2); int comm = 0; btserial *incoming, *outgoing; void echo(int socket, SocketState state, const u8* data, int len, void* userData) { const u8 connack[] = { 0xbe, 0xef, 8, 'C','O','N','N','_','A','C','K', 0x11}; printf("Echo: socket %d, state %d, len=%d\n", socket, state, len); if (state==SocketState_Open) { if (len == 0) { printf("Sending CONN_ACK\n"); Socket_Send(socket, connack, sizeof(connack)); } else { //Socket_Send(socket, data, len); printfBytes("echo:", data, len); } } } void TestShell() { int n=0; USBInit(); for (;;) { switch (state) { case 0: //inquiry and low-level connection break; case 1: {//initialisation printf("Ready to open ports\n"); InitFtBtDeviceList(); int n = GetNrOfFtBtDevices(); printf("%d ft BT devices have been found\n", n); if (n > 0) { ftbtdev *d = GetFtUsbDeviceHandle(0); if (d==0) printf("could not get device handle\n"); int sock = OpenFtBtDevice(d); } state = 2; //comm = Socket_Listen(SOCKET_RFCOM, 1, echo, 0); //incoming = new btserial(1); } break; case 2://main loop /* if (incoming->readable()>0){ int c= incoming->getc(); putc(c, stderr); incoming->putc(c); } else if (incoming->readable()<0){ state = 3; printf("end of session"); delete incoming; }*/ break; default: break; } loop=1; USBLoop(); loop=0; n++; if (n>=500000) { n=0; led = !led; } } //printf("Dropped out of main loop!\n"); } //********************************************************************************************************************************