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

Add manufacturer data filtering #23

Closed rohitsangwan01 closed 1 month ago

rohitsangwan01 commented 2 months ago

Type

enhancement


Description


Changes walkthrough

Relevant files
Enhancement
9 files
universal_ble.g.cpp
Implement Manufacturer Data Filtering in Windows Plugin   

windows/src/generated/universal_ble.g.cpp
  • Added UniversalManufacturerDataFilter class implementation.
  • Enhanced UniversalScanFilter to include manufacturer data filtering.
  • Updated serialization methods to handle manufacturer data filtering.
  • +103/-5 
    universal_ble_plugin.cpp
    Apply Manufacturer Data Filter in Scan Process                     

    windows/src/universal_ble_plugin.cpp
  • Implemented manufacturer data filtering logic in the scan process.
  • Modified StartScan to setup device watcher and apply manufacturer data
    filter.
  • +104/-21
    home.dart
    Integrate Manufacturer Data Filtering in Example App         

    example/lib/home/home.dart
  • Removed WebRequestOptionsBuilder usage.
  • Added manufacturer data filtering in the startScan method.
  • +24/-12 
    scan_filter.dart
    Add Manufacturer Data Filtering Model                                       

    lib/src/models/scan_filter.dart
  • Added ManufacturerDataFilter class for manufacturer data filtering.
  • Enhanced ScanFilter to include manufacturer data filtering.
  • +22/-0   
    universal_ble.dart
    Update `startScan` to Support Manufacturer Data Filtering

    lib/src/universal_ble.dart
  • Removed WebRequestOptionsBuilder parameter from startScan.
  • Updated startScan to support manufacturer data filtering.
  • +1/-5     
    universal_ble_platform_interface.dart
    Interface Update for Manufacturer Data Filtering                 

    lib/src/universal_ble_platform_interface.dart - Removed `WebRequestOptionsBuilder` parameter from `startScan`.
    +0/-1     
    universal_ble_web.dart
    Web Support for Manufacturer Data Filtering                           

    lib/src/universal_ble_web/universal_ble_web.dart
  • Updated startScan to support manufacturer data filtering on the web.
  • +32/-14 
    universal_ble_linux.dart
    Placeholder for Manufacturer Data Filtering in Linux         

    lib/src/universal_ble_linux/universal_ble_linux.dart
  • Placeholder for manufacturer data filtering in Linux (marked as TODO).

  • +104/-1 
    universal_ble.dart
    Pigeon Schema for Manufacturer Data Filtering                       

    pigeon/universal_ble.dart
  • Added UniversalManufacturerDataFilter class for Pigeon.
  • Enhanced UniversalScanFilter to include manufacturer data filtering.
  • +17/-1   

    โœจ 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 2 months ago

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

    codiumai-pr-agent[bot] commented 2 months ago

    PR Review

    (Review updated until commit https://github.com/Navideck/universal_ble/commit/206e677aacff1eb48130e37654ca1d28c0836edc)

    โฑ๏ธ Estimated effort to review [1-5] 4, because the PR introduces significant changes across multiple platforms (Windows, Android, iOS, and Dart), including new functionality for manufacturer data filtering in BLE scans. The changes affect core components and require thorough testing across all supported platforms to ensure compatibility and correctness. Additionally, the integration of manufacturer data filtering involves complex data structures and platform-specific APIs, increasing the complexity of the review.
    ๐Ÿงช Relevant tests No
    ๐Ÿ” Possible issues Possible Bug: The implementation of manufacturer data filtering on different platforms (Windows, Android, iOS) requires careful attention to the format and byte order of manufacturer data. Any discrepancies in handling this data across platforms could lead to inconsistent filtering behavior.
    Performance Concern: The addition of manufacturer data filtering in the BLE scan process could potentially impact the performance of the scan, especially if the filters are complex or if there are a large number of devices being scanned. Performance testing should be conducted to ensure that the impact is minimal.
    Compatibility Issue: Changes to the platform-specific code (especially in the Windows and Android implementations) need to be tested on a wide range of devices and OS versions to ensure that there are no compatibility issues.
    ๐Ÿ”’ Security concerns No

    โœจ Review tool usage guide:
    **Overview:** The `review` tool scans the PR code changes, and generates a PR review. 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#L19) 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=... ```
    Utilizing extra instructions
    The `review` tool can be configured with extra instructions, which can be used to guide the model to a feedback tailored to the needs of your project. Be specific, clear, and concise in the instructions. With extra instructions, you are the prompter. Specify the relevant sub-tool, and the relevant aspects of the PR that you want to emphasize. Examples for extra instructions: ``` [pr_reviewer] # /review # extra_instructions=""" In the 'possible issues' section, emphasize the following: - Does the code logic cover relevant edge cases? - Is the code logic clear and easy to understand? - Is the code logic efficient? ... """ ``` Use triple quotes to write multi-line instructions. Use bullet points to make the instructions more readable.
    How to enable\disable automation
    - When you first install PR-Agent app, the [default mode](https://pr-agent-docs.codium.ai/usage-guide/automations_and_usage/#github-app-automatic-tools-when-a-new-pr-is-opened) for the `review` tool is: ``` pr_commands = ["/review", ...] ``` meaning the `review` tool will run automatically on every PR, with the default configuration. Edit this field to enable/disable the tool, or to change the used configurations
    Auto-labels
    The `review` tool can auto-generate two specific types of labels for a PR: - a `possible security issue` label, that detects possible [security issues](https://github.com/Codium-ai/pr-agent/blob/tr/user_description/pr_agent/settings/pr_reviewer_prompts.toml#L136) (`enable_review_labels_security` flag) - a `Review effort [1-5]: x` label, where x is the estimated effort to review the PR (`enable_review_labels_effort` flag)
    Extra sub-tools
    The `review` tool provides a collection of possible feedbacks about a PR. It is recommended to review the [possible options](https://pr-agent-docs.codium.ai/tools/review/#enabledisable-features), and choose the ones relevant for your use case. Some of the feature that are disabled by default are quite useful, and should be considered for enabling. For example: `require_score_review`, `require_soc2_ticket`, `require_can_be_split_review`, and more.
    Auto-approve PRs
    By invoking: ``` /review auto_approve ``` The tool will automatically approve the PR, and add a comment with the approval. To ensure safety, the auto-approval feature is disabled by default. To enable auto-approval, you need to actively set in a pre-defined configuration file the following: ``` [pr_reviewer] enable_auto_approval = true ``` (this specific flag cannot be set with a command line argument, only in the configuration file, committed to the repository) You can also enable auto-approval only if the PR meets certain requirements, such as that the `estimated_review_effort` is equal or below a certain threshold, by adjusting the flag: ``` [pr_reviewer] maximal_review_effort = 5 ```
    More PR-Agent commands
    > To invoke the PR-Agent, add a comment using one of the following commands: > - **/review**: Request a review of your Pull Request. > - **/describe**: Update the PR title and description based on the contents of the PR. > - **/improve [--extended]**: Suggest code improvements. Extended mode provides a higher quality feedback. > - **/ask \**: Ask a question about the PR. > - **/update_changelog**: Update the changelog based on the PR's contents. > - **/add_docs** ๐Ÿ’Ž: Generate docstring for new components introduced in the PR. > - **/generate_labels** ๐Ÿ’Ž: Generate labels for the PR based on the PR's contents. > - **/analyze** ๐Ÿ’Ž: Automatically analyzes the PR, and presents changes walkthrough for each component. >See the [tools guide](https://pr-agent-docs.codium.ai/tools/) for more details. >To list the possible configuration parameters, add a **/config** comment.
    See the [review usage](https://pr-agent-docs.codium.ai/tools/review/) page for a comprehensive guide on using this tool.
    codiumai-pr-agent[bot] commented 2 months ago

    PR Code Suggestions

    CategorySuggestions                                                                                                                                                       
    Best practice
    Use std::make_optional for clarity when initializing optional members. ___ **When using std::optional for pointers like company_identifier, data, and mask in
    UniversalManufacturerDataFilter constructor, it's more idiomatic to use std::make_optional
    instead of ternary operator for clarity and consistency.** [windows/src/generated/universal_ble.g.cpp [323-325]](https://github.com/Navideck/universal_ble/pull/23/files#diff-92e69b3dc0c97a5367d2a46ee4a042924534973f5adbc808f2ba303168895f45R323-R325) ```diff -: company_identifier_(company_identifier ? std::optional(*company_identifier) : std::nullopt), - data_(data ? std::optional>(*data) : std::nullopt), - mask_(mask ? std::optional>(*mask) : std::nullopt) {} +: company_identifier_(company_identifier ? std::make_optional(*company_identifier) : std::nullopt), + data_(data ? std::make_optional>(*data) : std::nullopt), + mask_(mask ? std::make_optional>(*mask) : std::nullopt) {} ```
    Add validation to ensure data and mask lengths match in ManufacturerDataFilter. ___ **For the ManufacturerDataFilter class, consider validating the lengths of data and mask in
    the constructor to ensure they are of the same length, as this is a requirement for the
    filter to work correctly.** [lib/src/models/scan_filter.dart [24-28]](https://github.com/Navideck/universal_ble/pull/23/files#diff-3855acfe8c6c77715a45e6abbf2757d06d7bb8eb65c325745f7f40d8765d79a7R24-R28) ```diff ManufacturerDataFilter({ this.companyIdentifier, - this.data, - this.mask, -}); + Uint8List? data, + Uint8List? mask, +}) : assert(data == null || mask == null || data.length == mask.length, 'Data and mask must be of the same length'), + data = data, + mask = mask; ```
    Use val for immutable references. ___ **Instead of using var for scanFilters, use val since the reference to the list does not
    change, only its contents do.** [android/src/main/kotlin/com/navideck/universal_ble/UniversalBleHelper.kt [147]](https://github.com/Navideck/universal_ble/pull/23/files#diff-07528325c9af8065d3fe07cc2436350a5db4dde75378b96e4801cdc7675b128aR147-R147) ```diff -var scanFilters: ArrayList = arrayListOf() +val scanFilters: ArrayList = arrayListOf() ```
    Performance
    Pass EncodableList by const reference to avoid unnecessary copying. ___ **To improve performance and avoid unnecessary copying, consider passing EncodableList by
    const reference in the constructor of UniversalScanFilter and other similar constructors.** [windows/src/generated/universal_ble.g.cpp [276-280]](https://github.com/Navideck/universal_ble/pull/23/files#diff-92e69b3dc0c97a5367d2a46ee4a042924534973f5adbc808f2ba303168895f45R276-R280) ```diff UniversalScanFilter::UniversalScanFilter( const EncodableList& with_services, - const EncodableList& with_manufacturer_data) + const EncodableList& with_manufacturer_data) {} ```
    Optimize device filtering by breaking early if a device does not match any filters. ___ **The _isValidDevice method in UniversalBleLinux class could be made more efficient by
    breaking early if a device does not match any of the filters, instead of continuing to
    check other filters.** [lib/src/universal_ble_linux/universal_ble_linux.dart [448-477]](https://github.com/Navideck/universal_ble/pull/23/files#diff-bd61ea0530e3e409336cd7d8a6d93c00911618355a9bf99fd1cf3d92cb6a02d9R448-R477) ```diff for (var filter in manufacturerDataFilter) { ... - return false; + if (!matchesFilter) return false; // Use a flag to break early if not matching } +return true; // Return true outside the loop if none of the filters excluded the device ```
    Combine service and manufacturer data filters into a single RequestFilterBuilder to improve efficiency. ___ **When converting ScanFilter to RequestOptionsBuilder in ScanFilterExtension, it's more
    efficient to combine service and manufacturer data filters into a single
    RequestFilterBuilder instance if possible, instead of creating separate instances for each
    filter.** [lib/src/universal_ble_web/universal_ble_web.dart [381-404]](https://github.com/Navideck/universal_ble/pull/23/files#diff-dc72e700f7c098e3f4e71b5d1f38c8514d3007af606d0fd15b1e5f0ecbd580cdR381-R404) ```diff -for (var service in withServices.toValidUUIDList()) { +if (!withServices.isEmpty || !withManufacturerData.isEmpty) { filters.add( RequestFilterBuilder( - services: [service], - ), - ); -} -for (var manufacturerData in withManufacturerData) { - filters.add( - RequestFilterBuilder( - manufacturerData: [ - ManufacturerDataFilterBuilder( - companyIdentifier: manufacturerData.companyIdentifier, - dataPrefix: manufacturerData.data, - mask: manufacturerData.mask, - ), - ], + services: withServices.toValidUUIDList(), + manufacturerData: withManufacturerData.map((manufacturerData) => ManufacturerDataFilterBuilder( + companyIdentifier: manufacturerData.companyIdentifier, + dataPrefix: manufacturerData.data, + mask: manufacturerData.mask, + )).toList(), ), ); } ```
    Optimize data matching function. ___ **To improve the performance and readability of the findData function, consider using zip to
    combine find and mask arrays instead of accessing them by index.** [darwin/Classes/UniversalBleHelper.swift [191-195]](https://github.com/Navideck/universal_ble/pull/23/files#diff-64579e5454d2beef64b5056e1f9eea6e9f92006164a448fcd4207c126df2af48R191-R195) ```diff -for i in 0 ..< find.count { - if (find[i] & mask[i]) != (data[i] & mask[i]) { +for (findByte, maskByte) in zip(find, mask) { + if (findByte & maskByte) != (data[i] & maskByte) { return false } } ```
    Possible issue
    Improve type safety in list casting. ___ **When casting lists from Any? to a specific type, it's safer to check the type before
    casting to avoid ClassCastException. Use as? with a null check or a safe cast function.** [android/src/main/kotlin/com/navideck/universal_ble/UniversalBle.g.kt [143-144]](https://github.com/Navideck/universal_ble/pull/23/files#diff-d6e68c26f4000d9fc6e49ecc16fe5da3071f5852ba7354c7dd6fee39ecfb931eR143-R144) ```diff -val withServices = list[0] as List -val withManufacturerData = list[1] as List +val withServices = list[0] as? List ?: listOf() +val withManufacturerData = list[1] as? List ?: listOf() ```
    Improve safety in integer conversion. ___ **When converting an Int32 to Int64, it's safer to directly cast it instead of checking for
    Int64? and then using as! Int64?. This avoids potential runtime crashes due to force
    unwrapping.** [darwin/Classes/UniversalBle.g.swift [163]](https://github.com/Navideck/universal_ble/pull/23/files#diff-f59aea8772c56741cf3c3214485fddd93400c4a3b9e2fb61acc7b468d0cd0d03R163-R163) ```diff -let companyIdentifier: Int64? = isNullish(list[0]) ? nil : (list[0] is Int64? ? list[0] as! Int64? : Int64(list[0] as! Int32)) +let companyIdentifier: Int64? = isNullish(list[0]) ? nil : Int64(truncatingIfNeeded: list[0] as? Int32 ?? 0) ```
    Enhancement
    Use std::optional for optional fields. ___ **For optional fields like company_identifier, data, and mask in
    UniversalManufacturerDataFilter, consider using std::optional for clearer semantics
    instead of pointers.** [windows/src/generated/universal_ble.g.h [224-234]](https://github.com/Navideck/universal_ble/pull/23/files#diff-dbad6e1282f7cdf4426043b48a2e8b8cb554988b2dd450b91822c5d7436016d4R224-R234) ```diff -const int64_t* company_identifier() const; -const std::vector* data() const; -const std::vector* mask() const; +std::optional company_identifier() const; +std::optional> data() const; +std::optional> mask() const; ```

    โœจ 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#L69) 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=... ```
    Enabling\disabling automation
    When you first install the app, the [default mode](https://pr-agent-docs.codium.ai/usage-guide/automations_and_usage/#github-app-automatic-tools-when-a-new-pr-is-opened) for the improve tool is: ``` pr_commands = ["/improve --pr_code_suggestions.summarize=true", ...] ``` meaning the `improve` tool will run automatically on every PR, with summarization enabled. Delete this line to disable the tool from running automatically.
    Utilizing extra instructions
    Extra instructions are very important for the `improve` tool, since they enable to guide the model to suggestions that are more relevant to the specific needs of the project. Be specific, clear, and concise in the instructions. With extra instructions, you are the prompter. Specify relevant aspects that you want the model to focus on. Examples for extra instructions: ``` [pr_code_suggestions] # /improve # extra_instructions=""" Emphasize the following aspects: - Does the code logic cover relevant edge cases? - Is the code logic clear and easy to understand? - Is the code logic efficient? ... """ ``` Use triple quotes to write multi-line instructions. Use bullet points to make the instructions more readable.
    A note on code suggestions quality
    - While the current AI for code is getting better and better (GPT-4), it's not flawless. Not all the suggestions will be perfect, and a user should not accept all of them automatically. - Suggestions are not meant to be simplistic. Instead, they aim to give deep feedback and raise questions, ideas and thoughts to the user, who can then use his judgment, experience, and understanding of the code base. - Recommended to use the 'extra_instructions' field to guide the model to suggestions that are more relevant to the specific needs of the project, or use the [custom suggestions :gem:](https://pr-agent-docs.codium.ai/tools/custom_suggestions/) tool - With large PRs, best quality will be obtained by using 'improve --extended' mode.
    More PR-Agent commands
    > To invoke the PR-Agent, add a comment using one of the following commands: > - **/review**: Request a review of your Pull Request. > - **/describe**: Update the PR title and description based on the contents of the PR. > - **/improve [--extended]**: Suggest code improvements. Extended mode provides a higher quality feedback. > - **/ask \**: Ask a question about the PR. > - **/update_changelog**: Update the changelog based on the PR's contents. > - **/add_docs** ๐Ÿ’Ž: Generate docstring for new components introduced in the PR. > - **/generate_labels** ๐Ÿ’Ž: Generate labels for the PR based on the PR's contents. > - **/analyze** ๐Ÿ’Ž: Automatically analyzes the PR, and presents changes walkthrough for each component. >See the [tools guide](https://pr-agent-docs.codium.ai/tools/) for more details. >To list the possible configuration parameters, add a **/config** comment.
    See the [improve usage](https://pr-agent-docs.codium.ai/tools/improve/) page for a more comprehensive guide on using this tool.
    codiumai-pr-agent[bot] commented 1 month ago

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

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

    Persistent review updated to latest commit https://github.com/Navideck/universal_ble/commit/206e677aacff1eb48130e37654ca1d28c0836edc

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

    PR Code Suggestions

    CategorySuggestions                                                                                                                                                       
    Possible issue
    Add null pointer checks before dereferencing pointers in the constructor. ___ **Consider checking for null pointers before dereferencing company_identifier, data, and
    mask in the constructor of UniversalManufacturerDataFilter. This will prevent potential
    segmentation faults if null pointers are accidentally passed.** [windows/src/generated/universal_ble.g.cpp [319-325]](https://github.com/Navideck/universal_ble/pull/23/files#diff-92e69b3dc0c97a5367d2a46ee4a042924534973f5adbc808f2ba303168895f45R319-R325) ```diff UniversalManufacturerDataFilter::UniversalManufacturerDataFilter( const int64_t* company_identifier, const std::vector* data, const std::vector* mask) - : company_identifier_(company_identifier ? std::optional(*company_identifier) : std::nullopt), - data_(data ? std::optional>(*data) : std::nullopt), - mask_(mask ? std::optional>(*mask) : std::nullopt) {} + : company_identifier_(company_identifier && *company_identifier ? std::optional(*company_identifier) : std::nullopt), + data_(data && *data ? std::optional>(*data) : std::nullopt), + mask_(mask && *mask ? std::optional>(*mask) : std::nullopt) {} ```
    Add bounds checking to prevent out-of-bounds access. ___ **For the findData function, consider adding bounds checking for the data parameter to
    ensure it's not accessed out of bounds, improving the function's robustness.** [darwin/Classes/UniversalBleHelper.swift [193]](https://github.com/Navideck/universal_ble/pull/23/files#diff-64579e5454d2beef64b5056e1f9eea6e9f92006164a448fcd4207c126df2af48R193-R193) ```diff -if (find[i] & mask[i]) != (data[i] & mask[i]) { +if i >= data.count || (find[i] & mask[i]) != (data[i] & mask[i]) { return false } ```
    Performance
    Use an unordered_map for efficient manufacturer data filtering. ___ **To improve performance and maintainability, consider using a std::unordered_map for
    manufacturerScanFilter instead of a std::vector. This allows for constant time complexity
    for lookups by company_identifier, which can improve efficiency when filtering
    manufacturer data.** [windows/src/universal_ble_plugin.cpp [34]](https://github.com/Navideck/universal_ble/pull/23/files#diff-c744a38517e9dcb9177126ffd1392b9decc2b53e55772d4270f4387a4f4c9357R34-R34) ```diff -std::vector manufacturerScanFilter = std::vector(); +std::unordered_map manufacturerScanFilter; ```
    Use Data's prefix method for better performance. ___ **To improve performance, consider using Data's prefix method instead of subdata(in:) when
    extracting the manufacturer ID from msd in the isManufacturerDataMatchingFilters function.** [darwin/Classes/UniversalBleHelper.swift [172]](https://github.com/Navideck/universal_ble/pull/23/files#diff-64579e5454d2beef64b5056e1f9eea6e9f92006164a448fcd4207c126df2af48R172-R172) ```diff -let manufacturerId = msd.subdata(in: 0 ..< 2).withUnsafeBytes { $0.load(as: UInt16.self) } +let manufacturerId = msd.prefix(2).withUnsafeBytes { $0.load(as: UInt16.self) } ```
    Enhancement
    Use std::equal for byte array comparison with a mask. ___ **Instead of manually iterating and comparing byte arrays in filterByManufacturerData,
    consider using std::equal with a custom predicate that applies the mask during comparison.
    This can make the code more concise and potentially more efficient.** [windows/src/universal_ble_plugin.cpp [805-822]](https://github.com/Navideck/universal_ble/pull/23/files#diff-c744a38517e9dcb9177126ffd1392b9decc2b53e55772d4270f4387a4f4c9357R805-R822) ```diff -for (size_t i = 0; i < data_filter->size(); i++) -{ - if (mask != nullptr && mask->size() > i) - { - if (((*mask)[i] & (*data_filter)[i]) != ((*mask)[i] & deviceData[i])) - { - isMatch = false; - break; - } - } - else - { - if ((*data_filter)[i] != deviceData[i]) - { - isMatch = false; - break; - } - } -} +isMatch = std::equal(data_filter->begin(), data_filter->end(), deviceData.begin(), + [mask](const uint8_t &filterByte, const uint8_t &deviceByte) { + return mask ? (filterByte & (*mask)[&filterByte - &(*data_filter)[0]]) == (deviceByte & (*mask)[&filterByte - &(*data_filter)[0]]) : filterByte == deviceByte; + }); ```
    Implement manufacturer data filtering logic. ___ **Implement the logic inside the if block for manufacturer data filtering in _onDeviceAdd
    method. Currently, it checks if the manufacturer data filter is not empty but does not
    perform any filtering logic. This is crucial for ensuring that only devices matching the
    manufacturer data criteria are processed.** [lib/src/universal_ble_linux/universal_ble_linux.dart [379-382]](https://github.com/Navideck/universal_ble/pull/23/files#diff-bd61ea0530e3e409336cd7d8a6d93c00911618355a9bf99fd1cf3d92cb6a02d9R379-R382) ```diff if (manufacturerDataFilter != null && - manufacturerDataFilter.isNotEmpty) {} + manufacturerDataFilter.isNotEmpty) { + // Implement filtering logic here +} ```
    Add null or empty check for data in ManufacturerDataFilter. ___ **Consider checking for null or empty data before adding ManufacturerDataFilter to the list.
    This can prevent potential runtime errors or unexpected behavior when the data or mask
    arrays are not properly initialized.** [example/lib/home/home.dart [78-82]](https://github.com/Navideck/universal_ble/pull/23/files#diff-da1b5bdcb6f7b90bf5ad0c250e3af4c06567c23d1ebe6135325b8d30241a3838R78-R82) ```diff -ManufacturerDataFilter( - companyIdentifier: 0x012D, - data: Uint8List.fromList( - [0x03, 0x00, 0x64, 0x00], +if (data.isNotEmpty) { + ManufacturerDataFilter( + companyIdentifier: 0x012D, + data: Uint8List.fromList( + [0x03, 0x00, 0x64, 0x00], + ), ), -), +} ```
    Add warning or exception when no scan filters are provided. ___ **Instead of directly returning RequestOptionsBuilder.acceptAllDevices() when no filters are
    added, consider logging a warning or throwing an exception to inform the developer that no
    filters are being applied. This can help prevent unintentional scans of all devices, which
    can be inefficient and potentially problematic in terms of privacy and performance.** [lib/src/universal_ble_web/universal_ble_web.dart [406-408]](https://github.com/Navideck/universal_ble/pull/23/files#diff-dc72e700f7c098e3f4e71b5d1f38c8514d3007af606d0fd15b1e5f0ecbd580cdR406-R408) ```diff if (filters.isEmpty) { - return RequestOptionsBuilder.acceptAllDevices(); + // Log a warning or throw an exception + throw Exception("No scan filters provided. Scanning all devices is not recommended."); } ```
    Simplify conditional checks by utilizing internal function logic. ___ **Instead of manually checking if manufacturerFilter is empty and then calling
    isManufacturerDataMatchingFilters, you can directly call the function as it internally
    checks for an empty filter. This simplifies the didDiscover method.** [darwin/Classes/UniversalBlePlugin.swift [252-253]](https://github.com/Navideck/universal_ble/pull/23/files#diff-87832239a271a17152d0bd5fd33a705cd1398bda21bfdfff19934f405c09965fR252-R253) ```diff -if !manufacturerFilter.isEmpty, !isManufacturerDataMatchingFilters(filters: manufacturerFilter, msd: manufacturerData) { +if !isManufacturerDataMatchingFilters(filters: manufacturerFilter, msd: manufacturerData) { return } ```
    Maintainability
    Extract manufacturer data filtering logic into a separate method. ___ **For better code organization and readability, consider extracting the manufacturer data
    filtering logic in _isValidDevice into a separate method. This will make _isValidDevice
    cleaner and the filtering logic more reusable and testable.** [lib/src/universal_ble_linux/universal_ble_linux.dart [441-446]](https://github.com/Navideck/universal_ble/pull/23/files#diff-bd61ea0530e3e409336cd7d8a6d93c00911618355a9bf99fd1cf3d92cb6a02d9R441-R446) ```diff -// Check manufacturerData filter -if (!_isValidManufacturerData( - scanFilter.withManufacturerData, - device.manufacturerDataFilter, -)) { +bool _matchesManufacturerDataFilter(ScanFilter scanFilter, BlueZDevice device) { + // Implement the manufacturer data filtering logic here +} + +// In _isValidDevice method +if (!_matchesManufacturerDataFilter(scanFilter, device)) { return false; } ```
    Handle web-specific configurations after removing webRequestOptions. ___ **Since the webRequestOptions parameter is removed, ensure that all web-specific
    configurations are migrated or handled appropriately within the ScanFilter or through
    other mechanisms to maintain feature parity and functionality on web platforms.** [lib/src/universal_ble.dart [47-48]](https://github.com/Navideck/universal_ble/pull/23/files#diff-0299ec0dda75c972b21ca1a2d8ac5fc87bc4dc3f354c49c7995bcb3d18054304R47-R48) ```diff +// Ensure web-specific configurations are handled appropriately static Future startScan({ ScanFilter? scanFilter, }) async { ```
    Return a descriptive type from filter functions for better debuggability. ___ **The filterByManufacturerData function should return a more descriptive type than bool to
    indicate the reason for filtering out data, enhancing debuggability and maintainability.** [windows/src/universal_ble_plugin.h [126]](https://github.com/Navideck/universal_ble/pull/23/files#diff-5e53d816e18b3a55d63090396aac40ab0c2159f0bf24d5ae5687d003c22c809fR126-R126) ```diff -bool filterByManufacturerData(IVector deviceManufactureData); +FilterResult filterByManufacturerData(IVector deviceManufactureData); ```
    Best practice
    Make companyIdentifier non-nullable in ManufacturerDataFilter. ___ **For better type safety and to avoid potential runtime errors, consider making the
    companyIdentifier field non-nullable in ManufacturerDataFilter class. This change ensures
    that every manufacturer data filter has a valid company identifier.** [lib/src/models/scan_filter.dart [14]](https://github.com/Navideck/universal_ble/pull/23/files#diff-3855acfe8c6c77715a45e6abbf2757d06d7bb8eb65c325745f7f40d8765d79a7R14-R14) ```diff -int? companyIdentifier; +int companyIdentifier; ```
    Validate length of data and mask arrays in manufacturer data filters. ___ **When adding manufacturer data filters, it's important to validate the length of the data
    and mask arrays to ensure they match. This validation can prevent runtime errors and
    ensure the filters work as expected.** [android/src/main/kotlin/com/navideck/universal_ble/UniversalBleHelper.kt [174-175]](https://github.com/Navideck/universal_ble/pull/23/files#diff-07528325c9af8065d3fe07cc2436350a5db4dde75378b96e4801cdc7675b128aR174-R175) ```diff val data: ByteArray = manufacturerData.data ?: ByteArray(0) val mask: ByteArray? = manufacturerData.mask +if (data.size != mask?.size) { + throw IllegalArgumentException("Data and mask arrays must be of the same length.") +} ```
    Use guard for early exits to improve code readability. ___ **Consider using guard for early exits to make the code more readable and to reduce nesting.
    This applies to the validation of UUID from service.validFullUUID in the startScan
    function.** [darwin/Classes/UniversalBlePlugin.swift [65-66]](https://github.com/Navideck/universal_ble/pull/23/files#diff-87832239a271a17152d0bd5fd33a705cd1398bda21bfdfff19934f405c09965fR65-R66) ```diff -if UUID(uuidString: service.validFullUUID) == nil { +guard UUID(uuidString: service.validFullUUID) != nil else { throw FlutterError(code: "IllegalArgument", message: "Invalid service UUID:\(service)", details: nil) } ```

    โœจ 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#L69) 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=... ```
    Enabling\disabling automation
    When you first install the app, the [default mode](https://pr-agent-docs.codium.ai/usage-guide/automations_and_usage/#github-app-automatic-tools-when-a-new-pr-is-opened) for the improve tool is: ``` pr_commands = ["/improve --pr_code_suggestions.summarize=true", ...] ``` meaning the `improve` tool will run automatically on every PR, with summarization enabled. Delete this line to disable the tool from running automatically.
    Utilizing extra instructions
    Extra instructions are very important for the `improve` tool, since they enable to guide the model to suggestions that are more relevant to the specific needs of the project. Be specific, clear, and concise in the instructions. With extra instructions, you are the prompter. Specify relevant aspects that you want the model to focus on. Examples for extra instructions: ``` [pr_code_suggestions] # /improve # extra_instructions=""" Emphasize the following aspects: - Does the code logic cover relevant edge cases? - Is the code logic clear and easy to understand? - Is the code logic efficient? ... """ ``` Use triple quotes to write multi-line instructions. Use bullet points to make the instructions more readable.
    A note on code suggestions quality
    - While the current AI for code is getting better and better (GPT-4), it's not flawless. Not all the suggestions will be perfect, and a user should not accept all of them automatically. - Suggestions are not meant to be simplistic. Instead, they aim to give deep feedback and raise questions, ideas and thoughts to the user, who can then use his judgment, experience, and understanding of the code base. - Recommended to use the 'extra_instructions' field to guide the model to suggestions that are more relevant to the specific needs of the project, or use the [custom suggestions :gem:](https://pr-agent-docs.codium.ai/tools/custom_suggestions/) tool - With large PRs, best quality will be obtained by using 'improve --extended' mode.
    More PR-Agent commands
    > To invoke the PR-Agent, add a comment using one of the following commands: > - **/review**: Request a review of your Pull Request. > - **/describe**: Update the PR title and description based on the contents of the PR. > - **/improve [--extended]**: Suggest code improvements. Extended mode provides a higher quality feedback. > - **/ask \**: Ask a question about the PR. > - **/update_changelog**: Update the changelog based on the PR's contents. > - **/add_docs** ๐Ÿ’Ž: Generate docstring for new components introduced in the PR. > - **/generate_labels** ๐Ÿ’Ž: Generate labels for the PR based on the PR's contents. > - **/analyze** ๐Ÿ’Ž: Automatically analyzes the PR, and presents changes walkthrough for each component. >See the [tools guide](https://pr-agent-docs.codium.ai/tools/) for more details. >To list the possible configuration parameters, add a **/config** comment.
    See the [improve usage](https://pr-agent-docs.codium.ai/tools/improve/) page for a more comprehensive guide on using this tool.