1 /*
2  * Copyright (c) 2022 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define LOG_MODULE_NAME net_lwm2m_obj_portfolio
8 #define LOG_LEVEL CONFIG_LWM2M_LOG_LEVEL
9 
10 #include <zephyr/logging/log.h>
11 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
12 
13 #include <stdint.h>
14 #include <zephyr/init.h>
15 
16 #include "lwm2m_object.h"
17 #include "lwm2m_engine.h"
18 #include "lwm2m_resource_ids.h"
19 
20 #define PORTFOLIO_VERSION_MAJOR 1
21 #define PORTFOLIO_VERSION_MINOR 0
22 
23 #define PORTFOLIO_IDENTITY_ID			0
24 #define PORTFOLIO_GET_AUTH_DATA_ID		1
25 #define PORTFOLIO_AUTH_DATA_ID			2
26 #define PORTFOLIO_AUTH_STATUS_ID		3
27 
28 #define PORTFOLIO_MAX_ID 4
29 
30 /* Identity max based on LwM2M v1.1 conformance test requirements */
31 #define PORTFOLIO_IDENTITY_MAX 4
32 #define PORTFOLIO_AUTH_DATA_MAX 4
33 /* Support 2 multi instance object */
34 #define MAX_INSTANCE_COUNT	2
35 
36 /* Default Identity buffer length 40 */
37 #define DEFAULT_IDENTITY_BUFFER_LENGTH 40
38 
39 /*
40  * Calculate resource instances as follows:
41  * start with PORTFOLIO_MAX_ID
42  * subtract MULTI resources and execute because their counts include 0 resource (3)
43  * add PORTFOLIO_IDENTITY_ID resource instances
44  * add PORTFOLIO_AUTH_DATA_ID resource instances
45  */
46 #define RESOURCE_INSTANCE_COUNT        (PORTFOLIO_MAX_ID - 3 + \
47 					PORTFOLIO_IDENTITY_MAX + \
48 					PORTFOLIO_AUTH_DATA_MAX)
49 
50 static struct lwm2m_engine_obj portfolio;
51 static struct lwm2m_engine_obj_field fields[] = {
52 	OBJ_FIELD_DATA(PORTFOLIO_IDENTITY_ID, RW, STRING), /* Mandatory, multi-instance */
53 	OBJ_FIELD_EXECUTE(PORTFOLIO_GET_AUTH_DATA_ID), /* Optional, single-instance */
54 	OBJ_FIELD_DATA(PORTFOLIO_AUTH_DATA_ID, R_OPT, OPAQUE), /* Optional, multi-instance */
55 	OBJ_FIELD_DATA(PORTFOLIO_AUTH_STATUS_ID, R_OPT, U8) /* Optional, single-instance*/
56 };
57 
58 
59 static struct lwm2m_engine_obj_inst inst[MAX_INSTANCE_COUNT];
60 static struct lwm2m_engine_res res[MAX_INSTANCE_COUNT][PORTFOLIO_MAX_ID];
61 static struct lwm2m_engine_res_inst res_inst[MAX_INSTANCE_COUNT][RESOURCE_INSTANCE_COUNT];
62 static char identity[MAX_INSTANCE_COUNT][PORTFOLIO_IDENTITY_MAX][DEFAULT_IDENTITY_BUFFER_LENGTH];
63 
portfolio_create(uint16_t obj_inst_id)64 static struct lwm2m_engine_obj_inst *portfolio_create(uint16_t obj_inst_id)
65 {
66 	int index, avail = -1, i = 0, j = 0;
67 
68 	/* Check that there is no other instance with this ID */
69 	for (index = 0; index < ARRAY_SIZE(inst); index++) {
70 		if (inst[index].obj && inst[index].obj_inst_id == obj_inst_id) {
71 			LOG_ERR("Can not create instance - "
72 				"already existing: %u",
73 				obj_inst_id);
74 			return NULL;
75 		}
76 
77 		/* Save first available slot index */
78 		if (avail < 0 && !inst[index].obj) {
79 			avail = index;
80 		}
81 	}
82 
83 	if (avail < 0) {
84 		LOG_ERR("Can not create instance - no more room: %u", obj_inst_id);
85 		return NULL;
86 	}
87 
88 	(void)memset(res[avail], 0, sizeof(res[avail][0]) * ARRAY_SIZE(res[avail]));
89 	(void)memset(identity[avail], 0, DEFAULT_IDENTITY_BUFFER_LENGTH);
90 
91 	init_res_instance(res_inst[avail], ARRAY_SIZE(res_inst[avail]));
92 
93 	/* initialize instance resource data */
94 	INIT_OBJ_RES_MULTI_DATA_LEN(PORTFOLIO_IDENTITY_ID, res[avail], i, res_inst[avail], j,
95 				    PORTFOLIO_IDENTITY_MAX, false, identity[avail],
96 				    DEFAULT_IDENTITY_BUFFER_LENGTH, 0);
97 	INIT_OBJ_RES_EXECUTE(PORTFOLIO_GET_AUTH_DATA_ID, res[avail], i, NULL);
98 	INIT_OBJ_RES_MULTI_OPTDATA(PORTFOLIO_AUTH_DATA_ID, res[avail], i, res_inst[avail], j,
99 				   PORTFOLIO_AUTH_DATA_MAX, false);
100 	INIT_OBJ_RES_OPTDATA(PORTFOLIO_AUTH_STATUS_ID, res[avail], i, res_inst[avail], j);
101 
102 	inst[avail].resources = res[avail];
103 	inst[avail].resource_count = i;
104 
105 	LOG_DBG("Create LwM2M Portfolio instance: %d", obj_inst_id);
106 
107 	return &inst[avail];
108 }
109 
lwm2m_portfolio_init(void)110 static int lwm2m_portfolio_init(void)
111 {
112 	portfolio.obj_id = LWM2M_OBJECT_PORTFOLIO_ID;
113 	portfolio.version_major = PORTFOLIO_VERSION_MAJOR;
114 	portfolio.version_minor = PORTFOLIO_VERSION_MINOR;
115 	portfolio.is_core = false;
116 	portfolio.fields = fields;
117 	portfolio.field_count = ARRAY_SIZE(fields);
118 	portfolio.max_instance_count = MAX_INSTANCE_COUNT;
119 	portfolio.create_cb = portfolio_create;
120 	lwm2m_register_obj(&portfolio);
121 
122 	return 0;
123 }
124 
125 LWM2M_OBJ_INIT(lwm2m_portfolio_init);
126