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

Add Mcumgr handlers for group enumeration #70704

Closed

Conversation

hsearle
Copy link
Contributor

@hsearle hsearle commented Mar 25, 2024

Mcumgr currently has no method of enumerating all registered groups. This commit adds that capability, as well as adding a separate Mcumgr group for retrieving this information.

Mcumgr currently has no method of enumerating all registered groups.
This commit adds that capability, as well as adding a separate Mcumgr
group for retrieving this information.

Signed-off-by: Hunter Searle <[email protected]>
@hsearle hsearle force-pushed the mcumgr_add_enumeration_group branch from 006f433 to 976432a Compare March 25, 2024 22:19
subsys/mgmt/mcumgr/grp/enum_mgmt/src/enum_mgmt.c Outdated Show resolved Hide resolved
include/zephyr/mgmt/mcumgr/grp/enum_mgmt/enum_mgmt.h Outdated Show resolved Hide resolved
include/zephyr/mgmt/mcumgr/grp/enum_mgmt/enum_mgmt.h Outdated Show resolved Hide resolved
subsys/mgmt/mcumgr/grp/enum_mgmt/src/enum_mgmt.c Outdated Show resolved Hide resolved
subsys/mgmt/mcumgr/grp/enum_mgmt/src/enum_mgmt.c Outdated Show resolved Hide resolved
subsys/mgmt/mcumgr/grp/enum_mgmt/src/enum_mgmt.c Outdated Show resolved Hide resolved
Comment on lines 147 to 159
int mgmt_get_group_ids(int *ids)
{
int count = 0;
sys_snode_t *snp, *sns;

SYS_SLIST_FOR_EACH_NODE_SAFE(&mgmt_group_list, snp, sns) {
struct mgmt_group *loop_group =
CONTAINER_OF(snp, struct mgmt_group, node);
ids[count] = loop_group->mg_group_id;
count++;
}
return count;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should call a callback instead so that the memory usage is bounded not unbounded which is the zephyr way of doing this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not fully understanding your comment here. I get that using a callback instead of a direct function call could be more of the zephyr way, but how does it change whether the memory usage is bounded or unbounded? Either way, to get all group IDs, we need to iterate through the whole mgmt_group_list array.

Copy link
Collaborator

@nordicjm nordicjm Mar 27, 2024

Choose a reason for hiding this comment

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

If you have 3 groups, this returns 3 and your code creates a stack variable of size 3*4 = 12 bytes. If you have 200 groups, this returns 200 and your code creates a stack variable of size 200*4 = 800 bytes, thus it is unbounded.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I understand that, but I'm not clear how moving to a callback implementation would cause the memory to be bounded. If we want a list of all group ids, no matter how we retrieve it, that will inherently be unbounded by the number of groups in the system.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Not true, each callback occupies the same amount of stack space, if you are appending data to the response buffer then that is a pre-defined buffer of a certain size (or multiple if fragmented) so nothing is unbounded. See https://github.com/zephyrproject-rtos/zephyr/blob/main/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c#L338 for an example

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, if I'm understanding correctly, I need to introduce a variable that caps the number of groups that can be returned, and if there are more groups registered than the variable allows, this command will just return an error?

Copy link
Collaborator

@nordicjm nordicjm Apr 2, 2024

Choose a reason for hiding this comment

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

No? The callback is called for every entry. If in the callback in your .c which adds the groups to the response cannot add any more then that needs to return an SMP error

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are still errors to work out, but do you think that my updated approach is acceptable? Or, am I at least getting closer?

subsys/mgmt/mcumgr/grp/enum_mgmt/src/enum_mgmt.c Outdated Show resolved Hide resolved
subsys/mgmt/mcumgr/grp/enum_mgmt/Kconfig Outdated Show resolved Hide resolved
subsys/mgmt/mcumgr/grp/enum_mgmt/Kconfig Outdated Show resolved Hide resolved
@nordicjm
Copy link
Collaborator

count = sys_slist_len(groups);

ok = zcbor_tstr_put_lit(zse, "groups") &&
zcbor_list_start_encode(zse, count);
Copy link
Collaborator

Choose a reason for hiding this comment

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

count needs to be more e.g. if canonical mode is enabled

*
* @return Pointer to list of registered groups
*/
sys_slist_t *mgmt_get_group_list();
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should be a function that calls a callback multiple times, once per group, and returns the group object, it should not be just returning a list directly or using sys_slist_t when the type should be the mgmt_group type (should also be const in the callback)

Comment on lines +24 to +26
#define ENUMERATION_MGMT_LIST 0
#define ENUMERATION_MGMT_GP_ID 10

Copy link
Collaborator

Choose a reason for hiding this comment

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

.h file

@@ -29,7 +30,7 @@ static sys_slist_t mgmt_callback_list =
void
mgmt_unregister_group(struct mgmt_group *group)
{
(void)sys_slist_find_and_remove(&mgmt_group_list, &group->node);
sys_slist_find_and_remove(&mgmt_group_list, &group->node);
Copy link
Collaborator

Choose a reason for hiding this comment

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

??

@hsearle
Copy link
Contributor Author

hsearle commented Apr 8, 2024

My work focus is shifting away from Zephyr, so I'm going to close out this PR. If someone else sees value in this change and wants to move the work forward, please do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants