net: lwm2m: Rework bootstrap DELETE operation
Rework the bootstrap DELETE operation, to support deletion of multiple resources. Current implementation had several oversimplifications, making it not spec-compliant: * DELETE `/` removed only Security object instances (!= 0) * DELETE `/x` was handled as DELETE `/x/0`, therefore not removing all of the object instances. Since the above is only supported during bootstrap and not regular Device management, this functionality was implemented in the `bootstrap_delete` function, which now will be called for all DELETE operations initiated during bootstrap. The regular LwM2M DELETE handler will only be called during regular Device management, as it has more strict limitations on what can be deleted. Additionally, handle empty URI Path option as `/`, therefore indicating deletion of all resources. Fixes #29964 Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
parent
03ce61004b
commit
1c8f52a670
1 changed files with 97 additions and 26 deletions
|
@ -2842,9 +2842,17 @@ static int lwm2m_delete_handler(struct lwm2m_message *msg)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Device management interface is not allowed to delete Security and
|
||||||
|
* Device objects instances.
|
||||||
|
*/
|
||||||
|
if (msg->path.obj_id == LWM2M_OBJECT_SECURITY_ID ||
|
||||||
|
msg->path.obj_id == LWM2M_OBJECT_DEVICE_ID) {
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
ret = lwm2m_delete_obj_inst(msg->path.obj_id, msg->path.obj_inst_id);
|
ret = lwm2m_delete_obj_inst(msg->path.obj_id, msg->path.obj_inst_id);
|
||||||
#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT)
|
#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT)
|
||||||
if (!ret && !msg->ctx->bootstrap_mode) {
|
if (!ret) {
|
||||||
engine_trigger_update(true);
|
engine_trigger_update(true);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -3282,21 +3290,74 @@ static int do_write_op(struct lwm2m_message *msg,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
|
#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
|
||||||
static int bootstrap_delete(void)
|
static bool bootstrap_delete_allowed(int obj_id, int obj_inst_id)
|
||||||
|
{
|
||||||
|
char pathstr[MAX_RESOURCE_LEN];
|
||||||
|
bool bootstrap_server;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (obj_id == LWM2M_OBJECT_SECURITY_ID) {
|
||||||
|
snprintk(pathstr, sizeof(pathstr), "%d/%d/1",
|
||||||
|
LWM2M_OBJECT_SECURITY_ID, obj_inst_id);
|
||||||
|
ret = lwm2m_engine_get_bool(pathstr, &bootstrap_server);
|
||||||
|
if (ret < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bootstrap_server) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj_id == LWM2M_OBJECT_DEVICE_ID) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int bootstrap_delete(struct lwm2m_message *msg)
|
||||||
{
|
{
|
||||||
struct lwm2m_engine_obj_inst *obj_inst, *tmp;
|
struct lwm2m_engine_obj_inst *obj_inst, *tmp;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* delete SECURITY instances > 0 */
|
if (msg->path.level > 2) {
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg->path.level == 2) {
|
||||||
|
if (!bootstrap_delete_allowed(msg->path.obj_id,
|
||||||
|
msg->path.obj_inst_id)) {
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lwm2m_delete_obj_inst(msg->path.obj_id,
|
||||||
|
msg->path.obj_inst_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DELETE all instances of a specific object or all object instances if
|
||||||
|
* not specified, excluding the following exceptions (according to the
|
||||||
|
* LwM2M specification v1.0.2, ch 5.2.7.5):
|
||||||
|
* - LwM2M Bootstrap-Server Account (Bootstrap Security object, ID 0)
|
||||||
|
* - Device object (ID 3)
|
||||||
|
*/
|
||||||
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&engine_obj_inst_list,
|
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&engine_obj_inst_list,
|
||||||
obj_inst, tmp, node) {
|
obj_inst, tmp, node) {
|
||||||
if (obj_inst->obj->obj_id == LWM2M_OBJECT_SECURITY_ID &&
|
if (msg->path.level == 1 &&
|
||||||
obj_inst->obj_inst_id > 0) {
|
obj_inst->obj->obj_id != msg->path.obj_id) {
|
||||||
ret = lwm2m_delete_obj_inst(obj_inst->obj->obj_id,
|
continue;
|
||||||
obj_inst->obj_inst_id);
|
}
|
||||||
if (ret < 0) {
|
|
||||||
return ret;
|
if (!bootstrap_delete_allowed(obj_inst->obj->obj_id,
|
||||||
}
|
obj_inst->obj_inst_id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = lwm2m_delete_obj_inst(obj_inst->obj->obj_id,
|
||||||
|
obj_inst->obj_inst_id);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3343,27 +3404,30 @@ static int handle_request(struct coap_packet *request,
|
||||||
/* parse the URL path into components */
|
/* parse the URL path into components */
|
||||||
r = coap_find_options(msg->in.in_cpkt, COAP_OPTION_URI_PATH, options,
|
r = coap_find_options(msg->in.in_cpkt, COAP_OPTION_URI_PATH, options,
|
||||||
ARRAY_SIZE(options));
|
ARRAY_SIZE(options));
|
||||||
if (r <= 0) {
|
if (r < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Treat empty URI path option as is there were no option - this will be
|
||||||
|
* represented as a level "zero" in the path structure.
|
||||||
|
*/
|
||||||
|
if (r == 1 && options[0].len == 0) {
|
||||||
|
r = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r == 0) {
|
||||||
|
/* No URI path or empty URI path option - allowed only during
|
||||||
|
* bootstrap.
|
||||||
|
*/
|
||||||
switch (code & COAP_REQUEST_MASK) {
|
switch (code & COAP_REQUEST_MASK) {
|
||||||
#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
|
#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
|
||||||
case COAP_METHOD_DELETE:
|
case COAP_METHOD_DELETE:
|
||||||
if (msg->ctx->bootstrap_mode) {
|
if (msg->ctx->bootstrap_mode) {
|
||||||
r = bootstrap_delete();
|
break;
|
||||||
if (r < 0) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg->code = COAP_RESPONSE_CODE_DELETED;
|
|
||||||
r = lwm2m_init_message(msg);
|
|
||||||
} else {
|
|
||||||
r = -EPERM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r < 0) {
|
r = -EPERM;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
r = -EPERM;
|
r = -EPERM;
|
||||||
|
@ -3431,7 +3495,8 @@ static int handle_request(struct coap_packet *request,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!well_known) {
|
if (!well_known && !(msg->ctx->bootstrap_mode &&
|
||||||
|
msg->path.level == 0)) {
|
||||||
/* find registered obj */
|
/* find registered obj */
|
||||||
obj = get_engine_obj(msg->path.obj_id);
|
obj = get_engine_obj(msg->path.obj_id);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
|
@ -3630,6 +3695,12 @@ static int handle_request(struct coap_packet *request,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LWM2M_OP_DELETE:
|
case LWM2M_OP_DELETE:
|
||||||
|
#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
|
||||||
|
if (msg->ctx->bootstrap_mode) {
|
||||||
|
r = bootstrap_delete(msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
r = lwm2m_delete_handler(msg);
|
r = lwm2m_delete_handler(msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue