Joe Nagata / 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 
00029 #include "Utils.h"
00030 #include "USBHost.h"
00031 #include "hci.h"
00032 
00033 #include "TextLCD.h"
00034 TextLCD     lcd( p24, p26, p27, p28, p29, p30 ); // rs, e, d4-d7
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                 
00141                 case 0x01: // Mini Keyboard
00142                  {
00143                      int keycode = (d[4]);
00144                      int shiftcode = (d[2]);
00145 //                     printf("Keycode = %02x \n",keycode);
00146 //  d[2] 0x01 ... Ctrl
00147 //  d[2] 0x02 ... Shift(L)
00148 //  d[2] 0x20 ... Shift(R)
00149 //  d[2] 0x40 ... Alt
00150 //  d[4] 0x28 ... Enter
00151 //  d[4] 0x2a ... <-
00152 
00153                      if(keycode>=0x04 && keycode<=0x1d){
00154                          if(shiftcode==0x02 || shiftcode==0x20){
00155                              lcd.printf("%c", keycode-0x04+'A');
00156                          } else {
00157                              lcd.printf("%c", keycode-0x04+'a');
00158                          }
00159                      } else {
00160                          if(shiftcode==0x02 || shiftcode==0x20){
00161                              switch(keycode){
00162                                  case 0x1e: { lcd.printf("!"); break; }
00163                                  case 0x1f: { lcd.printf("@"); break; }
00164                                  case 0x20: { lcd.printf("#"); break; }
00165                                  case 0x21: { lcd.printf("$"); break; }
00166                                  case 0x22: { lcd.printf("%%"); break; }
00167                                  case 0x23: { lcd.printf("^"); break; }
00168                                  case 0x24: { lcd.printf("&"); break; }
00169                                  case 0x25: { lcd.printf("*"); break; }
00170                                  case 0x26: { lcd.printf("("); break; }
00171                                  case 0x27: { lcd.printf(")"); break; }
00172                                  case 0x28: { lcd.printf("\n"); break; } // Enter
00173                                  case 0x2a: { lcd.printf("%c",0x7f); break; } // Del
00174                                  case 0x2c: { lcd.printf(" "); break; }
00175                                  case 0x33: { lcd.printf(":"); break; }
00176                                  case 0x36: { lcd.printf("<"); break; }
00177                                  case 0x37: { lcd.printf(">"); break; }
00178                                  case 0x38: { lcd.printf("?"); break; }
00179                              }
00180                          } else {
00181                              switch(keycode){
00182                                  case 0x1e: { lcd.printf("1"); break; }
00183                                  case 0x1f: { lcd.printf("2"); break; }
00184                                  case 0x20: { lcd.printf("3"); break; }
00185                                  case 0x21: { lcd.printf("4"); break; }
00186                                  case 0x22: { lcd.printf("5"); break; }
00187                                  case 0x23: { lcd.printf("6"); break; }
00188                                  case 0x24: { lcd.printf("7"); break; }
00189                                  case 0x25: { lcd.printf("8"); break; }
00190                                  case 0x26: { lcd.printf("9"); break; }
00191                                  case 0x27: { lcd.printf("0"); break; }
00192                                  case 0x28: { lcd.printf("\n"); break; } // Enter
00193                                  case 0x2a: { lcd.printf("%c",0x7f); break; } // Del
00194                                  case 0x2c: { lcd.printf(" "); break; }
00195                                  case 0x33: { lcd.printf(";"); break; }
00196                                  case 0x36: { lcd.printf(","); break; }
00197                                  case 0x37: { lcd.printf("."); break; }
00198                                  case 0x38: { lcd.printf("/"); break; }
00199                              }
00200                          }
00201                      }
00202                  }
00203                  break;
00204                  case 0x03: // Connected?
00205                  {
00206                      lcd.printf("Connect!\n");
00207                      break;
00208                   
00209                  }
00210                 
00211                 
00212                 
00213                 
00214                 default:
00215                     printHex(data,len);
00216             }
00217         }
00218     }
00219 
00220     static void OnHidControl(int socket, SocketState state, const u8* data, int len, void* userData)
00221     {
00222         printf("OnHidControl\n");
00223         if (data)
00224             printHex(data,len);
00225     }
00226 
00227     void Open(BD_ADDR* bdAddr, inquiry_info* info)
00228     {
00229         printf("L2CAPAddr size %d\n",sizeof(L2CAPAddr));
00230         _addr = *bdAddr;
00231         L2CAPAddr sockAddr;
00232         sockAddr.bdaddr = _addr;
00233         sockAddr.psm = L2CAP_PSM_HID_INTR;
00234                 printf("Socket_Open size %d\n",sizeof(L2CAPAddr));
00235         _interrupt = Socket_Open(SOCKET_L2CAP,&sockAddr.hdr,OnHidInterrupt,this);
00236         sockAddr.psm = L2CAP_PSM_HID_CNTL;
00237         _control = Socket_Open(SOCKET_L2CAP,&sockAddr.hdr,OnHidControl,this);
00238 
00239         printfBytes("OPEN DEVICE CLASS",info->dev_class,3);
00240         _devClass = (info->dev_class[0] << 16) | (info->dev_class[1] << 8) | info->dev_class[2];
00241     }
00242 
00243     void Close()
00244     {
00245         if (_control)
00246             Socket_Close(_control);
00247         if (_interrupt)
00248             Socket_Close(_interrupt);
00249        _control = _interrupt = 0;
00250     }
00251 
00252     void Led(int id = 0x10)
00253     {
00254         u8 led[3] = {0x52, 0x11, id};
00255         if (_control)
00256             Socket_Send(_control,led,3);
00257     }
00258 
00259     void Hid(int report = 0x37)
00260     {
00261         u8 hid[4] = { 0x52, 0x12, 0x00, report };
00262         if (_control != -1)
00263             Socket_Send(_control,hid,4);
00264     }
00265 };
00266 
00267 
00268 HCI* gHCI = 0;
00269 
00270 #define MAX_HID_DEVICES 8
00271 
00272 int GetConsoleChar();
00273 class ShellApp
00274 {
00275     char _line[64];
00276     HIDBluetooth    _hids[MAX_HID_DEVICES];
00277 
00278 public:
00279     void Ready()
00280     {
00281     printf("HIDBluetooth %d\n",sizeof(HIDBluetooth));
00282          memset(_hids,0,sizeof(_hids));
00283         Inquiry();
00284 
00285     }
00286 
00287     //  We have connected to a device
00288     void ConnectionComplete(HCI* hci, connection_info* info)
00289     {
00290     printf("ConnectionComplete ");
00291         BD_ADDR* a = &info->bdaddr;
00292         printf(a);
00293         BTDevice* bt = hci->Find(a);
00294         HIDBluetooth* hid = NewHIDBluetooth();
00295         printf("%08x %08x\n",bt,hid);
00296         if (hid)
00297             hid->Open(a,&bt->_info);
00298     }
00299 
00300     HIDBluetooth* NewHIDBluetooth()
00301     {
00302         for (int i = 0; i < MAX_HID_DEVICES; i++)
00303             if (!_hids[i].InUse())
00304                 return _hids+i;
00305         return 0;
00306     }
00307 
00308     void ConnectDevices()
00309     {
00310         BTDevice* devs[8];
00311         int count = gHCI->GetDevices(devs,8);
00312         for (int i = 0; i < count; i++)
00313         {
00314             printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
00315             if (devs[i]->_handle == 0)
00316             {
00317                 BD_ADDR* bd = &devs[i]->_info.bdaddr;
00318                 printf("Connecting to ");
00319                 printf(bd);
00320                 printf("\n");
00321                 gHCI->CreateConnection(bd);
00322             }
00323         }
00324     }
00325 
00326     const char* ReadLine()
00327     {
00328         int i;
00329         for (i = 0; i < 255; )
00330         {
00331             USBLoop();
00332             int c = GetConsoleChar();
00333             if (c == -1)
00334                 continue;
00335             if (c == '\n' || c == 13)
00336                 break;
00337             _line[i++] = c;
00338         }
00339         _line[i] = 0;
00340         return _line;
00341     }
00342 
00343     void Inquiry()
00344     {
00345         printf("Inquiry..\n");
00346         gHCI->Inquiry();
00347     }
00348 
00349     void List()
00350     {
00351         #if 0
00352         printf("%d devices\n",_deviceCount);
00353         for (int i = 0; i < _deviceCount; i++)
00354         {
00355             printf(&_devices[i].info.bdaddr);
00356             printf("\n");
00357         }
00358         #endif
00359     }
00360 
00361     void Connect()
00362     {
00363         ConnectDevices();
00364     }
00365 
00366     void Disconnect()
00367     {
00368         gHCI->DisconnectAll();
00369     }
00370 
00371     void CloseMouse()
00372     {
00373     }
00374 
00375     void Quit()
00376     {
00377         CloseMouse();
00378     }
00379 
00380     void Run()
00381     {
00382         for(;;)
00383         {
00384             const char* cmd = ReadLine();
00385             
00386             if (strcmp(cmd,"scan") == 0 || strcmp(cmd,"inquiry") == 0)
00387                 Inquiry();
00388             else if (strcmp(cmd,"ls") == 0)
00389                 List();
00390             else if (strcmp(cmd,"connect") == 0)
00391                 Connect();
00392             else if (strcmp(cmd,"disconnect") == 0)
00393                 Disconnect();
00394             else if (strcmp(cmd,"q")== 0)
00395             {
00396                 Quit();
00397                 break;
00398             } else {
00399                 printf("eh? %s\n",cmd);
00400             }
00401         }
00402     }
00403 };
00404 
00405 //  Instance
00406 ShellApp gApp;
00407 
00408 static int HciCallback(HCI* hci, HCI_CALLBACK_EVENT evt, const u8* data, int len)
00409 {
00410     switch (evt)
00411     {
00412         case CALLBACK_READY:
00413             printf("CALLBACK_READY\n");
00414             gApp.Ready();
00415             break;
00416 
00417         case CALLBACK_INQUIRY_RESULT:
00418             printf("CALLBACK_INQUIRY_RESULT ");
00419             printf((BD_ADDR*)data);
00420             printf("\n");
00421             break;
00422 
00423         case CALLBACK_INQUIRY_DONE:
00424             printf("CALLBACK_INQUIRY_DONE\n");
00425             gApp.ConnectDevices();
00426             break;
00427 
00428         case CALLBACK_REMOTE_NAME:
00429             {
00430                 BD_ADDR* addr = (BD_ADDR*)data;
00431                 const char* name = (const char*)(data + 6);
00432                 printf(addr);
00433                 printf(" % s\n",name);
00434             }
00435             break;
00436 
00437         case CALLBACK_CONNECTION_COMPLETE:
00438             gApp.ConnectionComplete(hci,(connection_info*)data);
00439             break;
00440     };
00441     return 0;
00442 }
00443 
00444 //  these should be placed in the DMA SRAM
00445 typedef struct
00446 {
00447     u8 _hciBuffer[MAX_HCL_SIZE];
00448     u8 _aclBuffer[MAX_ACL_SIZE];
00449 } SRAMPlacement;
00450 
00451 HCITransportUSB _HCITransportUSB;
00452 HCI _HCI;
00453 
00454 u8* USBGetBuffer(u32* len);
00455 int OnBluetoothInsert(int device)
00456 {
00457     printf("Bluetooth inserted of %d\n",device);
00458     u32 sramLen;
00459     u8* sram =  USBGetBuffer(&sramLen);
00460     sram = (u8*)(((u32)sram + 1023) & ~1023);
00461     SRAMPlacement* s = (SRAMPlacement*)sram;
00462     _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);
00463     _HCI.Open(&_HCITransportUSB,HciCallback);
00464     RegisterSocketHandler(SOCKET_L2CAP,&_HCI);
00465     gHCI = &_HCI;
00466     gApp.Inquiry();
00467     return 0;
00468 }
00469 
00470 void TestShell()
00471 {
00472     USBInit();
00473     printf("*** TestShell Started ***\n");
00474     gApp.Run();
00475     printf("*** TestShell Ended ***\n");
00476 }