ARMmbed / mbed-os-example-ble

BLE demos using mbed OS and mbed cli
Apache License 2.0
134 stars 118 forks source link

Missing examples for reusable services #376

Open ghost opened 3 years ago

ghost commented 3 years ago

Description of defect

Previously this repository contained services that one could easily look at to see how they could be reused in your own code (like the LED service).

Now all the examples seem to have code in which the application is tied up with the service itself, so I can't figure out how standalone resuable services are supposed to look anymore.

I'd like to see an example in which BLE is just one aspect of the program, but doesn't dictate the application itself.

I went from the blinky examples to a BLE enabled app by comparing blinky with those previous examples by comparing them.

Maybe the problem is just that I don't know how to migrate from something that looked like the old code that didn't use the new ble helper library to the new ones that do.

What version of the example and mbed-os are you using (tag or sha) ?

6.x

ciarmcom commented 3 years ago

@jrobeson This issue has an incomplete or old issue template.For future reference please use an up to date clone of the repository before raising issues. Many thanks.

ciarmcom commented 3 years ago

Thank you for raising this detailed GitHub issue. I am now notifying our internal issue triagers. Internal Jira reference: https://jira.arm.com/browse/IOTOSM-4002

AGlass0fMilk commented 3 years ago

Hi @jrobeson,

The Mbed BLE services working group has been working on this for the past few months. We've been trying to come up with a robust framework for creating new services and integrating BLE as a modular subsystem.

This work has been mostly done in the mbed-os-experimental-ble-services. There, you can see the current state of how we envision creating modular/reusable BLE services. We'd love to get your feedback!

ghost commented 3 years ago

