class library to access fischertechnik interfaces via USB

Dependencies:   FatFileSystem mbed myBlueUSB neigbourhood rfcomm sdp

Committer:
networker
Date:
Mon Mar 11 08:04:37 2013 +0000
Revision:
1:4676e8b9b357
Parent:
0:7da612835693
first publication of this experimental class, just for sharing wip

Who changed what in which revision?

UserRevisionLine numberNew contents of line
networker 0:7da612835693 1 #include "mbed.h"
networker 0:7da612835693 2 #include "USBHost.h"
networker 0:7da612835693 3 #include "ftusb.h"
networker 0:7da612835693 4 #include <vector>
networker 1:4676e8b9b357 5 #include "Utils.h"
networker 0:7da612835693 6 #include "HCITransportUSB.h"
networker 0:7da612835693 7 #include "Socket.h"
networker 0:7da612835693 8 #include "RFCOMM.h"
networker 0:7da612835693 9 #include "sdp.h"
networker 1:4676e8b9b357 10 #include "neighbourhood.h"
networker 0:7da612835693 11
networker 0:7da612835693 12 // these should be placed in the DMA SRAM
networker 0:7da612835693 13 typedef struct {
networker 0:7da612835693 14 u8 _hciBuffer[MAX_HCL_SIZE];
networker 0:7da612835693 15 u8 _aclBuffer[MAX_ACL_SIZE];
networker 0:7da612835693 16 } SRAMPlacement;
networker 0:7da612835693 17
networker 0:7da612835693 18 const char FtDevClass[3] = {0x00, 0x1F, 0x82 };
networker 0:7da612835693 19 const char SerDevClass[3] = {4, 1, 0x00};
networker 0:7da612835693 20
networker 0:7da612835693 21 HCITransportUSB _HCITransportUSB; //use USB as the transport to the radio
networker 0:7da612835693 22 BTApp Bluetooth;
networker 0:7da612835693 23 vector<_ftdev> devs;
networker 1:4676e8b9b357 24 bool tx_emulation = false;
networker 0:7da612835693 25
networker 0:7da612835693 26 void OnLoadFtDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc) {
networker 0:7da612835693 27 for (int i = 0; i < devs.size(); i++)
networker 0:7da612835693 28 if (devs[i].device == device) {
networker 0:7da612835693 29 printf("device %d was already in the list\n", device);
networker 0:7da612835693 30 return;
networker 0:7da612835693 31 }
networker 0:7da612835693 32 switch (deviceDesc->idProduct) {
networker 0:7da612835693 33 case 1:
networker 0:7da612835693 34 devs.push_back(*new _ftdev(device, deviceDesc->idProduct, deviceDesc->iSerialNumber));
networker 0:7da612835693 35 printf("RoboInterface\n");
networker 0:7da612835693 36 break;
networker 0:7da612835693 37 case 2:
networker 0:7da612835693 38 devs.push_back(*new _ftdev(device, deviceDesc->idProduct, deviceDesc->iSerialNumber));
networker 0:7da612835693 39 printf("RoboExtension\n");
networker 0:7da612835693 40 break;
networker 0:7da612835693 41 case 3:
networker 0:7da612835693 42 devs.push_back(*new _ftdev(device, deviceDesc->idProduct, deviceDesc->iSerialNumber, 0));
networker 0:7da612835693 43 printf("Robo RF Interface\n");
networker 0:7da612835693 44 break;
networker 0:7da612835693 45 case 4:
networker 0:7da612835693 46 printf("Sound\n");
networker 0:7da612835693 47 break;
networker 0:7da612835693 48 case 4096:
networker 0:7da612835693 49 devs.push_back(*new _ftdev(device, deviceDesc->idProduct, deviceDesc->iSerialNumber));
networker 0:7da612835693 50 printf("TX Controller\n");
networker 0:7da612835693 51 break;
networker 0:7da612835693 52 default:
networker 0:7da612835693 53 printf("fischertechnik product %d\n", deviceDesc->idProduct);
networker 0:7da612835693 54 break;
networker 0:7da612835693 55 }
networker 0:7da612835693 56 }
networker 0:7da612835693 57
networker 0:7da612835693 58
networker 0:7da612835693 59 int OnBluetoothInsert(int device) {//install the HCI and start discovery, user callbacks are made to HciCalback
networker 0:7da612835693 60 printf("Bluetooth inserted of %d\n",device);
networker 0:7da612835693 61 u32 sramLen;
networker 0:7da612835693 62 u8* sram = USBGetBuffer(&sramLen);
networker 0:7da612835693 63 sram = (u8*)(((u32)sram + 1023) & ~1023);
networker 0:7da612835693 64 SRAMPlacement* s = (SRAMPlacement*)sram;
networker 0:7da612835693 65 _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);//setup buffers for USB host, incoming data goes first to HCIRecv and ACLRecv
networker 0:7da612835693 66 RegisterSocketHandler(SOCKET_L2CAP,&Bluetooth); //register the application::hci as handler for L2CAP events
networker 0:7da612835693 67 RegisterSocketHandler(SOCKET_RFCOM, &rfcomm_manager);//set the RFCOMMManager as the RFCOM socket handler
networker 0:7da612835693 68 if (RegisterSocketHandler(SOCKET_SDP, &SDP))
networker 0:7da612835693 69 printf("Could not register SDP socket type\n");
networker 0:7da612835693 70 Bluetooth.Open(&_HCITransportUSB);//the callback is virtual, calls BTApp::Callback
networker 0:7da612835693 71 Bluetooth.Inquiry();//start discovery of BT devices phase 0
networker 0:7da612835693 72 return 0;
networker 0:7da612835693 73 }
networker 0:7da612835693 74
networker 0:7da612835693 75 void printf(const BD_ADDR* addr) {
networker 0:7da612835693 76 const u8* a = addr->addr;
networker 0:7da612835693 77 printf("%02X:%02X:%02X:%02X:%02X:%02X",a[5],a[4],a[3],a[2],a[1],a[0]);
networker 0:7da612835693 78 }
networker 0:7da612835693 79
networker 0:7da612835693 80 // We have connected to a device
networker 0:7da612835693 81 void BTApp::ConnectionComplete(connection_info* info) {
networker 0:7da612835693 82 printf("ConnectionComplete ");
networker 0:7da612835693 83 BD_ADDR* a = &info->bdaddr;
networker 0:7da612835693 84 printf(a);
networker 0:7da612835693 85 printf("\n");
networker 0:7da612835693 86 RemoteNameRequest(a);
networker 0:7da612835693 87 for (i++; i < count; i++) {//find the next ft device to open
networker 0:7da612835693 88 //printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
networker 0:7da612835693 89 if (devs[i]->_handle == 0 && memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0) {//or some other way to connect to RFCOMM devices
networker 0:7da612835693 90 BD_ADDR* bd = &devs[i]->_info.bdaddr;
networker 0:7da612835693 91 printf("Connecting to ");
networker 0:7da612835693 92 printf(bd);
networker 0:7da612835693 93 printf("\n");
networker 0:7da612835693 94 pending++;
networker 0:7da612835693 95 CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.)
networker 0:7da612835693 96 printf("connection cmd was sent\n");
networker 0:7da612835693 97 return;
networker 0:7da612835693 98 }
networker 0:7da612835693 99 }
networker 0:7da612835693 100 }
networker 0:7da612835693 101
networker 0:7da612835693 102 void BTApp::ConnectDevices() {
networker 0:7da612835693 103 count = GetDevices(devs,8);//get pointers to all bluetooth devices
networker 0:7da612835693 104 pending = 0;
networker 0:7da612835693 105 for (i = 0; i < count; i++) {//find first ft device (when filter works, all devices are ft devices)
networker 0:7da612835693 106 //printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
networker 0:7da612835693 107 if (devs[i]->_handle == 0 && memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0) {//or some other way to connect to RFCOMM devices
networker 0:7da612835693 108 BD_ADDR* bd = &devs[i]->_info.bdaddr;
networker 0:7da612835693 109 printf("Connecting to ");
networker 0:7da612835693 110 printf(bd);
networker 0:7da612835693 111 printf("\n");
networker 0:7da612835693 112 pending++;
networker 0:7da612835693 113 CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.)
networker 0:7da612835693 114 printf("connection cmd was sent\n");
networker 0:7da612835693 115 return;
networker 0:7da612835693 116 }
networker 0:7da612835693 117 }
networker 0:7da612835693 118 }
networker 0:7da612835693 119
networker 0:7da612835693 120 void BTApp::Callback(HCI_CALLBACK_EVENT evt, const u8* data, int len) {//these events are forwarded (in)directly from HCIRecv
networker 0:7da612835693 121 unsigned char pin[] = "1234";
networker 0:7da612835693 122 u8 filter[] = {0x00, 0x1F, 0x82, 0xFF, 0xFF, 0xFF };
networker 1:4676e8b9b357 123 unsigned char ftaddr[] = {0x2c, 0x07, 0x54, 0x7b, 0x13, 0x00};//possible ft TX address (ROBO TX-277)
networker 1:4676e8b9b357 124 unsigned char newaddr[] = {0x2c, 0x07, 0x54, 0x7b, 0x13, 0x00};//possible ft TX address (ROBO TX-277)
networker 1:4676e8b9b357 125 // unsigned char newaddr[] = {0x57, 0x0a, 0x3d, 0x83, 0x15, 0x00};//original address of the cheap round BT dongle
networker 0:7da612835693 126 printf("\x1b[%dm", 33);
networker 0:7da612835693 127 switch (evt) {
networker 0:7da612835693 128 case CALLBACK_READY:
networker 0:7da612835693 129 printf("CALLBACK_READY\n");
networker 0:7da612835693 130 printf("my address = ");
networker 0:7da612835693 131 printf((BD_ADDR*)data);
networker 1:4676e8b9b357 132 if (memcmp(newaddr, data, 6) != 0) { //spoof address
networker 1:4676e8b9b357 133 printf("programming new spoofed address\n");
networker 1:4676e8b9b357 134 //csr_write_bd_addr((BD_ADDR*)newaddr, false);
networker 1:4676e8b9b357 135 }
networker 1:4676e8b9b357 136 if (memcmp(ftaddr+3, data+3, 3) == 0) {
networker 1:4676e8b9b357 137 tx_emulation = true;
networker 1:4676e8b9b357 138 printf("ft BT address => TX emulation mode\n");
networker 1:4676e8b9b357 139 }
networker 0:7da612835693 140 SetEventFilter(1, 1, filter);
networker 0:7da612835693 141 Inquiry();//start the second phase of the discovery
networker 0:7da612835693 142 break;
networker 0:7da612835693 143
networker 0:7da612835693 144 case CALLBACK_INQUIRY_RESULT: //optionally build the list of FT devices here
networker 0:7da612835693 145 printf("CALLBACK_INQUIRY_RESULT ");
networker 0:7da612835693 146 printf((BD_ADDR*)data);
networker 0:7da612835693 147 printf("\n");//data points to inquiry_info struct
networker 0:7da612835693 148 break;
networker 0:7da612835693 149
networker 0:7da612835693 150 case CALLBACK_INQUIRY_DONE:
networker 0:7da612835693 151 printf("CALLBACK_INQUIRY_DONE\n");
networker 1:4676e8b9b357 152 neighbors = new neighbourhood(&Bluetooth);
networker 1:4676e8b9b357 153 neighbors->read();
networker 0:7da612835693 154 ConnectDevices();
networker 0:7da612835693 155 break;
networker 0:7da612835693 156
networker 0:7da612835693 157 case CALLBACK_REMOTE_NAME: {
networker 0:7da612835693 158 BD_ADDR* addr = (BD_ADDR*)data;
networker 0:7da612835693 159 const char* name = (const char*)(data + 6);
networker 0:7da612835693 160 printf(addr);
networker 0:7da612835693 161 printf(" = % s\n",name);
networker 0:7da612835693 162 pending--;
networker 0:7da612835693 163 }
networker 0:7da612835693 164 break;
networker 0:7da612835693 165
networker 0:7da612835693 166 case CALLBACK_CONNECTION_COMPLETE: {
networker 0:7da612835693 167 connection_info *ci = (connection_info*)data;
networker 0:7da612835693 168 if (ci->status>0) {
networker 0:7da612835693 169 printf("Connection failed, status=0x%02X\n", ci->status);
networker 0:7da612835693 170 break;
networker 0:7da612835693 171 }
networker 0:7da612835693 172 ConnectionComplete(ci);
networker 0:7da612835693 173 /*
networker 0:7da612835693 174 printf("Going to open sdp socket\n");
networker 0:7da612835693 175 L2CAPAddr addr;
networker 0:7da612835693 176 memcpy(&addr.bdaddr, &ci->bdaddr, 6);
networker 0:7da612835693 177 int s = SDP.Open(&addr.hdr);
networker 0:7da612835693 178 */
networker 0:7da612835693 179 }
networker 0:7da612835693 180 break;
networker 0:7da612835693 181 case CALLBACK_PIN_REQ:
networker 0:7da612835693 182 printf("Enter PIN for ");
networker 0:7da612835693 183 printf((BD_ADDR*)data);
networker 0:7da612835693 184 printf(" : submitting %s\n", pin);
networker 0:7da612835693 185 PinCodeReply(data, pin);
networker 0:7da612835693 186 break;
networker 0:7da612835693 187 default:
networker 0:7da612835693 188 printf("Unhandled HCI Callback %d\n", evt);
networker 0:7da612835693 189 };
networker 0:7da612835693 190 printf("\x1b[%dm", 0);
networker 0:7da612835693 191 }
networker 0:7da612835693 192
networker 1:4676e8b9b357 193 #define CSR_WRITE 0xFC00
networker 0:7da612835693 194
networker 1:4676e8b9b357 195 int BTApp::csr_write_bd_addr(BD_ADDR *bdaddr, bool transient) {
networker 1:4676e8b9b357 196 unsigned char cmd[] = { 0xc2,
networker 1:4676e8b9b357 197 0x02, 0x00, 0x0c, 0x00, 0x11, 0x47, 0x03, 0x70,
networker 1:4676e8b9b357 198 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
networker 1:4676e8b9b357 199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
networker 1:4676e8b9b357 200 };
networker 1:4676e8b9b357 201
networker 1:4676e8b9b357 202 if (transient)
networker 1:4676e8b9b357 203 cmd[15] = 0x08;
networker 1:4676e8b9b357 204
networker 1:4676e8b9b357 205 cmd[17] = bdaddr->addr[2];
networker 1:4676e8b9b357 206 cmd[18] = 0x00;
networker 1:4676e8b9b357 207 cmd[19] = bdaddr->addr[0];
networker 1:4676e8b9b357 208 cmd[20] = bdaddr->addr[1];
networker 1:4676e8b9b357 209 cmd[21] = bdaddr->addr[3];
networker 1:4676e8b9b357 210 cmd[22] = 0x00;
networker 1:4676e8b9b357 211 cmd[23] = bdaddr->addr[4];
networker 1:4676e8b9b357 212 cmd[24] = bdaddr->addr[5];
networker 1:4676e8b9b357 213
networker 1:4676e8b9b357 214 return SendCmd(CSR_WRITE, cmd, sizeof(cmd));
networker 1:4676e8b9b357 215 }
networker 1:4676e8b9b357 216
networker 1:4676e8b9b357 217 int BTApp::csr_reset_device(bool transient) {
networker 1:4676e8b9b357 218 unsigned char cmd[] = { 0xc2, 0x02, 0x00, 0x09, 0x00,
networker 1:4676e8b9b357 219 0x00, 0x00, 0x01, 0x40, 0x00, 0x00,
networker 1:4676e8b9b357 220 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
networker 1:4676e8b9b357 221 };
networker 1:4676e8b9b357 222
networker 1:4676e8b9b357 223 if (transient)
networker 1:4676e8b9b357 224 cmd[7] = 0x02;
networker 1:4676e8b9b357 225
networker 1:4676e8b9b357 226 return SendCmd(CSR_WRITE, cmd, sizeof(cmd));
networker 1:4676e8b9b357 227 }
networker 1:4676e8b9b357 228
networker 1:4676e8b9b357 229