// Copyright © 2009 MergeIt, Aps. // // License LGPLv3+: GNU lesser LGPL version 3 or later . // 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 . #define VERSION 0 #define VERSION_REV 9 #define VC_EXTRALEAN #include "toolsfun.h" #include "wiiuse.h" #include "usbm.h" #include "delcomdll.h" #include #include #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 << ""; 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 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 . 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(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 hbf(BluetoothFindFirstRadio(&btfrp,&hRadio),&BluetoothFindRadioClose); if (hbf()==NULL) { if (dbg) log << " " << 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 infos; BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp=Get_BLUETOOTH_DEVICE_SEARCH_PARAMS(timeout); BLUETOOTH_DEVICE_INFO bdi=Get_BLUETOOTH_DEVICE_INFO(); DeviceAutoClose 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 << " " << endl; else for(size_t i=0;i0 ? s : "") << 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 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& 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(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& 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 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 hbf(BluetoothFindFirstDevice(&bdsp,&bdi),&BluetoothFindDeviceClose); // DWORD status=GetLastError(); unsigned long tid=0; DeviceAutoClose 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 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(&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 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 entry"); if (!c.hasEntry("active_usb_hub")) throw_("config file missing entry"); if (!c.hasEntry("allowed_wiimote_adr")) throw_("config file missing entry"); if (!c.hasEntry("whiteboard_software")) throw_("config file missing 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 " << endl; else System(c.Get("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("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=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 " << endl; else System(c.Get("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 | -c | -d | -r | -s | -usbup | -usbdown> [-cf ] [-lf ] [-b ] [-t ] [-u ] [-p ] [-w ] [-q ] [-f ] [-m ] [-l ] [-y] [-wb] [-v] " << endl; log << " " << Version() << " " << Config() << endl; log << " modes:" << endl; log << " -a : autoconnect to device" << endl; log << " -c : connect the device, that matches this name" << endl; log << " -d : 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 : specify a distinct configurationfile, default=" << DEFAULT_configfile << endl; log << " -lf : specify a distinct logfile, default=" << DEFAULT_logfile << endl; log << " -b : automode bluetooth connection sleep in milliseconds, default=" << DEFAULT_btsleep << endl; log << " -t : timeout for bluetooth stack in milliseconds, default=" << DEFAULT_timeout << endl; log << " -u : automode usb connection sleep in milliseconds, default=" << DEFAULT_usbsleep << endl; log << " -p : automode usbm post-connection sleep in milliseconds, default=" << DEFAULT_usbmsleep << endl; log << " -w : timeout for wiimote in milliseconds, default=" << DEFAULT_wiitimeout << endl; log << " -q : use bluetooth radio with this address (not working), default=any device" << endl; log << " -f : pre-remove mode of device, 0=remove if not connectable, 1=always remove, 2=never remove, default=" << DEFAULT_removemode << endl; log << " -m : 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 : use specific wiimote library, lib can be one-of {wiiuse,wiimotelib, default=" << DEFAULT_wiilib << endl; log << " -y : 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 #include #include 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(&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(&bdi),sizeof(bdi)); DeviceAutoClose 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("-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("option_device"),'"'); if (cnf.hasEntry("option_timeout")) timeout=cnf.Get("option_timeout"); if (cnf.hasEntry("option_wiitimeout")) wiitimeout=cnf.Get("option_wiitimeout"); if (cnf.hasEntry("option_usbsleep")) usbsleep=cnf.Get("option_usbsleep"); if (cnf.hasEntry("option_usbmsleep")) usbmsleep=cnf.Get("option_usbmsleep"); if (cnf.hasEntry("option_btsleep")) btsleep=cnf.Get("option_btsleep"); if (cnf.hasEntry("option_usbpowermode")) usbmode=cnf.Get("option_usbpowermode"); if (cnf.hasEntry("option_removemode")) removemode=cnf.Get("option_removemode"); if (cnf.hasEntry("option_debug")) v=cnf.Get("option_debug"); if (cnf.hasEntry("option_startwhiteboard")) wb=cnf.Get("option_startwhiteboard"); if (cnf.hasEntry("option_logfile")) lf=cnf.Get("option_logfile"); if (cnf.hasEntry("option_btradio")) btr=cnf.Get("option_btradio"); if (cnf.hasEntry("option_wiilib")) lib=cnf.Get("option_wiilib"); if (cnf.hasEntry("option_scanretries"))scanretries=cnf.Get("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("-t",timeout); wiitimeout=arg.parseval("-w",wiitimeout); usbsleep =arg.parseval("-u",usbsleep); usbmsleep =arg.parseval("-p",usbmsleep); btsleep =arg.parseval("-b",btsleep); usbmode =arg.parseval("-m",usbmode); removemode=arg.parseval("-f",removemode); a=arg.parseval("-a",""); c=arg.parseval("-c",""); d=arg.parseval("-d",""); lf=arg.parseval("-lf",lf); btr=arg.parseval("-q",btr); lib=arg.parseval("-l",lib); scanretries=arg.parseval("-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(),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("active_usb_hub",true)); else if (usbdown) ret=USBupdown (usbmode,false,v,Configfile(cf).Get("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(); } } */