Skip to content

Commit

Permalink
Merge pull request #34 in XP/xp-v-golden-gate from andy/be-a-better-g…
Browse files Browse the repository at this point in the history
…att-citizen to master

* commit 'bf7ed3da8d4d25314ca401696b4ae8162901aded':
  Add unit test
  Fix unit tests
  improve logging
  Send failure response for descriptors other than CCCD
  Further improvements to respond with the correct value
  Be a better GATT citizen by responding to descriptor reads
  • Loading branch information
droolingsheep committed Feb 5, 2021
2 parents 265fed8 + bf7ed3d commit 3ee24ba
Show file tree
Hide file tree
Showing 6 changed files with 300 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ private val DEFAULT_PREFERRED_CONNECTION_MODE = PreferredConnectionMode.SLOW
*/
class LinkController internal constructor(
private val gattConnection: GattConnection,
private val linkConfigurationSubscriptionObservable: Observable<GattCharacteristicSubscriptionStatus>,
private val connectionModeSubscriptionObservable: Observable<GattCharacteristicSubscriptionStatus>,
private val connectionConfigurationSubscriptionObservable: Observable<GattCharacteristicSubscriptionStatus>,
private val generalPurposeSubscriptionObservable: Observable<GattCharacteristicSubscriptionStatus>,
private val linkConfigurationCharacteristicNotifier: GattCharacteristicNotifier = GattCharacteristicNotifier(
gattConnection.device.btDevice
),
Expand Down Expand Up @@ -142,7 +144,7 @@ class LinkController internal constructor(
fun setPreferredConnectionConfiguration(preferredConnectionConfiguration: PreferredConnectionConfiguration): Completable {
//notify server characteristics
this.preferredConnectionConfiguration = preferredConnectionConfiguration
return linkConfigurationSubscriptionObservable.take(1).flatMapCompletable {
return connectionConfigurationSubscriptionObservable.take(1).flatMapCompletable {
if (it == GattCharacteristicSubscriptionStatus.ENABLED) {
linkConfigurationCharacteristicNotifier.notify(
LinkConfigurationService.uuid,
Expand All @@ -165,7 +167,7 @@ class LinkController internal constructor(
fun setPreferredConnectionMode(connectionMode: PreferredConnectionMode): Completable {
Timber.d("Setting preferred connection mode to $connectionMode")
this.preferredConnectionMode = connectionMode
return linkConfigurationSubscriptionObservable.take(1).flatMapCompletable {
return connectionModeSubscriptionObservable.take(1).flatMapCompletable {
if (it == GattCharacteristicSubscriptionStatus.ENABLED) {
linkConfigurationCharacteristicNotifier.notify(
LinkConfigurationService.uuid,
Expand Down Expand Up @@ -200,15 +202,15 @@ class LinkController internal constructor(
fun setGeneralPurposeCommand(commandCode: GeneralPurposeCommandCode): Completable {
Timber.w("Set General Purpose Command: $commandCode")
this.generalPurposeCommand = commandCode
return linkConfigurationSubscriptionObservable.take(1).flatMapCompletable {
if (this.generalPurposeCommand == GeneralPurposeCommandCode.DISCONNECT) {
return generalPurposeSubscriptionObservable.take(1).flatMapCompletable {
if (this.generalPurposeCommand == GeneralPurposeCommandCode.DISCONNECT && it == GattCharacteristicSubscriptionStatus.ENABLED) {
linkConfigurationCharacteristicNotifier.notify(
LinkConfigurationService.uuid,
GeneralPurposeCommandCharacteristic.uuid,
commandCode.toByteArray()
)
} else {
Completable.error(IllegalStateException("Device not subscribed to the Link Configuration Service"))
Completable.error(IllegalStateException("Device not subscribed to the General Purpose Command characteristic or invalid command given"))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import com.fitbit.bluetooth.fbgatt.FitbitBluetoothDevice
import com.fitbit.bluetooth.fbgatt.FitbitGatt
import com.fitbit.bluetooth.fbgatt.GattConnection
import com.fitbit.bluetooth.fbgatt.rx.server.BitGattServer
import com.fitbit.linkcontroller.services.configuration.ClientPreferredConnectionConfigurationCharacteristic
import com.fitbit.linkcontroller.services.configuration.ClientPreferredConnectionModeCharacteristic
import com.fitbit.linkcontroller.services.configuration.GeneralPurposeCommandCharacteristic
import com.fitbit.linkcontroller.services.configuration.LinkConfigurationService
import com.fitbit.linkcontroller.services.configuration.LinkConfigurationServiceEventListener
import io.reactivex.Completable
Expand All @@ -18,7 +21,7 @@ import io.reactivex.Completable
* These are used to configure connection parameters between the mobile app and the peripheral device
*/

class LinkControllerProvider private constructor (
class LinkControllerProvider private constructor(
private val fitbitGatt: FitbitGatt = FitbitGatt.getInstance(),
private val gattServer: BitGattServer = BitGattServer(),
private val linkConfigurationService: LinkConfigurationService = LinkConfigurationService(),
Expand Down Expand Up @@ -56,12 +59,7 @@ class LinkControllerProvider private constructor (
private fun add(bluetoothDevice: BluetoothDevice): LinkController? {
val gattConnection = fitbitGatt.getConnection(bluetoothDevice)
return gattConnection?.let {
val linkController = LinkController(
it,
linkConfigurationServiceEventListener.getDataObservable(bluetoothDevice)
)
linkControllersMap[bluetoothDevice] = linkController
linkController
add(it)
}
}

Expand All @@ -70,7 +68,18 @@ class LinkControllerProvider private constructor (
val bluetoothDevice = gattConnection.device.btDevice
val linkController = LinkController(
gattConnection,
linkConfigurationServiceEventListener.getDataObservable(bluetoothDevice)
linkConfigurationServiceEventListener.getDataObservable(
bluetoothDevice,
ClientPreferredConnectionModeCharacteristic.uuid
),
linkConfigurationServiceEventListener.getDataObservable(
bluetoothDevice,
ClientPreferredConnectionConfigurationCharacteristic.uuid
),
linkConfigurationServiceEventListener.getDataObservable(
bluetoothDevice,
GeneralPurposeCommandCharacteristic.uuid
)
)
linkControllersMap[bluetoothDevice] = linkController
return linkController
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.BluetoothGattDescriptor
import android.bluetooth.BluetoothGattService
import com.fitbit.bluetooth.fbgatt.rx.CLIENT_CONFIG_UUID
import java.util.*
import java.util.UUID

/**
* Represents a Bluetooth GATT Link Configuration Service hosted on mobile that allows setting up
Expand All @@ -16,7 +16,7 @@ import java.util.*
*/
class LinkConfigurationService : BluetoothGattService(
uuid,
BluetoothGattService.SERVICE_TYPE_PRIMARY
SERVICE_TYPE_PRIMARY
) {

companion object {
Expand All @@ -36,8 +36,8 @@ class LinkConfigurationService : BluetoothGattService(
*/
class ClientPreferredConnectionConfigurationCharacteristic : BluetoothGattCharacteristic(
uuid,
BluetoothGattCharacteristic.PROPERTY_READ or BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_READ
PROPERTY_READ or PROPERTY_NOTIFY,
PERMISSION_READ
) {
init {
val descriptor = BluetoothGattDescriptor(
Expand All @@ -57,8 +57,8 @@ class ClientPreferredConnectionConfigurationCharacteristic : BluetoothGattCharac
*/
class ClientPreferredConnectionModeCharacteristic : BluetoothGattCharacteristic(
uuid,
BluetoothGattCharacteristic.PROPERTY_READ or BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_READ
PROPERTY_READ or PROPERTY_NOTIFY,
PERMISSION_READ
) {
init {
val descriptor = BluetoothGattDescriptor(
Expand All @@ -78,8 +78,8 @@ class ClientPreferredConnectionModeCharacteristic : BluetoothGattCharacteristic(
*/
class GeneralPurposeCommandCharacteristic : BluetoothGattCharacteristic(
uuid,
BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_READ
PROPERTY_NOTIFY,
PERMISSION_READ
) {
init {
val descriptor = BluetoothGattDescriptor(
Expand Down
Loading

0 comments on commit 3ee24ba

Please sign in to comment.