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, indentity_buffer_start = 0;
67
68 /* Check that there is no other instance with this ID */
69 for (index = 0; index < ARRAY_SIZE(inst); index++) {
70 if (index) {
71 indentity_buffer_start += PORTFOLIO_IDENTITY_MAX;
72 }
73 if (inst[index].obj && inst[index].obj_inst_id == obj_inst_id) {
74 LOG_ERR("Can not create instance - "
75 "already existing: %u",
76 obj_inst_id);
77 return NULL;
78 }
79
80 /* Save first available slot index */
81 if (avail < 0 && !inst[index].obj) {
82 avail = index;
83 }
84 }
85
86 if (avail < 0) {
87 LOG_ERR("Can not create instance - no more room: %u", obj_inst_id);
88 return NULL;
89 }
90
91 (void)memset(res[avail], 0, sizeof(res[avail][0]) * ARRAY_SIZE(res[avail]));
92 (void)memset(identity[avail], 0, DEFAULT_IDENTITY_BUFFER_LENGTH);
93
94 init_res_instance(res_inst[avail], ARRAY_SIZE(res_inst[avail]));
95
96 /* initialize instance resource data */
97 INIT_OBJ_RES_MULTI_DATA_LEN(PORTFOLIO_IDENTITY_ID, res[avail], i, res_inst[avail], j,
98 PORTFOLIO_IDENTITY_MAX, false, identity[indentity_buffer_start],
99 DEFAULT_IDENTITY_BUFFER_LENGTH, 0);
100 INIT_OBJ_RES_EXECUTE(PORTFOLIO_GET_AUTH_DATA_ID, res[avail], i, NULL);
101 INIT_OBJ_RES_MULTI_OPTDATA(PORTFOLIO_AUTH_DATA_ID, res[avail], i, res_inst[avail], j,
102 PORTFOLIO_AUTH_DATA_MAX, false);
103 INIT_OBJ_RES_OPTDATA(PORTFOLIO_AUTH_STATUS_ID, res[avail], i, res_inst[avail], j);
104
105 inst[avail].resources = res[avail];
106 inst[avail].resource_count = i;
107
108 LOG_DBG("Create LwM2M Portfolio instance: %d", obj_inst_id);
109
110 return &inst[avail];
111 }
112
lwm2m_portfolio_init(void)113 static int lwm2m_portfolio_init(void)
114 {
115 portfolio.obj_id = LWM2M_OBJECT_PORTFOLIO_ID;
116 portfolio.version_major = PORTFOLIO_VERSION_MAJOR;
117 portfolio.version_minor = PORTFOLIO_VERSION_MINOR;
118 portfolio.is_core = false;
119 portfolio.fields = fields;
120 portfolio.field_count = ARRAY_SIZE(fields);
121 portfolio.max_instance_count = MAX_INSTANCE_COUNT;
122 portfolio.create_cb = portfolio_create;
123 lwm2m_register_obj(&portfolio);
124
125 return 0;
126 }
127
128 SYS_INIT(lwm2m_portfolio_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
129