1 /*
2  * Copyright (c) 2022 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef LWM2M_REGISTRY_H
7 #define LWM2M_REGISTRY_H
8 #include <zephyr/sys/ring_buffer.h>
9 #include "lwm2m_object.h"
10 
11 /**
12  * @brief Creates and registers an object instance to the registry. Object specified by
13  * @p obj_id must exist.
14  *
15  * @param[in] obj_id Object id of the object instance.
16  * @param[in] obj_inst_id Object instance id of the object instance to be created.
17  * @param[out] obj_inst Engine object instance buffer pointer.
18  * @return 0 for success or negative in case of error.
19  */
20 int lwm2m_create_obj_inst(uint16_t obj_id, uint16_t obj_inst_id,
21 			  struct lwm2m_engine_obj_inst **obj_inst);
22 
23 /**
24  * @brief Deletes the object instance given by @p obj_id / @p obj_inst_id.
25  *
26  * @param[in] obj_id Object id of the object instance to be deleted
27  * @param[in] obj_inst_id Object instance id of the object instance to be deleted
28  * @return 0 for success or negative in case of error.
29  */
30 int lwm2m_delete_obj_inst(uint16_t obj_id, uint16_t obj_inst_id);
31 
32 /**
33  * @brief Get the engine object instance specified by @p msg->path. Usually only used in do_write
34  * functions in the different encoders.
35  *
36  * @param[in] msg lwm2m message containing the path to the object instance.
37  * @param[out] obj_inst Engine object instance buffer pointer.
38  * @param[out] created Points to a 1 if an object instance was created. Else 0. Can also be NULL.
39  * @return 0 for success or negative in case of error.
40  */
41 int lwm2m_get_or_create_engine_obj(struct lwm2m_message *msg,
42 				   struct lwm2m_engine_obj_inst **obj_inst, uint8_t *created);
43 
44 /**
45  * @brief Appends an object to the registry. Usually called in the init function
46  * of an object.
47  *
48  * @param[in] obj Object to be registered.
49  */
50 void lwm2m_register_obj(struct lwm2m_engine_obj *obj);
51 
52 /**
53  * @brief Removes an object from the registry.
54  *
55  * @param[in] obj Object to be removed
56  */
57 void lwm2m_unregister_obj(struct lwm2m_engine_obj *obj);
58 
59 /**
60  * @brief Get the resource instance specified by @p path. Creates and allocates a new one
61  * if the resource instance does not exist.
62  *
63  * @param[in] path Path to resource instance (i.e 100/100/100/1)
64  * @param[out] res Engine resource buffer pointer.
65  * @param[out] res_inst Engine resource instance buffer pointer.
66  * @return 0 for success or negative in case of error.
67  */
68 int lwm2m_engine_get_create_res_inst(const struct lwm2m_obj_path *path,
69 				     struct lwm2m_engine_res **res,
70 				     struct lwm2m_engine_res_inst **res_inst);
71 
72 /**
73  * @brief Gets the resource specified by @p pathstr.
74  *
75  * @deprecated Use lwm2m_get_resource() instead.
76  *
77  * @param[in] pathstr Path to resource (i.e 100/100/100/x, the fourth component is optional)
78  * @param[out] res Engine resource buffer pointer.
79  * @return 0 for success or negative in case of error.
80  */
81 int lwm2m_engine_get_resource(const char *pathstr, struct lwm2m_engine_res **res);
82 
83 /**
84  * @brief Gets the resource specified by @p path.
85  *
86  * @param[in] path Path to resource (i.e 100/100/100/x, the fourth component is optional)
87  * @param[out] res Engine resource buffer pointer.
88  * @return 0 for success or negative in case of error.
89  */
90 int lwm2m_get_resource(const struct lwm2m_obj_path *path, struct lwm2m_engine_res **res);
91 
92 /**
93  * @brief Returns pointer to the object in the registry specified by @p path.
94  * Returns NULL if it does not exist.
95  *
96  * @param[in] path lwm2m_obj_path to the object.
97  * @return Pointer to engine object in the registry
98  */
99 struct lwm2m_engine_obj *lwm2m_engine_get_obj(const struct lwm2m_obj_path *path);
100 
101 /**
102  * @brief Returns pointer to the object instance in the registry specified by @p path.
103  * Returns NULL if it does not exist.
104  *
105  * @param[in] path lwm2m_obj_path to the object instance.
106  * @return Pointer to engine object instance in the registry
107  */
108 struct lwm2m_engine_obj_inst *lwm2m_engine_get_obj_inst(const struct lwm2m_obj_path *path);
109 
110 /**
111  * @brief Returns pointer to the resource in the registry specified by @p path.
112  * Returns NULL if it does not exist.
113  *
114  * @param[in] path lwm2m_obj_path to the resource.
115  * @return Pointer to engine resource in the registry
116  */
117 struct lwm2m_engine_res *lwm2m_engine_get_res(const struct lwm2m_obj_path *path);
118 
119 /**
120  * @brief Returns pointer to the resource instance in the registry specified by @p path.
121  * Returns NULL if it does not exist.
122  *
123  * @param[in] path lwm2m_obj_path to the resource instance.
124  * @return Pointer to the engine resource instance in the registry
125  */
126 struct lwm2m_engine_res_inst *lwm2m_engine_get_res_inst(const struct lwm2m_obj_path *path);
127 
128 /**
129  * @brief Get the engine obj specified by @p obj_id.
130  *
131  * @param[in] obj_id Object id of the object.
132  * @return Pointer to the engine object.
133  */
134 struct lwm2m_engine_obj *get_engine_obj(int obj_id);
135 
136 /**
137  * @brief Get the engine object instance @p obj_id /@p obj_inst_id
138  *
139  * @param[in] obj_id Object if of the object instance.
140  * @param[in] obj_inst_id Object instance id of object instance
141  * @return Pointer to the object instance.
142  */
143 struct lwm2m_engine_obj_inst *get_engine_obj_inst(int obj_id, int obj_inst_id);
144 
145 /**
146  * @brief Get object instance, field, resource and resource instance. All variables may be NULL.
147  * Example to get resource instance:
148  * int ret = path_to_objs(&path, NULL, NULL, NULL, &res_inst);
149  *
150  * @param[in] path lwm2m object path to the object/object instance/resource/resource instance
151  * to get.
152  * @param[out] obj_inst Engine object instance buffer pointer.
153  * @param[out] obj_field Engine object field buffer pointer.
154  * @param[out] res Engine resource buffer pointer.
155  * @param[out] res_inst Engine resource instance buffer pointer.
156  * @return 0 for success or negative in case of error.
157  */
158 int path_to_objs(const struct lwm2m_obj_path *path, struct lwm2m_engine_obj_inst **obj_inst,
159 		 struct lwm2m_engine_obj_field **obj_field, struct lwm2m_engine_res **res,
160 		 struct lwm2m_engine_res_inst **res_inst);
161 
162 /**
163  * @brief Returns the object instance in the registry with object id = @p obj_id that has the
164  * smalles object instance id strictly larger than @p obj_inst_id.
165  *
166  * @param[in] obj_id Object id of the object instance.
167  * @param[in] obj_inst_id Lower bound of the object instance id.
168  * @return Pointer to the object instance. NULL if not found.
169  */
170 struct lwm2m_engine_obj_inst *next_engine_obj_inst(int obj_id, int obj_inst_id);
171 
172 /**
173  * @brief Returns a boolean to signal whether or not or it's needed to report object version.
174  *
175  * @param[in] obj Pointer to engine object.
176  * @return True if it's needed to report object version, else false
177  */
178 bool lwm2m_engine_shall_report_obj_version(const struct lwm2m_engine_obj *obj);
179 
180 /**
181  * @brief Returns the binding mode in use.
182  *
183  * Defaults to UDP (U). In LwM2M 1.0 when queue mode is enabled, return "UQ".
184  *
185  * @param[out] binding Data buffer.
186  */
187 void lwm2m_engine_get_binding(char *binding);
188 
189 /**
190  * @brief Returns the queue mode (Q) if queue mode is enabled. Else an empty string.
191  *
192  * @param[out] queue Queue mode data buffer
193  */
194 void lwm2m_engine_get_queue_mode(char *queue);
195 
196 /**
197  * @brief Returns the engine object field with resource id @p res_id of the object @p obj.
198  *
199  * @param[in] obj lwm2m engine object of the field.
200  * @param[in] res_id Resource id of the field.
201  * @return Pointer to an engine object field, or NULL if it does not exist
202  */
203 struct lwm2m_engine_obj_field *lwm2m_get_engine_obj_field(struct lwm2m_engine_obj *obj, int res_id);
204 
205 size_t lwm2m_engine_get_opaque_more(struct lwm2m_input_context *in, uint8_t *buf, size_t buflen,
206 				    struct lwm2m_opaque_context *opaque, bool *last_block);
207 
208 
209 /* Resources */
210 sys_slist_t *lwm2m_engine_obj_list(void);
211 sys_slist_t *lwm2m_engine_obj_inst_list(void);
212 
213 /* Data cache Internal API */
214 
215 /**
216  * LwM2M Time series resoursce data storage
217  */
218 struct lwm2m_time_series_resource {
219 	/* object list */
220 	sys_snode_t node;
221 	/* Resource Path url */
222 	struct lwm2m_obj_path path;
223 	/* Ring buffer */
224 	struct ring_buf rb;
225 };
226 
227 #if defined(CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT)
228 
229 #define LWM2M_LIMITED_TIMESERIES_RESOURCE_COUNT 20
230 
231 struct lwm2m_cache_read_entry {
232 	struct lwm2m_time_series_resource *cache_data;
233 	int32_t original_get_head;
234 	int32_t original_get_tail;
235 	int32_t original_get_base;
236 };
237 
238 struct lwm2m_cache_read_info {
239 	struct lwm2m_cache_read_entry read_info[CONFIG_LWM2M_MAX_CACHED_RESOURCES];
240 	int entry_limit;
241 	int entry_size;
242 };
243 #endif
244 
245 int lwm2m_engine_data_cache_init(void);
246 struct lwm2m_time_series_resource *
247 lwm2m_cache_entry_get_by_object(const struct lwm2m_obj_path *obj_path);
248 bool lwm2m_cache_write(struct lwm2m_time_series_resource *cache_entry,
249 		       struct lwm2m_time_series_elem *buf);
250 bool lwm2m_cache_read(struct lwm2m_time_series_resource *cache_entry,
251 		      struct lwm2m_time_series_elem *buf);
252 size_t lwm2m_cache_size(const struct lwm2m_time_series_resource *cache_entry);
253 
254 #endif /* LWM2M_REGISTRY_H */
255