File syn_lwm2m.h¶
File List > proto > syn_lwm2m.h
Go to the documentation of this file
#ifndef SYN_LWM2M_H
#define SYN_LWM2M_H
#include "syntropic/common/syn_defs.h"
#include "syntropic/net/syn_coap.h"
#if !defined(SYN_USE_LWM2M) || SYN_USE_LWM2M
#ifdef __cplusplus
extern "C" {
#endif
/* ── Standard OMA LwM2M Object IDs ───────────────────────────────────────── */
#define SYN_LWM2M_OBJ_SECURITY 0U
#define SYN_LWM2M_OBJ_SERVER 1U
#define SYN_LWM2M_OBJ_ACCESS_CONTROL 2U
#define SYN_LWM2M_OBJ_DEVICE 3U
#define SYN_LWM2M_OBJ_CONNECTIVITY_MONITORING 4U
#define SYN_LWM2M_OBJ_FIRMWARE_UPDATE 5U
#define SYN_LWM2M_OBJ_LOCATION 6U
#define SYN_LWM2M_OBJ_CONNECTIVITY_STATS 7U
#define SYN_LWM2M_OBJ_GENERIC_SENSOR 3300U
#define SYN_LWM2M_OBJ_TEMPERATURE 3303U
#define SYN_LWM2M_OBJ_HUMIDITY 3304U
#define SYN_LWM2M_OBJ_ACTUATION 3306U
/* ── Standard OMA Content-Formats ────────────────────────────────────────── */
#define SYN_LWM2M_FORMAT_TEXT 0U
#define SYN_LWM2M_FORMAT_LINK_FORMAT 40U
#define SYN_LWM2M_FORMAT_OPAQUE 42U
#define SYN_LWM2M_FORMAT_SENML_CBOR 112U
#define SYN_LWM2M_FORMAT_TLV 11542U
#define SYN_LWM2M_FORMAT_JSON 11543U
#define SYN_LWM2M_FORMAT_CBOR 11544U
/* ── Limits & Constants ─────────────────────────────────────────────────── */
#define SYN_LWM2M_MAX_OBJECTS 16U
#define SYN_LWM2M_MAX_OBSERVERS 8U
#define SYN_LWM2M_MAX_URI_PATH_LEN 64U
/* ── Resource Operations Bitmask ─────────────────────────────────────────── */
#define SYN_LWM2M_OP_NONE 0x00U
#define SYN_LWM2M_OP_R 0x01U
#define SYN_LWM2M_OP_W 0x02U
#define SYN_LWM2M_OP_E 0x04U
#define SYN_LWM2M_OP_RW (SYN_LWM2M_OP_R | SYN_LWM2M_OP_W)
/* ── Resource Value Types ────────────────────────────────────────────────── */
typedef enum {
SYN_LWM2M_TYPE_NONE = 0,
SYN_LWM2M_TYPE_STRING,
SYN_LWM2M_TYPE_INT,
SYN_LWM2M_TYPE_FLOAT,
SYN_LWM2M_TYPE_BOOL,
SYN_LWM2M_TYPE_OPAQUE,
SYN_LWM2M_TYPE_TIME,
SYN_LWM2M_TYPE_OBJLNK,
} SYN_LwM2M_ValType;
typedef struct {
SYN_LwM2M_ValType type;
union {
int64_t integer;
double floating;
bool boolean;
const char *str;
struct {
const uint8_t *data;
size_t len;
} opaque;
struct {
uint16_t obj_id;
uint16_t inst_id;
} objlnk;
} val;
} SYN_LwM2M_Value;
/* ── TLV (Type-Length-Value) Binary Format ────────────────────────────────── */
typedef enum {
SYN_LWM2M_TLV_OBJECT_INSTANCE = 0x00U,
SYN_LWM2M_TLV_RESOURCE_INSTANCE = 0x40U,
SYN_LWM2M_TLV_MULTIPLE_RESOURCE = 0x80U,
SYN_LWM2M_TLV_RESOURCE = 0xC0U,
} SYN_LwM2M_TLV_Type;
typedef struct {
SYN_LwM2M_TLV_Type type;
uint16_t id;
const uint8_t *val;
size_t len;
} SYN_LwM2M_TLV;
/* ── Object & Resource Descriptors ───────────────────────────────────────── */
typedef struct {
uint16_t id;
uint8_t operations;
SYN_LwM2M_ValType type;
} SYN_LwM2M_ResourceDesc;
typedef struct SYN_LwM2M_Object SYN_LwM2M_Object;
typedef SYN_Status (*SYN_LwM2M_ReadCb)(uint16_t instance_id, uint16_t resource_id,
SYN_LwM2M_Value *out_val, void *user_ctx);
typedef SYN_Status (*SYN_LwM2M_WriteCb)(uint16_t instance_id, uint16_t resource_id,
const SYN_LwM2M_Value *in_val, void *user_ctx);
typedef SYN_Status (*SYN_LwM2M_ExecCb)(uint16_t instance_id, uint16_t resource_id,
const uint8_t *args, size_t args_len, void *user_ctx);
struct SYN_LwM2M_Object {
uint16_t id;
uint16_t instance_count;
const uint16_t *instances;
size_t resource_count;
const SYN_LwM2M_ResourceDesc *resources;
SYN_LwM2M_ReadCb read;
SYN_LwM2M_WriteCb write;
SYN_LwM2M_ExecCb exec;
void *user_ctx;
};
/* ── Observation Table ───────────────────────────────────────────────────── */
typedef struct {
bool active;
uint8_t token_len;
uint8_t token[8];
uint16_t obj_id;
uint16_t inst_id;
int32_t res_id;
uint32_t pmin;
uint32_t pmax;
uint32_t last_notify_ms;
uint32_t seq;
} SYN_LwM2M_Observation;
/* ── LwM2M Client State Machine ──────────────────────────────────────────── */
typedef enum {
SYN_LWM2M_STATE_DEREGISTERED = 0,
SYN_LWM2M_STATE_REGISTERING,
SYN_LWM2M_STATE_REGISTERED,
SYN_LWM2M_STATE_UPDATING,
} SYN_LwM2M_ClientState;
typedef struct {
const char *endpoint_name;
uint32_t lifetime_s;
const char *binding;
SYN_Transport *transport;
SYN_LwM2M_ClientState state;
char location_path[SYN_LWM2M_MAX_URI_PATH_LEN];
uint32_t last_update_ms;
const SYN_LwM2M_Object *objects[SYN_LWM2M_MAX_OBJECTS];
size_t object_count;
SYN_LwM2M_Observation observations[SYN_LWM2M_MAX_OBSERVERS];
} SYN_LwM2M_Client;
/* ── TLV Codec API ───────────────────────────────────────────────────────── */
size_t syn_lwm2m_tlv_encode(const SYN_LwM2M_TLV *tlv, uint8_t *buf, size_t max_len);
size_t syn_lwm2m_tlv_encode_int(uint16_t res_id, int64_t val, uint8_t *buf, size_t max_len);
size_t syn_lwm2m_tlv_encode_float(uint16_t res_id, double val, uint8_t *buf, size_t max_len);
size_t syn_lwm2m_tlv_encode_bool(uint16_t res_id, bool val, uint8_t *buf, size_t max_len);
size_t syn_lwm2m_tlv_encode_string(uint16_t res_id, const char *str, uint8_t *buf, size_t max_len);
size_t syn_lwm2m_tlv_encode_opaque(uint16_t res_id, const uint8_t *data, size_t len, uint8_t *buf,
size_t max_len);
size_t syn_lwm2m_tlv_encode_value(uint16_t res_id, const SYN_LwM2M_Value *val, uint8_t *buf,
size_t max_len);
size_t syn_lwm2m_tlv_encode_instance(uint16_t inst_id, const uint8_t *tlv_payload,
size_t payload_len, uint8_t *buf, size_t max_len);
bool syn_lwm2m_tlv_decode(const uint8_t *buf, size_t buf_len, SYN_LwM2M_TLV *tlv, size_t *consumed);
bool syn_lwm2m_tlv_decode_int(const SYN_LwM2M_TLV *tlv, int64_t *out_val);
bool syn_lwm2m_tlv_decode_float(const SYN_LwM2M_TLV *tlv, double *out_val);
bool syn_lwm2m_tlv_decode_bool(const SYN_LwM2M_TLV *tlv, bool *out_val);
bool syn_lwm2m_tlv_decode_string(const SYN_LwM2M_TLV *tlv, char *out_str, size_t max_len);
bool syn_lwm2m_tlv_decode_value(const SYN_LwM2M_TLV *tlv, SYN_LwM2M_ValType expected_type,
SYN_LwM2M_Value *out_val);
/* ── Core Link Format & Registration API ─────────────────────────────────── */
size_t syn_lwm2m_generate_link_format(const SYN_LwM2M_Client *client, char *buf, size_t max_len);
bool syn_lwm2m_client_init(SYN_LwM2M_Client *client, const char *endpoint_name, uint32_t lifetime_s,
SYN_Transport *transport);
bool syn_lwm2m_register_object(SYN_LwM2M_Client *client, const SYN_LwM2M_Object *obj);
size_t syn_lwm2m_build_register_request(const SYN_LwM2M_Client *client, uint16_t msg_id,
const uint8_t *token, uint8_t token_len, SYN_CoapMsg *req,
SYN_CoapOption *req_opts, size_t max_req_opts,
size_t *req_opt_cnt, uint8_t *payload_buf,
size_t payload_buf_sz);
size_t syn_lwm2m_build_update_request(const SYN_LwM2M_Client *client, uint16_t msg_id,
const uint8_t *token, uint8_t token_len, uint32_t lifetime_s,
SYN_CoapMsg *req, SYN_CoapOption *req_opts,
size_t max_req_opts, size_t *req_opt_cnt,
uint8_t *payload_buf, size_t payload_buf_sz);
size_t syn_lwm2m_build_deregister_request(const SYN_LwM2M_Client *client, uint16_t msg_id,
const uint8_t *token, uint8_t token_len, SYN_CoapMsg *req,
SYN_CoapOption *req_opts, size_t max_req_opts,
size_t *req_opt_cnt);
bool syn_lwm2m_handle_register_response(SYN_LwM2M_Client *client, const SYN_CoapMsg *resp,
const SYN_CoapOption *resp_opts, size_t resp_opt_cnt);
/* ── Request Processing & Device Management ──────────────────────────────── */
SYN_Status syn_lwm2m_process_request(SYN_LwM2M_Client *client, const SYN_CoapMsg *req,
const SYN_CoapOption *req_opts, size_t req_opt_cnt,
SYN_CoapMsg *resp, SYN_CoapOption *resp_opts,
size_t max_resp_opts, size_t *resp_opt_cnt, uint8_t *resp_buf,
size_t resp_buf_sz);
/* ── Observation & Notification API (RFC 7641) ───────────────────────────── */
bool syn_lwm2m_observe_add(SYN_LwM2M_Client *client, uint16_t obj_id, uint16_t inst_id,
int32_t res_id, const uint8_t *token, uint8_t token_len, uint32_t pmin,
uint32_t pmax);
bool syn_lwm2m_observe_remove(SYN_LwM2M_Client *client, const uint8_t *token, uint8_t token_len);
size_t syn_lwm2m_build_notify(SYN_LwM2M_Client *client, uint16_t obj_id, uint16_t inst_id,
int32_t res_id, uint16_t msg_id, SYN_CoapMsg *resp,
SYN_CoapOption *resp_opts, size_t max_resp_opts, size_t *resp_opt_cnt,
uint8_t *resp_buf, size_t resp_buf_sz);
/* ── Standard Standard Object Constructors ───────────────────────────────── */
typedef struct {
const char *manufacturer;
const char *model_number;
const char *serial_number;
const char *firmware_ver;
int64_t battery_level;
int64_t memory_free_kb;
int64_t error_code;
int64_t current_time;
const char *utc_offset;
const char *timezone;
bool reboot_requested;
bool factory_reset_requested;
} SYN_LwM2M_DeviceContext;
SYN_LwM2M_Object syn_lwm2m_make_device_object(SYN_LwM2M_DeviceContext *ctx);
typedef enum {
SYN_LWM2M_FW_STATE_IDLE = 0,
SYN_LWM2M_FW_STATE_DOWNLOADING,
SYN_LWM2M_FW_STATE_DOWNLOADED,
SYN_LWM2M_FW_STATE_UPDATING,
} SYN_LwM2M_FirmwareState;
typedef enum {
SYN_LWM2M_FW_RESULT_DEFAULT = 0,
SYN_LWM2M_FW_RESULT_SUCCESS,
SYN_LWM2M_FW_RESULT_NO_FLASH,
SYN_LWM2M_FW_RESULT_OUT_OF_RAM,
SYN_LWM2M_FW_RESULT_CONN_LOST,
SYN_LWM2M_FW_RESULT_INTEGRITY_FAIL,
SYN_LWM2M_FW_RESULT_BAD_PKG_TYPE,
SYN_LWM2M_FW_RESULT_INVALID_URI,
} SYN_LwM2M_FirmwareResult;
typedef struct {
SYN_LwM2M_FirmwareState state;
SYN_LwM2M_FirmwareResult result;
char package_uri[128];
char pkg_name[32];
char pkg_version[32];
bool update_requested;
} SYN_LwM2M_FirmwareContext;
SYN_LwM2M_Object syn_lwm2m_make_firmware_object(SYN_LwM2M_FirmwareContext *ctx);
typedef struct {
double sensor_value;
const char *unit;
double min_measured_val;
double max_measured_val;
} SYN_LwM2M_SensorContext;
SYN_LwM2M_Object syn_lwm2m_make_temperature_object(SYN_LwM2M_SensorContext *ctx);
#ifdef __cplusplus
}
#endif
#endif /* SYN_USE_LWM2M */
#endif /* SYN_LWM2M_H */