-
Notifications
You must be signed in to change notification settings - Fork 3k
BLE streamlining #13365
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
BLE streamlining #13365
Conversation
This has been tested with the new pytest suite. |
@paul-szczepanek-arm, thank you for your changes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @paul-szczepanek-arm, the structure looks good to me. Please see my comment regarding the inclusion of TARGET_CORDIO headers in generic code.
connectivity/FEATURE_BLE/cordio/TARGET_CORDIO/driver/CordioHCIDriver.h
Outdated
Show resolved
Hide resolved
|
||
class PalGenericAccessService; | ||
class PalSecurityManager; | ||
class PalGap; | ||
class BLEInstanceBase; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we include their headers instead? Same for other class <CLASS_NAME>;
in other files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't, cyclic dependency
} // ble | ||
|
||
using ble::impl::SecurityManager; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For compatibility we should add Gap, SecurityManager, etc. back to the global namespace (with using
for example). Our examples and cliapp should continue to compile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought Gap and the rest are supposed to be in ble:: namespace, looking at the old files I don't see a using ble::Gap
Examples don't compile because they were incorrectly failing to include headers and relying on the happy coincidence of other headers including what they needed, I have made the fixes but not pushed to master yet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added it as a config option
} // namespace ble | ||
|
||
|
||
#if (BLE_PAL_API_IMPLEMENTATION == 1) | ||
#include "ble/internal/PalGapImpl.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is in TARGET_CORDIO - we'd better not include it here.
How to achieve that? In non-Cordio code, just use ble::interface::PalGap
where possible, and this is the point of virtual functions/interface classes. It's only a few lines' change and it worked as far as I tried.
Same for the other virtual Pal classes.
Once the generic code has no dependency on headers in TARGET_CORDIO, the headers/classes in TARGET_CORDIO can be renamed to contain "Cordio" in my opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point is to remove virtual calls. Alternative implementation can override this include with their implementation.
@0xc0170 How do I make exceptions for astyle? this is thirdparty code that is tripping the astyle tests. |
Use .astyleignore located at the root of mbed-os. |
This PR cannot be merged due to conflicts. Please rebase to resolve them. |
953b33b
to
4fe6928
Compare
Thank Lingkai, anything else I should look at? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The structure looks very good to me. I didn't and couldn't review every single line of diff given how big it is. But since the PR mostly cuts and pastes code around, we can assume nothing is missing as ble-tests and examples continue to work (otherwise things probably wouldn't even compile...).
@@ -1,9 +1,9 @@ | |||
^BUILD | |||
^cmsis | |||
^connectivity/FEATURE_BLE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not related to this PR - no need to fix it here:
We'd better only ignore external components (e.g. Cordio) while keeping checks on our code. If any styles don't match, the CI generates a diff we can apply without manual fixes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the old check was for features/FEATURE_BLE so I figured I'd better move it as is since I don't want to get bogged down with astyle right now, we can fix this in a later PR
#if (BLE_API_IMPLEMENTATION == 1) | ||
#include "ble/internal/GapImpl.h" | ||
#else | ||
#error "please provide alternate BLE implementation" | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#if (BLE_API_IMPLEMENTATION == 1) | |
#include "ble/internal/GapImpl.h" | |
#else | |
#error "please provide alternate BLE implementation" | |
#endif | |
#include "ble/internal/GapImpl.h" |
As discussed offline, this include is okay. I guess the standardised header name can be considered part of the "porting interface", and I've seen a few other projects doing this too.
Actually the BLE_API_IMPLEMENTATION
macro may not be needed. If a user doesn't want Cordio, they can simply undeclare Cordio from the Mbed config so TARGET_CORDIO
isn't built, and provide their implementation with the same "ble/internal/GapImpl.h"
file path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, totally agreed, this was only to show the porting point but this can be made better in a readme somewhere
"ble-api-implementation": { | ||
"help": "What BLE user API implementation is used. Available options: 1 (Mbed). You may add more. See headers in include/ble/.", | ||
"value": 1, | ||
"macro_name": "BLE_API_IMPLEMENTATION" | ||
}, | ||
"ble-pal-api-implementation": { | ||
"help": "What Pal API implementation is used. Available options: 1 (Cordio). You may add more. See headers in include/ble/internal/Pal*.", | ||
"value": 1, | ||
"macro_name": "BLE_PAL_API_IMPLEMENTATION" | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment above. If impl header names are standardised, we can always assume they exist.
The TARGET_CORDIO magic name already does the switch to use Cordio (i.e. default) impl or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, let me remove that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@paul-szczepanek-arm Nitpicking over the public headers mostly. I'll approve this once these are resolved.
|
||
/*! Maximum count of characteristics that can be stored for authorisation purposes */ | ||
#define MAX_CHARACTERISTIC_AUTHORIZATION_CNT 20 | ||
|
||
/*! client characteristic configuration descriptors settings */ | ||
#define MAX_CCCD_CNT 20 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicated from the Impl header which is a better place for those?
/*! Maximum count of characteristics that can be stored for authorisation purposes */ | |
#define MAX_CHARACTERISTIC_AUTHORIZATION_CNT 20 | |
/*! client characteristic configuration descriptors settings */ | |
#define MAX_CCCD_CNT 20 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they should not exist as defines at all, they should be a config - added
Gap::PreferredConnectionParams_t getPreferredConnectionParams(); | ||
|
||
/** | ||
* The registered callback handler for confirmation received events. | ||
* Set preferred connection parameters. | ||
* | ||
* @param[in] params Preferred connection parameter values to set. | ||
*/ | ||
EventCallback_t confirmationReceivedCallback; | ||
|
||
private: | ||
/* Disallow copy and assignment. */ | ||
GattServer(const GattServer &); | ||
GattServer& operator=(const GattServer &); | ||
void setPreferredConnectionParams(const Gap::PreferredConnectionParams_t& params); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding them back - I removed them from the public API a few months (thought they were deprecated but were actually missing...), please mention them in the PR description as a new feature.
/** For backwards compatibility. This enm is now in BLETypes.h | ||
* @deprecated, use the enum in ble namespace */ | ||
enum Keypress_t { | ||
KEYPRESS_STARTED, /**< Passkey entry started */ | ||
KEYPRESS_ENTERED, /**< Passkey digit entered */ | ||
KEYPRESS_ERASED, /**< Passkey digit erased */ | ||
KEYPRESS_CLEARED, /**< Passkey cleared */ | ||
KEYPRESS_COMPLETED, /**< Passkey entry completed */ | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/** For backwards compatibility. This enm is now in BLETypes.h | |
* @deprecated, use the enum in ble namespace */ | |
enum Keypress_t { | |
KEYPRESS_STARTED, /**< Passkey entry started */ | |
KEYPRESS_ENTERED, /**< Passkey digit entered */ | |
KEYPRESS_ERASED, /**< Passkey digit erased */ | |
KEYPRESS_CLEARED, /**< Passkey cleared */ | |
KEYPRESS_COMPLETED, /**< Passkey entry completed */ | |
}; | |
/** For backwards compatibility. This enum is now in BLETypes.h | |
* @deprecated, use the enum in ble namespace */ | |
using using ble::Keypress_t; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume you meant a typedef
connectivity/FEATURE_BLE/include/ble/internal/BLEInstanceBase.h
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for it! @paul-szczepanek-arm
@adbridge Could you please trigger a CI run? Thanks.
I'll also try a few things locally tomorrow, though this kind of refactoring (moving files and classes around) should be low risk, as long as things compile.
CI started |
Jenkins CI Test : ❌ FAILEDBuild Number: 1 | 🔒 Jenkins CI Job | 🌐 Logs & ArtifactsCLICK for Detailed Summary
|
@paul-szczepanek-arm looks like the failures are BLE related. For one of the failing boards I see:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still looking into it...
@@ -21,7 +21,6 @@ | |||
#if (DEVICE_SERIAL && DEVICE_SERIAL_FC) || defined(DOXYGEN_ONLY) | |||
|
|||
#include <stdint.h> | |||
#include "mbed.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is one of several causes of the CI failures.
Because this is removed, you need to
- Include a number of headers (e.g.
"drivers/InterruptIn.h"
) - Use the qualified class names (e.g.
mbed::InterruptIn
) instead of short one (e.g.InterruptIn
), becausembed.h
which we removed has ausing namespace mbed
.
Please keep fixing errors until
mbed test -t <TOOLCHAIN> -m CY8CKIT_062S2_43012 --compile
succeeds.
@paul-szczepanek-arm
Note: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying to dismiss the previous review
Jenkins CI Test : ❌ FAILEDBuild Number: 2 | 🔒 Jenkins CI Job | 🌐 Logs & ArtifactsCLICK for Detailed Summary
|
Jenkins CI Test : ❌ FAILEDBuild Number: 3 | 🔒 Jenkins CI Job | 🌐 Logs & ArtifactsCLICK for Detailed Summary
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. @adbridge Could you please trigger CI again? Hopefully it'll pass this time, thanks!
CI started |
@@ -111,7 +109,16 @@ class GattClient : public StaticInterface<Impl, GattClient> { | |||
virtual void onAttMtuChange( | |||
ble::connection_handle_t connectionHandle, | |||
uint16_t attMtuSize | |||
) | |||
) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting is incorrect here, for functions opening { go on their own line
@@ -117,22 +114,20 @@ class GattServer { | |||
virtual void onAttMtuChange( | |||
ble::connection_handle_t connectionHandle, | |||
uint16_t attMtuSize | |||
) | |||
) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
incorrect formatting
namespace interface { | ||
#endif // !defined(DOXYGEN_ONLY) | ||
class SecurityManager | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
formatting
@@ -339,7 +325,7 @@ class SecurityManager { | |||
* @param[in] connectionHandle connection connectionHandle | |||
* @param[in] passkey 6 digit passkey to be displayed | |||
*/ | |||
virtual void passkeyDisplay(ble::connection_handle_t connectionHandle, const SecurityManager::Passkey_t passkey) { | |||
virtual void passkeyDisplay(ble::connection_handle_t connectionHandle, const Passkey_t passkey) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
formatting
@@ -373,7 +359,7 @@ class SecurityManager { | |||
* @param[in] connectionHandle connection connectionHandle | |||
* @param[in] keypress type of keypress event | |||
*/ | |||
virtual void keypressNotification(ble::connection_handle_t connectionHandle, SecurityManager::Keypress_t keypress) { | |||
virtual void keypressNotification(ble::connection_handle_t connectionHandle, ble::Keypress_t keypress) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
formatting
* | ||
* @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. | ||
*/ | ||
ble_error_t setPrivateAddressTimeout( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this on multiple lines ?
/** | ||
* @see ble::PalGattClient::when_server_message_received | ||
*/ | ||
void when_server_message_received( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
formatting
/** | ||
* @see ble::PalGattClient::when_transaction_timeout | ||
*/ | ||
void when_transaction_timeout( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
formatting, others below here too
ble_error_t PalGattClient::get_mtu_size( | ||
connection_handle_t connection_handle, | ||
uint16_t& mtu_size | ||
) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
formatting
|
||
ble_error_t PalGenericAccessService::get_peripheral_preferred_connection_parameters( | ||
ble::Gap::PreferredConnectionParams_t& parameters | ||
) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
formatting
We've always had the entire FEATURE_BLE in |
@@ -1,9 +1,10 @@ | |||
^BUILD | |||
^cmsis | |||
^connectivity/drivers/ble | |||
^connectivity/FEATURE_BLE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^connectivity/FEATURE_BLE | |
^connectivity/FEATURE_BLE/libraries/TARGET_CORDIO/stack | |
^connectivity/FEATURE_BLE/libraries/TARGET_CORDIO_LL/stack |
This is what I mean - external code only. See my discussion with Paul earlier. @adbridge
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or can we do another PR to fix this, since this one is already pretty big?
If it's our code then we shouldn't be ignoring astyle.... |
Ci started |
Jenkins CI Test : ✔️ SUCCESSBuild Number: 4 | 🔒 Jenkins CI Job | 🌐 Logs & ArtifactsCLICK for Detailed Summary
|
Jenkins CI Test : ✔️ SUCCESSBuild Number: 5 | 🔒 Jenkins CI Job | 🌐 Logs & ArtifactsCLICK for Detailed Summary
|
Summary of changes
This is a refactor of BLE that makes Cordio the official BLE stack. There are no changes from the user's perspective. The API remains the same. This is to lessen the maintenance load. Other implementations are welcome but must implement the user API directly.
The internal changes are as follows:
This retains the separation at the PAL level, but without the templated implementation. Alternative implementations are possible by implementing the PAL API.
In simple words:
BLE is now a singleton. All implementation are non virtual concrete classes that implement interfaces directly. Any alternative implementation will have to be switched at compile time (see mbed_lib.json).
Impact of changes
Migration actions required
There are no other known BLE implementations but any porter who has one will need to adjust their implementation of BLEInstanceBase as we no longer support multiple instances within the BLE singleton. Multiple instances of BLE are supported but must be managed by the user/porter by creating their own instance of BLE.
This is already the case. The change is that this is now enforced by the API.
Documentation
None
Pull request type
Test results
Reviewers
@donatieng
@LDong-Arm