1 /* 2 * Copyright (c) 2017 Linaro Limited 3 * Copyright (c) 2018-2019 Foundries.io 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 #ifndef LWM2M_ENGINE_H 9 #define LWM2M_ENGINE_H 10 11 #include "lwm2m_message_handling.h" 12 #include "lwm2m_object.h" 13 #include "lwm2m_observation.h" 14 #include "lwm2m_registry.h" 15 16 #define LWM2M_PROTOCOL_VERSION_MAJOR 1 17 #if defined(CONFIG_LWM2M_VERSION_1_1) 18 #define LWM2M_PROTOCOL_VERSION_MINOR 1 19 #else 20 #define LWM2M_PROTOCOL_VERSION_MINOR 0 21 #endif 22 23 #define LWM2M_PROTOCOL_VERSION_STRING \ 24 STRINGIFY(LWM2M_PROTOCOL_VERSION_MAJOR) \ 25 "." STRINGIFY(LWM2M_PROTOCOL_VERSION_MINOR) 26 27 /* Use this value to generate new token */ 28 #define LWM2M_MSG_TOKEN_GENERATE_NEW 0xFFU 29 30 /* length of time in milliseconds to wait for buffer allocations */ 31 #define BUF_ALLOC_TIMEOUT K_SECONDS(1) 32 33 /** 34 * @brief Validates that writing is a legal operation on the field given by the object in 35 * @p obj_inst and the resource id in @p msg. Returns the field to obj_field (if it exists). 36 * 37 * @param[in] msg lwm2m message to signal for which resource the write access should checked 38 * @param[in] obj_inst Engine object instance to signal which object the resource belongs to 39 * @param[out] obj_field Engine obejct field buffer pointer to store the field being checked 40 * @return 0 for successful validation and negative in all other cases 41 */ 42 int lwm2m_engine_validate_write_access(struct lwm2m_message *msg, 43 struct lwm2m_engine_obj_inst *obj_inst, 44 struct lwm2m_engine_obj_field **obj_field); 45 46 /* LwM2M context functions */ 47 /** 48 * @brief Removes all observes, clears all pending coap messages and resets all messages 49 * associated with this context. 50 * 51 * @param[in] client_ctx Context to close 52 */ 53 void lwm2m_engine_context_close(struct lwm2m_ctx *client_ctx); 54 55 /** 56 * @brief Initializes a lwm2m_ctx before a socket can be associated with it. 57 * 58 * @param[in] client_ctx Context to initialize 59 */ 60 void lwm2m_engine_context_init(struct lwm2m_ctx *client_ctx); 61 62 /* Message buffer functions */ 63 uint8_t *lwm2m_get_message_buf(void); 64 int lwm2m_put_message_buf(uint8_t *buf); 65 int lwm2m_perform_composite_observation_op(struct lwm2m_message *msg, uint8_t *token, 66 uint8_t token_length, sys_slist_t *lwm2m_path_list); 67 68 /** 69 * @brief Checks if context has access to the object specified by @p path 70 * 71 * @param[in] client_ctx lwm2m ctx of the connection 72 * @param[in] path Path of the object 73 * @return Returns false if the bootstrap flag of @p client_ctx is not set 74 */ 75 bool lwm2m_engine_bootstrap_override(struct lwm2m_ctx *client_ctx, struct lwm2m_obj_path *path); 76 77 /** 78 * @brief Deletes the object instance specified by msg->path. If the object instance id of the 79 * path is null (i.e path.level == 1), all object instances of that object will be deleted. 80 * Should only be called if delete request comes from a bootstrap server. 81 * 82 * @param[in] msg lwm2m message with operation delete 83 * @return 0 for success or negative in case of error 84 */ 85 int bootstrap_delete(struct lwm2m_message *msg); 86 87 /** 88 * @brief Adds the periodic @p service to the work queue. The period of the service becomes 89 * @p period_ms. 90 * 91 * @param[in] service Periodic service to be added 92 * @param[in] period_ms Period of the periodic service 93 * @return 0 for success or negative in case of error 94 */ 95 int lwm2m_engine_add_service(k_work_handler_t service, uint32_t period_ms); 96 97 /** 98 * @brief Update the period of a given service or remove it. 99 * 100 * Allow the period modification on an existing service created with 101 * lwm2m_engine_add_service(). When period is zero, service is removed. 102 * 103 * @param[in] service Handler of the periodic_service 104 * @param[in] period_ms New period for the periodic_service (in milliseconds) or zero. 105 * 106 * @return 0 for success, 1 when service was removed or negative in case of error. 107 */ 108 int lwm2m_engine_update_service_period(k_work_handler_t service, uint32_t period_ms); 109 110 /** 111 * @brief Call specific service handler only once at given timestamp. 112 * 113 * @param[in] service service to be called 114 * @param[in] timestamp Time when to call 115 * @return 0 for success or negative in case of error 116 */ 117 int lwm2m_engine_call_at(k_work_handler_t service, int64_t timestamp); 118 119 /** 120 * @brief Call given handler from engine context. 121 * 122 * @param[in] service Service callback to be called. 123 * @return 0 for success or negative in case of error 124 */ 125 int lwm2m_engine_call_now(k_work_handler_t service); 126 127 /** 128 * @brief Returns the index in the security objects list corresponding to the object instance 129 * id given by @p obj_inst_id 130 * 131 * @param[in] obj_inst_id object instance id of the security instance 132 * @return index in the list or negative in case of error 133 */ 134 int lwm2m_security_inst_id_to_index(uint16_t obj_inst_id); 135 136 /** 137 * @brief Returns the object instance id of the security object instance at @p index 138 * in the security object list. 139 * 140 * @param[in] index Index in the security object list 141 * @return Object instance id of the security instance or negative in case of error 142 */ 143 int lwm2m_security_index_to_inst_id(int index); 144 145 /** 146 * @brief Returns the default minimum period for an observation set for the server 147 * with object instance id given by @p obj_inst_id. 148 * 149 * @param[in] obj_inst_id Object instance id of the server object instance 150 * @return int32_t pmin value 151 */ 152 int32_t lwm2m_server_get_pmin(uint16_t obj_inst_id); 153 154 /** 155 * @brief Returns the default maximum period for an observation set for the server 156 * with object instance id given by @p obj_inst_id. 157 * 158 * @param[in] obj_inst_id Object instance id of the server object instance 159 * @return int32_t pmax value 160 */ 161 int32_t lwm2m_server_get_pmax(uint16_t obj_inst_id); 162 163 /** 164 * @brief Returns the Short Server ID of the server object instance with 165 * object instance id given by @p obj_inst_id. 166 * 167 * @param[in] obj_inst_id Object instance id of the server object 168 * @return SSID or negative in case not found 169 */ 170 int lwm2m_server_get_ssid(uint16_t obj_inst_id); 171 172 /** 173 * @brief Returns the object instance id of the server having ssid given by @p short_id. 174 * 175 * @param[in] short_id ssid of the server object 176 * @return Object instance id or negative in case not found 177 */ 178 int lwm2m_server_short_id_to_inst(uint16_t short_id); 179 180 #if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) 181 bool lwm2m_server_get_mute_send(uint16_t obj_inst_id); 182 #endif 183 184 #if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_OBJ_SUPPORT) 185 /** 186 * @brief Sets the update state (as specified in LWM2M SPEC E.6 regarding the firmware update) 187 * of the Firmware object instance given by @p obj_inst_id to @p state. 188 * (i.e Sets the value of resource 5/ @p obj_inst_id /3) 189 * 190 * @param[in] obj_inst_id Object instance id of the firmware object instance 191 * @param[in] state (STATE_IDLE through STATE_UPDATING) 192 */ 193 void lwm2m_firmware_set_update_state_inst(uint16_t obj_inst_id, uint8_t state); 194 195 /** 196 * @brief Sets the result state (as specified in LWM2M SPEC E.6 regarding the firmware update) 197 * of the Firmware object instance given by @p obj_inst_id to @p result. 198 * (i.e Sets the value of resource 5/ @p obj_inst_id /5) 199 * 200 * @param[in] obj_inst_id Object instance id of the firmware object instance 201 * @param[in] result (RESULT_DEFAULT through RESULT_UNSUP_PROTO) 202 */ 203 void lwm2m_firmware_set_update_result_inst(uint16_t obj_inst_id, uint8_t result); 204 205 /** 206 * @brief Equivalent to lwm2m_firmware_set_update_state_inst(0, state). 207 * 208 * @param[in] state (STATE_IDLE through STATE_UPDATING) 209 */ 210 void lwm2m_firmware_set_update_state(uint8_t state); 211 212 /** 213 * @brief Equivalent to lwm2m_firmware_set_update_result_inst(0, result). 214 * 215 * @param[in] result (RESULT_DEFAULT through RESULT_UNSUP_PROTO) 216 */ 217 void lwm2m_firmware_set_update_result(uint8_t result); 218 219 /** 220 * @brief Returns the update state (as specified in LWM2M SPEC E.6 regarding the firmware update) 221 * of the Firmware object instance given by @p obj_inst_id. 222 * (i.e Gets the value of resource 5/ @p obj_inst_id /3) 223 * @param[in] obj_inst_id Object instance id of the firmware object 224 * @return (STATE_IDLE through STATE_UPDATING) 225 */ 226 uint8_t lwm2m_firmware_get_update_state_inst(uint16_t obj_inst_id); 227 228 /** 229 * @brief Equivalent to lwm2m_firmware_get_update_state_inst(0). 230 * 231 * @return (STATE_IDLE through STATE_UPDATING) 232 */ 233 uint8_t lwm2m_firmware_get_update_state(void); 234 235 /** 236 * @brief Returns the result state (as specified in LWM2M SPEC E.6 regarding the firmware update) 237 * of the Firmware object instance given by @p obj_inst_id. 238 * (i.e Gets the value of resource 5/ @p obj_inst_id /5) 239 * @param[in] obj_inst_id Object instance id of the firmware object 240 * @return (RESULT_DEFAULT through RESULT_UNSUP_PROTO) 241 */ 242 uint8_t lwm2m_firmware_get_update_result_inst(uint16_t obj_inst_id); 243 244 /** 245 * @brief Equivalent to lwm2m_firmware_get_update_result_inst(0). 246 * 247 * @return (RESULT_DEFAULT through RESULT_UNSUP_PROTO) 248 */ 249 uint8_t lwm2m_firmware_get_update_result(void); 250 #endif 251 252 /* Network Layer */ 253 /** 254 * @brief Opens a socket for the client_ctx if it does not exist. Saves the 255 * socket file descriptor to client_ctx->sock_fd. 256 * 257 * @param[in] client_ctx lwm2m context to open a socket for 258 * @return 0 for success or negative in case of error 259 */ 260 int lwm2m_open_socket(struct lwm2m_ctx *client_ctx); 261 262 /** 263 * @brief Closes the socket with the file descriptor given by client_ctx->sock_fd. 264 * Does nothing if the context's socket is already closed. 265 * 266 * @param[in, out] client_ctx lwm2m context whose socket is to be closed 267 * @return 0 for success or negative in case of error 268 */ 269 int lwm2m_close_socket(struct lwm2m_ctx *client_ctx); 270 271 /** 272 * @brief Removes the socket with the file descriptor given by client_ctx->sock_fd from the 273 * lwm2m work loop. Keeps the socket open. 274 * 275 * @param[in, out] client_ctx lwm2m context whose socket is being suspended 276 * @return 0 for success or negative in case of error 277 */ 278 int lwm2m_socket_suspend(struct lwm2m_ctx *client_ctx); 279 /** 280 * @brief Adds an existing socket to the lwm2m work loop. (The socket specified by the file 281 * descriptor in ctx->sock_fd) 282 * 283 * @param[in] ctx lwm2m context being added to the lwm2m work loop 284 * @return 0 for success or negative in case of error 285 */ 286 int lwm2m_socket_add(struct lwm2m_ctx *ctx); 287 288 /** 289 * @brief Removes a socket from the lwm2m work loop. 290 * 291 * @param[in] ctx lwm2m context to be removed from the lwm2m work loop 292 */ 293 void lwm2m_socket_del(struct lwm2m_ctx *ctx); 294 295 /** 296 * @brief Creates a socket for the @p client_ctx (if it does not exist) and adds it to 297 * the lwm2m work loop. 298 * 299 * @param client_ctx lwm2m context that the socket is being added for 300 * @return 0 for success or negative in case of error 301 */ 302 int lwm2m_socket_start(struct lwm2m_ctx *client_ctx); 303 304 /** 305 * @brief Closes the socket with file descriptor given by client_ctx->sock_fd. 306 * 307 * @param client_ctx Context whose socket is being closed 308 * @return 0 for success or negative in case of error 309 */ 310 int lwm2m_socket_close(struct lwm2m_ctx *client_ctx); 311 312 /** 313 * @brief Closes the socket connection when queue mode is enabled. 314 * 315 * @param[in, out] client_ctx lwm2m context to be closed 316 * @return 0 for success or negative in case of error 317 */ 318 int lwm2m_engine_close_socket_connection(struct lwm2m_ctx *client_ctx); 319 320 /** 321 * @brief Starts the socket of @p client_ctx. Requires CONFIG_LWM2M_DTLS_SUPPORT=y. 322 * 323 * @param[in] client_ctx lwm2m context to be re-added to the lwm2m work loop 324 * @return 0 for success or negative in case of error 325 */ 326 int lwm2m_engine_connection_resume(struct lwm2m_ctx *client_ctx); 327 328 /** 329 * @brief Moves all queued messages to pending. 330 * 331 * @param[in, out] client_ctx 332 * @return 0 for success or negative in case of error 333 */ 334 int lwm2m_push_queued_buffers(struct lwm2m_ctx *client_ctx); 335 336 /* Resources */ 337 struct lwm2m_ctx **lwm2m_sock_ctx(void); 338 int lwm2m_sock_nfds(void); 339 340 /** 341 * @brief Trigger the LwM2M engine to run. 342 * 343 * This function wakes up ongoing poll() from the socket-loop. 344 * It should be called when new transmissions are scheduled or service schedules are modified. 345 */ 346 void lwm2m_engine_wake_up(void); 347 348 #endif /* LWM2M_ENGINE_H */ 349