1662 lines
54 KiB
C++
1662 lines
54 KiB
C++
// Copyright © 2009 MergeIt, Aps.
|
|
//
|
|
// License LGPLv3+: GNU lesser LGPL version 3 or later <http://gnu.org/licenses/lgpl.html>.
|
|
// This is free software: you are free to change and redistribute it.
|
|
// There is NO WARRANTY, to the extent permitted by law.
|
|
//
|
|
// This file is part of wiiscan.
|
|
//
|
|
// wiiscan is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// any later version.
|
|
//
|
|
// wiiscan is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with wiiscan. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#define VERSION 0
|
|
#define VERSION_REV 9
|
|
|
|
#define VC_EXTRALEAN
|
|
|
|
#include "toolsfun.h"
|
|
#include "wiiuse.h"
|
|
#include "usbm.h"
|
|
#include "delcomdll.h"
|
|
#include <bthdef.h>
|
|
#include <BluetoothAPIs.h>
|
|
|
|
#pragma comment ( lib, "Lib/wiiuse.lib")
|
|
#pragma comment ( lib, "Lib/delcomdll.lib")
|
|
#pragma comment ( lib, "Irprops.lib")
|
|
#pragma comment ( lib, "Ws2_32.lib")
|
|
|
|
void Connect_using_BT_Api();
|
|
|
|
namespace Wiiscan {
|
|
|
|
// default values
|
|
const int MAX_DEVICE_COUNT =256;
|
|
const int DEFAULT_timeout =2000;
|
|
const int DEFAULT_wiitimeout=2000;
|
|
const int DEFAULT_usbsleep =500;
|
|
const int DEFAULT_usbmsleep =3000;
|
|
const int DEFAULT_btsleep =2000;
|
|
const int DEFAULT_usbmode =0;
|
|
const int DEFAULT_removemode=0;
|
|
const int DEFAULT_scanretries=1;
|
|
const string NINTENDO_DEV="Nintendo RVL-CNT-01";
|
|
const string DEFAULT_configfile="wiiscan.ini";
|
|
const string DEFAULT_logfile="cout";
|
|
const string DEFAULT_wiilib="wiimotelib";
|
|
|
|
Logger& log=g_log;
|
|
void (*g_automode_callback)(const int)=0;
|
|
void DummyCallback(const int){FUNSTACK;}
|
|
|
|
string ConvertName(const WCHAR* szName)
|
|
{
|
|
FUNSTACK;
|
|
assert( MAX_PATH >= BLUETOOTH_MAX_NAME_SIZE );
|
|
CHAR szDevName[MAX_PATH];
|
|
memset(szDevName, 0x00, sizeof(szDevName));
|
|
sprintf_s(szDevName,MAX_PATH,"%S", szName);
|
|
return string(szDevName);
|
|
}
|
|
|
|
string ConvertAddress(const BLUETOOTH_ADDRESS& address)
|
|
{
|
|
FUNSTACK;
|
|
string s;
|
|
char t[256];
|
|
for(int i=5;i>=0;i--) {
|
|
sprintf_s(t,256,"%X",address.rgBytes[i]);
|
|
string x=t;
|
|
if (x.size()==1) x="0"+x;
|
|
s+=x+(i==0 ? "" : ":");
|
|
}
|
|
return s;
|
|
}
|
|
|
|
string tostring(const SYSTEMTIME& x)
|
|
{
|
|
FUNSTACK;
|
|
// XXX warning: no converstion of GMT to local time
|
|
ostringstream s;
|
|
if (x.wHour==0 && x.wMinute==0 && x.wDay==0 && x.wYear==0 && x.wYear==0) s << "<N/A>";
|
|
else s << x.wHour << ":" << (x.wMinute<10 ? "0" : "") << x.wMinute << " d. " << x.wDay << "/" << x.wMonth << ", " << x.wYear;
|
|
return s.str();
|
|
}
|
|
|
|
string tostring(const BLUETOOTH_DEVICE_INFO& x)
|
|
{
|
|
FUNSTACK;
|
|
ostringstream s;
|
|
s << " BLUETOOTH_DEVICE_INFO:" << endl;
|
|
s << " dwSize: " << x.dwSize << endl;
|
|
s << " Address: " << ConvertAddress(x.Address) << endl;
|
|
s << " ulClassofDevice:" << x.ulClassofDevice << endl;
|
|
s << " fConnected: " << x.fConnected << endl;
|
|
s << " fRemembered: " << x.fRemembered << endl;
|
|
s << " fAuthenticated: " << x.fAuthenticated << endl;
|
|
s << " stLastSeen: " << tostring(x.stLastSeen) << " [GMT]" << endl;
|
|
s << " stLastUsed: " << tostring(x.stLastUsed) << " [GMT]" << endl;
|
|
s << " szName: " << ConvertName(x.szName) << endl;
|
|
return s.str();
|
|
}
|
|
|
|
string tostring(const BLUETOOTH_RADIO_INFO& x)
|
|
{
|
|
FUNSTACK;
|
|
ostringstream s;
|
|
s << " PBLUETOOTH_RADIO_INFO:" << endl;
|
|
s << " dwSize: " << x.dwSize << endl;
|
|
s << " Address: " << ConvertAddress(x.address) << endl;
|
|
s << " szName: " << ConvertName(x.szName) << endl;
|
|
s << " ulClassofDevice:" << x.ulClassofDevice << endl;
|
|
s << " lmpSubversion: " << x.lmpSubversion << endl;
|
|
s << " manufacturer: " << x.manufacturer << endl;
|
|
return s.str();
|
|
}
|
|
|
|
bool USB_hub_updown(const bool up,const string& usbhub)
|
|
{
|
|
FUNSTACK;
|
|
log << (up ? "Enabling" : "Disabling") << " 'USB hub..." << endl;
|
|
int n=-1;
|
|
System(string("devcon ") + (up ? "enable " : "disable ") + usbhub,false,false,&n);
|
|
if (n!=0) throw_("devcon failed, this can be to a erroneous usbhub string or if devcon.exe is not found in path, please install it from http://support.microsoft.com/kb/311272");
|
|
log << "Done [OK]" << endl;
|
|
return true;
|
|
}
|
|
|
|
int ScanforUSBmicrodevs()
|
|
{
|
|
USBio io;
|
|
io.USBm_FindDevices();
|
|
return io.Devices();
|
|
}
|
|
|
|
bool USB_microio_updown(const bool up,const bool dbg)
|
|
{
|
|
FUNSTACK;
|
|
log << (up ? "Enabling" : "Disabling") << " USBm io..." << endl;
|
|
|
|
// Discover the USBmicro devices
|
|
USBio io;
|
|
io.USBm_FindDevices();
|
|
const int d=io.Devices();
|
|
if (d==0) return false; // throw_("could not find an USBm device");
|
|
else if (d>1) throw_("found more that one USBm devices");
|
|
|
|
static bool premable=true;
|
|
if (dbg && premable) {
|
|
premable=false;
|
|
log << " USBm info:" << endl << io.version();
|
|
}
|
|
|
|
io.USBm_InitPorts(0);
|
|
io.USBm_DirectionA(0, 0xff, 0xff);
|
|
|
|
if(up) io.USBm_ResetBit(0,5);
|
|
else io.USBm_SetBit (0,5);
|
|
|
|
log << "Done [OK]" << endl;
|
|
return true;
|
|
}
|
|
|
|
bool __stdcall CloseDelcomhandle(HANDLE h){return DelcomCloseDevice(h)==0;}
|
|
|
|
void do_cmd(HANDLE di, int ma, int mi, int lsb, int msb, unsigned char *data, unsigned datalen)
|
|
{
|
|
//static struct delcom_packet p;
|
|
PacketStruct p;
|
|
memset(&p, 0, sizeof(p));
|
|
p.MajorCmd = ma;
|
|
p.MinorCmd = mi;
|
|
p.DataLSB = lsb;
|
|
p.DataMSB = msb;
|
|
if (DelcomSendPacket(di,&p,&p)<0) throw_("DelcomSendPacket() failed");
|
|
}
|
|
|
|
int ScanforDelcomdevs()
|
|
{
|
|
// Discover the USB Delcom devices
|
|
DeviceNameStruct names[10]; // array to hold the device names found
|
|
return DelcomScanDevices(USBIODS, names, 10);
|
|
}
|
|
|
|
bool USB_delconio_updown(const bool up,const bool dbg)
|
|
{
|
|
FUNSTACK;
|
|
log << (up ? "Enabling" : "Disabling") << " USB Delcom io..." << endl;
|
|
|
|
DeviceNameStruct names[10]; // array to hold the device names found
|
|
const int d=DelcomScanDevices(USBIODS, names, 10);
|
|
if (d==0) return false; //throw_("could not find an USB Delcon device");
|
|
else if (d>1) throw_("found more that one USB Delcon devices");
|
|
|
|
static bool premable=true;
|
|
if (dbg && premable) {
|
|
premable=false;
|
|
log << " USB Delcon info:" << (char*)&names[0] << "\n SN=" << DelcomReadDeviceSerialNum((char*)&names[0], NULL) << endl;
|
|
}
|
|
|
|
DeviceAutoClose<HANDLE,bool> h(DelcomOpenDevice((char*)&names[0],0),CloseDelcomhandle);
|
|
if(up) do_cmd(h(),10,1,0xFE,0,0,0);
|
|
else do_cmd(h(),10,1,0xFF,0,0,0);
|
|
|
|
log << "Done [OK]" << endl;
|
|
return true;
|
|
}
|
|
|
|
bool USBupdown(const int iomode,const bool up,const bool dbg,const string& usbhub="")
|
|
{
|
|
if (iomode==0) return true;
|
|
if (iomode==1) return USB_hub_updown(up,usbhub);
|
|
if (iomode==2) return USB_microio_updown(up,dbg);
|
|
else if (iomode==3) return USB_delconio_updown(up,dbg);
|
|
else throw_("bad io mode");
|
|
return false;
|
|
}
|
|
|
|
class Wiilib
|
|
{
|
|
// Wiilib class based on wiiuse library by Michael Laforest.
|
|
// Library located at http://www.wiiuse.net
|
|
// Wiiuse premable from wiiuse_v0.12/example/example.c:
|
|
|
|
//
|
|
// wiiuse
|
|
//
|
|
// Written By:
|
|
// Michael Laforest < para >
|
|
// Email: < thepara (--AT--) g m a i l [--DOT--] com >
|
|
//
|
|
// Copyright 2006-2007
|
|
//
|
|
// This file is part of wiiuse.
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation; either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
private:
|
|
enum {MAX_WIIMOTES=1}; // use only one wiimote, but can connect to four
|
|
wiimote** m_wiimotes;
|
|
static int m_instantiations;
|
|
|
|
int finddevices(const int wiitimeout,const bool rumble,const bool dbg)
|
|
{
|
|
FUNSTACK;
|
|
|
|
// Find wiimote devices
|
|
const int to=wiitimeout/1000;
|
|
if (to<1) throw_("bad wiitimeout value, should be >=1000");
|
|
const int found=wiiuse_find(m_wiimotes,MAX_WIIMOTES,to);
|
|
if (dbg) log << " wiiuse_find(0x0," << MAX_WIIMOTES << "," << to << ") return " << found << endl;
|
|
|
|
if (found==0) {
|
|
if (dbg) log << " ** error: no wiimotes found" << endl;
|
|
return 0;
|
|
}
|
|
|
|
// Connect to the wiimotes
|
|
assert(found>0);
|
|
|
|
const int connected = wiiuse_connect(m_wiimotes, MAX_WIIMOTES);
|
|
if (connected==0){
|
|
log << " ** error: could not connect to any wiimotes" << endl;
|
|
return 0;
|
|
}
|
|
if (dbg) log << " connected to " << connected<< " wiimotes (of " << MAX_WIIMOTES << " found)" << endl;
|
|
|
|
|
|
// Now set the LEDs and rumble for a second so it's easy
|
|
// to tell which wiimotes are connected (just like the wii does).
|
|
wiiuse_set_leds(m_wiimotes[0], WIIMOTE_LED_1);
|
|
|
|
if (rumble){
|
|
wiiuse_rumble(m_wiimotes[0], 1);
|
|
#ifndef WIN32
|
|
usleep(200000);
|
|
#else
|
|
Sleep(200);
|
|
#endif
|
|
wiiuse_rumble(m_wiimotes[0], 0);
|
|
}
|
|
|
|
// read some data to be sure of connection
|
|
for(int i=0;i<8;++i){
|
|
Sleep(50);
|
|
|
|
int led=0;
|
|
switch(i%6){
|
|
case 0 : led=WIIMOTE_LED_1; break;
|
|
case 1 : led=WIIMOTE_LED_2; break;
|
|
case 2 : led=WIIMOTE_LED_3; break;
|
|
case 3 : led=WIIMOTE_LED_4; break;
|
|
case 4 : led=WIIMOTE_LED_3; break;
|
|
case 5 : led=WIIMOTE_LED_2; break;
|
|
}
|
|
wiiuse_rumble(m_wiimotes[0], 0); // to be sure
|
|
wiiuse_set_leds(m_wiimotes[0],led);
|
|
wiiuse_status(m_wiimotes[0]);
|
|
if (led!=m_wiimotes[0]->leds) throw_("bad LED status on wiimote, is it connected properly?");
|
|
}
|
|
|
|
// set all leds, retry a couple of time to be sure
|
|
for(int i=0;i<4;++i){
|
|
wiiuse_set_leds(m_wiimotes[0],WIIMOTE_LED_1 | WIIMOTE_LED_2 | WIIMOTE_LED_3 | WIIMOTE_LED_4);
|
|
Sleep(100);
|
|
}
|
|
|
|
return connected;
|
|
}
|
|
|
|
Wiilib() : m_wiimotes(0)
|
|
{
|
|
FUNSTACK;
|
|
if (m_instantiations!=0) throw_("can only instatiate one Wiilib at a time");
|
|
++m_instantiations; // assumes a single-thread application, else we have a race condition here
|
|
|
|
// Initialize an array of wiimote objects.
|
|
// The parameter is the number of wiimotes I want to create.
|
|
m_wiimotes = wiiuse_init(MAX_WIIMOTES);
|
|
// wiiuse_set_bluetooth_stack(m_wiimotes, MAX_WIIMOTES,WIIUSE_STACK_MS); must be done automatically
|
|
assert(m_instantiations==1);
|
|
}
|
|
|
|
~Wiilib()
|
|
{
|
|
FUNSTACK;
|
|
assert( m_instantiations==1 );
|
|
|
|
// Disconnect the wiimotes
|
|
if (m_wiimotes!=0) wiiuse_cleanup(m_wiimotes, MAX_WIIMOTES);
|
|
m_wiimotes=0;
|
|
--m_instantiations;
|
|
assert(m_instantiations==0);
|
|
}
|
|
|
|
static int OpenDevices_wiilib(const int wiitimeout,const bool rumble,const bool dbg,const bool precheck=false)
|
|
{
|
|
FUNSTACK;
|
|
int n=0,retries=0;
|
|
while(n==0 && retries++<10) {
|
|
n=Wiilib().finddevices(wiitimeout,rumble,dbg);
|
|
if (precheck) break;
|
|
if (n==0) {
|
|
if (dbg) log << " OpenDevice()...delaying " << (retries<5 ? "250" : "1000") << " [ms]" << endl;
|
|
if (retries<5) Sleep(250);
|
|
else Sleep(1000);
|
|
}
|
|
}
|
|
if (dbg) {cerr.flush(); log << " Wiilib::OpenDevice..." << n << endl;}
|
|
return n;
|
|
}
|
|
|
|
static int OpenDevices_wiimotelib(const int wiitimeout,const bool rumble,const bool dbg,const bool precheck=false)
|
|
{
|
|
FUNSTACK;
|
|
int n=0,retries=0;
|
|
while(n==0 && retries++<10) {
|
|
n=system("wiimotelibpoll")==0 ? 1 : 0;
|
|
if (precheck) break;
|
|
if (n==0) {
|
|
if (dbg) log << " OpenDevice()...delaying " << (retries<5 ? "250" : "1000") << " [ms]" << endl;
|
|
if (retries<5) Sleep(250);
|
|
else Sleep(1000);
|
|
}
|
|
}
|
|
if (dbg) {cerr.flush(); log << " Wiilib::OpenDevice..." << n << endl;}
|
|
return n;
|
|
}
|
|
|
|
public:
|
|
|
|
static int OpenDevices(const string& wiilib,const int wiitimeout,const bool rumble,const bool dbg,const bool precheck=false)
|
|
{
|
|
FUNSTACK;
|
|
if (wiilib=="wiiuse") return OpenDevices_wiilib(wiitimeout,rumble,dbg,precheck);
|
|
else if (wiilib=="wiimotelib") return OpenDevices_wiimotelib(wiitimeout,rumble,dbg,precheck);
|
|
else if (wiilib=="none") return -1;
|
|
else throw_("Wiilib::OpenDevices(), library must be one-of {wiiuse,wiimotelib,none}");
|
|
return -1; // avoid compiler error
|
|
}
|
|
|
|
};
|
|
|
|
int Wiilib::m_instantiations=0;
|
|
|
|
BLUETOOTH_DEVICE_SEARCH_PARAMS Get_BLUETOOTH_DEVICE_SEARCH_PARAMS(const int timeout)
|
|
{
|
|
FUNSTACK;
|
|
BLUETOOTH_DEVICE_SEARCH_PARAMS b;
|
|
ZeroMemory(&b, sizeof(b));
|
|
b.dwSize = sizeof(b);
|
|
b.fReturnAuthenticated = TRUE;
|
|
b.fReturnRemembered = TRUE;
|
|
b.fReturnUnknown = TRUE;
|
|
b.fReturnConnected = TRUE;
|
|
b.fIssueInquiry = TRUE;
|
|
|
|
const int to=static_cast<int>(1.0*timeout/1000.0/1.28+0.5);
|
|
assert(to>=0 && to<48 );
|
|
b.cTimeoutMultiplier = (to==0 ? 1 : to); // timeout of 0 causes havac
|
|
b.hRadio = NULL;
|
|
|
|
assert( b.cTimeoutMultiplier>0 );
|
|
return b;
|
|
}
|
|
|
|
BLUETOOTH_DEVICE_INFO Get_BLUETOOTH_DEVICE_INFO()
|
|
{
|
|
FUNSTACK;
|
|
BLUETOOTH_DEVICE_INFO b;
|
|
ZeroMemory(&b, sizeof(b));
|
|
b.dwSize = sizeof(b);
|
|
return b;
|
|
}
|
|
|
|
BLUETOOTH_RADIO_INFO Get_BLUETOOTH_RADIO_INFO()
|
|
{
|
|
FUNSTACK;
|
|
BLUETOOTH_RADIO_INFO b;
|
|
ZeroMemory(&b, sizeof(b));
|
|
b.dwSize = sizeof(b);
|
|
return b;
|
|
}
|
|
|
|
BLUETOOTH_FIND_RADIO_PARAMS Get_BLUETOOTH_FIND_RADIO_PARAMS()
|
|
{
|
|
FUNSTACK;
|
|
BLUETOOTH_FIND_RADIO_PARAMS b;
|
|
ZeroMemory(&b, sizeof(b));
|
|
b.dwSize = sizeof(b);
|
|
return b;
|
|
}
|
|
|
|
bool ReachedMax(const int i)
|
|
{
|
|
FUNSTACK;
|
|
if (i>MAX_DEVICE_COUNT) {
|
|
log << " ** warning: too many devices found, can only handle " << MAX_DEVICE_COUNT << " devices" << endl;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool RemoveDev(const BLUETOOTH_DEVICE_INFO& bdi)
|
|
{
|
|
FUNSTACK;
|
|
DWORD status=BluetoothUpdateDeviceRecord(&bdi);
|
|
if (status!=ERROR_SUCCESS) throw_("BluetoothUpdateDeviceRecord() failed");
|
|
|
|
status=BluetoothRemoveDevice(&bdi.Address);
|
|
if (status==ERROR_SUCCESS) log << " removed device successfully..." << endl << "Done [OK]" << endl;
|
|
else log << " ** error: removing the device failed, was it registred at all?" << endl <<"Done [FAILED]" << endl;
|
|
|
|
return status==ERROR_SUCCESS;
|
|
}
|
|
|
|
HANDLE RadioInfo(const string& btr,const bool dbg)
|
|
{
|
|
FUNSTACK;
|
|
if (dbg) log << " Radio info" << endl;
|
|
assert( btr.size()==17 || btr.size()==0 || btr=="all");
|
|
|
|
HANDLE hRadio=NULL;
|
|
BLUETOOTH_FIND_RADIO_PARAMS btfrp=Get_BLUETOOTH_FIND_RADIO_PARAMS();
|
|
DeviceAutoClose<HBLUETOOTH_RADIO_FIND,BOOL> hbf(BluetoothFindFirstRadio(&btfrp,&hRadio),&BluetoothFindRadioClose);
|
|
|
|
if (hbf()==NULL) {
|
|
if (dbg) log << " <EMPTY>" << endl;
|
|
return NULL;
|
|
}
|
|
|
|
while(hbf()!=NULL){
|
|
if (hbf()==NULL) throw_("BluetoothFindFirstRadio() failed");
|
|
|
|
BLUETOOTH_RADIO_INFO r=Get_BLUETOOTH_RADIO_INFO();
|
|
if (BluetoothGetRadioInfo(hRadio,&r)!=ERROR_SUCCESS) throw_("BluetoothGetRadioInfo() failed");
|
|
|
|
const int c=BluetoothIsConnectable(hRadio);
|
|
const int d=BluetoothIsDiscoverable(hRadio);
|
|
|
|
if (dbg){
|
|
log << indent(tostring(r)," ");
|
|
log << " connectable: " << c << endl;
|
|
log << " discoverabel: " << d << endl;
|
|
}
|
|
|
|
if (btr.size()==0) break;
|
|
else if (btr==ConvertAddress(r.address)){
|
|
if (dbg) log << " found radio address match " << (btr.size()>0 ? ": " + btr : "") << endl;
|
|
break;
|
|
}
|
|
|
|
if (!BluetoothFindNextRadio(&btfrp,&hRadio)) break;
|
|
}
|
|
|
|
if (dbg) log << "Done [" << (hRadio==NULL ? "FAILED" : "OK") << "]" << endl;
|
|
return hRadio;
|
|
}
|
|
|
|
bool ScanDevices(const int timeout)
|
|
{
|
|
FUNSTACK;
|
|
log << "Scanning devices" << endl;
|
|
|
|
vector<BLUETOOTH_DEVICE_INFO> infos;
|
|
|
|
BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp=Get_BLUETOOTH_DEVICE_SEARCH_PARAMS(timeout);
|
|
BLUETOOTH_DEVICE_INFO bdi=Get_BLUETOOTH_DEVICE_INFO();
|
|
|
|
DeviceAutoClose<HBLUETOOTH_DEVICE_FIND,BOOL> hbf(BluetoothFindFirstDevice(&bdsp,&bdi),&BluetoothFindDeviceClose);
|
|
const DWORD dwErr = GetLastError();
|
|
|
|
if (hbf()==NULL) {
|
|
log << " ** warning: no devices found" << endl << "Done [FAILED]" << endl;
|
|
return false;;
|
|
}
|
|
|
|
if (hbf()!= NULL) {
|
|
log << "Looking for devices..." << endl;
|
|
|
|
int i=0;
|
|
while(1){
|
|
if (ReachedMax(i)) break;
|
|
|
|
const string t=ConvertName(bdi.szName);
|
|
log << " found device [" << i << "]: <" << (t.size()>0 ? t : "NONAME") << ">" << endl;
|
|
|
|
infos.push_back(bdi);
|
|
|
|
if (BluetoothFindNextDevice(hbf(), &bdi) == FALSE)
|
|
break;
|
|
|
|
++i;
|
|
}
|
|
}
|
|
|
|
log << "BTDevices info:" << endl;
|
|
if (infos.size()==0) log << " <EMPTY>" << endl;
|
|
else for(size_t i=0;i<infos.size();++i){
|
|
const BLUETOOTH_DEVICE_INFO& t=infos[i];
|
|
const string s=ConvertName(t.szName);
|
|
log << "Device [" << i << "]: " << (s.size()>0 ? s : "<NONAME>") << endl;
|
|
log << tostring(t);
|
|
}
|
|
log << "Done [OK]" << endl;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool RemoveDevice(const string& d,const bool dbg)
|
|
{
|
|
FUNSTACK;
|
|
log << "Removing device <" << d << ">" << endl;
|
|
|
|
BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp=Get_BLUETOOTH_DEVICE_SEARCH_PARAMS(1); // timout must be greater than zero, eventhough I only return remembered devices!
|
|
BLUETOOTH_DEVICE_INFO bdi=Get_BLUETOOTH_DEVICE_INFO();
|
|
|
|
bdsp.fReturnAuthenticated = FALSE;
|
|
bdsp.fReturnRemembered = TRUE;
|
|
bdsp.fReturnUnknown = FALSE;
|
|
bdsp.fReturnConnected = TRUE;
|
|
|
|
DeviceAutoClose<HBLUETOOTH_DEVICE_FIND,BOOL> hbf(BluetoothFindFirstDevice(&bdsp,&bdi),&BluetoothFindDeviceClose);
|
|
|
|
const DWORD dwErr = GetLastError();
|
|
|
|
if (hbf()==NULL) {
|
|
log << " ** error: failed to find device" << endl << "Done [FAILED]" << endl;
|
|
return false;
|
|
}
|
|
|
|
int i=0;
|
|
while(true){
|
|
if (ReachedMax(i)) break;
|
|
const string fd=ConvertName(bdi.szName);
|
|
log << " found device [" << i << "]: <" << (fd.size()>0 ? fd : "NONAME") << ">" << endl;
|
|
|
|
if (fd==d){
|
|
log << " found match..." << endl;
|
|
log << " trying to remove..." << endl;
|
|
|
|
return RemoveDev(bdi);
|
|
}
|
|
if (BluetoothFindNextDevice(hbf(), &bdi) == FALSE) break;
|
|
++i;
|
|
}
|
|
log << " ** error: failed to find device" << endl << "Done [FAILED]" << endl;
|
|
return false;
|
|
}
|
|
|
|
bool MatchAdr(const string& pattern,const string& adr)
|
|
{
|
|
assert(pattern.size()==17 && adr.size()==17);
|
|
for(size_t i=0;i<17;++i){
|
|
if (!(pattern[i]=='?' || pattern[i]==adr[i])) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool MatchDevice(const string& d,const vector<string>& known_adr,const BLUETOOTH_DEVICE_INFO& bdi,const bool dbg)
|
|
{
|
|
FUNSTACK;
|
|
|
|
const string found_adr=ConvertAddress(bdi.Address);
|
|
bool wildcard=false;
|
|
for(size_t i=0;i<known_adr.size();++i) {
|
|
if (known_adr[i].size()!=17) throw_("bad format in bluetooth adr, expected af form of 00:00:00:00:00:00, found " + known_adr[i]);
|
|
if (MatchAdr(known_adr[i],found_adr)) {
|
|
if (dbg) log << " match on adr " << found_adr << endl;
|
|
return true;
|
|
}
|
|
else if (known_adr[i]=="00:00:00:00:00:00") wildcard=true;
|
|
}
|
|
if (wildcard || known_adr.size()==0) return d==ConvertName(bdi.szName);
|
|
else return false;
|
|
}
|
|
|
|
struct BluetoothFindFirstDevice_struct
|
|
{
|
|
int timeout;
|
|
BLUETOOTH_DEVICE_INFO bdi;
|
|
HBLUETOOTH_DEVICE_FIND hbf;
|
|
volatile bool done;
|
|
|
|
BluetoothFindFirstDevice_struct(const int t) : timeout(t), bdi(Get_BLUETOOTH_DEVICE_INFO()), hbf(0), done(false) {}
|
|
};
|
|
|
|
unsigned long __stdcall BluetoothFindFirstDevice_thread(void* p)
|
|
{
|
|
// no funstack due to thread safety, FUNSTACK;
|
|
|
|
BluetoothFindFirstDevice_struct* q=reinterpret_cast<BluetoothFindFirstDevice_struct*>(p);
|
|
assert(p!=0 && q->done==false && q->timeout>0 && q->hbf==0 );
|
|
|
|
BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp=Get_BLUETOOTH_DEVICE_SEARCH_PARAMS(q->timeout);
|
|
|
|
q->hbf=BluetoothFindFirstDevice(&bdsp,&q->bdi);
|
|
const DWORD status=GetLastError();
|
|
|
|
if (status==ERROR_INVALID_PARAMETER) throw_("BluetoothFindFirstDevice(), returned status=ERROR_INVALID_PARAMETER");
|
|
else if (status==ERROR_REVISION_MISMATCH) throw_("BluetoothFindFirstDevice(), returned status=ERROR_REVISION_MISMATCH");
|
|
|
|
q->done=true;
|
|
return 0;
|
|
}
|
|
|
|
bool OpenDevice(const string& d,const string& btr,const int timeout,const int wiitimeout,const vector<string>& known_adr,const int btsleep,const string& lib,const bool precheckwiimotes,const bool rumble,const bool dbg,bool& invalidargflag)
|
|
{
|
|
FUNSTACK;
|
|
assert( invalidargflag==false );
|
|
log << "Open device <" << d << ">" << endl;
|
|
|
|
if (precheckwiimotes && Wiilib::OpenDevices(lib,wiitimeout,false,dbg,true)>=1) {
|
|
log << " service is already opened..." << endl << "Done [OK]" << endl;
|
|
return true;
|
|
}
|
|
|
|
if (dbg && known_adr.size()>0) {
|
|
log << " known addresses=";
|
|
for(size_t i=0;i<known_adr.size();++i) log << known_adr[i] << " ";
|
|
log << endl;
|
|
}
|
|
|
|
BluetoothFindFirstDevice_struct p(timeout);
|
|
{
|
|
// Fix of bug 15: BluetoothFindFirstDevice() stalls (FIXED)
|
|
// The BluetoothFindFirstDevice() sometimes newer returns. Happens only for MS stack version
|
|
// "Microsoft BT stack: date 13-04-2008, driver 5.1.2600.5512" (eee stack).
|
|
//
|
|
// Code stalls here:
|
|
//
|
|
// DeviceAutoClose<HBLUETOOTH_DEVICE_FIND,BOOL> hbf(BluetoothFindFirstDevice(&bdsp,&bdi),&BluetoothFindDeviceClose);
|
|
//
|
|
// FIX: start the BluetoothFindFirstDevice() function in a thread, terminate the thread if it has run for longer than, say 2+timeout.
|
|
//
|
|
// Old code:
|
|
// BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp=Get_BLUETOOTH_DEVICE_SEARCH_PARAMS(timeout);
|
|
// BLUETOOTH_DEVICE_INFO bdi=Get_BLUETOOTH_DEVICE_INFO();
|
|
// DeviceAutoClose<HBLUETOOTH_DEVICE_FIND,BOOL> hbf(BluetoothFindFirstDevice(&bdsp,&bdi),&BluetoothFindDeviceClose);
|
|
// DWORD status=GetLastError();
|
|
|
|
unsigned long tid=0;
|
|
DeviceAutoClose<HANDLE,BOOL> h(CreateThread(0,0,BluetoothFindFirstDevice_thread,&p,0,&tid),CloseHandle);
|
|
timer tthread;
|
|
|
|
Sleep(timeout);
|
|
while(!p.done && tthread.elapsed()*1000<2*timeout) Sleep(20); // or use WaitForMultipleObjects(...);
|
|
}
|
|
|
|
if(!p.done){
|
|
log << " ** error: BluetoothFindFirstDevice() stalled" << endl<< "Done [FAILED]" << endl;
|
|
return false;
|
|
}
|
|
else if(p.hbf==0){
|
|
log << " ** error: BluetoothFindFirstDevice() returned null hbf" << endl<< "Done [FAILED]" << endl;
|
|
return false;
|
|
}
|
|
|
|
assert(p.hbf!=0);
|
|
BLUETOOTH_DEVICE_INFO bdi=p.bdi;
|
|
DeviceAutoClose<HBLUETOOTH_DEVICE_FIND,BOOL> hbf(p.hbf,&BluetoothFindDeviceClose);
|
|
|
|
if (hbf()==NULL) {
|
|
log << " ** error: no devices found" << endl << "Done [FAILED]" << endl;
|
|
return false;
|
|
}
|
|
|
|
int i=0;
|
|
while(true){
|
|
if (ReachedMax(i)) break;
|
|
const string fd=ConvertName(bdi.szName);
|
|
log << " found device [" << i << "]: <" << (fd.size()>0 ? fd : "NONAME") << ">" << endl;
|
|
|
|
if (MatchDevice(d,known_adr,bdi,dbg)){
|
|
log << " found match..." << endl;
|
|
if (dbg) log << tostring(bdi);
|
|
|
|
// write binary dbi, test code for now
|
|
//ofstream ox("bdi.out",ios::binary);
|
|
//ox.write(reinterpret_cast<const char*>(&bdi),sizeof(bdi));
|
|
|
|
log << " trying to open..." << endl;
|
|
DWORD status=BluetoothUpdateDeviceRecord(&bdi);
|
|
if (status!=ERROR_SUCCESS) throw_("BluetoothUpdateDeviceRecord() failed");
|
|
if (dbg) log << " BluetoothUpdateDeviceRecord()...OK" << endl;
|
|
|
|
{
|
|
DeviceAutoClose<HANDLE,BOOL> hRadio(RadioInfo(btr,dbg),&CloseHandle);
|
|
if (hRadio()==NULL) throw_("failed to get radio");
|
|
if (dbg) log << " RadioInfo()...OK" << endl;
|
|
|
|
const GUID service=HumanInterfaceDeviceServiceClass_UUID;
|
|
status=BluetoothSetServiceState(hRadio(),&bdi,&service,BLUETOOTH_SERVICE_ENABLE);
|
|
|
|
if (dbg && status==ERROR_SUCCESS) log << " BluetoothSetServiceState()...OK" << endl;
|
|
if (dbg && status!=ERROR_SUCCESS) log << " BluetoothSetServiceState()...ERROR" << endl;
|
|
}
|
|
|
|
if (status!=ERROR_SUCCESS) {
|
|
string t;
|
|
if (status==ERROR_INVALID_PARAMETER) t="ERROR_INVALID_PARAMETER";
|
|
else if (status==ERROR_SERVICE_DOES_NOT_EXIST) t="ERROR_SERVICE_DOES_NOT_EXIST";
|
|
else if (status==E_INVALIDARG) t="E_INVALIDARG";
|
|
// if (status!=E_INVALIDARG) throw_("BluetoothSetServiceState() failed with errorcode " + t);
|
|
// else log << " ** error: BluetoothSetServiceState() returned " << t << endl;
|
|
|
|
if (status==E_INVALIDARG) invalidargflag=true;
|
|
log << " ** error: BluetoothSetServiceState() returned " << t << endl;
|
|
log << endl << "Done [FAILED]" << endl;
|
|
return false;
|
|
}
|
|
|
|
// sleep while windows slowly does strange things
|
|
Sleep(btsleep);
|
|
|
|
if (lib!="none")
|
|
{
|
|
if (Wiilib::OpenDevices(lib,wiitimeout,rumble,dbg)==0) {
|
|
log << " ** error: service could not be opened..." << endl<< "Done [FAILED]" << endl;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
log << " service on device enabled..." << endl << " opended device successfully..." << endl << "Done [OK]" << endl;
|
|
return true;
|
|
}
|
|
|
|
if (BluetoothFindNextDevice(hbf(), &bdi) == FALSE) break;
|
|
++i;
|
|
}
|
|
log << " ** error: device not mathced" << endl<< "Done [FAILED]" << endl;
|
|
return false;
|
|
}
|
|
|
|
bool AutoOpenDevice(const string& d,const string& btr,const int timeout,const int wiitimeout,const int usbsleep,const int btsleep,const int usbmsleep,const string& cf,const string& lib,const int removemode,const int usbmode,const bool wb,const int scanretries,const bool dbg,bool& invalidargflag)
|
|
{
|
|
FUNSTACK;
|
|
|
|
int cl=0;
|
|
if (g_automode_callback==0) g_automode_callback=&DummyCallback;
|
|
|
|
if (usbmode==2 && ScanforUSBmicrodevs()!=1) {
|
|
log << "Could not find any USBm devices" << endl << "Wiiscan done [FAILED]" << endl;
|
|
return false;
|
|
}
|
|
if (usbmode==3 && ScanforDelcomdevs()!=1) {
|
|
log << "Could not find any Delcom devices" << endl << "Wiiscan done [FAILED]" << endl;
|
|
return false;
|
|
}
|
|
|
|
g_automode_callback(cl++);
|
|
|
|
timer total;
|
|
assert(usbsleep>=0 && btsleep>=0 && usbmsleep>=0);
|
|
|
|
log << "Auto-connecting to device <" << d << ">" << endl;
|
|
|
|
// check valid config file
|
|
if (!FileExists(cf)) throw_("config file <" + cf + "> is missing");
|
|
const Configfile c(cf);
|
|
if (dbg) log << c;
|
|
if (!c.hasEntry("all_usb_hubs")) throw_("config file missing <all_usb_hubs> entry");
|
|
if (!c.hasEntry("active_usb_hub")) throw_("config file missing <active_usb_hub> entry");
|
|
if (!c.hasEntry("allowed_wiimote_adr")) throw_("config file missing <allowed_wiimote_adr> entry");
|
|
if (!c.hasEntry("whiteboard_software")) throw_("config file missing <whiteboard_software> entry");
|
|
|
|
// test if already opened
|
|
g_automode_callback(cl++);
|
|
|
|
if (removemode==0 && Wiilib::OpenDevices(lib,wiitimeout,false,dbg,true)>=1) {
|
|
log << " service is already opened..." << endl << "Done [OK]" << endl;
|
|
|
|
if (wb){
|
|
// fireup whiteboard software
|
|
if (!c.hasEntry("whiteboard_software")) log << " ** warning: config file is missing entry <whiteboard_software>" << endl;
|
|
else System(c.Get<string>("whiteboard_software",true),false,false);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// power down now if using USB io board
|
|
g_automode_callback(cl++);
|
|
USBupdown(usbmode,false,dbg);
|
|
timer t;
|
|
|
|
// remove old entries in HID
|
|
g_automode_callback(cl++);
|
|
if(removemode!=2) RemoveDevice(d,dbg);
|
|
|
|
// Cycle usb hub, turn off usb power and restart the wiimote
|
|
g_automode_callback(cl++);
|
|
if(usbmode==1){
|
|
const string usbhub=c.Get<string>("active_usb_hub");
|
|
if(usbhub!="\"\""){
|
|
USBupdown(usbmode,false,dbg,usbhub);
|
|
Sleep(usbsleep);
|
|
USBupdown(usbmode,true,dbg,usbhub);
|
|
|
|
g_automode_callback(cl++);
|
|
|
|
// wait for usb hub to be up, takes some seconds (1000ms to 2000ms approx)
|
|
Sleep(1800);
|
|
|
|
// wait for usb radio to be ready
|
|
g_automode_callback(cl++);
|
|
HANDLE hRadio=RadioInfo(btr,dbg);
|
|
|
|
int i=0;
|
|
while(hRadio==NULL) {
|
|
if (i++==0) log << " radio not ready, delaying.";
|
|
else log << ".";
|
|
Sleep(500);
|
|
hRadio=RadioInfo(btr,dbg);
|
|
if (i>10) throw_("could not connect to bluetooth radio device");
|
|
}
|
|
CloseHandle(hRadio);
|
|
if (i>0) log << endl;
|
|
}
|
|
} else if (usbmode!=0) {
|
|
while (t.elapsed()*1000<usbsleep) Sleep(20);
|
|
USBupdown(usbmode,true,dbg); // just do an up, power down was done before
|
|
g_automode_callback(cl++);
|
|
Sleep(usbmsleep); // wait for wiimote to be powered up
|
|
} else g_automode_callback(cl++);
|
|
|
|
// try to connect bt to wii
|
|
g_automode_callback(cl++);
|
|
|
|
int retries=0;
|
|
bool openok=false;
|
|
|
|
assert( scanretries>=1 );
|
|
while(!openok && ++retries<=scanretries){
|
|
openok=OpenDevice(d,btr,min(retries*timeout,8000),wiitimeout,c("allowed_wiimote_adr"),btsleep,lib,false,false,dbg,invalidargflag);
|
|
}
|
|
|
|
if (openok){
|
|
g_automode_callback(cl++);
|
|
if (wb){
|
|
g_automode_callback(cl++);
|
|
// terminate running wb's
|
|
|
|
// fireup whiteboard software
|
|
if (!c.hasEntry("whiteboard_software")) log << " ** warning: config file is missing entry <whiteboard_software>" << endl;
|
|
else System(c.Get<string>("whiteboard_software",true),false,false);
|
|
}
|
|
}
|
|
if (dbg) log << " Elapsed time: " << total.elapsed() << " [s]" << endl;
|
|
|
|
// taking longer than 20 sec will bring up an annoying windows reboot dialog,
|
|
// that can be ignored, hence warn at 18 sec
|
|
if (total.elapsed()>18) log << " ** warning: connection took a long time to finish, this may cause a windows reboot dialog, that can be ignored" << endl;
|
|
|
|
if (!openok) log << " ** warning: could not open device" << endl << "Done [FAILED]" << endl;
|
|
|
|
assert(cl<10);
|
|
g_automode_callback(42);
|
|
return openok;
|
|
}
|
|
|
|
int Usage(const args& arg,const string msg="")
|
|
{
|
|
FUNSTACK;
|
|
if (msg.size()>0) log << msg << endl;
|
|
log << "Usage: " << arg[0] << " <-a <device> | -c <device> | -d <device> | -r | -s | -usbup | -usbdown> [-cf <file>] [-lf <file>] [-b <sleep>] [-t <sleep>] [-u <sleep>] [-p <sleep>] [-w <sleep>] [-q <usbradio>] [-f <removemode>] [-m <powermode>] [-l <wiilibrary>] [-y] [-wb] [-v] " << endl;
|
|
log << " " << Version() << " " << Config() << endl;
|
|
log << " modes:" << endl;
|
|
log << " -a <name>: autoconnect to device" << endl;
|
|
log << " -c <name>: connect the device, that matches this name" << endl;
|
|
log << " -d <name>: deletes the device, that matches this name" << endl;
|
|
log << " -r: lookup and list bluetooth radio devices" << endl;
|
|
log << " -s: scan external bluetooth devices" << endl;
|
|
log << " -usbdown: disable usb hubs" << endl;
|
|
log << " -usbup: enable usb hubs" << endl;
|
|
log << " options:" << endl;
|
|
log << " -cf <file>: specify a distinct configurationfile, default=" << DEFAULT_configfile << endl;
|
|
log << " -lf <file>: specify a distinct logfile, default=" << DEFAULT_logfile << endl;
|
|
log << " -b <int>: automode bluetooth connection sleep in milliseconds, default=" << DEFAULT_btsleep << endl;
|
|
log << " -t <int>: timeout for bluetooth stack in milliseconds, default=" << DEFAULT_timeout << endl;
|
|
log << " -u <int>: automode usb connection sleep in milliseconds, default=" << DEFAULT_usbsleep << endl;
|
|
log << " -p <int>: automode usbm post-connection sleep in milliseconds, default=" << DEFAULT_usbmsleep << endl;
|
|
log << " -w <int>: timeout for wiimote in milliseconds, default=" << DEFAULT_wiitimeout << endl;
|
|
log << " -q <string>: use bluetooth radio with this address (not working), default=any device" << endl;
|
|
log << " -f <int>: pre-remove mode of device, 0=remove if not connectable, 1=always remove, 2=never remove, default=" << DEFAULT_removemode << endl;
|
|
log << " -m <int>: choose USB powercycle mode, 0=no power cycle, 1=use USB hub, 2=use USBm IO hardware, 3=use USB Delcon IO hardware" << endl;
|
|
log << " -l <string>: use specific wiimote library, lib can be one-of {wiiuse,wiimotelib, default=" << DEFAULT_wiilib << endl;
|
|
log << " -y <int>: scan retries in automode, default=" << DEFAULT_scanretries<< endl;
|
|
log << " -wb: start whiteboard in automode" << endl;
|
|
log << " -nowb: do not start whiteboard in automode" << endl;
|
|
log << " -v: enable extra debugging printouts" << endl;
|
|
log << " default mode: -a \"" << NINTENDO_DEV << "\"" << endl;
|
|
log << " note: \"nintendo\" is a shortcut for \"" << NINTENDO_DEV << "\"" << endl;
|
|
return -1;
|
|
}
|
|
|
|
|
|
//#include <winsock2.h>
|
|
#include <windows.h>
|
|
#include <ws2bth.h>
|
|
|
|
int DoConnect()
|
|
{
|
|
//BLUETOOTH_DEVICE_INFO device;
|
|
//device=*(BLUETOOTH_DEVICE_INFO*)lpParam;
|
|
|
|
BLUETOOTH_DEVICE_INFO device=Get_BLUETOOTH_DEVICE_INFO();
|
|
ifstream ix("bdi.out",ios::binary);
|
|
ix.read(reinterpret_cast<char*>(&device),sizeof(device));
|
|
|
|
string info;
|
|
//SOCKET s = socket(AF_BTH, SOCK_STREAM, BTHPROTO_L2CAP);
|
|
SOCKET s = socket(AF_BTH, SOCK_SEQPACKET , BTHPROTO_L2CAP);
|
|
|
|
if (s == INVALID_SOCKET)
|
|
{
|
|
MessageBox(NULL,"","Invalid Socket",MB_OK);
|
|
exit(1);
|
|
}
|
|
|
|
SOCKADDR_BTH bthSockAddr;
|
|
|
|
bthSockAddr.addressFamily=AF_BTH;
|
|
bthSockAddr.btAddr=device.Address.ullLong;
|
|
bthSockAddr.port=0x11; //BT_PORT_ANY;
|
|
//bthSockAddr.serviceClassId=SerialPortServiceClass_UUID;
|
|
bthSockAddr.serviceClassId=HumanInterfaceDeviceServiceClass_UUID;
|
|
|
|
if(0!=connect(s,(sockaddr*)&bthSockAddr,sizeof(bthSockAddr)))
|
|
MessageBox(NULL,"","Connect",MB_OK);
|
|
else
|
|
{
|
|
info="Connected to: ";
|
|
//info+=device.szName;
|
|
MessageBox(NULL,info.c_str(),"Connect",MB_OK);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
BOOL RegFun(LPVOID p,PBLUETOOTH_DEVICE_INFO pDevice)
|
|
{
|
|
cout << "\n## RegFun called backed...";
|
|
return 0;
|
|
}
|
|
|
|
int TestOpen(const string& d,const string& btr,const bool dbg)
|
|
{
|
|
|
|
//Connect_using_BT_Api();
|
|
//return 0;
|
|
|
|
int status;
|
|
|
|
USBupdown(3,true,dbg);
|
|
//Sleep(1000);
|
|
//return DoConnect();½
|
|
|
|
// USBupdown(3,false,dbg);
|
|
|
|
BLUETOOTH_DEVICE_INFO bdi=Get_BLUETOOTH_DEVICE_INFO();
|
|
ifstream ix("bdi.out",ios::binary);
|
|
ix.read(reinterpret_cast<char*>(&bdi),sizeof(bdi));
|
|
|
|
DeviceAutoClose<HANDLE,BOOL> hRadio(RadioInfo(btr,dbg),&CloseHandle);
|
|
if (hRadio()==NULL) throw_("failed to get radio");
|
|
if (dbg) log << " RadioInfo()...OK" << endl;
|
|
|
|
|
|
BluetoothEnableIncomingConnections(hRadio(),1);
|
|
/*
|
|
for(int ii=0;ii<6;++ii) bdi.Address.rgBytes[ii]=0;
|
|
|
|
HBLUETOOTH_AUTHENTICATION_REGISTRATION reg;
|
|
status=BluetoothRegisterForAuthentication(&bdi,®,RegFun,0);
|
|
*/
|
|
|
|
|
|
Sleep(500);
|
|
USBupdown(3,true,dbg);
|
|
Sleep(1000);
|
|
|
|
// Lenovo BT adr= 00:50:B6:A0:48:8C
|
|
|
|
WCHAR pass[256];
|
|
pass[5]=0x00; // 0x00 = 0
|
|
pass[4]=0x50;
|
|
pass[3]=0xB6;
|
|
pass[2]=0xA0;
|
|
pass[1]=0x48;
|
|
pass[0]=0x8C;
|
|
|
|
pass[6]=0;
|
|
|
|
for(int i=0;i<6;++i) cout << dec << " [" << i << "]=" << hex << pass[i];
|
|
|
|
status=BluetoothAuthenticateDevice(NULL,hRadio(),&bdi,pass,6);
|
|
//status=BluetoothAuthenticateDevice(NULL,hRadio(),&bdi,0,0);
|
|
|
|
// status=BluetoothAuthenticateDeviceEx(); // only found on Vista
|
|
|
|
if (status==ERROR_SUCCESS) cout << "** OK: BluetoothAuthenticateDevice";
|
|
else cout << "** ERROR: BluetoothAuthenticateDevice, " << status;
|
|
|
|
if (status==ERROR_INVALID_PARAMETER) cout << "(ERROR_INVALID_PARAMETER)";
|
|
if (status==ERROR_NO_MORE_ITEMS) cout << "(BTH_ERROR_NO_CONNECTION)";
|
|
|
|
|
|
if (status==BTH_ERROR_AUTHENTICATION_FAILURE) cout << "(BTH_ERROR_AUTHENTICATION_FAILURE)";
|
|
if (status==BTH_ERROR_NO_CONNECTION) cout << "(BTH_ERROR_NO_CONNECTION)";
|
|
if (status==BTH_ERROR_PAGE_TIMEOUT ) cout << "(BTH_ERROR_PAGE_TIMEOUT )";
|
|
if (status==BTH_ERROR_HARDWARE_FAILURE ) cout << "(BTH_ERROR_HARDWARE_FAILURE )";
|
|
if (status==BTH_ERROR_AUTHENTICATION_FAILURE) cout << "(BTH_ERROR_AUTHENTICATION_FAILURE)";
|
|
if (status==BTH_ERROR_MEMORY_FULL ) cout << "(BTH_ERROR_MEMORY_FULL )";
|
|
if (status==BTH_ERROR_CONNECTION_TIMEOUT ) cout << "(BTH_ERROR_CONNECTION_TIMEOUT )";
|
|
if (status==BTH_ERROR_LMP_RESPONSE_TIMEOUT) cout << "(BTH_ERROR_LMP_RESPONSE_TIMEOUT)";
|
|
if (status==BTH_ERROR_MAX_NUMBER_OF_CONNECTIONS ) cout << "(BTH_ERROR_MAX_NUMBER_OF_CONNECTIONS)";
|
|
if (status==BTH_ERROR_PAIRING_NOT_ALLOWED ) cout << "(BTH_ERROR_PAIRING_NOT_ALLOWED )";
|
|
if (status==BTH_ERROR_UNSPECIFIED_ERROR ) cout << "(BTH_ERROR_UNSPECIFIED_ERROR)";
|
|
if (status==BTH_ERROR_LOCAL_HOST_TERMINATED_CONNECTION ) cout << "(BTH_ERROR_LOCAL_HOST_TERMINATED_CONNECTION)½";
|
|
|
|
if (status==ERROR_SUCCESS) {
|
|
cout << "Running wb...\n";
|
|
int n= system("D:\\wiiscan-0.9-release-2.0\\bin\\Release\\WiimoteWhiteboard.exe");
|
|
cout << " returned n=" << n << "\n";
|
|
}
|
|
|
|
/*
|
|
const GUID service=HumanInterfaceDeviceServiceClass_UUID;
|
|
|
|
status=BluetoothSetServiceState(hRadio(),&bdi,&service,BLUETOOTH_SERVICE_ENABLE);
|
|
if (dbg && status==ERROR_SUCCESS) log << " BluetoothSetServiceState(0)...OK" << endl;
|
|
else if (dbg && status==E_INVALIDARG) log << " BluetoothSetServiceState(0)...E_INVALIDARG" << endl;
|
|
else if (dbg && status!=ERROR_SUCCESS) log << " BluetoothSetServiceState(0)...ERROR" << endl;
|
|
|
|
*/
|
|
cout << "\n";
|
|
Sleep(100000);
|
|
|
|
/*
|
|
//RemoveDevice(d,dbg);
|
|
Sleep(2000);
|
|
USBupdown(3,true,dbg);
|
|
Sleep(3000);
|
|
|
|
//return Wiilib::OpenDevices("wiiuse",4000,false,true,false);
|
|
|
|
WCHAR pass[]=L"1234";
|
|
return BluetoothAuthenticateDevice(NULL,hRadio(),&bdi,pass,4);
|
|
|
|
if (dbg) log << tostring(bdi);
|
|
|
|
status=BluetoothSetServiceState(hRadio(),&bdi,&service,BLUETOOTH_SERVICE_ENABLE);
|
|
if (dbg && status==ERROR_SUCCESS) log << " BluetoothSetServiceState(1)...OK" << endl;
|
|
else if (dbg && status==E_INVALIDARG) log << " BluetoothSetServiceState(1)...E_INVALIDARG" << endl;
|
|
else if (dbg && status!=ERROR_SUCCESS) log << " BluetoothSetServiceState(1)...ERROR" << endl;
|
|
*/
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
int main(int argc,char** argv)
|
|
{
|
|
FUNSTACK;
|
|
bool invalidargflag=false;
|
|
try{
|
|
SetNiceLevel(-15); // set to time-critical
|
|
args arg(argc,argv);
|
|
|
|
// first, parse the command line configfile, then load the config, finally override any configfile options with given command line options
|
|
string cf=arg.parseval<string>("-cf",DEFAULT_configfile);
|
|
|
|
bool v=false,wb=false;
|
|
int timeout =DEFAULT_timeout;
|
|
int wiitimeout=DEFAULT_wiitimeout;
|
|
int usbsleep =DEFAULT_usbsleep;
|
|
int usbmsleep =DEFAULT_usbmsleep;
|
|
int btsleep =DEFAULT_btsleep;
|
|
int usbmode =DEFAULT_usbmode;
|
|
int removemode=DEFAULT_removemode;
|
|
int scanretries=DEFAULT_scanretries;
|
|
string a,c,d,btr,lf=DEFAULT_logfile,dev=NINTENDO_DEV,lib=DEFAULT_wiilib;
|
|
|
|
if (FileExists(cf)){
|
|
const Configfile cnf(cf);
|
|
if (cnf.hasEntry("option_device")) dev=strip(cnf.Get<string>("option_device"),'"');
|
|
if (cnf.hasEntry("option_timeout")) timeout=cnf.Get<int>("option_timeout");
|
|
if (cnf.hasEntry("option_wiitimeout")) wiitimeout=cnf.Get<int>("option_wiitimeout");
|
|
if (cnf.hasEntry("option_usbsleep")) usbsleep=cnf.Get<int>("option_usbsleep");
|
|
if (cnf.hasEntry("option_usbmsleep")) usbmsleep=cnf.Get<int>("option_usbmsleep");
|
|
if (cnf.hasEntry("option_btsleep")) btsleep=cnf.Get<int>("option_btsleep");
|
|
if (cnf.hasEntry("option_usbpowermode")) usbmode=cnf.Get<int>("option_usbpowermode");
|
|
if (cnf.hasEntry("option_removemode")) removemode=cnf.Get<int>("option_removemode");
|
|
if (cnf.hasEntry("option_debug")) v=cnf.Get<bool>("option_debug");
|
|
if (cnf.hasEntry("option_startwhiteboard")) wb=cnf.Get<bool>("option_startwhiteboard");
|
|
if (cnf.hasEntry("option_logfile")) lf=cnf.Get<string>("option_logfile");
|
|
if (cnf.hasEntry("option_btradio")) btr=cnf.Get<string>("option_btradio");
|
|
if (cnf.hasEntry("option_wiilib")) lib=cnf.Get<string>("option_wiilib");
|
|
if (cnf.hasEntry("option_scanretries"))scanretries=cnf.Get<int>("option_scanretries");
|
|
}
|
|
|
|
// parse argumets via args class
|
|
const bool r=arg.parseopt("-r");
|
|
const bool s=arg.parseopt("-s");
|
|
const bool u=arg.parseopt("-?");
|
|
const bool usbdown=arg.parseopt("-usbdown");
|
|
const bool usbup=arg.parseopt("-usbup");
|
|
v=arg.parseopt("-v") || v;
|
|
wb=arg.parseopt("-wb") || wb;
|
|
wb=!arg.parseopt("-nowb") && wb;
|
|
timeout =arg.parseval<int>("-t",timeout);
|
|
wiitimeout=arg.parseval<int>("-w",wiitimeout);
|
|
usbsleep =arg.parseval<int>("-u",usbsleep);
|
|
usbmsleep =arg.parseval<int>("-p",usbmsleep);
|
|
btsleep =arg.parseval<int>("-b",btsleep);
|
|
usbmode =arg.parseval<int>("-m",usbmode);
|
|
removemode=arg.parseval<int>("-f",removemode);
|
|
a=arg.parseval<string>("-a","");
|
|
c=arg.parseval<string>("-c","");
|
|
d=arg.parseval<string>("-d","");
|
|
lf=arg.parseval<string>("-lf",lf);
|
|
btr=arg.parseval<string>("-q",btr);
|
|
lib=arg.parseval<string>("-l",lib);
|
|
scanretries=arg.parseval<int>("-y",scanretries);
|
|
|
|
if (arg.size()!=1) return Usage(arg);
|
|
|
|
// apply shortcuts
|
|
if (a=="nintendo") a=dev;
|
|
if (c=="nintendo") c=dev;
|
|
if (d=="nintendo") d=dev;
|
|
|
|
// open log file before Usage call
|
|
if(lf!=DEFAULT_logfile){
|
|
lf=strip(lf,'"'); // cannot handle filenames in citation quotes
|
|
if (lf=="cout" || lf=="std::cout") g_log=&cout;
|
|
else if (lf=="cerr" || lf=="std::cerr") g_log=&cerr;
|
|
else {
|
|
g_log.open(lf,ios_base::app);
|
|
g_log.writelogheader("Wiiscan::main()");
|
|
if (v) log << "Using logfile <" << lf << ">" << endl;
|
|
}
|
|
}
|
|
|
|
const int check=(r ? 1 : 0)+ (s ? 1 : 0) + (a.size()>0 ? 1 : 0) + (c.size()>0 ? 1 : 0) + (d.size()>0 ? 1 : 0) + usbup + usbdown;
|
|
if (check>1 || u) return Usage(arg);
|
|
|
|
if (timeout<20) throw_("bad value of timeout, should be >=20");
|
|
if (wiitimeout<20)throw_("bad value of wiitimeout, should be >=20");
|
|
if (usbsleep<20) throw_("bad value of usbsleep, should be >=20");
|
|
if (usbmsleep<20) throw_("bad value of usbmsleep, should be >=20");
|
|
if (btsleep<20) throw_("bad value of btsleep, should be >=20");
|
|
if (usbdown && usbup) throw_("bad value of usbdown/up, cannot be used at the same time");
|
|
if (wiitimeout%1000!=0) throw_("bad value, wiitimeout should be divisable with 1000");
|
|
if (btr.size()>0 && btr.size()!=17) throw_("bluetooth radio must be in the form xx:xx:xx:xx:xx:xx");
|
|
if (usbmode<0 || usbmode>3) throw_("bad usbpowermode, must be 0,1,2, or 3");
|
|
if (removemode<0 || removemode>2) throw_("bad removemode, must be 0,1 or 2");
|
|
if (scanretries<=0) throw_("bad value of scanretries, should be > 0");
|
|
if (a.size()==0) a=NINTENDO_DEV;
|
|
|
|
if (v) {
|
|
log << Version() << " " << Config() << endl;
|
|
log << "Values:" << endl;
|
|
log << " a=" << a << endl;
|
|
log << " c=" << c << endl;
|
|
log << " d=" << d << endl;
|
|
log << " r=" << r << endl;
|
|
log << " s=" << s << endl;
|
|
log << " v=" << v << endl;
|
|
log << " cf=" << cf << endl;
|
|
log << " lf=" << lf << endl;
|
|
log << " wb=" << wb << endl;
|
|
log << " btr=" << btr << endl;
|
|
log << " lib=" << lib << endl;
|
|
log << " usbmode=" << usbmode << endl;
|
|
log << " removemode=" << removemode << endl;
|
|
log << " scanretries=" << scanretries << endl;
|
|
log << " usbup =" << usbup << endl;
|
|
log << " usbdown=" << usbup << endl;
|
|
log << "Timeouts:" << endl;
|
|
log << " timeout =" << timeout << endl;
|
|
log << " wiitimeout=" << wiitimeout << endl;
|
|
log << " usbsleep =" << usbsleep << endl;
|
|
log << " usbmsleep =" << usbmsleep << endl;
|
|
log << " btsleep =" << btsleep << endl;
|
|
}
|
|
|
|
bool ret=true;
|
|
|
|
return TestOpen(NINTENDO_DEV,btr,true);
|
|
|
|
if (r) ret=RadioInfo (btr.size()==0 ? "all" : btr,v)!=NULL;
|
|
else if (s) ret=ScanDevices (timeout);
|
|
else if (c.size()>0) ret=OpenDevice (c,btr,timeout,wiitimeout,vector<string>(),btsleep,lib,true,true,v,invalidargflag);
|
|
else if (d.size()>0) ret=RemoveDevice(d,v);
|
|
else if (usbup) ret=USBupdown (usbmode,true, v,Configfile(cf).Get<string>("active_usb_hub",true));
|
|
else if (usbdown) ret=USBupdown (usbmode,false,v,Configfile(cf).Get<string>("active_usb_hub",true));
|
|
else ret=AutoOpenDevice(a,btr,timeout,wiitimeout,usbsleep,btsleep,usbmsleep,cf,lib,removemode,usbmode,wb,scanretries,v,invalidargflag); // default mode
|
|
|
|
log << "Wiiscan done " << (ret ? "[OK]" : "[FAILED]") << endl;
|
|
|
|
if (invalidargflag) {
|
|
if (v) log << "** warning: return=-3 (E_INVALIDARG)" << endl;
|
|
return -3;
|
|
}
|
|
|
|
if (v) log << "returning: return=" << (ret ? "0" : "-1") << endl;
|
|
return ret ? 0 : -1; // 0=Ok, -1=fail, -2=fail with exception, -3=fail with E_INVALIDARG
|
|
}
|
|
CATCH_ALL;
|
|
|
|
assert(invalidargflag==false); // flag not setted => no throw in when E_INVALIDARG encoutered
|
|
log << "Wiiscan done [FAILED]" << endl;
|
|
return -2;
|
|
}
|
|
|
|
}; // namespace Wiiscan
|
|
|
|
|
|
const int MAX_RADIOS=1;
|
|
const int MAX_DEVICES=16;
|
|
const int MAX_MAC_ADDR_LENGHT=256;
|
|
const int MAX_STRING_LENGHT=1024;
|
|
|
|
string GetLastErrorMessage(const int n) {return "error n";}
|
|
|
|
// PFN_DEVICE_CALLBACK
|
|
|
|
BOOL WINAPI RegFun2(LPVOID pvParam,const BLUETOOTH_DEVICE_INFO* pDevice)
|
|
{
|
|
cout << "\n**RegFun2**\n";
|
|
return 1;
|
|
}
|
|
|
|
int BT_radio_find_radios(HANDLE hRadio[MAX_RADIOS])
|
|
{
|
|
int i = 0;
|
|
HBLUETOOTH_RADIO_FIND hFind;
|
|
BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(btfrp) };
|
|
|
|
hFind = BluetoothFindFirstRadio( &btfrp, &(hRadio[i]) );
|
|
if ( NULL != hFind )
|
|
{
|
|
//printf("found first radio\n");
|
|
i++;
|
|
while(TRUE == BluetoothFindNextRadio(hFind, &hRadio[i]))
|
|
{
|
|
i++;
|
|
if (i >= MAX_RADIOS)
|
|
{
|
|
printf("Cannot assign next radio, MAX_RADIOS = %d reached\n", MAX_RADIOS);
|
|
return MAX_RADIOS;
|
|
}
|
|
}
|
|
if (FALSE == BluetoothFindRadioClose(hFind))
|
|
{
|
|
printf("%s\n", GetLastErrorMessage(GetLastError()));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("%s\n", GetLastErrorMessage(GetLastError()));
|
|
}
|
|
return i;
|
|
}
|
|
|
|
int BT_radio_find_devices(unsigned char address_table[MAX_DEVICES][MAX_MAC_ADDR_LENGHT],
|
|
char nameAsString_table[MAX_DEVICES][MAX_STRING_LENGHT],
|
|
HANDLE* hRadio)
|
|
{
|
|
BLUETOOTH_DEVICE_INFO deviceInfo;
|
|
deviceInfo.dwSize = sizeof(deviceInfo);
|
|
HBLUETOOTH_DEVICE_FIND hDeviceFind;
|
|
|
|
BLUETOOTH_DEVICE_SEARCH_PARAMS deviceSearchParams;
|
|
memset(&deviceSearchParams, 0, sizeof(deviceSearchParams));
|
|
deviceSearchParams.dwSize = sizeof(deviceSearchParams);
|
|
deviceSearchParams.fReturnAuthenticated = true;
|
|
deviceSearchParams.fReturnRemembered = true;
|
|
deviceSearchParams.fReturnUnknown = true;
|
|
deviceSearchParams.fReturnConnected = true;
|
|
deviceSearchParams.fIssueInquiry = true;
|
|
deviceSearchParams.cTimeoutMultiplier = 10;
|
|
deviceSearchParams.hRadio = *hRadio;
|
|
int i = 0;
|
|
|
|
hDeviceFind = BluetoothFindFirstDevice(&deviceSearchParams, &deviceInfo);
|
|
if (NULL != hDeviceFind)
|
|
{
|
|
do
|
|
{
|
|
memcpy(address_table[i], &deviceInfo.Address.rgBytes[0], MAX_MAC_ADDR_LENGHT);
|
|
memcpy(&nameAsString_table[i], &deviceInfo.szName, MAX_STRING_LENGHT);
|
|
//wprintf(L"Device: %s\n", deviceInfo.szName);
|
|
//BluetoothDisplayDeviceProperties(0, &deviceInfo);
|
|
i++;
|
|
if (i >= MAX_DEVICES)
|
|
{
|
|
printf("Cannot assign next device, MAX_DEVICES = %d reached\n", MAX_DEVICES);
|
|
return MAX_DEVICES;
|
|
}
|
|
}
|
|
while(BluetoothFindNextDevice(hDeviceFind, &deviceInfo));
|
|
|
|
if (FALSE == BluetoothFindDeviceClose(hDeviceFind))
|
|
{
|
|
printf("%s\n", GetLastErrorMessage(GetLastError()));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("%s\n", GetLastErrorMessage(GetLastError()));
|
|
}
|
|
return i;
|
|
}
|
|
|
|
void Connect_using_BT_Api()
|
|
{
|
|
int i, j, result;
|
|
HANDLE hRadio[MAX_RADIOS];
|
|
int found_radio_cnt = 0;
|
|
int selected_radio;
|
|
int found_radio_dev_cnt = 0;
|
|
int selected_radio_dev;
|
|
|
|
BLUETOOTH_RADIO_INFO radioInfo;
|
|
radioInfo.dwSize = sizeof(radioInfo);
|
|
BLUETOOTH_DEVICE_INFO deviceInfo;
|
|
memset(&deviceInfo, 0, sizeof(deviceInfo));
|
|
deviceInfo.dwSize = sizeof(deviceInfo);
|
|
|
|
unsigned char radio_dev_address[MAX_DEVICES][MAX_MAC_ADDR_LENGHT];
|
|
char radio_dev_names [MAX_DEVICES][MAX_STRING_LENGHT];
|
|
|
|
found_radio_cnt = BT_radio_find_radios(hRadio);
|
|
if (found_radio_cnt == 0)
|
|
{
|
|
printf("no radios found\n");
|
|
exit(1);
|
|
}
|
|
for (i = 0; i < found_radio_cnt; i++)
|
|
{
|
|
if (ERROR_SUCCESS == BluetoothGetRadioInfo(hRadio[0], &radioInfo))
|
|
{
|
|
wprintf(L"Radio[%2d]: %10s\n", i, radioInfo.szName);
|
|
}
|
|
}
|
|
printf("Select radio: ");
|
|
//scanf("%d", &selected_radio);
|
|
selected_radio=0;
|
|
|
|
if (selected_radio < 0) selected_radio = 0;
|
|
if (selected_radio >= found_radio_cnt) selected_radio = found_radio_cnt - 1;
|
|
|
|
if (ERROR_SUCCESS == BluetoothGetRadioInfo(hRadio[selected_radio], &radioInfo))
|
|
{
|
|
wprintf(L"selected: %10s\n", radioInfo.szName);
|
|
}
|
|
|
|
if (FALSE == BluetoothEnableDiscovery(hRadio[selected_radio], TRUE))
|
|
{
|
|
printf("%s\n", GetLastErrorMessage(GetLastError()));
|
|
}
|
|
if (FALSE == BluetoothEnableIncomingConnections(hRadio[selected_radio], TRUE))
|
|
{
|
|
printf("%s\n", GetLastErrorMessage(GetLastError()));
|
|
}
|
|
|
|
found_radio_dev_cnt = BT_radio_find_devices(radio_dev_address, radio_dev_names, &hRadio[selected_radio]);
|
|
if (found_radio_dev_cnt == 0)
|
|
{
|
|
printf("no radio devices found\n");
|
|
exit(1);
|
|
}
|
|
|
|
for (i = 0; i < found_radio_dev_cnt; i++)
|
|
{
|
|
wprintf(L"Radio device[%2d]: %20s ", i, radio_dev_names[i]);
|
|
printf("addr: (%2x:%2x:%2x:%2x:%2x:%2x)\n",
|
|
radio_dev_address[i][5],
|
|
radio_dev_address[i][4],
|
|
radio_dev_address[i][3],
|
|
radio_dev_address[i][2],
|
|
radio_dev_address[i][1],
|
|
radio_dev_address[i][0]);
|
|
}
|
|
|
|
printf("Select device: ");
|
|
scanf("%d", &selected_radio_dev);
|
|
if (selected_radio_dev < 0) selected_radio_dev = 0;
|
|
if (selected_radio_dev >= found_radio_dev_cnt) selected_radio_dev = found_radio_dev_cnt - 1;
|
|
|
|
#if 1 //function works, but not needed
|
|
BLUETOOTH_SELECT_DEVICE_PARAMS seldevquery;
|
|
memset(&seldevquery, 0, sizeof(seldevquery));
|
|
seldevquery.dwSize = sizeof(seldevquery);
|
|
seldevquery.cNumOfClasses = 5;
|
|
seldevquery.hwndParent = 0;
|
|
seldevquery.fForceAuthentication = true;
|
|
seldevquery.fShowAuthenticated = true;
|
|
seldevquery.fShowRemembered = true;
|
|
seldevquery.fShowUnknown = true;
|
|
seldevquery.fAddNewDeviceWizard = false;
|
|
seldevquery.fSkipServicesPage = false;
|
|
seldevquery.pfnDeviceCallback = RegFun2, //dev_callback;
|
|
seldevquery.pvParam = 0;
|
|
seldevquery.cNumDevices = 2;
|
|
seldevquery.pDevices = &deviceInfo;
|
|
|
|
if (FALSE == (&seldevquery))
|
|
{
|
|
printf("%s\n", GetLastErrorMessage(GetLastError()));
|
|
}
|
|
else
|
|
{
|
|
printf("poszlo: BluetoothSelectDevices\n");
|
|
wprintf(L"Selected device: %20s ", deviceInfo.szName);
|
|
printf("addr: (%2x:%2x:%2x:%2x:%2x:%2x)\n",
|
|
deviceInfo.Address.rgBytes[5],
|
|
deviceInfo.Address.rgBytes[4],
|
|
deviceInfo.Address.rgBytes[3],
|
|
deviceInfo.Address.rgBytes[2],
|
|
deviceInfo.Address.rgBytes[1],
|
|
deviceInfo.Address.rgBytes[0]);
|
|
}
|
|
#endif
|
|
|
|
#if 1
|
|
memcpy(&deviceInfo.Address.rgBytes[0], radio_dev_address[selected_radio_dev], MAX_MAC_ADDR_LENGHT);
|
|
if (ERROR_SUCCESS == BluetoothGetDeviceInfo(hRadio[selected_radio], &deviceInfo))
|
|
{
|
|
wprintf(L"Selected device: %20s ", deviceInfo.szName);
|
|
printf("addr: (%2x:%2x:%2x:%2x:%2x:%2x)\n",
|
|
deviceInfo.Address.rgBytes[5],
|
|
deviceInfo.Address.rgBytes[4],
|
|
deviceInfo.Address.rgBytes[3],
|
|
deviceInfo.Address.rgBytes[2],
|
|
deviceInfo.Address.rgBytes[1],
|
|
deviceInfo.Address.rgBytes[0]);
|
|
|
|
// BluetoothUpdateDeviceRecord(&deviceInfo);
|
|
// BluetoothRemoveDevice(deviceInfo.Address);
|
|
}
|
|
else
|
|
{
|
|
printf("%s\n", GetLastErrorMessage(GetLastError()));
|
|
}
|
|
#endif
|
|
|
|
//GUID pService = {0x00001101, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
|
|
GUID pService = (GUID)SerialPortServiceClass_UUID;
|
|
//GUID pService = (GUID)OBEXFileTransferServiceClass_UUID;
|
|
//GUID pService = (GUID)OBEXObjectPushServiceClass_UUID;
|
|
|
|
if (ERROR_SUCCESS != BluetoothSetServiceState(hRadio[selected_radio], &deviceInfo, &pService, BLUETOOTH_SERVICE_ENABLE))
|
|
{
|
|
printf("%s\n", GetLastErrorMessage(GetLastError()));
|
|
}
|
|
else
|
|
{
|
|
printf("BluetoothSetServiceState enabled (COM)\n");
|
|
}
|
|
|
|
#if 1
|
|
GUID guidServices[MAX_DEVICES];
|
|
memset(guidServices, 0, sizeof(guidServices));
|
|
DWORD numServices = MAX_DEVICES;
|
|
memcpy(&deviceInfo.Address.rgBytes[0], radio_dev_address[selected_radio_dev], MAX_MAC_ADDR_LENGHT);
|
|
|
|
if (ERROR_SUCCESS == BluetoothEnumerateInstalledServices(hRadio[selected_radio],
|
|
&deviceInfo,
|
|
&numServices,
|
|
guidServices))
|
|
{
|
|
printf("enumerated services: %d\n", numServices);
|
|
}
|
|
else
|
|
{
|
|
printf("%s\n", GetLastErrorMessage(GetLastError()));
|
|
}
|
|
#endif
|
|
|
|
#if 1
|
|
if (ERROR_SUCCESS != BluetoothSetServiceState(hRadio[selected_radio], &deviceInfo, &pService, BLUETOOTH_SERVICE_DISABLE))
|
|
{
|
|
printf("%s\n", GetLastErrorMessage(GetLastError()));
|
|
}
|
|
else
|
|
{
|
|
printf("BluetoothSetServiceState disabled (COM)\n");
|
|
}
|
|
#endif
|
|
|
|
//function works
|
|
HBLUETOOTH_AUTHENTICATION_REGISTRATION phRegHandle;
|
|
if (ERROR_SUCCESS != BluetoothRegisterForAuthentication(&deviceInfo,
|
|
&phRegHandle,
|
|
Wiiscan::RegFun, // auth_callback,
|
|
hRadio[selected_radio]))
|
|
{
|
|
printf("%s\n", GetLastErrorMessage(GetLastError()));
|
|
}
|
|
|
|
WCHAR tempkey[12] = {0};
|
|
PWCHAR pszPasskey = tempkey;
|
|
for (j = 0; j < 8; j+=2)
|
|
{
|
|
((unsigned char*)pszPasskey)[j] = '0';
|
|
}
|
|
for (j = 1; j < 8; j+=2)
|
|
{
|
|
((unsigned char*)pszPasskey)[j] = 0x0;
|
|
}
|
|
ULONG ulPasskeyLength = 4;
|
|
wprintf(L"pszPasskey: %20s\n", pszPasskey);
|
|
|
|
//works!!!!
|
|
result = BluetoothAuthenticateDevice(0, hRadio[selected_radio], &deviceInfo, pszPasskey, ulPasskeyLength);
|
|
if (result == ERROR_NO_MORE_ITEMS)
|
|
{
|
|
printf("%s\n", "device already authenticated");
|
|
}
|
|
else if(result != ERROR_SUCCESS)
|
|
{
|
|
printf("%s\n", GetLastErrorMessage(GetLastError()));
|
|
}
|
|
CloseHandle( hRadio[selected_radio] );
|
|
}
|
|
|
|
/*
|
|
void Connect_using_SWA()
|
|
{
|
|
int i;
|
|
//--- to open a socket -----
|
|
SOCKET s;
|
|
WORD wVersionRequested = 0x202;
|
|
WSADATA m_data;
|
|
|
|
WSAPROTOCOL_INFO protocolInfo;
|
|
int protocolInfoSize = sizeof(protocolInfo);
|
|
|
|
char known_addresses[MAX_DEVICES][MAX_STRING_LENGHT];
|
|
char known_names [MAX_DEVICES][MAX_STRING_LENGHT];
|
|
char selected_addresses [MAX_DEVICES][MAX_STRING_LENGHT];
|
|
char selected_names [MAX_DEVICES][MAX_STRING_LENGHT];
|
|
|
|
//BTH_DEVICE_INFO *pDeviceInfo;
|
|
|
|
int found_dev_cnt = 0;;
|
|
int selected_dev;
|
|
int found_serv_cnt = 0;
|
|
int selected_serv;
|
|
|
|
if (0 == WSAStartup(wVersionRequested, &m_data))
|
|
{
|
|
if (0 != BT_open_socket(&s, &protocolInfo, &protocolInfoSize))
|
|
{
|
|
exit(1);
|
|
}
|
|
|
|
found_dev_cnt = BT_find_all_devices(known_addresses, known_names, &protocolInfo);
|
|
if (found_dev_cnt == 0)
|
|
{
|
|
printf("no devices found\n");
|
|
exit(1);
|
|
}
|
|
|
|
for (i = 0; i < found_dev_cnt; i++)
|
|
{
|
|
printf("[%2d]: %20s ", i, known_names[i]);
|
|
printf("addr: %s\n", known_addresses[i]);
|
|
}
|
|
printf("Select device: ");
|
|
scanf("%d", &selected_dev);
|
|
if (selected_dev < 0) selected_dev = 0;
|
|
if (selected_dev >= found_dev_cnt) selected_dev = found_dev_cnt - 1;
|
|
|
|
found_serv_cnt = BT_find_devices_by_context(selected_addresses, selected_names, &protocolInfo, known_addresses[selected_dev]);
|
|
if (found_serv_cnt == 0)
|
|
{
|
|
printf("no services found\n");
|
|
exit(1);
|
|
}
|
|
|
|
for (i = 0; i < found_serv_cnt; i++)
|
|
{
|
|
printf("[%2d]: %20s ", i, selected_names[i]);
|
|
printf("addr: %s\n", selected_addresses[i]);
|
|
}
|
|
printf("Select service: ");
|
|
scanf("%d", &selected_serv);
|
|
if (selected_serv < 0) selected_serv = 0;
|
|
if (selected_serv >= found_serv_cnt) selected_serv = found_serv_cnt - 1;
|
|
|
|
printf("selected: %s\n", selected_names[selected_serv]);
|
|
|
|
|
|
WSACleanup();
|
|
}
|
|
}
|
|
*/ |