Loading android/pandora/server/src/com/android/pandora/Host.kt +1 −1 Original line number Diff line number Diff line Loading @@ -277,7 +277,7 @@ class Host(private val context: Context, private val server: Server) : HostImplB responseObserver: StreamObserver<ConnectLEResponse> ) { grpcUnary<ConnectLEResponse>(scope, responseObserver) { val ptsAddress = request.address.decodeToString() val ptsAddress = request.address.decodeAsMacAddressToString() Log.i(TAG, "connect LE: $ptsAddress") val device = scanLeDevice(ptsAddress) GattInstance(device!!, TRANSPORT_LE, context).waitForState(BluetoothProfile.STATE_CONNECTED) Loading android/pandora/server/src/com/android/pandora/Security.kt +23 −12 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.pandora import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothDevice.DEVICE_TYPE_CLASSIC import android.bluetooth.BluetoothDevice.DEVICE_TYPE_LE import android.bluetooth.BluetoothDevice.EXTRA_PAIRING_VARIANT import android.bluetooth.BluetoothManager import android.content.Context Loading Loading @@ -105,26 +107,31 @@ class Security(private val context: Context) : SecurityImplBase() { responseObserver: StreamObserver<PairingEvent> ): StreamObserver<PairingEventAnswer> = grpcBidirectionalStream(globalScope, responseObserver) { Log.i(TAG, "OnPairing: Starting stream") it .map { answer -> Log.i( TAG, "OnPairing: Handling PairingEventAnswer ${answer.answerCase} for device ${answer.event.address}" ) val device = answer.event.address.toBluetoothDevice(bluetoothAdapter) when (answer.answerCase!!) { PairingEventAnswer.AnswerCase.CONFIRM -> device.setPairingConfirmation(true) PairingEventAnswer.AnswerCase.PASSKEY -> error("We don't support SSP PASSKEY_ENTRY, since we always have a Display") device.setPin(answer.passkey.toString().toByteArray()) PairingEventAnswer.AnswerCase.PIN -> device.setPin(answer.pin.toByteArray()) PairingEventAnswer.AnswerCase.ANSWER_NOT_SET -> error("unexpected pairing answer type") } } .launchIn(this) // TODO(243977710) - Resolve the transport on which pairing is taking place // so we can disambiguate intents val transport = BluetoothDevice.TRANSPORT_AUTO flow.map { intent -> val device = intent.getBluetoothDeviceExtra() val variant = intent.getIntExtra(EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR) Log.i( TAG, "OnPairing: Handling PairingEvent ${variant} for device ${device.address}" ) val eventBuilder = PairingEvent.newBuilder().setAddress(ByteString.copyFrom(device.toByteArray())) when (variant) { Loading @@ -136,6 +143,11 @@ class Security(private val context: Context) : SecurityImplBase() { BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION -> eventBuilder.numericComparison = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR) BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY -> { val passkey = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR) eventBuilder.passkeyEntryNotification = passkey } // Out-Of-Band not currently supported BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT -> Loading @@ -143,10 +155,9 @@ class Security(private val context: Context) : SecurityImplBase() { // Legacy PIN entry, or LE legacy passkey entry, depending on transport BluetoothDevice.PAIRING_VARIANT_PIN -> when (transport) { BluetoothDevice.TRANSPORT_BREDR -> eventBuilder.pinCodeRequest = Empty.getDefaultInstance() BluetoothDevice.TRANSPORT_LE -> when (device.type) { DEVICE_TYPE_CLASSIC -> eventBuilder.pinCodeRequest = Empty.getDefaultInstance() DEVICE_TYPE_LE -> eventBuilder.passkeyEntryRequest = Empty.getDefaultInstance() else -> error("cannot determine pairing variant, since transport is unknown") } Loading @@ -158,11 +169,11 @@ class Security(private val context: Context) : SecurityImplBase() { BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN -> { val passkey = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR) when (transport) { BluetoothDevice.TRANSPORT_BREDR -> when (device.type) { DEVICE_TYPE_CLASSIC -> eventBuilder.pinCodeNotification = ByteString.copyFrom(passkey.toString().toByteArray()) BluetoothDevice.TRANSPORT_LE -> eventBuilder.passkeyEntryNotification = passkey DEVICE_TYPE_LE -> eventBuilder.passkeyEntryNotification = passkey else -> error("cannot determine pairing variant, since transport is unknown") } } Loading android/pandora/server/src/com/android/pandora/Utils.kt +3 −5 Original line number Diff line number Diff line Loading @@ -221,15 +221,13 @@ fun <T> getProfileProxy(context: Context, profile: Int): T { fun Intent.getBluetoothDeviceExtra(): BluetoothDevice = this.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, BluetoothDevice::class.java) fun ByteString.decodeToString(): String = fun ByteString.decodeAsMacAddressToString(): String = MacAddress.fromBytes(this.toByteArray()).toString().uppercase() fun ByteString.toBluetoothDevice(adapter: BluetoothAdapter): BluetoothDevice = adapter.getRemoteDevice(this.decodeToString()) adapter.getRemoteDevice(this.decodeAsMacAddressToString()) fun Connection.toBluetoothDevice(adapter: BluetoothAdapter): BluetoothDevice = adapter.getRemoteDevice(this.cookie.toByteArray().decodeToString()) fun String.toByteArray(): ByteArray = MacAddress.fromString(this).toByteArray() fun BluetoothDevice.toByteArray(): ByteArray = this.address.toByteArray() fun BluetoothDevice.toByteArray(): ByteArray = MacAddress.fromString(this.address).toByteArray() Loading
android/pandora/server/src/com/android/pandora/Host.kt +1 −1 Original line number Diff line number Diff line Loading @@ -277,7 +277,7 @@ class Host(private val context: Context, private val server: Server) : HostImplB responseObserver: StreamObserver<ConnectLEResponse> ) { grpcUnary<ConnectLEResponse>(scope, responseObserver) { val ptsAddress = request.address.decodeToString() val ptsAddress = request.address.decodeAsMacAddressToString() Log.i(TAG, "connect LE: $ptsAddress") val device = scanLeDevice(ptsAddress) GattInstance(device!!, TRANSPORT_LE, context).waitForState(BluetoothProfile.STATE_CONNECTED) Loading
android/pandora/server/src/com/android/pandora/Security.kt +23 −12 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.pandora import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothDevice.DEVICE_TYPE_CLASSIC import android.bluetooth.BluetoothDevice.DEVICE_TYPE_LE import android.bluetooth.BluetoothDevice.EXTRA_PAIRING_VARIANT import android.bluetooth.BluetoothManager import android.content.Context Loading Loading @@ -105,26 +107,31 @@ class Security(private val context: Context) : SecurityImplBase() { responseObserver: StreamObserver<PairingEvent> ): StreamObserver<PairingEventAnswer> = grpcBidirectionalStream(globalScope, responseObserver) { Log.i(TAG, "OnPairing: Starting stream") it .map { answer -> Log.i( TAG, "OnPairing: Handling PairingEventAnswer ${answer.answerCase} for device ${answer.event.address}" ) val device = answer.event.address.toBluetoothDevice(bluetoothAdapter) when (answer.answerCase!!) { PairingEventAnswer.AnswerCase.CONFIRM -> device.setPairingConfirmation(true) PairingEventAnswer.AnswerCase.PASSKEY -> error("We don't support SSP PASSKEY_ENTRY, since we always have a Display") device.setPin(answer.passkey.toString().toByteArray()) PairingEventAnswer.AnswerCase.PIN -> device.setPin(answer.pin.toByteArray()) PairingEventAnswer.AnswerCase.ANSWER_NOT_SET -> error("unexpected pairing answer type") } } .launchIn(this) // TODO(243977710) - Resolve the transport on which pairing is taking place // so we can disambiguate intents val transport = BluetoothDevice.TRANSPORT_AUTO flow.map { intent -> val device = intent.getBluetoothDeviceExtra() val variant = intent.getIntExtra(EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR) Log.i( TAG, "OnPairing: Handling PairingEvent ${variant} for device ${device.address}" ) val eventBuilder = PairingEvent.newBuilder().setAddress(ByteString.copyFrom(device.toByteArray())) when (variant) { Loading @@ -136,6 +143,11 @@ class Security(private val context: Context) : SecurityImplBase() { BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION -> eventBuilder.numericComparison = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR) BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY -> { val passkey = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR) eventBuilder.passkeyEntryNotification = passkey } // Out-Of-Band not currently supported BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT -> Loading @@ -143,10 +155,9 @@ class Security(private val context: Context) : SecurityImplBase() { // Legacy PIN entry, or LE legacy passkey entry, depending on transport BluetoothDevice.PAIRING_VARIANT_PIN -> when (transport) { BluetoothDevice.TRANSPORT_BREDR -> eventBuilder.pinCodeRequest = Empty.getDefaultInstance() BluetoothDevice.TRANSPORT_LE -> when (device.type) { DEVICE_TYPE_CLASSIC -> eventBuilder.pinCodeRequest = Empty.getDefaultInstance() DEVICE_TYPE_LE -> eventBuilder.passkeyEntryRequest = Empty.getDefaultInstance() else -> error("cannot determine pairing variant, since transport is unknown") } Loading @@ -158,11 +169,11 @@ class Security(private val context: Context) : SecurityImplBase() { BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN -> { val passkey = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR) when (transport) { BluetoothDevice.TRANSPORT_BREDR -> when (device.type) { DEVICE_TYPE_CLASSIC -> eventBuilder.pinCodeNotification = ByteString.copyFrom(passkey.toString().toByteArray()) BluetoothDevice.TRANSPORT_LE -> eventBuilder.passkeyEntryNotification = passkey DEVICE_TYPE_LE -> eventBuilder.passkeyEntryNotification = passkey else -> error("cannot determine pairing variant, since transport is unknown") } } Loading
android/pandora/server/src/com/android/pandora/Utils.kt +3 −5 Original line number Diff line number Diff line Loading @@ -221,15 +221,13 @@ fun <T> getProfileProxy(context: Context, profile: Int): T { fun Intent.getBluetoothDeviceExtra(): BluetoothDevice = this.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, BluetoothDevice::class.java) fun ByteString.decodeToString(): String = fun ByteString.decodeAsMacAddressToString(): String = MacAddress.fromBytes(this.toByteArray()).toString().uppercase() fun ByteString.toBluetoothDevice(adapter: BluetoothAdapter): BluetoothDevice = adapter.getRemoteDevice(this.decodeToString()) adapter.getRemoteDevice(this.decodeAsMacAddressToString()) fun Connection.toBluetoothDevice(adapter: BluetoothAdapter): BluetoothDevice = adapter.getRemoteDevice(this.cookie.toByteArray().decodeToString()) fun String.toByteArray(): ByteArray = MacAddress.fromString(this).toByteArray() fun BluetoothDevice.toByteArray(): ByteArray = this.address.toByteArray() fun BluetoothDevice.toByteArray(): ByteArray = MacAddress.fromString(this.address).toByteArray()