Test Ver

Dependencies:   mbed FatFileSystem

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