Esempio n. 1
0
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;
}
Esempio n. 3
0
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);
    }
}
Esempio n. 4
0
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;
}
Esempio n. 6
0
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;
    }
}