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