![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Code to control a Traxster robot using a Wimote and Android app
Fork of BlueUSB by
Diff: BlueUSB/TestShell.cpp
- Revision:
- 1:accdaa84fe8d
diff -r 606b230e5b4a -r accdaa84fe8d BlueUSB/TestShell.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BlueUSB/TestShell.cpp Mon Apr 28 16:06:32 2014 +0000 @@ -0,0 +1,392 @@ + +/* +Copyright (c) 2010 Peter Barrett + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "mbed.h" +#include "Utils.h" +#include "USBHost.h" +#include "hci.h" + + + +void ProcessHID(const unsigned char*); + +void printf(const BD_ADDR* addr) +{ + const u8* a = addr->addr; + printf("%02X:%02X:%02X:%02X:%02X:%02X",a[5],a[4],a[3],a[2],a[1],a[0]); +} + +#define MAX_HCL_SIZE 260 +#define MAX_ACL_SIZE 400 + +class HCITransportUSB : public HCITransport +{ + int _device; + u8* _hciBuffer; + u8* _aclBuffer; + + public: + void Open(int device, u8* hciBuffer, u8* aclBuffer) + { + _device = device; + _hciBuffer = hciBuffer; + _aclBuffer = aclBuffer; + USBInterruptTransfer(_device,0x81,_hciBuffer,MAX_HCL_SIZE,HciCallback,this); + USBBulkTransfer(_device,0x82,_aclBuffer,MAX_ACL_SIZE,AclCallback,this); + } + + static void HciCallback(int device, int endpoint, int status, u8* data, int len, void* userData) + { + HCI* t = ((HCITransportUSB*)userData)->_target; + if (t) + t->HCIRecv(data,len); + USBInterruptTransfer(device,0x81,data,MAX_HCL_SIZE,HciCallback,userData); + } + + static void AclCallback(int device, int endpoint, int status, u8* data, int len, void* userData) + { + HCI* t = ((HCITransportUSB*)userData)->_target; + if (t) + t->ACLRecv(data,len); + USBBulkTransfer(device,0x82,data,MAX_ACL_SIZE,AclCallback,userData); + } + + virtual void HCISend(const u8* data, int len) + { + USBControlTransfer(_device,REQUEST_TYPE_CLASS, 0, 0, 0,(u8*)data,len); + } + + virtual void ACLSend(const u8* data, int len) + { + USBBulkTransfer(_device,0x02,(u8*)data,len); + } +}; + + +#define WII_REMOTE 0x042500 + +class HIDBluetooth +{ + int _control; // Sockets for control (out) and interrupt (in) + int _interrupt; + int _devClass; + BD_ADDR _addr; + u8 _pad[2]; // Struct align + +public: + HIDBluetooth() : _control(0),_interrupt(0),_devClass(0) {}; + + bool InUse() + { + return _control != 0; + } + + static void OnHidInterrupt(int socket, SocketState state, const u8* data, int len, void* userData) + { + HIDBluetooth* t = (HIDBluetooth*)userData; + if (data) + { + if (t->_devClass == WII_REMOTE && data[1] == 0x30) + { + printf("================wii====================\n"); + t->Led(); + t->Hid(); // ask for accelerometer + t->_devClass = 0; + } + + const u8* d = data; + switch (d[1]) + { + case 0x02: + { + int x = (signed char)d[3]; + int y = (signed char)d[4]; + printf("Mouse %2X dx:%d dy:%d\n",d[2],x,y); + } + break; + + case 0x37: // Accelerometer http://wiki.wiimoteproject.com/Reports + { + int pad = (d[2] & 0x9F) | ((d[3] & 0x9F) << 8); + int x = (d[2] & 0x60) >> 5 | d[4] << 2; + int y = (d[3] & 0x20) >> 4 | d[5] << 2; + int z = (d[3] & 0x40) >> 5 | d[6] << 2; + printf("WII %04X %d %d %d\n",pad,x,y,z); + } + break; + + // STUFF ACTUALLY HAPPENS HERE + case 0x31: // basic button/accel report + ProcessHID(data); + break; + default: + printHex(data,len); + } + } + } + + void Led(int id = 0x10) + { + u8 led[3] = {0x52, 0x11, id}; + if (_control) + Socket_Send(_control,led,3); + } + + void Hid(int report = 0x31) + { + u8 hid[4] = { 0x52, 0x12, 0x00, report }; + if (_control != -1) + Socket_Send(_control,hid,4); + } + + static void OnHidControl(int socket, SocketState state, const u8* data, int len, void* userData) + { + printf("OnHidControl\n"); + if (data) + printHex(data,len); + } + + void Open(BD_ADDR* bdAddr, inquiry_info* info) + { + printf("L2CAPAddr size %d\n",sizeof(L2CAPAddr)); + _addr = *bdAddr; + L2CAPAddr sockAddr; + sockAddr.bdaddr = _addr; + sockAddr.psm = L2CAP_PSM_HID_INTR; + printf("Socket_Open size %d\n",sizeof(L2CAPAddr)); + _interrupt = Socket_Open(SOCKET_L2CAP,&sockAddr.hdr,OnHidInterrupt,this); + sockAddr.psm = L2CAP_PSM_HID_CNTL; + _control = Socket_Open(SOCKET_L2CAP,&sockAddr.hdr,OnHidControl,this); + + printfBytes("OPEN DEVICE CLASS",info->dev_class,3); + _devClass = (info->dev_class[0] << 16) | (info->dev_class[1] << 8) | info->dev_class[2]; + } + + void Close() + { + if (_control) + Socket_Close(_control); + if (_interrupt) + Socket_Close(_interrupt); + _control = _interrupt = 0; + } +}; + + +HCI* gHCI = 0; + +#define MAX_HID_DEVICES 8 + +int GetConsoleChar(); +class ShellApp +{ + char _line[64]; + HIDBluetooth _hids[MAX_HID_DEVICES]; + +public: + void Ready() + { + printf("HIDBluetooth %d\n",sizeof(HIDBluetooth)); + memset(_hids,0,sizeof(_hids)); + Inquiry(); + + } + + // We have connected to a device + void ConnectionComplete(HCI* hci, connection_info* info) + { + printf("ConnectionComplete "); + BD_ADDR* a = &info->bdaddr; + printf(a); + BTDevice* bt = hci->Find(a); + HIDBluetooth* hid = NewHIDBluetooth(); + printf("%08x %08x\n",bt,hid); + if (hid) + hid->Open(a,&bt->_info); + } + + HIDBluetooth* NewHIDBluetooth() + { + for (int i = 0; i < MAX_HID_DEVICES; i++) + if (!_hids[i].InUse()) + return _hids+i; + return 0; + } + + void ConnectDevices() + { + BTDevice* devs[8]; + int count = gHCI->GetDevices(devs,8); + for (int i = 0; i < count; i++) + { + printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3); + if (devs[i]->_handle == 0) + { + BD_ADDR* bd = &devs[i]->_info.bdaddr; + if ((bd->addr)[0] == 0xA8) + { + printf("Connecting to "); + printf(bd); + printf("\n"); + gHCI->CreateConnection(bd); + } + } + } + } + + const char* ReadLine() + { + int i; + for (i = 0; i < 255; ) + { + USBLoop(); + int c = GetConsoleChar(); + if (c == -1) + continue; + if (c == '\n' || c == 13) + break; + _line[i++] = c; + } + _line[i] = 0; + return _line; + } + + void Inquiry() + { + printf("Inquiry..\n"); + gHCI->Inquiry(3); + } + + void List() + { + #if 0 + printf("%d devices\n",_deviceCount); + for (int i = 0; i < _deviceCount; i++) + { + printf(&_devices[i].info.bdaddr); + printf("\n"); + } + #endif + } + + void Connect() + { + ConnectDevices(); + } + + void Disconnect() + { + gHCI->DisconnectAll(); + } + + void CloseMouse() + { + } + + void Quit() + { + CloseMouse(); + } + + void Run() + { + for (;;) + USBLoop(); + } +}; + +// Instance +ShellApp gApp; + +static int HciCallback(HCI* hci, HCI_CALLBACK_EVENT evt, const u8* data, int len) +{ + switch (evt) + { + case CALLBACK_READY: + printf("CALLBACK_READY\n"); + gApp.Ready(); + break; + + case CALLBACK_INQUIRY_RESULT: + printf("CALLBACK_INQUIRY_RESULT "); + printf((BD_ADDR*)data); + printf("\n"); + break; + + case CALLBACK_INQUIRY_DONE: + printf("CALLBACK_INQUIRY_DONE\n"); + gApp.ConnectDevices(); + break; + + case CALLBACK_REMOTE_NAME: + { + BD_ADDR* addr = (BD_ADDR*)data; + const char* name = (const char*)(data + 6); + printf(addr); + printf(" % s\n",name); + } + break; + + case CALLBACK_CONNECTION_COMPLETE: + gApp.ConnectionComplete(hci,(connection_info*)data); + break; + }; + return 0; +} + +// these should be placed in the DMA SRAM +typedef struct +{ + u8 _hciBuffer[MAX_HCL_SIZE]; + u8 _aclBuffer[MAX_ACL_SIZE]; +} SRAMPlacement; + +HCITransportUSB _HCITransportUSB; +HCI _HCI; + +u8* USBGetBuffer(u32* len); +int OnBluetoothInsert(int device) +{ + printf("Bluetooth inserted of %d\n",device); + u32 sramLen; + u8* sram = USBGetBuffer(&sramLen); + sram = (u8*)(((u32)sram + 1023) & ~1023); + SRAMPlacement* s = (SRAMPlacement*)sram; + _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer); + _HCI.Open(&_HCITransportUSB,HciCallback); + RegisterSocketHandler(SOCKET_L2CAP,&_HCI); + gHCI = &_HCI; + gApp.Inquiry(); + return 0; +} + +void RunWiimote() +{ + USBInit(); + gApp.Run(); +}