the services seem fine, but the only example of their usage is in the tests, which only do BLE stuff. I just wanted to see something that assumes you already have a working application of some level of complexity (even if it's not shown in the example) and wanted to integrate BLE into it.

paul-szczepanek-arm commented 3 years ago

Not sure what this kind of example would need to look like. The existing examples are extremely simple and if you want to embed them in an existing application all you have to do is rename the main function into run_ble function and call it from your application.

idea--list commented 3 years ago

@paul-szczepanek-arm I think @jrobeson wanted to tell that nobody begins by implementing the BLE code. Before that all of us need to reach some level of complexity in our program logic where we already have something useful info to get BLEd to another location. Those who have newer coded any Bluetooth will try to pick up new info about it just in that phase.

As you pointed out in that case one just needs to rename main() of these examples to something else. I think run_ble() sounds as official as the name of an actual API member function which i would find distracting at the very beginning of one's BLE education. Maybe something like run_my_custom_ble_func would suit better for educational purposes in all these examples. In that case main() would look like this:

main() {
run_my_custom_ble_func();
/* Rest of your custom program logic comes here */
}

I know this might sound like trivial for anyone who has some experince with BLE but for those who just start to learn implementing BLE there are way too many pitfalls currently (mainly because of the language of the doc. You need to read it 1000 times before you begin to understand some parts of that as a newcomer, though even the current doc may be good enough for BLE experts who only need some refresher).

paul-szczepanek-arm commented 3 years ago

Not official team position, ask @pan-, but I don't think we're here to teach developers about BLE. There is already an extraordinary amount of resources that can teach you about BLE in general, how it works, etc available for free on the Internet. Not least on the official website: https://www.bluetooth.com/bluetooth-resources/bluetooth-le-developer-starter-kit/ We are a small team and cannot compete with websites dedicated to teaching about BLE - please use them. I think what we CAN do is teach you how to use the BLE API that we offer.

ghost commented 3 years ago

I ended up working out my problem by going line by line. However, I still think there's a bit of confusion regards to where onDataWritten and other similar events happen. I see that chainable GAP handler happened, but it's not really well used. It'd be nice to see best practices about when and whether to use the chainable gap handler and where best to handle onDataWritten and similar events and make sure my own isn't clobbered or becomes clobbered by the services I used.

They might be clobbered by either mishandling the events, or simply because they got overwritten.

@paul-szczepanek-arm that run_my_custom_ble function can't work atm because BleProcess and friends takes over the event handler.

idea--list commented 3 years ago

@paul-szczepanek-arm Wow... you might be really tired tonight if you think only average Joes have trouble with the API your team develops. Well... first of average Joes abandon Mbed OS way before they would try to use it's BLE implementation. If anyone has hard time using MBED's BLE APIs then it might also mean that there is something wrong with the implementation and/or with its documentation. Who should address these if not the team? If the team is small, then you really need more people of the community who would like to engage in BLE subject, but with such comments you are actively acting against that to happen.

While i might relative new to BLE i am sure @jrobeson has way more experience with BLE than you think. In case he does not understand something, it does not mean the problem must be on his side. Just watch what else he might still find if he digs deep enough 😉 Bye for now!

AGlass0fMilk commented 3 years ago

@jrobeson

It'd be nice to see best practices about when and whether to use the chainable gap handler and where best to handle onDataWritten and similar events and make sure my own isn't clobbered or becomes clobbered by the services I used.

See the Mbed-os-experimental-services repository for examples of the current best practices we have developed. Many of the services I've started to develop follow closely to the structure of the ones in that repo. They are designed to be flexible, modular, and lightweight. The focus of the BLE stack and services is on communication rather than figuring everything out for you. The example services leave a lot of the logic decisions up to the application to accommodate a variety of use cases.

@idea--list

Wow... you might be really tired tonight if you think only average Joes have trouble with the API your team develops. Well... first of average Joes abandon Mbed OS way before they would try to use it's BLE implementation. If anyone has hard time using MBED's BLE APIs then it might also mean that there is something wrong with the implementation and/or with its documentation.

I think that many, many, BLE stacks out there that are easy to use trade off flexibility and access to more advanced features of BLE. I've used some of the other stacks out there and things are a lot more "canned". Sure, they have end to end examples but good luck shoehorning that into your actual application.

I think the Mbed team has done a fantastic job making a well-tested, performant, and modern BLE API/implementation. BLE is much different from its first iteration and Mbed has made it possible to use many of the new features (eg: extended advertising, different PHYs, etc)

Who should address these if not the team? If the team is small, then you really need more people of the community who would like to engage in BLE subject, but with such comments you are actively acting against that to happen.

I agree with you here, I think the documentation could use some help. The same goes for examples. I think ARM should hire some entry-level, possibly even freelance technical writers to do how-to articles and getting started guides. Having these available would drastically reduce the learning curve.

I think there might be a misunderstanding -- @paul-szczepanek-arm is very polite person. His tone may be getting lost in the text (use more emojis, Paul 😁). I don't think he meant any offense to you.

We gladly welcome contributions and questions. Please put questions on the forum and reserve GitHub issues for actual bugs.

I haven't read back far enough to see what your issue is, but whatever you're trying to do I would be happy to point you in the right direction.

P.S. I do not work for ARM but I am a contributor to Mbed and the BLE stack.

pan- commented 3 years ago

@idea--list We are reworking the documentation to provide content which we think is more relevant to our audience. While doing this we stated goal for the documentation: it should explain how to use the Mbed OS API. It is not a place to explain how the Bluetooth protocol works in detail. There are other great resources available for that. To make an analogy, you wouldn't expect a socket library documentation as a reference to IP protocols that it offers but you expect from it to explain you how to use them in your application.

Following this we want to add more useful content around the use of the API. For example, how to optimize an application for throughput, how to optimize an application for power, how to debug, ...

If you have more suggestion, we are happy to review them.

Previously this repository contained services that one could easily look at to see how they could be reused in your own code (like the LED service).

Now all the examples seem to have code in which the application is tied up with the service itself, so I can't figure out how standalone resuable services are supposed to look anymore.

@jrobeson We have one repository open where we explore how we can improve the experience when Bluetooth is used: https://github.com/ARMmbed/mbed-os-experimental-ble-services . A standard way of describing a service is key if we want to offer some service management latter on.

For now, you can look at how the BLE_GattServer_ExperimentalServices example uses the reusable LinkLoss and CurrentTime services.

idea--list commented 3 years ago

@pan- I am very interested in the reworked doc! I mean for sure that has a potential to reduce the time until one can do useful things with the APIs and would also reduce the number of people asking anything after reading that. Of course there are great resources, that explain general aspects of BLE. For sure a new doc may contain links for such, it would not hurt anyone.

Until the reworked doc i will just rely on BLEIntros i mentioned in another topic as i find it miles better than the current one. The more i read it, the less it seems to be deprecated as i initially thought.

paul-szczepanek-arm commented 3 years ago

@jrobeson this issue appears to have broadened in scope. Can you clarify what you think is broken? Just going by the title, there is an example for reusable services: https://github.com/ARMmbed/mbed-os-example-ble/tree/development/BLE_GattServer_ExperimentalServices As for integrating with your application that is outside of scope of this repository.

If there are particular problems you are facing with your applications feel free to ask about those.

ghost commented 3 years ago

I think that one does does cover my initial problem. I honestly ignored that specific one because it has the word experimental in it.

I guess the last issues i have will be covered as mbed-ble-utils stops dispatching events by itself, so it can be used freely in another application and once the examples converge on the same style and usage of BLEProcess vs BLeApp and the ones that don't use any of the common code from mbed-ble-utils.

ghost commented 3 years ago

I was just browsing the mbed discourse and saw this, so I"m not the only one with similar problems https://forums.mbed.com/t/ble-proper-way-to-add-several-services/13628

AGlass0fMilk commented 3 years ago

I was just browsing the mbed discourse and saw this, so I"m not the only one with similar problems https://forums.mbed.com/t/ble-proper-way-to-add-several-services/13628

So it is clear from our discussions that even the Mbed team has not yet established "best practices" for making complex BLE apps. Therefore, I think we should all work together with this understanding in mind.

The pattern I currently use in my apps pretty much has the following:

Typically, services have their own EventHandler type that a user can register a handler for. All application logic goes in this handler. The service primarily is concerned with BLE communication rather than acting on the data passed through it.

This has been the most flexible way to structure a BLE app so far that I have found. It does have a lot of code duplication between projects that I think a proper framework could encapsulate.

paul-szczepanek-arm commented 3 years ago

I think that one does does cover my initial problem. I honestly ignored that specific one because it has the word experimental in it.

I guess the last issues i have will be covered as mbed-ble-utils stops dispatching events by itself, so it can be used freely in another application and once the examples converge on the same style and usage of BLEProcess vs BLeApp and the ones that don't use any of the common code from mbed-ble-utils.

Yes, not all examples have been upgraded to BleApp but both BLEProcess and BleApp are there just to make the examples simpler. They are not meant for production code. All the examples here are not meant for production code.

Each examples tries to teach you one thing. A basic one one like the advertising one will show you how to set up the ble instance and run advertising. An example for subscription will concentrate only on that - avoiding duplicating the code as its goal is to only show you how to do one thing - subscribe to updates.

At some point this year (I hope) we'll publish a production ready BleApp and I will convert most examples to use that. I will still leave some examples setting up the instance manually to show how that is done in case you don't want to use the BleApp.

pan- commented 3 years ago

I guess the last issues i have will be covered as mbed-ble-utils stops dispatching events by itself, so it can be used freely in another application and once the examples converge on the same style and usage of BLEProcess vs BLeApp and the ones that don't use any of the common code from mbed-ble-utils.

That can easily be fixed by providing a flag in the start function so it doesn't dispatch the event queue.

@AGlass0fMilk What you described would be the best practices minus when using Mbed BLE and that is what we're converging to in the experimental service.

idea--list commented 3 years ago

@paul-szczepanek-arm , @pan- I think a newbie will try to compare different examples of this repo to find a common pattern to figure out the current best practice. However it is rendered nearly impossible if one lacks all the info shared in the last 2-3 comments here.

If i am right there are 6 different approaches to program BLE logic: Approach 1: direct programming of the HCI controller (masochists' area) Approach 2: inclusion of any other BLE stack than Cordio (for conquerors of a new world) Approach 3: direct usage of the Cordio stack bundled into Mbed OS (for those who reinvent the wheel) Approach 4: manual usage of Mbed BLE APIs (easy way to introduce single aspects of BLE, original flavour of all these examples) Approach 5: BLEProcess (tries to define a skeleton how to use Mbed BLE APIs for a complete BLE logic, superseded by approach 6) Approach 6: BLEApp (current recommended skeleton & future way of rounded-up examples)

IMHO it would be worth putting all the info of the last few comments here into the readme of this repo, that would help to cut through all the confusion one might face without these info.