class library to access fischertechnik interfaces via USB
Dependencies: FatFileSystem mbed myBlueUSB neigbourhood rfcomm sdp
ftlib/ftusb.cpp
- Committer:
- networker
- Date:
- 2013-03-11
- Revision:
- 1:4676e8b9b357
- Parent:
- 0:7da612835693
File content as of revision 1:4676e8b9b357:
#include "mbed.h" #include "USBHost.h" #include "ftusb.h" #include <vector> #include "Utils.h" #include "HCITransportUSB.h" #include "Socket.h" #include "RFCOMM.h" #include "sdp.h" #include "neighbourhood.h" // these should be placed in the DMA SRAM typedef struct { u8 _hciBuffer[MAX_HCL_SIZE]; u8 _aclBuffer[MAX_ACL_SIZE]; } SRAMPlacement; const char FtDevClass[3] = {0x00, 0x1F, 0x82 }; const char SerDevClass[3] = {4, 1, 0x00}; HCITransportUSB _HCITransportUSB; //use USB as the transport to the radio BTApp Bluetooth; vector<_ftdev> devs; bool tx_emulation = false; void OnLoadFtDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc) { for (int i = 0; i < devs.size(); i++) if (devs[i].device == device) { printf("device %d was already in the list\n", device); return; } switch (deviceDesc->idProduct) { case 1: devs.push_back(*new _ftdev(device, deviceDesc->idProduct, deviceDesc->iSerialNumber)); printf("RoboInterface\n"); break; case 2: devs.push_back(*new _ftdev(device, deviceDesc->idProduct, deviceDesc->iSerialNumber)); printf("RoboExtension\n"); break; case 3: devs.push_back(*new _ftdev(device, deviceDesc->idProduct, deviceDesc->iSerialNumber, 0)); printf("Robo RF Interface\n"); break; case 4: printf("Sound\n"); break; case 4096: devs.push_back(*new _ftdev(device, deviceDesc->idProduct, deviceDesc->iSerialNumber)); printf("TX Controller\n"); break; default: printf("fischertechnik product %d\n", deviceDesc->idProduct); break; } } 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,&Bluetooth); //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"); Bluetooth.Open(&_HCITransportUSB);//the callback is virtual, calls BTApp::Callback Bluetooth.Inquiry();//start discovery of BT devices phase 0 return 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]); } // We have connected to a device void BTApp::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 ft 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; } } } void BTApp::ConnectDevices() { count = GetDevices(devs,8);//get pointers to all bluetooth devices pending = 0; for (i = 0; i < count; i++) {//find first ft device (when filter works, all devices are ft devices) //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; } } } void BTApp::Callback(HCI_CALLBACK_EVENT evt, const u8* data, int len) {//these events are forwarded (in)directly from HCIRecv unsigned char pin[] = "1234"; u8 filter[] = {0x00, 0x1F, 0x82, 0xFF, 0xFF, 0xFF }; unsigned char ftaddr[] = {0x2c, 0x07, 0x54, 0x7b, 0x13, 0x00};//possible ft TX address (ROBO TX-277) 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) { //spoof address printf("programming new spoofed address\n"); //csr_write_bd_addr((BD_ADDR*)newaddr, false); } if (memcmp(ftaddr+3, data+3, 3) == 0) { tx_emulation = true; printf("ft BT address => TX emulation mode\n"); } SetEventFilter(1, 1, filter); 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 break; case CALLBACK_INQUIRY_DONE: printf("CALLBACK_INQUIRY_DONE\n"); neighbors = new neighbourhood(&Bluetooth); 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--; } 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); PinCodeReply(data, pin); break; default: printf("Unhandled HCI Callback %d\n", evt); }; printf("\x1b[%dm", 0); } #define CSR_WRITE 0xFC00 int BTApp::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 BTApp::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)); }