-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
Bluetooth: Mesh: Network management #20259
Comments
Overall, I think this is the right approach. The way I imagine it, this management module would essentially be a database that you store addresses, keys and nodes in. Then, when you call the config client and provisioner APIs, you use the entries in this database as parameters, but you'd still be calling the config client and provisioner APIs directly. Is this what you want this module to cover, or do you think it should wrap the config client and provisioner? I think we should discuss the scope of what we want to store in this module. Should it be everything we know about the nodes and the network, or just the stuff the other nodes won't be able to tell us if we ask? For instance, should we store all the network keys each node has? Should we store the composition data of each node, so that we can give each model the right application keys? If we don't, how will the user know which model ID it should call Your draft for the structures looks pretty good to me, but there are some details I'd like to highlight:
I assume you have some kind of endgame in mind for the configurator here, where it can be used to configure all aspects of the entire mesh. Are you envisioning this as a shell application, where the user is in the loop, or are you looking for a way to establish an automated configurator that can set up a network according to some user defined recipe? We made an automated configurator for the Nordic Mesh SDK, but I'm not very happy with it, to be honest. The module I linked to works directly on top of the config client, provisioner and management module, and defines the configuration as a set of steps that must be done for each device "type". IMO, the first mistake we made was to make this module a part of the application, and not a generic module with a high level API. Everything it does is generic, and could be covered by an API that closer resembles what the user wants to do ("give all onoff models this application key", "make all nodes use TTL=6"). The second mistake was to make the configuration "process"-centric, instead of data-centric. It shouldn't be "first, add this key to this device, then make this model subscribe to that group", it should be "when the configuration is complete, the device should look like this". I think there's value in an automated configurator, but it should have a high level data-centric API, otherwise it'll make for horribly complex applications. Regardless of whether the next step is to create a configurator shell application or an automated configurator, I think we need some module that wraps the provisioner, config client and mesh network database, as the API for these modules is very low level and not very close to what I think the users actually want to accomplish. |
@trond-snekvik Thanks for the feedback! The way I see it we are discussing two things here:
I think these should be implemented as two separate things and since 2 has a dependency on 1, my first goal would be to have this sort of database in place. Solving 1 would also help make a distiction between the local node and the rest of the network as discussed in #17729. Having said that, it is always good to stay one step ahead and think a discussion about 2 can maybe shed some light on specific requirements on 1 :) Anyway, I think it would make sense to have a small and simple module in the stack itself, ie Maybe this module should be called something like
I was thinking you would still call the config client and provisioner API yes. Using the entries as parameters I haven't really thought about...
To begin with I think we should just store the necessary info, ie the things that the node can't tell us. Not really sure what that invloves exactly though :p
I'm thinking that the "user" here is some sort of network admin that knows about model id's and such.
Good question. I assume you don't talk about subnets and I don't really understand how it would actually work when a device becomes part of two networks? Can a new network be created with the config client or must the device be provisioned again somehow? There's nothing preventing two networks from using the same NetKey indices so if a node can be part of two networks a NetKey index would not be enough to select a key so some other network index would be necessary. I'm thinking that a node on two different networks can be seen as two completely different nodes from a configurator perspective? Is it necessary to know that node X on network A is actually the same physical device as node Y on network B?
Yea that sounds right.
I don't think that would need to be part of the stack itself but could be a nice thing in some kind of helper library.
Actually my "endgame" is quite simple. I want to be able to provision and configure a node but I'm totally okay with doing it the way that is done in the configurator that you linked to. For simple use cases like having one type of node with one or two models I think that approach is fine (albeit I haven't done it yet :p).
TBH that was sort of what I was thinking that I would do in my application as well :O. I don't think that there is anything wrong with that but I can see that it could be nice to have a higher level API to ease the work a bit.
Sounds interesting, have you thought about what an API like that might look like? I guess you would need to be able to specify some kind of 'filters' and 'actions'?
That sounds like a quite advanced implementation. Do you mean something like:
Wouldn't it be possible to create some sort of data-centric API on top of the API that you have developed? |
I'm sorry, I think I used outdated terminology, I actually meant subnets. I agree with you, we don't need to keep track of a device's presence in multiple networks. Also, if the scope is just storing the stuff we need to know about the nodes, we probably just need to know the network index we want to use with the device key for configuration, like in your draft.
I made a prototype with this API over a year ago, but it ended up like more of a weekend project than anything. The application code for this API mirrors the composition data API pretty well, which is a big advantage 🙂 I didn't really see the need for an API between this one and the config client when I implemented it, but I didn't bring this all the way to a release, so I I think I'm derailing a bit here though, this first step should focus on the database module. The only thing I can think of that hasn't been mentioned yet is persistent storage. @jhedberg any comments on this RFC? |
Hey, sorry for the late answer. I've started doing some initial implementation and it seems to be pretty easy to separate the stack from the db at least. I've ran into some questions quite quickly though.
|
@tsvehagen I'd exclude this until someone comes with a really strong use case. Zephyr is intended for constrained devices, whereas multiple networks sounds like something you'd have on a more powerful system (e.g. something capable of running Linux).
I might not have done a very good job here... to me the difference is mainly in terms of perceived probability of success, i.e. find() implies a higher probability of the lookup failing, whereas get() means that it will likely succeed. That's without looking at the code though - it's possible this doesn't match reality, and I apologise for the inconsistency in that case. For new code I'd suggest to go with what feels most intuitive and we can then discuss it in the PR if there's disagreement.
At least in my mind alloc() is mainly for allocating the needed memory for the object, whereas create() is assumed to do more extensive initialisation as well. But again, I might not have been completely consistent with this. |
Please move the conversation to #21544 |
Introduction
The following is taken from the Bluetooth Mesh Profile specification, 3.10.1 Mesh Network Creation procedure
To create a mesh network, a Provisioner is required. A Provisioner shall generate a network key, provide an IV Index, and allocate a unicast address.
...
The Provisioner can then find unprovisioned devices by scanning for Unprovisioned Device beacons using active or passive scanning. The Provisioner can then provision these devices to become nodes within the mesh network. Once these nodes have been provisioned, the Configuration Client can then configure the nodes by providing them application keys and setting publish and subscribe addresses so that the nodes can communicate with each other.
As I can't find any term in the Mesh specification for the node that uses the Configuration Client, I will refer to it as the Configurator.
Problem description
Proposed change
Add a network management component that can be used by the Provisioner and Configurator. This component will be responsible for adding and providing access to all information that is needed to manage the network.
This management component should have no need for the local device to be provisioned and it should have no special handling for the local node.
Detailed RFC
The way that network information is stored today is in
struct bt_mesh_net
and related structures innet.c
. The way I see it is that the information stored in there are used for the local node, ie when the local device has been provisioned to a network.Since we would like to keep the local node data separate from the management data I suggest adding a
mgmt.c
andmgmt.h
. The interface and data structures will probably be quite similar to the ones innet.h
.I also suggest adding a public API that can be used by an application to get all the information needed to manage the network.
Proposed change (Detailed)
So this is just a very rough idea just to get the ball rolling.
The management API would need to include functions like add/remove/find/list for nodes, subnets and app keys.
The
struct bt_mesh_node
array instruct bt_mesh_net
should be removed and this interface should be used instead.The
struct bt_mesh_mgmt_node
could be extended to actually contain "all" the information about the node composition, e.g. all its models, subscriptions etc.Dependencies
Being a Provisioner or a Configurator would depend on having the network management code.
The provisioning code (
prov.c
) and some access code (access.c
) would probably need to be changed to use this new management API to store/ get nodes and keys.Concerns and Unresolved Questions
Alternatives
One alternative would be to have on module that the Provisioner uses and one that the Configurator uses. The reason why I think that it might be a good idea to share is that it seems that the Configurator actually needs almost everything that the Provisioner needs.
The text was updated successfully, but these errors were encountered: