1 /**
2  * @file aiot_subdev_api.h
3  * @brief subdev模块头文件, 提供子设备管理的能力
4  *
5  * @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited
6  *
7  */
8 #ifndef __AIOT_SUBDEV_API_H__
9 #define __AIOT_SUBDEV_API_H__
10 
11 #if defined(__cplusplus)
12 extern "C" {
13 #endif
14 
15 #include <stdint.h>
16 
17 /**
18  * @brief -0x0C00~-0x0CFF表达SDK在subdev模块内的状态码
19  */
20 #define STATE_SUBDEV_BASE                                             (-0x0C00)
21 
22 /**
23  * @brief subdev模块收到从网络上来的报文时, 通知用户的报文类型
24  */
25 typedef enum {
26     AIOT_SUBDEVRECV_TOPO_ADD_REPLY,
27     AIOT_SUBDEVRECV_TOPO_DELETE_REPLY,
28     AIOT_SUBDEVRECV_TOPO_GET_REPLY,
29     AIOT_SUBDEVRECV_BATCH_LOGIN_REPLY,
30     AIOT_SUBDEVRECV_BATCH_LOGOUT_REPLY,
31     AIOT_SUBDEVRECV_SUB_REGISTER_REPLY,
32     AIOT_SUBDEVRECV_PRODUCT_REGISTER_REPLY,
33     AIOT_SUBDEVRECV_TOPO_CHANGE_NOTIFY
34 } aiot_subdev_recv_type_t;
35 
36 typedef struct {
37     uint32_t     msg_id;
38     uint32_t     code;
39     char*        data;
40     char*        message;
41     char*        product_key;
42     char*        device_name;
43 } aiot_subdev_generic_reply_t;
44 
45 typedef struct {
46     uint32_t     msg_id;
47     char*        params;
48     char*        product_key;
49     char*        device_name;
50 } aiot_subdev_generic_notify_t;
51 
52 /**
53  * @brief subdev模块收到从网络上来的报文时, 通知用户的报文内容
54  */
55 typedef struct {
56     /**
57      * @brief 报文内容所对应的报文类型, 更多信息请参考@ref aiot_subdev_recv_type_t
58      */
59     aiot_subdev_recv_type_t  type;
60     union {
61         /**
62          * @brief 从设备发起请求消息后,收到的云端的应答
63          */
64         aiot_subdev_generic_reply_t  generic_reply;
65 
66         /**
67          * @brief 收到的云端的通知
68          */
69         aiot_subdev_generic_notify_t generic_notify;
70     } data;
71 } aiot_subdev_recv_t;
72 
73 /**
74  * @brief subdev模块收到从网络上来的报文时, 通知用户所调用的数据回调函数
75  *
76  * @param[in] handle subdev会话句柄
77  * @param[in] packet subdev消息结构体, 存放收到的subdev报文内容
78  * @param[in] userdata 用户上下文
79  *
80  * @return void
81  */
82 typedef void (* aiot_subdev_recv_handler_t)(void *handle,
83         const aiot_subdev_recv_t *packet, void *user_data);
84 
85 
86 /* TODO: 列举 SUBDEV 可能发生的所有内部状态变更(可选), 如MQTT重连, OTA收到通知, CoAP的token过期, 与上一段之间有2个空行 */
87 /* TODO: 填上 doxygen 的注释说明 */
88 /* TODO: 由于面向用户, 模块名字符串长度 > 6个字符的时候, 改成缩写, 例如: DYNREG_HTTP_EVT -> DRHTTPEVT */
89 
90 /**
91  * @brief subdev模块内部发生值得用户关注的状态变化时, 通知用户的事件类型
92  */
93 typedef enum {
94     /**
95      * @brief 非法的应答报文
96      */
97     AIOT_SUBDEVEVT_INVALID_RESPONSE,
98     /**
99      * @brief 应答报文的id字段非法
100      */
101     AIOT_SUBDEVEVT_INVALID_ID,
102     /**
103      * @brief 应答报文的code字段非法
104      */
105     AIOT_SUBDEVEVT_INVALID_CODE
106 } aiot_subdev_event_type_t;
107 
108 /**
109  * @brief subdev模块内部发生值得用户关注的状态变化时, 通知用户的事件内容
110  */
111 typedef struct {
112     /**
113      * @brief 事件内容所对应的事件类型, 更多信息请参考@ref aiot_subdev_event_type_t
114      */
115     aiot_subdev_event_type_t  type;
116 } aiot_subdev_event_t;
117 
118 /**
119  * @brief subdev模块内部发生值得用户关注的状态变化时, 通知用户所调用的事件回调函数
120  *
121  * @param[in] handle, subdev会话句柄
122  * @param[in] event, subdev模块中发生的事件的内容
123  * @param[in] userdata, 用户上下文
124  *
125  * @return void
126  */
127 typedef void (*aiot_subdev_event_handler_t)(void *handle,
128         const aiot_subdev_event_t *event, void *userdata);
129 
130 /**
131  * @brief
132  *
133  */
134 typedef struct {
135     char *product_key;
136     char *device_name;
137     char *device_secret;
138     char *product_secret;
139 } aiot_subdev_dev_t;
140 
141 /**
142  * @brief @ref aiot_subdev_setopt 接口的option参数可选值.
143  *
144  * @details 下文每个选项中的数据类型, 指的是@ref aiot_subdev_setopt 中, data参数的数据类型
145  *
146  * 1. data的数据类型是char *时, 以配置@ref AIOT_SUBDEVOPT_MQTT_HANDLE 为例:
147  *
148  *    void *mqtt_handle = aiot_mqtt_init();
149  *    aiot_subdev_setopt(subdev_handle, AIOT_SUBDEVOPT_MQTT_HANDLE, mqtt_handle);
150  */
151 typedef enum {
152     /**
153      * @brief subdev会话 需要的MQTT句柄, 需要先建立MQTT连接,再设置MQTT句柄
154      *
155      * @details
156      *
157      * 数据类型: (void *)
158      */
159     AIOT_SUBDEVOPT_MQTT_HANDLE,
160 
161     /**
162      * @brief 设置回调, 它在SDK收到网络报文的时候被调用, 告知用户, 数据类型为(aiot_subdev_recv_handler_t)
163      *
164      * @details
165      *
166      * 数据类型: (aiot_subdev_recv_handler_t)
167      */
168     AIOT_SUBDEVOPT_RECV_HANDLER,
169 
170     /**
171      * @brief 设置回调, 它在SDK发生内部状态变更时被调用, 告知用户, 数据类型为(aiot_subdev_event_handler_t)
172      *
173      * @details
174      *
175      * 数据类型: (aiot_subdev_event_handler_t)
176      */
177     AIOT_SUBDEVOPT_EVENT_HANDLER,
178 
179     /**
180      * @brief 用户需要SDK暂存的上下文, 数据类型为(void *)
181      *
182      * @details 这个上下文指针会在 AIOT_SUBDEVOPT_RECV_HANDLER 和 AIOT_SUBDEVOPT_EVENT_HANDLER 设置的回调被调用时, 由SDK传给用户
183      *
184      * 数据类型: (void *)
185      */
186     AIOT_SUBDEVOPT_USERDATA,
187     AIOT_SUBDEVOPT_MAX
188 } aiot_subdev_option_t;
189 
190 /**
191  * @brief 创建subdev会话实例, 并以默认值配置会话参数
192  *
193  * @return void *
194  * @retval 非NULL subdev实例的句柄
195  * @retval NULL   初始化失败, 一般是内存分配失败导致
196  *
197  */
198 void *aiot_subdev_init(void);
199 
200 /**
201  * @brief 配置subdev会话
202  *
203  * @param[in] handle subdev会话句柄
204  * @param[in] option 配置选项, 更多信息请参考@ref aiot_subdev_option_t
205  * @param[in] data   配置选项数据, 更多信息请参考@ref aiot_subdev_option_t
206  *
207  * @return int32_t
208  * @retval <STATE_SUCCESS  参数配置失败
209  * @retval >=STATE_SUCCESS 参数配置成功
210  *
211  */
212 int32_t aiot_subdev_setopt(void *handle, aiot_subdev_option_t option, void *data);
213 
214 /**
215  * @brief 结束subdev会话, 销毁实例并回收资源
216  *
217  * @param[in] handle 指向subdev会话句柄的指针
218  *
219  * @return int32_t
220  * @retval <STATE_SUCCESS  执行失败
221  * @retval >=STATE_SUCCESS 执行成功
222  *
223  */
224 int32_t aiot_subdev_deinit(void **handle);
225 
226 /**
227  * @brief 向物联网平台发送添加子设备与网关topo关系的请求
228  *
229  * @param handle subdev会话句柄
230  * @param dev 需要添加topo关系的子设备数组
231  * @param dev_num 子设备数组中的子设备数量
232  *
233  * @return int32_t
234  * @retval <STATE_SUCCESS  请求发送失败
235  * @retval >=STATE_SUCCESS 请求发送成功
236  *
237  * @note
238  *
239  * @ref aiot_subdev_dev_t 中需要填写product key, device name 和 device secret
240  */
241 int32_t aiot_subdev_send_topo_add(void *handle, aiot_subdev_dev_t dev[], uint32_t dev_num);
242 
243 /**
244  * @brief 向物联网平台发送删除子设备与网关topo关系的请求
245  *
246  * @param handle subdev会话句柄
247  * @param dev 需要删除topo关系的子设备数组
248  * @param dev_num 子设备数组中的子设备数量
249  *
250  * @return int32_t
251  * @retval <STATE_SUCCESS  请求发送失败
252  * @retval >=STATE_SUCCESS 请求发送成功
253  *
254  * @note
255  *
256  * @ref aiot_subdev_dev_t 中需要填写product key, device name
257  */
258 int32_t aiot_subdev_send_topo_delete(void *handle, aiot_subdev_dev_t dev[], uint32_t dev_num);
259 
260 /**
261  * @brief 向物联网平台发送查询子设备与网关topo关系的请求
262  *
263  * @param handle subdev会话句柄
264  *
265  * @return int32_t
266  * @retval <STATE_SUCCESS  请求发送失败
267  * @retval >=STATE_SUCCESS 请求发送成功
268  *
269  * @note
270  *
271  * @ref aiot_subdev_dev_t 中需要填写product key, device name
272  */
273 int32_t aiot_subdev_send_topo_get(void *handle);
274 
275 /**
276  * @brief 向物联网平台发送子设备上线请求
277  *
278  * @param handle subdev会话句柄
279  * @param dev 需要上线的子设备数组
280  * @param dev_num 子设备数组中的子设备数量
281  *
282  * @return int32_t
283  * @retval <STATE_SUCCESS  请求发送失败
284  * @retval >=STATE_SUCCESS 请求发送成功
285  *
286  * @note
287  *
288  * @ref aiot_subdev_dev_t 中需要填写product key, device name, device secret
289  */
290 int32_t aiot_subdev_send_batch_login(void *handle, aiot_subdev_dev_t dev[], uint32_t dev_num);
291 
292 /**
293  * @brief 向物联网平台发送子设备下线请求
294  *
295  * @param handle subdev会话句柄
296  * @param dev 需要下线的子设备数组
297  * @param dev_num 子设备数组中的子设备数量
298  *
299  * @return int32_t
300  * @retval <STATE_SUCCESS  请求发送失败
301  * @retval >=STATE_SUCCESS 请求发送成功
302  *
303  * @note
304  *
305  * @ref aiot_subdev_dev_t 中需要填写product key, device name
306  */
307 int32_t aiot_subdev_send_batch_logout(void *handle, aiot_subdev_dev_t dev[], uint32_t dev_num);
308 
309 /**
310  * @brief 向物联网平台发送子设备动态注册请求
311  *
312  * @param handle subdev会话句柄
313  * @param dev 需要动态注册的子设备数组
314  * @param dev_num 子设备数组中的子设备数量
315  *
316  * @return int32_t
317  * @retval <STATE_SUCCESS  请求发送失败
318  * @retval >=STATE_SUCCESS 请求发送成功
319  *
320  * @note
321  *
322  * @ref aiot_subdev_dev_t 中需要填写product key, device name
323  */
324 int32_t aiot_subdev_send_sub_register(void *handle, aiot_subdev_dev_t dev[], uint32_t dev_num);
325 
326 /**
327  * @brief 向物联网平台发送子设备动态注册请求(可从其他网关抢绑子设备)
328  *
329  * @param handle subdev会话句柄
330  * @param dev 需要动态注册的子设备数组
331  * @param dev_num 子设备数组中的子设备数量
332  *
333  * @return int32_t
334  * @retval <STATE_SUCCESS  请求发送失败
335  * @retval >=STATE_SUCCESS 请求发送成功
336  *
337  * @note
338  *
339  * @ref aiot_subdev_dev_t 中需要填写product key, device name, product secret
340  */
341 int32_t aiot_subdev_send_product_register(void *handle, aiot_subdev_dev_t dev[], uint32_t dev_num);
342 
343 #if defined(__cplusplus)
344 }
345 #endif
346 
347 #endif  /* __AIOT_SUBDEV_API_H__ */
348 
349