Navideck / universal_ble

A cross-platform Android/iOS/macOS/Windows/Linux/Web Bluetooth Low Energy (BLE) plugin for Flutter
https://pub.dev/packages/universal_ble
Other
19 stars 2 forks source link

Fix characteristic keying on linux #35

Closed mortenboye closed 1 month ago

mortenboye commented 1 month ago

User description

As described in https://github.com/Navideck/universal_ble/issues/33, the Linux implementation did not allow for multiple simultaneous subscriptions to the same characteristic on different devices.

This PR fixes this by adding deviceId and serviceUUID to the key, identifying the characteristic.


Type

bug_fix


Description


Changes walkthrough

Relevant files
Enhancement
universal_ble_linux.dart
Enhance Characteristic Subscription Keying on Linux           

lib/src/universal_ble_linux/universal_ble_linux.dart
  • Introduced a new key format combining deviceId, service, and
    characteristic to uniquely identify characteristic subscriptions.
  • Replaced characteristic string with the new key format in
    _characteristicPropertiesSubscriptions for adding, checking, and
    removing subscriptions.
  • Simplified logging for unhandled characteristic value property
    changes.
  • +8/-9     

    PR-Agent usage: Comment /help on the PR to get a list of all available PR-Agent tools and their descriptions

    codiumai-pr-agent[bot] commented 1 month ago

    PR Description updated to latest commit (https://github.com/Navideck/universal_ble/commit/ed6809c6de8b622fb1332301d8f4b1a1cddf0775)

    codiumai-pr-agent[bot] commented 1 month ago

    PR Review

    ⏱️ Estimated effort to review [1-5] 2, because the changes are focused on a specific functionality (characteristic subscription keying) and involve a moderate amount of code. The logic is straightforward and mainly revolves around the generation and use of a new key format for characteristic subscriptions. The changes are localized and do not seem to affect other parts of the system, making the review process less complex.
    🧪 Relevant tests No
    🔍 Possible issues Possible Bug: The PR assumes that the combination of `deviceId`, `service`, and `characteristic` will always uniquely identify a subscription. While this is likely true, it's important to ensure that there are no edge cases where this assumption might fail, especially in environments with many devices and services.
    Error Handling: The PR throws generic exceptions for cases where a characteristic is already notifying or not notifying. It might be beneficial to provide more specific error messages or custom exception types to help with debugging and error handling in client code.
    🔒 Security concerns No

    ✨ Review tool usage guide:
    **Overview:** The `review` tool scans the PR code changes, and generates a PR review which includes several types of feedbacks, such as possible PR issues, security threats and relevant test in the PR. More feedbacks can be [added](https://pr-agent-docs.codium.ai/tools/review/#general-configurations) by configuring the tool. The tool can be triggered [automatically](https://pr-agent-docs.codium.ai/usage-guide/automations_and_usage/#github-app-automatic-tools-when-a-new-pr-is-opened) every time a new PR is opened, or can be invoked manually by commenting on any PR. - When commenting, to edit [configurations](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L23) related to the review tool (`pr_reviewer` section), use the following template: ``` /review --pr_reviewer.some_config1=... --pr_reviewer.some_config2=... ``` - With a [configuration file](https://pr-agent-docs.codium.ai/usage-guide/configuration_options/), use the following template: ``` [pr_reviewer] some_config1=... some_config2=... ``` See the review [usage page](https://pr-agent-docs.codium.ai/tools/review/) for a comprehensive guide on using this tool.
    codiumai-pr-agent[bot] commented 1 month ago

    PR Code Suggestions

    CategorySuggestions                                                                                                                                                       
    Enhancement
    Improve key generation for map access to enhance readability and avoid potential collisions. ___ **Consider using a more structured approach to generate the key for
    _characteristicPropertiesSubscriptions to ensure uniqueness and readability. For instance,
    you could use a tuple or a custom object as the key if the map supports it, or
    alternatively, create a method that generates a standardized key format. This approach can
    help avoid potential key collisions and improve code maintainability.** [lib/src/universal_ble_linux/universal_ble_linux.dart [151]](https://github.com/Navideck/universal_ble/pull/35/files#diff-bd61ea0530e3e409336cd7d8a6d93c00911618355a9bf99fd1cf3d92cb6a02d9R151-R151) ```diff -var key = "$deviceId-$service-$characteristic"; +var key = generateKey(deviceId, service, characteristic); +// Elsewhere in your code +String generateKey(String deviceId, String service, String characteristic) { + return "$deviceId-$service-$characteristic"; +} ```
    Enhance log messages with more context for better debugging. ___ **For logging unhandled characteristic value property changes, consider adding more context
    to the log message, such as the device ID, service, and characteristic. This can help in
    debugging by providing more information about where the unhandled property change
    occurred.** [lib/src/universal_ble_linux/universal_ble_linux.dart [174]](https://github.com/Navideck/universal_ble/pull/35/files#diff-bd61ea0530e3e409336cd7d8a6d93c00911618355a9bf99fd1cf3d92cb6a02d9R174-R174) ```diff -UniversalBlePlatform.logInfo("UnhandledCharValuePropertyChange: $property"); +UniversalBlePlatform.logInfo("UnhandledCharValuePropertyChange: $property for device $deviceId, service $service, characteristic $characteristic"); ```
    Possible issue
    Add null check for char to prevent null pointer exceptions. ___ **It's a good practice to check if the char variable is null after retrieving it with
    _getCharacteristic method and before proceeding with operations on it. This can prevent
    potential null pointer exceptions if _getCharacteristic fails to find the characteristic.** [lib/src/universal_ble_linux/universal_ble_linux.dart [153]](https://github.com/Navideck/universal_ble/pull/35/files#diff-bd61ea0530e3e409336cd7d8a6d93c00911618355a9bf99fd1cf3d92cb6a02d9R153-R153) ```diff var char = _getCharacteristic(deviceId, service, characteristic); +if (char == null) throw Exception('Characteristic not found'); ```
    Best practice
    Use specific exception types for better error context and handling. ___ **Instead of throwing a generic Exception when a characteristic is already notifying or not
    notifying, consider using a more specific exception type or creating a custom exception
    class. This can provide more context to the exception and make error handling more
    precise.** [lib/src/universal_ble_linux/universal_ble_linux.dart [155-179]](https://github.com/Navideck/universal_ble/pull/35/files#diff-bd61ea0530e3e409336cd7d8a6d93c00911618355a9bf99fd1cf3d92cb6a02d9R155-R179) ```diff -if (char.notifying) throw Exception('Characteristic already notifying'); +if (char.notifying) throw CharacteristicAlreadyNotifyingException(); ... -if (!char.notifying) throw Exception('Characteristic not notifying'); +if (!char.notifying) throw CharacteristicNotNotifyingException(); +// Define these exceptions somewhere in your code +class CharacteristicAlreadyNotifyingException implements Exception { + @override + String toString() => 'Characteristic is already notifying'; +} +class CharacteristicNotNotifyingException implements Exception { + @override + String toString() => 'Characteristic is not notifying'; +} ```
    Ensure proper cleanup of cancelled subscriptions to avoid memory leaks. ___ **When cancelling subscriptions, it's a good practice to also set the corresponding map
    entry to null or remove it entirely after cancellation. This helps in avoiding memory
    leaks and ensures that the map does not hold onto cancelled subscriptions, which are no
    longer needed.** [lib/src/universal_ble_linux/universal_ble_linux.dart [160-181]](https://github.com/Navideck/universal_ble/pull/35/files#diff-bd61ea0530e3e409336cd7d8a6d93c00911618355a9bf99fd1cf3d92cb6a02d9R160-R181) ```diff -_characteristicPropertiesSubscriptions[key]?.cancel(); +await _characteristicPropertiesSubscriptions[key]?.cancel(); +_characteristicPropertiesSubscriptions.remove(key); ```

    ✨ Improve tool usage guide:
    **Overview:** The `improve` tool scans the PR code changes, and automatically generates suggestions for improving the PR code. The tool can be triggered [automatically](https://pr-agent-docs.codium.ai/usage-guide/automations_and_usage/#github-app-automatic-tools-when-a-new-pr-is-opened) every time a new PR is opened, or can be invoked manually by commenting on a PR. - When commenting, to edit [configurations](https://github.com/Codium-ai/pr-agent/blob/main/pr_agent/settings/configuration.toml#L78) related to the improve tool (`pr_code_suggestions` section), use the following template: ``` /improve --pr_code_suggestions.some_config1=... --pr_code_suggestions.some_config2=... ``` - With a [configuration file](https://pr-agent-docs.codium.ai/usage-guide/configuration_options/), use the following template: ``` [pr_code_suggestions] some_config1=... some_config2=... ``` See the improve [usage page](https://pr-agent-docs.codium.ai/tools/improve/) for a comprehensive guide on using this tool.