zephyr/subsys/net/lib/lwm2m/ucifi_lpwan.c
Seppo Takalo ec3ec8cd2a net: lwm2m: Add LWM2M_ON_INIT() macro
Add macro that allows registration of initialization functions that
are called when LwM2M engine starts.

On LwM2M engine starts up, it first executes all initialization
functions in following priority order:
1. LWM2M_PRIO_ENGINE
2. LWM2M_PRIO_CORE, this is where all LwM2M core objects are initialized
3. LWM2M_PRIO_OBJ, this is where all other objects are initialized
4. LwM2M_PRIO_APP, application initialization.

Now on the initialization phase, we could rely that certain objects have
already been registered.
For example custom objects can register callbacks to core objects.
On application phase, we can initialize sensor objects and register
their callbacks because objects have already been initialized.

This LWM2M_ON_INIT() should replace all use of SYS_INIT()
with the default CONFIG_KERNEL_INIT_PRIORITY_DEFAULT.

Priority order is actually just alphabetical order of names, so
the order is set on a linkin phase, and we don't need any
runtime checking for it.

Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
2024-01-24 10:44:28 +01:00

182 lines
7.9 KiB
C

/*
* Copyright (c) 2022 FTP Technologies
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Source material for uCIFI LPWAN object (3412):
* https://raw.githubusercontent.com/OpenMobileAlliance/lwm2m-registry/prod/3412.xml
*/
#define LOG_MODULE_NAME net_ucifi_lpwan
#define LOG_LEVEL CONFIG_LWM2M_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include <stdio.h>
#include <string.h>
#include <zephyr/init.h>
#include "lwm2m_object.h"
#include "lwm2m_engine.h"
#include "ucifi_lpwan.h"
#define LPWAN_VERSION_MAJOR 1
#define LPWAN_VERSION_MINOR 0
/* clang-format off */
#define MAX_INSTANCE_COUNT CONFIG_LWM2M_UCIFI_LPWAN_INSTANCE_COUNT
#define IPV4_ADDRESS_MAX CONFIG_LWM2M_UCIFI_LPWAN_IPV4_ADDRESS_MAX
#define IPV6_ADDRESS_MAX CONFIG_LWM2M_UCIFI_LPWAN_IPV6_ADDRESS_MAX
#define NETWORK_ADDRESS_MAX CONFIG_LWM2M_UCIFI_LPWAN_NETWORK_ADDRESS_MAX
#define SECONDARY_NETWORK_ADDRESS_MAX CONFIG_LWM2M_UCIFI_LPWAN_SECONDARY_NETWORK_ADDRESS_MAX
#define PEER_ADDRESS_MAX CONFIG_LWM2M_UCIFI_LPWAN_PEER_ADDRESS_MAX
#define MULTICAST_GRP_ADDRESS_MAX CONFIG_LWM2M_UCIFI_LPWAN_MULTICAST_GRP_ADDRESS_MAX
#define MULTICAST_GRP_KEY_MAX CONFIG_LWM2M_UCIFI_LPWAN_MULTICAST_GRP_KEY_MAX
/* clang-format on */
/*
* Calculate resource instances as follows:
* start with UCIFI_LPWAN_MAX_RID
* subtract EXEC resources (0)
* subtract MULTI resources because their counts include 0 resource (7)
* add UCIFI_LPWAN_IPV4_ADDRESS_RID resource instances
* add UCIFI_LPWAN_IPV6_ADDRESS_RID resource instances
* add UCIFI_LPWAN_NETWORK_ADDRESS_RID resource instances
* add UCIFI_LPWAN_SECONDARY_ADDRESS_RID resource instances
* add UCIFI_LPWAN_PEER_ADDRESS_RID resource instances
* add UCIFI_LPWAN_MULTICAST_GRP_ADDRESS_RID resource instances
* add UCIFI_LPWAN_MULTICAST_GRP_KEY_RID resource instances
*/
#define NUMBER_EXEC_RESOURCES 0
#define NUMBER_MULTI_RESOURCES 7
#define RESOURCE_INSTANCE_COUNT \
(UCIFI_LPWAN_MAX_RID - NUMBER_EXEC_RESOURCES - NUMBER_MULTI_RESOURCES + IPV4_ADDRESS_MAX + \
IPV6_ADDRESS_MAX + NETWORK_ADDRESS_MAX + SECONDARY_NETWORK_ADDRESS_MAX + \
PEER_ADDRESS_MAX + MULTICAST_GRP_ADDRESS_MAX + MULTICAST_GRP_KEY_MAX)
static struct lwm2m_engine_obj lpwan;
static struct lwm2m_engine_obj_field fields[] = {
OBJ_FIELD_DATA(UCIFI_LPWAN_NETWORK_TYPE_RID, R_OPT, STRING),
OBJ_FIELD_DATA(UCIFI_LPWAN_IPV4_ADDRESS_RID, RW_OPT, STRING),
OBJ_FIELD_DATA(UCIFI_LPWAN_IPV6_ADDRESS_RID, RW_OPT, STRING),
OBJ_FIELD_DATA(UCIFI_LPWAN_NETWORK_ADDRESS_RID, RW_OPT, STRING),
OBJ_FIELD_DATA(UCIFI_LPWAN_SECONDARY_ADDRESS_RID, RW_OPT, STRING),
OBJ_FIELD_DATA(UCIFI_LPWAN_MAC_ADDRESS_RID, RW, STRING),
OBJ_FIELD_DATA(UCIFI_LPWAN_PEER_ADDRESS_RID, R_OPT, STRING),
OBJ_FIELD_DATA(UCIFI_LPWAN_MULTICAST_GRP_ADDRESS_RID, RW_OPT, STRING),
OBJ_FIELD_DATA(UCIFI_LPWAN_MULTICAST_GRP_KEY_RID, RW_OPT, STRING),
OBJ_FIELD_DATA(UCIFI_LPWAN_DATA_RATE_RID, RW_OPT, INT),
OBJ_FIELD_DATA(UCIFI_LPWAN_TRANSMIT_POWER_RID, R_OPT, FLOAT),
OBJ_FIELD_DATA(UCIFI_LPWAN_FREQUENCY_RID, RW_OPT, FLOAT),
OBJ_FIELD_DATA(UCIFI_LPWAN_SESSION_TIME_RID, RW_OPT, TIME),
OBJ_FIELD_DATA(UCIFI_LPWAN_SESSION_DURATION_RID, R_OPT, TIME),
OBJ_FIELD_DATA(UCIFI_LPWAN_MESH_NODE_RID, RW_OPT, BOOL),
OBJ_FIELD_DATA(UCIFI_LPWAN_MAX_REPEAT_TIME_RID, RW_OPT, INT),
OBJ_FIELD_DATA(UCIFI_LPWAN_NUMBER_REPEATS_RID, R_OPT, INT),
OBJ_FIELD_DATA(UCIFI_LPWAN_SIGNAL_NOISE_RATIO_RID, R_OPT, FLOAT),
OBJ_FIELD_DATA(UCIFI_LPWAN_COMM_FAILURE_RID, R_OPT, BOOL),
OBJ_FIELD_DATA(UCIFI_LPWAN_RSSI_RID, R_OPT, FLOAT),
OBJ_FIELD_DATA(UCIFI_LPWAN_IMSI_RID, R_OPT, STRING),
OBJ_FIELD_DATA(UCIFI_LPWAN_IMEI_RID, R_OPT, STRING),
OBJ_FIELD_DATA(UCIFI_LPWAN_COMM_OPERATOR_RID, R_OPT, STRING),
OBJ_FIELD_DATA(UCIFI_LPWAN_IC_CARD_IDENTIFIER_RID, R_OPT, STRING),
};
static struct lwm2m_engine_obj_inst inst[MAX_INSTANCE_COUNT];
static struct lwm2m_engine_res res[MAX_INSTANCE_COUNT][UCIFI_LPWAN_MAX_RID];
static struct lwm2m_engine_res_inst res_inst[MAX_INSTANCE_COUNT][RESOURCE_INSTANCE_COUNT];
/* resource state variables */
static char mac[MAX_INSTANCE_COUNT][MAC_ADDRESS_SIZE];
static struct lwm2m_engine_obj_inst *lpwan_create(uint16_t obj_inst_id)
{
int index, i = 0, j = 0;
/* Check that there is no other instance with this ID */
for (index = 0; index < MAX_INSTANCE_COUNT; index++) {
if ((inst[index].obj != NULL) && (inst[index].obj_inst_id == obj_inst_id)) {
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 == NULL) {
break;
}
}
if (index >= MAX_INSTANCE_COUNT) {
LOG_ERR("Can not create instance - no more room: %u", obj_inst_id);
return NULL;
}
/* Reset to uninitialised values */
(void)memset(res[index], 0, sizeof(res[index]));
mac[index][0] = '\0';
init_res_instance(res_inst[index], ARRAY_SIZE(res_inst[index]));
/* initialize instance resource data */
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_NETWORK_TYPE_RID, res[index], i, res_inst[index], j);
INIT_OBJ_RES_MULTI_OPTDATA(UCIFI_LPWAN_IPV4_ADDRESS_RID, res[index], i, res_inst[index], j,
IPV4_ADDRESS_MAX, false);
INIT_OBJ_RES_MULTI_OPTDATA(UCIFI_LPWAN_IPV6_ADDRESS_RID, res[index], i, res_inst[index], j,
IPV6_ADDRESS_MAX, false);
INIT_OBJ_RES_MULTI_OPTDATA(UCIFI_LPWAN_NETWORK_ADDRESS_RID, res[index], i, res_inst[index],
j, NETWORK_ADDRESS_MAX, false);
INIT_OBJ_RES_MULTI_OPTDATA(UCIFI_LPWAN_SECONDARY_ADDRESS_RID, res[index], i,
res_inst[index], j, SECONDARY_NETWORK_ADDRESS_MAX, false);
INIT_OBJ_RES_DATA_LEN(UCIFI_LPWAN_MAC_ADDRESS_RID, res[index], i, res_inst[index], j,
mac[index], MAC_ADDRESS_SIZE, 0);
INIT_OBJ_RES_MULTI_OPTDATA(UCIFI_LPWAN_PEER_ADDRESS_RID, res[index], i, res_inst[index], j,
PEER_ADDRESS_MAX, false);
INIT_OBJ_RES_MULTI_OPTDATA(UCIFI_LPWAN_MULTICAST_GRP_ADDRESS_RID, res[index], i,
res_inst[index], j, MULTICAST_GRP_ADDRESS_MAX, false);
INIT_OBJ_RES_MULTI_OPTDATA(UCIFI_LPWAN_MULTICAST_GRP_KEY_RID, res[index], i,
res_inst[index], j, MULTICAST_GRP_KEY_MAX, false);
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_DATA_RATE_RID, res[index], i, res_inst[index], j);
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_TRANSMIT_POWER_RID, res[index], i, res_inst[index], j);
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_FREQUENCY_RID, res[index], i, res_inst[index], j);
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_SESSION_TIME_RID, res[index], i, res_inst[index], j);
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_SESSION_DURATION_RID, res[index], i, res_inst[index], j);
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_MESH_NODE_RID, res[index], i, res_inst[index], j);
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_MAX_REPEAT_TIME_RID, res[index], i, res_inst[index], j);
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_NUMBER_REPEATS_RID, res[index], i, res_inst[index], j);
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_SIGNAL_NOISE_RATIO_RID, res[index], i, res_inst[index], j);
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_COMM_FAILURE_RID, res[index], i, res_inst[index], j);
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_RSSI_RID, res[index], i, res_inst[index], j);
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_IMSI_RID, res[index], i, res_inst[index], j);
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_IMEI_RID, res[index], i, res_inst[index], j);
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_COMM_OPERATOR_RID, res[index], i, res_inst[index], j);
INIT_OBJ_RES_OPTDATA(UCIFI_LPWAN_IC_CARD_IDENTIFIER_RID, res[index], i, res_inst[index], j);
inst[index].resources = res[index];
inst[index].resource_count = i;
LOG_DBG("Create access control instance: %d", obj_inst_id);
return &inst[index];
}
static int ucifi_lpwan_init(void)
{
lpwan.obj_id = LWM2M_UCIFI_LPWAN_ID;
lpwan.version_major = LPWAN_VERSION_MAJOR;
lpwan.version_minor = LPWAN_VERSION_MINOR;
lpwan.is_core = false;
lpwan.fields = fields;
lpwan.field_count = ARRAY_SIZE(fields);
lpwan.max_instance_count = MAX_INSTANCE_COUNT;
lpwan.create_cb = lpwan_create;
lwm2m_register_obj(&lpwan);
return 0;
}
LWM2M_OBJ_INIT(ucifi_lpwan_init);