1 /*
2  * Copyright (c) 2020 Endian Technologies AB
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_NET_LWM2M_PATH_H_
8 #define ZEPHYR_INCLUDE_NET_LWM2M_PATH_H_
9 
10 /**
11  * @file lwm2m.h
12  *
13  * @brief LwM2M path helper macros
14  *
15  * @defgroup lwm2m_path_helpers LwM2M path helper macros
16  * @since 2.5
17  * @version 0.8.0
18  * @ingroup lwm2m_api
19  * @{
20  */
21 
22 /**
23  * @brief Generate LwM2M string paths using numeric components.
24  *
25  * Accepts at least one and up to four arguments. Each argument will be
26  * stringified by the pre-processor, so calling this with non-literals will
27  * likely not do what you want.
28  *
29  * For example:
30  *
31  * @code{c}
32  * #define MY_OBJ_ID 3
33  * LWM2M_PATH(MY_OBJ_ID, 0, 1)
34  * @endcode
35  *
36  * would evaluate to "3/0/1", while
37  *
38  * @code{c}
39  * int x = 3;
40  * LWM2M_PATH(x, 0, 1)
41  * @endcode
42  *
43  * evaluates to "x/0/1".
44  */
45 #define LWM2M_PATH(...) \
46 	LWM2M_PATH_MACRO(__VA_ARGS__, LWM2M_PATH4, LWM2M_PATH3,	\
47 			 LWM2M_PATH2, LWM2M_PATH1)(__VA_ARGS__)
48 
49 
50 /** @cond INTERNAL_HIDDEN */
51 /* Internal helper macros for the LWM2M_PATH macro */
52 #define LWM2M_PATH_VA_NUM_ARGS(...) \
53 	LWM2M_PATH_VA_NUM_ARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)
54 #define LWM2M_PATH_VA_NUM_ARGS_IMPL(_1, _2, _3, _4, N, ...) N
55 
56 #define LWM2M_PATH1(_x) #_x
57 #define LWM2M_PATH2(_x, _y) #_x "/" #_y
58 #define LWM2M_PATH3(_x, _y, _z) #_x "/" #_y "/" #_z
59 #define LWM2M_PATH4(_a, _x, _y, _z) #_a "/" #_x "/" #_y "/" #_z
60 
61 #define LWM2M_PATH_MACRO(_1, _2, _3, _4, NAME, ...) NAME
62 /** @endcond */
63 
64 /**
65  * @brief Initialize LwM2M object structure
66  *
67  * Accepts at least one and up to four arguments. Fill up @ref lwm2m_obj_path structure
68  * and sets the level.
69  *
70  * For example:
71  *
72  * @code{c}
73  * struct lwm2m_obj_path p = LWM2M_OBJ(MY_OBJ, 0, RESOURCE);
74  * @endcode
75  *
76  * Can also be used in place of function argument to return the structure allocated from stack
77  *
78  * @code{c}
79  * lwm2m_notify_observer_path(&LWM2M_OBJ(MY_OBJ, inst_id, RESOURCE));
80  * @endcode
81  *
82  */
83 #define LWM2M_OBJ(...) \
84 	GET_OBJ_MACRO(__VA_ARGS__, LWM2M_OBJ4, LWM2M_OBJ3, LWM2M_OBJ2, LWM2M_OBJ1)(__VA_ARGS__)
85 
86 /** @cond INTERNAL_HIDDEN */
87 /* Internal helper macros for the LWM2M_OBJ macro */
88 #define GET_OBJ_MACRO(_1, _2, _3, _4, NAME, ...) NAME
89 #define LWM2M_OBJ1(oi) (struct lwm2m_obj_path) {.obj_id = oi, .level = 1}
90 #define LWM2M_OBJ2(oi, oii) (struct lwm2m_obj_path) {.obj_id = oi, .obj_inst_id = oii, .level = 2}
91 #define LWM2M_OBJ3(oi, oii, ri) (struct lwm2m_obj_path) \
92 	{.obj_id = oi, .obj_inst_id = oii, .res_id = ri, .level = 3}
93 #define LWM2M_OBJ4(oi, oii, ri, rii) (struct lwm2m_obj_path) \
94 	{.obj_id = oi, .obj_inst_id = oii, .res_id = ri, .res_inst_id = rii, .level = 4}
95 /** @endcond */
96 
97 /** @} */
98 
99 #endif /* ZEPHYR_INCLUDE_NET_LWM2M_PATH_H_ */
100