Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTL872x-based platforms: supports BLE GATT client, BLE central role and pairing APIs #2542

Merged
merged 21 commits into from
Sep 29, 2022

Conversation

XuGuohui
Copy link
Member

@XuGuohui XuGuohui commented Sep 23, 2022

As the title describes.

Features

  1. BLE GATT client APIs
  2. BLE central role APIs
  3. BLE pairing APIs
  4. Set desired ATT MTU

Improvements

  1. GATT server may lose data if characteristic's property is "INDICATE".
  2. Reliable scanning and broadcasting states

Steps to Test

  1. tests/wiring/ble_central_peripheral
  2. tests/wiring/ble_scanner_broadcaster
  3. tests/wiring/no_fixture_ble

References

N/A

Known issues

  1. Failed to get BLE security level
  2. BLE behaves lazily if Wi-Fi is connected due to Wi-Fi/BLE co-existence.

Completeness

  • User is totes amazing for contributing!
  • Contributor has signed CLA (Info here)
  • Problem and Solution clearly stated
  • Run unit/integration/application tests on device
  • Added documentation
  • Added to CHANGELOG.md after merging (add links to docs and issues)

@@ -52,6 +51,7 @@ test(BLE_00_Prepare) {
assertTrue(waitFor(getBleTestPeer().isValid, 60 * 1000));
#endif // PARTICLE_TEST_RUNNER
}
#endif // HAL_PLATFORM_NRF52840

#if HAL_PLATFORM_NRF52840
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this supposed to be still be disabled for P2?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. The scan API will finally timeout taking the scan semaphore on P2 and it doesn't rely BLE event to give the semaphore. This test case is to simulate the situation that nRF based platforms fail to give the scan semaphore due to missing specific expected BLE events.

{
WiringBleLock lk;
int ret = hal_ble_gap_connect(&connCfg, &impl()->connHandle(), nullptr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any effects on Gen 3?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should revert this change, since we have increased the BLE event thread priority to avoid some race conditions. The change here may cause dead lock on Gen3 if there is asynchronous BLE event generated and to be propagated prior to connected event.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recall that this change was going to fix the race condition that hal_ble_gap_connect() has exited, however, the peer device hasn't been added to wiring cache and a new BLE event is propagated, which results in peer device not found in the wiring event callback. So a new fix is to propagate the connected event to wiring layer followed by adding the peer device to cache, but not notifying (or maybe we can?) user application if user initiate the connection establishedment. @avtolstoy

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate on the

but not notifying (or maybe we can?) user application if user initiate the connection establishedment.

?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently the BLE.connect() API is designed to not generate connected event for application hook, because this API is a blocking API. So to iron out the race condition as I mentioned above, we can change the current scheme.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I see. What are the other events that are propagated from HAL to wiring right after hal_ble_gap_connect() ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E.g. BLE pairing request. It may be generated pretty fast if peer device send the request on connected. I have experienced this many times during the fixture test.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, in that case I don't see a way of resolving this unless we switch over to a CONNECTED event to fill in the necessary data in wiring directly from BLE stack events. So, let's add it. Perhaps to avoid breaking Gen 3 stuff, add a feature flag for now for rtl872x platforms specifically and have this behavior only on those for now until we have a bit more time.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.

#elif HAL_PLATFORM_RTL872X // RTL872x doesn't support rejecting legacy pairing request
assertTrue(BLE.isPaired(peer));
#else
// TODO
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: #error Unsupported platform

@@ -167,7 +167,7 @@ enum class BlePairingIoCaps : uint8_t {
enum class BlePairingAlgorithm : uint8_t {
AUTO = BLE_PAIRING_ALGORITHM_AUTO,
LEGACY_ONLY = BLE_PAIRING_ALGORITHM_LEGACY_ONLY,
LESC_ONLY = BLE_PAIRING_ALGORITHM_LESC_ONLY
LESC_ONLY = BLE_PAIRING_ALGORITHM_LESC_ONLY // nRF52840-based platforms only
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be supported with GAP_AUTHEN_BIT_SC_ONLY_FLAG, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added this in https://github.com/particle-iot/device-os/tree/feature%2Fp2_ble_central-v2, feel free to pull-in if necessary.

@avtolstoy
Copy link
Member

@XuGuohui Please rebase, this PR is quite out of date with develop.

@scott-brust scott-brust added this to the 5.1.0 milestone Sep 27, 2022
// Prefer LESC
authFlags = GAP_AUTHEN_BIT_SC_FLAG;
} else if (pairingConfig_.algorithm == BLE_PAIRING_ALGORITHM_LESC_ONLY) {
authFlags = GAP_AUTHEN_BIT_SC_ONLY_FLAG;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be GAP_AUTHEN_BIT_SC_ONLY_FLAG | GAP_AUTHEN_BIT_FLAG. I've tested in both roles, works fine.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

BleConnection connection = {};
connection.info.version = BLE_API_VERSION;
connection.info.size = sizeof(hal_ble_conn_info_t);
if (addressEqual(connectingAddr_, peerAddr)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check seems to be failing for me. In central role I'm getting Connected as Peripheral in the log and device crashes afterwards.

@avtolstoy
Copy link
Member

This should now be passing all the tests without issues in both roles. @XuGuohui and @avtolstoy to re-review the latest commits before merging.

@@ -445,11 +448,14 @@ static void pairingTestRoutine(bool request, BlePairingAlgorithm algorithm,
assertTrue(waitFor([&]{ return !BLE.isPairing(peer); }, 20000));
assertTrue(BLE.isPaired(peer));
assertEqual(pairingStatus, (int)SYSTEM_ERROR_NONE);
// FIXME: le_bond_get_sec_level() failed to retrieve the security level
#if !HAL_PLATFORM_RTL872X
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only issue that still needs to be resolved.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FAE just send mee a patch that has exposed an API to get the security level even if connnection is not bonded.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

@avtolstoy avtolstoy merged commit b64994e into develop Sep 29, 2022
@avtolstoy avtolstoy deleted the feature/p2_ble_central branch September 29, 2022 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants