Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-44792

QBluetoothSocket tries to connect to RFCOMM channel -1

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • 5.4.2
    • 5.3.2
    • None
    • Android

    Description

      There is a flaw in the solution of QTBUG-40172: in Android versions below 4.2, the getServiceChannel call doesn't always return BluetoothDevice.ERROR in case of an error. It can also return -1. QBluetoothSocket only checks for BluetoothDevice.ERROR, so the result is that QBluetoothSocket tries to use channel -1 to connect, but this is an invalid channel.

      More background info:
      Up to Android 4.1 the getServiceChannel function calls a lower level function on the BluetoothService and return ERROR in case an exception is thrown.

      /** @hide */
      public int getServiceChannel(ParcelUuid uuid) {
           try {
               return sService.getRemoteServiceChannel(mAddress, uuid);
           } catch (RemoteException e) {Log.e(TAG, "", e);}
           return BluetoothDevice.ERROR;
      }
      

      That lower level function however does not seem to throw any exception itself, but does return -1 in case of an error.

      public int getRemoteServiceChannel(String address, ParcelUuid uuid) {
          mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
          if (!isEnabledInternal()) return -1;
          if (!BluetoothAdapter.checkBluetoothAddress(address)) {
              return BluetoothDevice.ERROR;
          }
          // Check if we are recovering from a crash.
          if (mDeviceProperties.isEmpty()) {
              if (mDeviceProperties.updateCache(address) == null)
                  return -1;
          }
          Map<ParcelUuid, Integer> value = mDeviceServiceChannelCache.get(address);
          if (value != null && value.containsKey(uuid))
              return value.get(uuid);
          return -1;
      }
      

      Starting from Android 4.2, this function always returns ERROR.

      /** @hide */
      public int getServiceChannel(ParcelUuid uuid) {
          //TODO(BT)
          /*
           try {
               return sService.getRemoteServiceChannel(this, uuid);
           } catch (RemoteException e) {Log.e(TAG, "", e);}*/
           return BluetoothDevice.ERROR;
      }
      

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            ablasche Alex Blasche
            mbuijs Martijn Buijs
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes