static int is_connection_established(const HANDLE hRadio, BLUETOOTH_DEVICE_INFO *device_info) { /* NOTE: Sometimes the Bluetooth connection appears to be established * even though the Move decided that it is not really connected * yet. That is why we cannot simply stop trying to connect after * the first successful check. Instead, we require a minimum * number of successive successful checks to be sure. */ unsigned int i; for (i = 0; i < CONN_CHECK_NUM_TRIES; i++) { /* read device info again to check if we have a connection */ DWORD result = BluetoothGetDeviceInfo(hRadio, device_info); if (result != ERROR_SUCCESS) { WINPAIR_DEBUG("Failed to read device info"); return 0; } if (device_info->fConnected && device_info->fRemembered && is_hid_service_enabled(hRadio, device_info)) { } else { return 0; } Sleep(CONN_CHECK_DELAY); } return 1; }
static BluetoothPairDeviceState::eStatus AsyncBluetoothPairDeviceRequest__patchRegistry( BluetoothPairDeviceState *state) { assert(state->isWorkerThread()); BluetoothPairDeviceState::eStatus nextSubStatus= state->getSubStatus_WorkerThread<BluetoothPairDeviceState::eStatus>(); bool success= true; /* Windows 8 seems to require manual help with setting up the device * in the registry. Previous versions do this by themselves, but * doing it manually for them does not seem to harm them either. So we * do not single out Windows 8 but simply perform the necessary tweaks * for all versions of Windows. */ SERVER_MT_LOG_INFO("AsyncBluetoothPairDeviceRequest") << "Patching the registry ..."; patch_registry(&state->deviceInfo.Address, &state->radioInfo.address); // enable HID service only if necessary SERVER_MT_LOG_INFO("AsyncBluetoothPairDeviceRequest") << "Checking HID service"; if(!is_hid_service_enabled(state->hRadio, &state->deviceInfo)) { SERVER_MT_LOG_INFO("AsyncBluetoothPairDeviceRequest") << "HID service not enabled, attempting to enable"; GUID service = HumanInterfaceDeviceServiceClass_UUID; DWORD result = BluetoothSetServiceState(state->hRadio, &state->deviceInfo, &service, BLUETOOTH_SERVICE_ENABLE); if(result == ERROR_SUCCESS) { SERVER_MT_LOG_INFO("AsyncBluetoothPairDeviceRequest") << "Patching the registry ..."; patch_registry(&state->deviceInfo.Address, &state->radioInfo.address); } else { SERVER_MT_LOG_INFO("AsyncBluetoothPairDeviceRequest") << "Failed to enable HID service. Error code: " << result; success= false; } } if (success) { // On Success, Move on to the verify connection state // Reset the connection verification count before entering that state state->verifyConnectionCount= 0; nextSubStatus= BluetoothPairDeviceState::verifyConnection; } else { // On Failure, fall back to the device scanning nextSubStatus= BluetoothPairDeviceState::deviceScan; } return nextSubStatus; }
static void handle_windows_pre8(const BLUETOOTH_ADDRESS *move_addr, const BLUETOOTH_ADDRESS *radio_addr, const HANDLE hRadio) { int connected = 0; while (!connected) { BLUETOOTH_DEVICE_INFO device_info; if (get_bluetooth_device_info(hRadio, move_addr, &device_info, 0) != 0) { WINPAIR_DEBUG("No Bluetooth device found matching the given address"); } else { if (is_move_motion_controller(&device_info)) { WINPAIR_DEBUG("Found Move Motion Controller matching the given address"); if (device_info.fConnected) { /* enable HID service only if necessary */ WINPAIR_DEBUG("Checking HID service ..."); if (!is_hid_service_enabled(hRadio, &device_info)) { WINPAIR_DEBUG("Enabling HID service ..."); GUID service = HumanInterfaceDeviceServiceClass_UUID; DWORD result = BluetoothSetServiceState(hRadio, &device_info, &service, BLUETOOTH_SERVICE_ENABLE); if (result != ERROR_SUCCESS) { WINPAIR_DEBUG("Failed to enable HID service"); } } WINPAIR_DEBUG("Verifying successful connection ..."); if (is_connection_established(hRadio, &device_info)) { /* if we have a connection, stop trying to connect this device */ printf("Connection verified.\n"); connected = 1; break; } } } else { WINPAIR_DEBUG("Bluetooth device matching the given address is not a Move Motion Controller"); } } Sleep(SLEEP_BETWEEN_SCANS); } }
int windows_register_psmove(const char *move_addr_str, const HANDLE hRadio) { /* parse controller's Bluetooth device address string */ BLUETOOTH_ADDRESS *move_addr = string_to_btaddr(move_addr_str); if (!move_addr) { WINPAIR_DEBUG("Cannot parse controller address: '%s'", move_addr_str); return 1; } if (set_up_bluetooth_radio(hRadio) != 0) { WINPAIR_DEBUG("Failed to configure Bluetooth radio for use"); return 1; } /* Keep track of the number of times the loop iterates so we may timeout. */ int timeout_duration = 30; // seconds int sleep_interval = 1000; // msec int timeout_iterations = timeout_duration * 1000 / sleep_interval; int loop_count = 0; printf("\n" \ " Unplug the controller.\n" \ "\n" " Now press the controller's PS button. The red status LED\n" \ " will start blinking. Whenever it goes off, press the\n" \ " PS button again. Repeat this until the status LED finally\n" \ " remains lit. Press Ctrl+C to cancel anytime.\n"); for(;;) { BLUETOOTH_DEVICE_INFO device_info; if (get_bluetooth_device_info(hRadio, move_addr, &device_info) != 0) { WINPAIR_DEBUG("No Bluetooth device found matching the given address"); } else { if (is_move_motion_controller(&device_info)) { WINPAIR_DEBUG("Found Move Motion Controller matching the given address"); if (device_info.fConnected) { /* enable HID service only if necessary */ WINPAIR_DEBUG("Checking HID service ..."); if (!is_hid_service_enabled(hRadio, &device_info)) { WINPAIR_DEBUG("Enabling HID service ..."); GUID service = HumanInterfaceDeviceServiceClass_UUID; DWORD result = BluetoothSetServiceState(hRadio, &device_info, &service, BLUETOOTH_SERVICE_ENABLE); if (result != ERROR_SUCCESS) { WINPAIR_DEBUG("Failed to enable HID service"); } } WINPAIR_DEBUG("Verifying successful connection ..."); if (is_connection_established(hRadio, &device_info)) { /* if we have a connection, stop trying to connect this device */ printf("Connection verified.\n"); break; } } } else { WINPAIR_DEBUG("Bluetooth device matching the given address is not a Move Motion Controller"); } } if (loop_count >= timeout_iterations) { printf("\n" " A connection could not be established. This is not\n" " unusual in Windows. Please refer to the README document\n" " for your platform for more information. Press Ctrl+C to cancel."); } /* sleep for 1 second */ Sleep(1000); loop_count++; } free(move_addr); return 0; }
static BluetoothPairDeviceState::eStatus AsyncBluetoothPairDeviceRequest__verifyConnection( BluetoothPairDeviceState *state) { assert(state->isWorkerThread()); BluetoothPairDeviceState::eStatus nextSubStatus= state->getSubStatus_WorkerThread<BluetoothPairDeviceState::eStatus>(); bool success= true; SERVER_MT_LOG_INFO("AsyncBluetoothPairDeviceRequest") << "Verification attempt " << state->verifyConnectionCount << " / " << CONN_CHECK_NUM_TRIES; /* NOTE: Sometimes the Bluetooth connection appears to be established * even though the Move decided that it is not really connected * yet. That is why we cannot simply stop trying to connect after * the first successful check. Instead, we require a minimum * number of successive successful checks to be sure. */ if (BluetoothGetDeviceInfo(state->hRadio, &state->deviceInfo) == ERROR_SUCCESS) { if (state->deviceInfo.fConnected) { SERVER_MT_LOG_INFO("AsyncBluetoothPairDeviceRequest") << "Device Connected"; } if (state->deviceInfo.fRemembered) { SERVER_MT_LOG_INFO("AsyncBluetoothPairDeviceRequest") << "Device Remembered"; } if (is_hid_service_enabled(state->hRadio, &state->deviceInfo)) { SERVER_MT_LOG_INFO("AsyncBluetoothPairDeviceRequest") << "HID service enabled"; } if (state->deviceInfo.fConnected && state->deviceInfo.fRemembered && is_hid_service_enabled(state->hRadio, &state->deviceInfo)) { SERVER_MT_LOG_INFO("AsyncBluetoothPairDeviceRequest") << "Connected, Remembered, and HID service enabled"; } else { SERVER_MT_LOG_INFO("AsyncBluetoothPairDeviceRequest") << "HID service not enabled"; success= false; } } else { SERVER_MT_LOG_INFO("AsyncBluetoothPairDeviceRequest") << "Failed to read device info"; success= false; } if (success) { ++state->verifyConnectionCount; if (state->verifyConnectionCount >= CONN_CHECK_NUM_TRIES) { SERVER_MT_LOG_INFO("AsyncBluetoothPairDeviceRequest") << "Verified connection!"; nextSubStatus= BluetoothPairDeviceState::success; } else { nextSubStatus= BluetoothPairDeviceState::verifyConnection; Sleep(CONN_CHECK_DELAY); } } else { // Try and re-establish the connection SERVER_MT_LOG_INFO("AsyncBluetoothPairDeviceRequest") << "Verified failed. Re-establish connection"; nextSubStatus= BluetoothPairDeviceState::attemptConnection; // Reset the connection attempt count before starting the connection attempts state->connectionAttemptCount= 0; } return nextSubStatus; }
static void handle_windows8_and_later(const BLUETOOTH_ADDRESS *move_addr, const BLUETOOTH_ADDRESS *radio_addr, const HANDLE hRadio) { unsigned int scan = 0; int connected = 0; while (!connected) { BLUETOOTH_DEVICE_INFO device_info; if (get_bluetooth_device_info(hRadio, move_addr, &device_info, scan == 0) != 0) { WINPAIR_DEBUG("No Bluetooth device found matching the given address"); } else { if (is_move_motion_controller(&device_info)) { WINPAIR_DEBUG("Found Move Motion Controller matching the given address"); unsigned int conn_try; for (conn_try = 1; conn_try <= CONN_RETRIES; conn_try++) { WINPAIR_DEBUG("Connection try %d/%d", conn_try, CONN_RETRIES); if (update_device_info(hRadio, &device_info) != 0) { break; } if (device_info.fConnected) { /* Windows 8 (and later) seems to require manual help with setting up * the device in the registry. */ WINPAIR_DEBUG("Patching the registry ..."); if (patch_registry(move_addr, radio_addr) != 0) { WINPAIR_DEBUG("Failed to patch the registry"); } /* enable HID service only if necessary */ WINPAIR_DEBUG("Checking HID service ..."); if (!is_hid_service_enabled(hRadio, &device_info)) { WINPAIR_DEBUG("Enabling HID service ..."); GUID service = HumanInterfaceDeviceServiceClass_UUID; DWORD result = BluetoothSetServiceState(hRadio, &device_info, &service, BLUETOOTH_SERVICE_ENABLE); if (result != ERROR_SUCCESS) { WINPAIR_DEBUG("Failed to enable HID service"); } WINPAIR_DEBUG("Patching the registry ..."); if (patch_registry(move_addr, radio_addr) != 0) { WINPAIR_DEBUG("Failed to patch the registry"); } } WINPAIR_DEBUG("Verifying successful connection ..."); if (is_connection_established(hRadio, &device_info)) { /* if we have a connection, stop trying to connect this device */ printf("Connection verified.\n"); connected = 1; break; } } Sleep(CONN_DELAY); } if(!device_info.fConnected) { BluetoothRemoveDevice(&(device_info.Address)); WINPAIR_DEBUG("Device removed, starting all over again"); } } else { WINPAIR_DEBUG("Bluetooth device matching the given address is not a Move Motion Controller"); } } Sleep(SLEEP_BETWEEN_SCANS); scan = (scan + 1) % BT_SCAN_NEW_INQUIRY; } }