Jason Engelman / Mbed 2 deprecated BlueUSB

Dependencies:   mbed

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 
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027 #include <string.h>
00028 //#include "Devices/CP2103.h"
00029 
00030 #include "Utils.h"
00031 #include "USBHost.h"
00032 #include "hci.h"
00033 
00034 
00035 
00036 void printf(const BD_ADDR* addr)
00037 {
00038     const u8* a = addr->addr;
00039     printf("%02X:%02X:%02X:%02X:%02X:%02X",a[5],a[4],a[3],a[2],a[1],a[0]);
00040 }
00041 
00042 #define MAX_HCL_SIZE 260
00043 #define MAX_ACL_SIZE 400
00044 
00045 class HCITransportUSB : public HCITransport
00046 {
00047     int _device;
00048     u8* _hciBuffer;
00049     u8* _aclBuffer;
00050 
00051     public:
00052     void Open(int device, u8* hciBuffer, u8* aclBuffer)
00053     {
00054         _device = device;
00055         _hciBuffer = hciBuffer;
00056         _aclBuffer = aclBuffer;
00057         USBInterruptTransfer(_device,0x81,_hciBuffer,MAX_HCL_SIZE,HciCallback,this);
00058         USBBulkTransfer(_device,0x82,_aclBuffer,MAX_ACL_SIZE,AclCallback,this);
00059     }
00060 
00061     static void HciCallback(int device, int endpoint, int status, u8* data, int len, void* userData)
00062     {
00063         HCI* t = ((HCITransportUSB*)userData)->_target;
00064         if (t)
00065             t->HCIRecv(data,len);
00066         USBInterruptTransfer(device,0x81,data,MAX_HCL_SIZE,HciCallback,userData);
00067     }
00068 
00069     static void AclCallback(int device, int endpoint, int status, u8* data, int len, void* userData)
00070     {
00071         HCI* t = ((HCITransportUSB*)userData)->_target;
00072         if (t)
00073             t->ACLRecv(data,len);
00074         USBBulkTransfer(device,0x82,data,MAX_ACL_SIZE,AclCallback,userData);
00075     }
00076 
00077     virtual void HCISend(const u8* data, int len)
00078     {
00079         USBControlTransfer(_device,REQUEST_TYPE_CLASS, 0, 0, 0,(u8*)data,len);
00080     }
00081 
00082     virtual void ACLSend(const u8* data, int len)
00083     {
00084         USBBulkTransfer(_device,0x02,(u8*)data,len);
00085     }
00086 };
00087 
00088 
00089 #define WII_REMOTE 0x042500
00090 
00091 class HIDBluetooth
00092 {
00093     int _control;   // Sockets for control (out) and interrupt (in)
00094     int _interrupt;
00095     int _devClass;
00096     BD_ADDR _addr;
00097     u8  _pad[2];    // Struct align
00098     
00099 public:
00100     HIDBluetooth() : _control(0),_interrupt(0),_devClass(0) {};
00101 
00102     bool InUse()
00103     {
00104         return _control != 0;
00105     }
00106 
00107     static void OnHidInterrupt(int socket, SocketState state, const u8* data, int len, void* userData)
00108     {
00109         HIDBluetooth* t = (HIDBluetooth*)userData;
00110         if (data)
00111         {
00112             if (t->_devClass == WII_REMOTE && data[1] == 0x30)
00113             {
00114                 printf("================wii====================\n");
00115                 t->Led();
00116                 t->Hid();   // ask for accelerometer
00117                 t->_devClass = 0;
00118             }
00119 
00120             const u8* d = data;
00121             switch (d[1])
00122             {
00123                 case 0x02:
00124                 {
00125                     int x = (signed char)d[3];
00126                     int y = (signed char)d[4];
00127                     printf("Mouse %2X dx:%d dy:%d\n",d[2],x,y);
00128                 }
00129                 break;
00130 
00131                 case 0x37: // Accelerometer http://wiki.wiimoteproject.com/Reports
00132                 {
00133                     int pad = (d[2] & 0x9F) | ((d[3] & 0x9F) << 8);
00134                     int x = (d[2] & 0x60) >> 5 | d[4] << 2;
00135                     int y = (d[3] & 0x20) >> 4 | d[5] << 2;
00136                     int z = (d[3] & 0x40) >> 5 | d[6] << 2;
00137                     printf("WII %04X %d %d %d\n",pad,x,y,z);
00138                 }
00139                 break;
00140                 default:
00141                     printHex(data,len);
00142             }
00143         }
00144     }
00145 
00146     static void OnHidControl(int socket, SocketState state, const u8* data, int len, void* userData)
00147     {
00148         printf("OnHidControl\n");
00149         if (data)
00150             printHex(data,len);
00151     }
00152 
00153     void Open(BD_ADDR* bdAddr, inquiry_info* info)
00154     {
00155         printf("L2CAPAddr size %d\n",sizeof(L2CAPAddr));
00156         _addr = *bdAddr;
00157         L2CAPAddr sockAddr;
00158         sockAddr.bdaddr = _addr;
00159         sockAddr.psm = L2CAP_PSM_HID_INTR;
00160                 printf("Socket_Open size %d\n",sizeof(L2CAPAddr));
00161         _interrupt = Socket_Open(SOCKET_L2CAP,&sockAddr.hdr,OnHidInterrupt,this);
00162         sockAddr.psm = L2CAP_PSM_HID_CNTL;
00163         _control = Socket_Open(SOCKET_L2CAP,&sockAddr.hdr,OnHidControl,this);
00164 
00165         printfBytes("OPEN DEVICE CLASS",info->dev_class,3);
00166         _devClass = (info->dev_class[0] << 16) | (info->dev_class[1] << 8) | info->dev_class[2];
00167     }
00168 
00169     void Close()
00170     {
00171         if (_control)
00172             Socket_Close(_control);
00173         if (_interrupt)
00174             Socket_Close(_interrupt);
00175        _control = _interrupt = 0;
00176     }
00177 
00178     void Led(int id = 0x10)
00179     {
00180         u8 led[3] = {0x52, 0x11, id};
00181         if (_control)
00182             Socket_Send(_control,led,3);
00183     }
00184 
00185     void Hid(int report = 0x37)
00186     {
00187         u8 hid[4] = { 0x52, 0x12, 0x00, report };
00188         if (_control != -1)
00189             Socket_Send(_control,hid,4);
00190     }
00191 };
00192 
00193 
00194 HCI* gHCI = 0;
00195 
00196 #define MAX_HID_DEVICES 8
00197 
00198 int GetConsoleChar();
00199 class ShellApp
00200 {
00201     char _line[64];
00202     HIDBluetooth    _hids[MAX_HID_DEVICES];
00203 
00204 public:
00205     void Ready()
00206     {
00207     printf("HIDBluetooth %d\n",sizeof(HIDBluetooth));
00208          memset(_hids,0,sizeof(_hids));
00209         Inquiry();
00210 
00211     }
00212 
00213     //  We have connected to a device
00214     void ConnectionComplete(HCI* hci, connection_info* info)
00215     {
00216     printf("ConnectionComplete ");
00217         BD_ADDR* a = &info->bdaddr;
00218         printf(a);
00219         BTDevice* bt = hci->Find(a);
00220         HIDBluetooth* hid = NewHIDBluetooth();
00221         printf("%08x %08x\n",bt,hid);
00222         if (hid)
00223             hid->Open(a,&bt->_info);
00224     }
00225 
00226     HIDBluetooth* NewHIDBluetooth()
00227     {
00228         for (int i = 0; i < MAX_HID_DEVICES; i++)
00229             if (!_hids[i].InUse())
00230                 return _hids+i;
00231         return 0;
00232     }
00233 
00234     void ConnectDevices()
00235     {
00236         BTDevice* devs[8];
00237         int count = gHCI->GetDevices(devs,8);
00238         for (int i = 0; i < count; i++)
00239         {
00240             printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
00241             if (devs[i]->_handle == 0)
00242             {
00243                 BD_ADDR* bd = &devs[i]->_info.bdaddr;
00244                 printf("Connecting to ");
00245                 printf(bd);
00246                 printf("\n");
00247                 gHCI->CreateConnection(bd);
00248             }
00249         }
00250     }
00251 
00252     const char* ReadLine()
00253     {
00254         int i;
00255         for (i = 0; i < 255; )
00256         {
00257             USBLoop();
00258             int c = GetConsoleChar();
00259             if (c == -1)
00260                 continue;
00261             if (c == '\n' || c == 13)
00262                 break;
00263             _line[i++] = c;
00264         }
00265         _line[i] = 0;
00266         return _line;
00267     }
00268 
00269     void Inquiry()
00270     {
00271         printf("Inquiry..\n");
00272         gHCI->Inquiry();
00273     }
00274 
00275     void List()
00276     {
00277         #if 0
00278         printf("%d devices\n",_deviceCount);
00279         for (int i = 0; i < _deviceCount; i++)
00280         {
00281             printf(&_devices[i].info.bdaddr);
00282             printf("\n");
00283         }
00284         #endif
00285     }
00286 
00287     void Connect()
00288     {
00289         ConnectDevices();
00290     }
00291 
00292     void Disconnect()
00293     {
00294         gHCI->DisconnectAll();
00295     }
00296 
00297     void CloseMouse()
00298     {
00299     }
00300 
00301     void Quit()
00302     {
00303         CloseMouse();
00304     }
00305 
00306     void Run()
00307     {
00308         for(;;)
00309         {
00310             const char* cmd = ReadLine();
00311             if (strcmp(cmd,"scan") == 0 || strcmp(cmd,"inquiry") == 0)
00312                 Inquiry();
00313             else if (strcmp(cmd,"ls") == 0)
00314                 List();
00315             else if (strcmp(cmd,"connect") == 0)
00316                 Connect();
00317             else if (strcmp(cmd,"disconnect") == 0)
00318                 Disconnect();
00319             else if (strcmp(cmd,"q")== 0)
00320             {
00321                 Quit();
00322                 break;
00323             } else {
00324                 printf("eh? %s\n",cmd);
00325             }
00326         }
00327     }
00328 };
00329 
00330 //  Instance
00331 ShellApp gApp;
00332 
00333 static int HciCallback(HCI* hci, HCI_CALLBACK_EVENT evt, const u8* data, int len)
00334 {
00335     switch (evt)
00336     {
00337         case CALLBACK_READY:
00338             printf("CALLBACK_READY\n");
00339             gApp.Ready();
00340             break;
00341 
00342         case CALLBACK_INQUIRY_RESULT:
00343             printf("CALLBACK_INQUIRY_RESULT ");
00344             printf((BD_ADDR*)data);
00345             printf("\n");
00346             break;
00347 
00348         case CALLBACK_INQUIRY_DONE:
00349             printf("CALLBACK_INQUIRY_DONE\n");
00350             gApp.ConnectDevices();
00351             break;
00352 
00353         case CALLBACK_REMOTE_NAME:
00354             {
00355                 BD_ADDR* addr = (BD_ADDR*)data;
00356                 const char* name = (const char*)(data + 6);
00357                 printf(addr);
00358                 printf(" % s\n",name);
00359             }
00360             break;
00361 
00362         case CALLBACK_CONNECTION_COMPLETE:
00363             gApp.ConnectionComplete(hci,(connection_info*)data);
00364             break;
00365     };
00366     return 0;
00367 }
00368 
00369 //  these should be placed in the DMA SRAM
00370 typedef struct
00371 {
00372     u8 _hciBuffer[MAX_HCL_SIZE];
00373     u8 _aclBuffer[MAX_ACL_SIZE];
00374 } SRAMPlacement;
00375 
00376 HCITransportUSB _HCITransportUSB;
00377 HCI _HCI;
00378 
00379 u8* USBGetBuffer(u32* len);
00380 int OnBluetoothInsert(int device)
00381 {
00382     printf("Bluetooth inserted of %d\n",device);
00383     u32 sramLen;
00384     u8* sram =  USBGetBuffer(&sramLen);
00385     sram = (u8*)(((u32)sram + 1023) & ~1023);
00386     SRAMPlacement* s = (SRAMPlacement*)sram;
00387     _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);
00388     _HCI.Open(&_HCITransportUSB,HciCallback);
00389     RegisterSocketHandler(SOCKET_L2CAP,&_HCI);
00390     gHCI = &_HCI;
00391     gApp.Inquiry();
00392     return 0;
00393 }
00394 
00395 
00396 int OnFTDIInsert(int device)
00397 {
00398     printf("FTDI inserted of %d\n",device);
00399 /*    u32 sramLen;
00400     u8* sram =  USBGetBuffer(&sramLen);
00401     sram = (u8*)(((u32)sram + 1023) & ~1023);
00402     SRAMPlacement* s = (SRAMPlacement*)sram;
00403     _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);
00404     _HCI.Open(&_HCITransportUSB,HciCallback);
00405     RegisterSocketHandler(SOCKET_L2CAP,&_HCI);
00406     gHCI = &_HCI;
00407     gApp.Inquiry();*/
00408     return 0;
00409 }
00410 
00411 void TestShell()
00412 {
00413     USBInit();
00414     gApp.Run();
00415 }