うおーるぼっと用プログラム Wiiリモコンからのダイレクト操作モードのみ BlueUSBをベースに使用しています。

Dependencies:   BD6211F mbed SimpleFilter

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