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