void WiimoteScannerHidapi::FindWiimotes(std::vector<Wiimote*>& wiimotes, Wiimote*& board) { hid_device_info* list = hid_enumerate(0x0, 0x0); for (hid_device_info* device = list; device; device = device->next) { const std::string name = device->product_string ? UTF16ToUTF8(device->product_string) : ""; const bool is_wiimote = IsValidDeviceName(name) || (device->vendor_id == 0x057e && (device->product_id == 0x0306 || device->product_id == 0x0330)); if (!is_wiimote || !IsNewWiimote(device->path) || !IsDeviceUsable(device->path)) continue; auto* wiimote = new WiimoteHidapi(device->path); const bool is_balance_board = IsBalanceBoardName(name) || wiimote->IsBalanceBoard(); if (is_balance_board) board = wiimote; else wiimotes.push_back(wiimote); NOTICE_LOG(WIIMOTE, "Found %s at %s: %ls %ls (%04hx:%04hx)", is_balance_board ? "balance board" : "Wiimote", device->path, device->manufacturer_string, device->product_string, device->vendor_id, device->product_id); } hid_free_enumeration(list); }
void WiimoteScannerLinux::FindWiimotes(std::vector<Wiimote*>& found_wiimotes, Wiimote*& found_board) { // supposedly 1.28 seconds int const wait_len = 1; int const max_infos = 255; inquiry_info scan_infos[max_infos] = {}; auto* scan_infos_ptr = scan_infos; found_board = nullptr; // Use Limited Dedicated Inquiry Access Code (LIAC) to query, since third-party Wiimotes // cannot be discovered without it. const u8 lap[3] = {0x00, 0x8b, 0x9e}; // Scan for Bluetooth devices int const found_devices = hci_inquiry(m_device_id, wait_len, max_infos, lap, &scan_infos_ptr, IREQ_CACHE_FLUSH); if (found_devices < 0) { ERROR_LOG(WIIMOTE, "Error searching for Bluetooth devices."); return; } DEBUG_LOG(WIIMOTE, "Found %i Bluetooth device(s).", found_devices); // Display discovered devices for (int i = 0; i < found_devices; ++i) { NOTICE_LOG(WIIMOTE, "found a device..."); // BT names are a maximum of 248 bytes apparently char name[255] = {}; if (hci_read_remote_name(m_device_sock, &scan_infos[i].bdaddr, sizeof(name), name, 1000) < 0) { ERROR_LOG(WIIMOTE, "name request failed"); continue; } NOTICE_LOG(WIIMOTE, "device name %s", name); if (!IsValidDeviceName(name)) continue; char bdaddr_str[18] = {}; ba2str(&scan_infos[i].bdaddr, bdaddr_str); if (!IsNewWiimote(bdaddr_str)) continue; // Found a new device Wiimote* wm = new WiimoteLinux(scan_infos[i].bdaddr); if (IsBalanceBoardName(name)) { found_board = wm; NOTICE_LOG(WIIMOTE, "Found balance board (%s).", bdaddr_str); } else { found_wiimotes.push_back(wm); NOTICE_LOG(WIIMOTE, "Found Wiimote (%s).", bdaddr_str); } } }
void ProcessWiimotes(bool new_scan, T& callback) { BLUETOOTH_DEVICE_SEARCH_PARAMS srch; srch.dwSize = sizeof(srch); srch.fReturnAuthenticated = true; srch.fReturnRemembered = true; // Does not filter properly somehow, so we need to do an additional check on // fConnected BT Devices srch.fReturnConnected = true; srch.fReturnUnknown = true; srch.fIssueInquiry = new_scan; // multiple of 1.28 seconds srch.cTimeoutMultiplier = 2; BLUETOOTH_FIND_RADIO_PARAMS radioParam; radioParam.dwSize = sizeof(radioParam); HANDLE hRadio; // TODO: save radio(s) in the WiimoteScanner constructor? // Enumerate BT radios HBLUETOOTH_RADIO_FIND hFindRadio = pBluetoothFindFirstRadio(&radioParam, &hRadio); while (hFindRadio) { BLUETOOTH_RADIO_INFO radioInfo; radioInfo.dwSize = sizeof(radioInfo); auto const rinfo_result = pBluetoothGetRadioInfo(hRadio, &radioInfo); if (ERROR_SUCCESS == rinfo_result) { srch.hRadio = hRadio; BLUETOOTH_DEVICE_INFO btdi; btdi.dwSize = sizeof(btdi); // Enumerate BT devices HBLUETOOTH_DEVICE_FIND hFindDevice = pBluetoothFindFirstDevice(&srch, &btdi); while (hFindDevice) { // btdi.szName is sometimes missing it's content - it's a bt feature.. DEBUG_LOG(WIIMOTE, "Authenticated %i connected %i remembered %i ", btdi.fAuthenticated, btdi.fConnected, btdi.fRemembered); if (IsValidDeviceName(UTF16ToUTF8(btdi.szName))) { callback(hRadio, radioInfo, btdi); } if (false == pBluetoothFindNextDevice(hFindDevice, &btdi)) { pBluetoothFindDeviceClose(hFindDevice); hFindDevice = nullptr; } } } if (false == pBluetoothFindNextRadio(hFindRadio, &hRadio)) { pBluetoothFindRadioClose(hFindRadio); hFindRadio = nullptr; } } }