zephyr/subsys/net/lib/lwm2m/lwm2m_obj_security.c

129 lines
3.9 KiB
C
Raw Normal View History

net: lwm2m: initial library support for LWM2M Origin: SICS-IoT / Contiki OS URL: https://github.com/sics-iot/lwm2m-contiki/tree/lwm2m-standalone-dtls commit: d07b0bcd77ec7e8b93787669507f3d86cfbea64a Purpose: Introduction of LwM2M client library. Maintained-by: Zephyr Lightweight Machine-to-Machine (LwM2M) is a protocol stack extension of the Constrained Application Protocol (CoAP) which uses UDP transmission packets. This library was based on source worked on by Joakim Eriksson, Niclas Finne and Joel Hoglund which was adopted by Contiki and then later revamped to work as a stand-alone library. A VERY high level summary of the changes made: - [ALL] sources were re-formatted to Zephyr coding standards - [engine] The engine portion was re-written due to the heavy reliance on ER-CoAP APIs which are not compatible to the Zephyr CoAP APIs as well as other Zephyr specific needs. - [engine] All LWM2M/IPSO object data is now abstracted into resource data which stores information like the data type, length, callbacks to help with read/write. The engine modifies this data directly (or makes callbacks) instead of all of the logic for this living in each object's code. (This wasn't scaling well as I was implementing changes). - [engine] Related to the above change, I also added a generic set of getter/setter functions that user applications can call to change the object data instead of having to add getter/setting methods in each object. - [engine] The original sources shared the engine's context structure quite extensively causing a problem with portability. I broke up the context into it's individual parts: LWM2M path data, input data and output data and pass only the needed data into each set of APIs. - [content format read/writer] sources were re-organized into single .c/h files per content formatter. - [content format read/writer] sources were re-written where necessary to remove the sharing of the lwm2m engine's context and instead only requires the path and input or output data specific to it's function. - [LwM2M objects] re-written using the new engine's abstractions Signed-off-by: Michael Scott <michael.scott@linaro.org>
2017-07-08 02:04:03 +08:00
/*
* Copyright (c) 2017 Linaro Limited
*
* SPDX-License-Identifier: Apache-2.0
*/
#define SYS_LOG_DOMAIN "lwm2m_obj_security"
#define SYS_LOG_LEVEL CONFIG_SYS_LOG_LWM2M_LEVEL
#include <logging/sys_log.h>
#include <stdint.h>
#include <init.h>
#include "lwm2m_object.h"
#include "lwm2m_engine.h"
/* Security resource IDs */
#define SECURITY_SERVER_URI_ID 0
#define SECURITY_BOOTSTRAP_FLAG_ID 1
#define SECURITY_MODE_ID 2
#define SECURITY_CLIENT_PK_ID 3
#define SECURITY_SERVER_PK_ID 4
#define SECURITY_SECRET_KEY_ID 5
#define SECURITY_SHORT_SERVER_ID 10
#define SECURITY_MAX_ID 7
#define MAX_INSTANCE_COUNT CONFIG_LWM2M_SECURITY_INSTANCE_COUNT
#define SECURITY_URI_LEN 255
/* resource state variables */
static char security_uri[MAX_INSTANCE_COUNT][SECURITY_URI_LEN];
static bool bootstrap_flag[MAX_INSTANCE_COUNT];
static u8_t security_mode[MAX_INSTANCE_COUNT];
static u16_t short_server_id[MAX_INSTANCE_COUNT];
static struct lwm2m_engine_obj security;
static struct lwm2m_engine_obj_field fields[] = {
OBJ_FIELD_DATA(SECURITY_SERVER_URI_ID, RW, STRING),
OBJ_FIELD_DATA(SECURITY_BOOTSTRAP_FLAG_ID, W, BOOL),
OBJ_FIELD_DATA(SECURITY_MODE_ID, W, U8),
OBJ_FIELD_DATA(SECURITY_CLIENT_PK_ID, W, OPAQUE), /* TODO */
OBJ_FIELD_DATA(SECURITY_SERVER_PK_ID, W, OPAQUE), /* TODO */
OBJ_FIELD_DATA(SECURITY_SECRET_KEY_ID, W, OPAQUE), /* TODO */
OBJ_FIELD_DATA(SECURITY_SHORT_SERVER_ID, W, U16) /* TODO */
};
static struct lwm2m_engine_obj_inst inst[MAX_INSTANCE_COUNT];
static struct lwm2m_engine_res_inst res[MAX_INSTANCE_COUNT][SECURITY_MAX_ID];
static struct lwm2m_engine_obj_inst *security_create(u16_t obj_inst_id)
{
int index, i = 0;
/* Check that there is no other instance with this ID */
for (index = 0; index < MAX_INSTANCE_COUNT; index++) {
if (inst[index].obj && inst[index].obj_inst_id == obj_inst_id) {
SYS_LOG_ERR("Can not create instance - "
"already existing: %u", obj_inst_id);
return NULL;
}
}
for (index = 0; index < MAX_INSTANCE_COUNT; index++) {
if (!inst[index].obj) {
break;
}
}
if (index >= MAX_INSTANCE_COUNT) {
SYS_LOG_ERR("Can not create instance - "
"no more room: %u", obj_inst_id);
return NULL;
}
/* default values */
security_uri[index][0] = '\0';
bootstrap_flag[index] = 0;
security_mode[index] = 0;
short_server_id[index] = 0;
/* initialize instance resource data */
INIT_OBJ_RES_DATA(res[index], i, SECURITY_SERVER_URI_ID,
security_uri[index], SECURITY_URI_LEN);
INIT_OBJ_RES_DATA(res[index], i, SECURITY_BOOTSTRAP_FLAG_ID,
&bootstrap_flag[index], sizeof(*bootstrap_flag));
INIT_OBJ_RES_DATA(res[index], i, SECURITY_MODE_ID,
&security_mode[index], sizeof(*security_mode));
/* TODO: */
INIT_OBJ_RES_DUMMY(res[index], i, SECURITY_CLIENT_PK_ID);
INIT_OBJ_RES_DUMMY(res[index], i, SECURITY_SERVER_PK_ID),
INIT_OBJ_RES_DUMMY(res[index], i, SECURITY_SECRET_KEY_ID),
INIT_OBJ_RES_DATA(res[index], i, SECURITY_SHORT_SERVER_ID,
&short_server_id[index], sizeof(*short_server_id));
inst[index].resources = res[index];
inst[index].resource_count = i;
SYS_LOG_DBG("Create LWM2M security instance: %d", obj_inst_id);
return &inst[index];
}
static int lwm2m_security_init(struct device *dev)
{
struct lwm2m_engine_obj_inst *obj_inst = NULL;
int ret = 0;
/* Set default values */
memset(inst, 0, sizeof(*inst) * MAX_INSTANCE_COUNT);
memset(res, 0, sizeof(struct lwm2m_engine_res_inst) *
MAX_INSTANCE_COUNT * SECURITY_MAX_ID);
security.obj_id = LWM2M_OBJECT_SECURITY_ID;
security.fields = fields;
security.field_count = sizeof(fields) / sizeof(*fields);
security.max_instance_count = MAX_INSTANCE_COUNT;
security.create_cb = security_create;
lwm2m_register_obj(&security);
/* auto create the first instance */
ret = lwm2m_create_obj_inst(LWM2M_OBJECT_SECURITY_ID, 0, &obj_inst);
if (ret < 0) {
SYS_LOG_ERR("Create LWM2M security instance 0 error: %d", ret);
}
return ret;
}
SYS_INIT(lwm2m_security_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);