1 /** 2 * @file aiot_devinfo_api.h 3 * @brief devinfo模块头文件, 提供更新和删除设备标签的能力 4 * 5 * @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited 6 * 7 * @details 8 * 9 * Devinfo模块用于向阿里云物联网平台更新或删除设备的标签, API的使用流程如下: 10 * 11 * 1. 首先参考 @ref aiot_mqtt_api.h 的说明, 保证成功建立与物联网平台的`MQTT`连接 12 * 13 * 2. 调用 @ref aiot_devinfo_init 初始化devinfo会话, 获取会话句柄 14 * 15 * 3. 调用 @ref aiot_devinfo_setopt 配置devinfo会话的参数, 常用配置项见 @ref aiot_devinfo_setopt 的说明 16 * 17 * 4. 调用 @ref aiot_devinfo_send 发送标签变更的请求, 比如更新或删除 18 * 19 * 5. 收到的应答经SDK处理后会调用由 @ref aiot_devinfo_setopt 配置的 @ref AIOT_DEVINFOOPT_RECV_HANDLER 回调函数, 通知用户云端的应答 20 * 21 */ 22 #ifndef __AIOT_DEVINFO_API_H__ 23 #define __AIOT_DEVINFO_API_H__ 24 25 #if defined(__cplusplus) 26 extern "C" { 27 #endif 28 29 #include <stdint.h> 30 31 /** 32 * @brief -0x1200~-0x12FF表达SDK在devinfo模块内的状态码 33 */ 34 #define STATE_DEVINFO_BASE (-0x1200) 35 36 /** 37 * @brief MQTT会话句柄未设置, 请通过 @ref aiot_devinfo_setopt 设置MQTT会话句柄 38 */ 39 #define STATE_DEVINFO_MISSING_MQTT_HANDLE (-0x1201) 40 41 /** 42 * @brief devinfo模块收到从网络上来的报文时, 通知用户的报文类型 43 */ 44 typedef enum { 45 AIOT_DEVINFORECV_GENERIC_REPLY, 46 } aiot_devinfo_recv_type_t; 47 48 typedef struct { 49 /** 50 * @brief 消息标识符, uint64_t类型的整数, 与属性上报或事件上报的消息标示符一致 51 */ 52 uint32_t msg_id; 53 /** 54 * @brief 设备端错误码, 200-请求成功, 更多错误码码查看<a href="https://help.aliyun.com/document_detail/120329.html">设备端错误码</a> 55 */ 56 uint32_t code; 57 /** 58 * @brief 指向云端应答数据的指针 59 */ 60 char *data; 61 /** 62 * @brief 云端应答数据的长度 63 */ 64 uint32_t data_len; 65 /** 66 * @brief 指向状态消息字符串的指针, 当设备端上报请求成功时对应的应答消息为"success", 若请求失败则应答消息中包含错误信息 67 */ 68 char *message; 69 /** 70 * @brief 消息字符串的长度 71 */ 72 uint32_t message_len; 73 } aiot_devinfo_recv_generic_reply_t; 74 75 /** 76 * @brief devinfo模块收到从网络上来的报文时, 通知用户的报文内容 77 */ 78 typedef struct { 79 char *product_key; 80 char *device_name; 81 /** 82 * @brief 报文内容所对应的报文类型, 更多信息请参考@ref aiot_devinfo_recv_type_t 83 */ 84 aiot_devinfo_recv_type_t type; 85 union { 86 /** 87 * @brief 从云端收到的更新或删除设备标签的应答 88 */ 89 aiot_devinfo_recv_generic_reply_t generic_reply; 90 } data; 91 } aiot_devinfo_recv_t; 92 93 /** 94 * @brief devinfo模块收到从网络上来的报文时, 通知用户所调用的数据回调函数 95 * 96 * @param[in] handle devinfo会话句柄 97 * @param[in] packet devinfo消息结构体, 存放收到的devinfo报文内容 98 * @param[in] userdata 用户上下文 99 * 100 * @return void 101 */ 102 typedef void (* aiot_devinfo_recv_handler_t)(void *handle, const aiot_devinfo_recv_t *packet, void *userdata); 103 104 /** 105 * @brief devinfo模块内部发生值得用户关注的状态变化时, 通知用户的事件类型 106 */ 107 typedef enum { 108 /** 109 * @brief 收到的应答中设备信息不合法, 无法获取product key和device name 110 */ 111 AIOT_DEVINFOEVT_INVALID_DEVINFO, 112 /** 113 * @brief 收到的应答中字段不合法 114 */ 115 AIOT_DEVINFOEVT_INVALID_RESPONSE, 116 /** 117 * @brief 收到的应答中字段格式错误 118 */ 119 AIOT_DEVINFOEVT_INVALID_RESPONSE_FORMAT, 120 } aiot_devinfo_event_type_t; 121 122 /** 123 * @brief devinfo模块内部发生值得用户关注的状态变化时, 通知用户的事件内容 124 */ 125 typedef struct { 126 /** 127 * @brief 事件内容所对应的事件类型, 更多信息请参考@ref aiot_devinfo_event_type_t 128 */ 129 aiot_devinfo_event_type_t type; 130 } aiot_devinfo_event_t; 131 132 /** 133 * @brief devinfo模块内部发生值得用户关注的状态变化时, 通知用户所调用的事件回调函数 134 * 135 * @param[in] handle, devinfo会话句柄 136 * @param[in] event, devinfo模块中发生的事件的内容 137 * @param[in] userdata, 用户上下文 138 * 139 * @return void 140 */ 141 typedef void (*aiot_devinfo_event_handler_t)(void *handle, const aiot_devinfo_event_t *event, void *userdata); 142 143 /** 144 * @brief @ref aiot_devinfo_msg_t 中的发送消息类型 145 * 146 * @details 147 * 148 * 消息类型有两个, 分别是更新设备标签和删除设备标签 149 */ 150 typedef enum { 151 /** 152 * @brief 更新设备标签 153 */ 154 AIOT_DEVINFO_MSG_UPDATE, 155 /** 156 * @brief 删除设备标签 157 */ 158 AIOT_DEVINFO_MSG_DELETE 159 } aiot_devinfo_msg_type_t; 160 161 /** 162 * @brief 更新或删除设备标签的params内容 163 */ 164 typedef struct { 165 char *params; 166 } aiot_devinfo_msg_data_t; 167 168 typedef struct { 169 /** 170 * @brief 设备的product key 171 */ 172 char *product_key; 173 /** 174 * @brief 设备的device name 175 */ 176 char *device_name; 177 /** 178 * @brief 消息类型, 更多信息请参考@ref aiot_devinfo_msg_type_t 179 */ 180 aiot_devinfo_msg_type_t type; 181 union { 182 /** 183 * @brief 更新设备标签, 格式:"[{\"attrKey\":\"xxx\",\"attrValue\":\"yyy\"}]" 184 * 185 * @details 186 * 187 * 从上述格式可以看出,更新设备标签的格式是一个JSON数组,一次可按attrKey和attrValue上报多组设备标签 188 */ 189 aiot_devinfo_msg_data_t update; 190 /** 191 * @brief 删除设备标签, 格式:"[{\"attrKey\":\"xxx\"}]" 192 * 193 * @details 194 * 195 * 从上述格式可以看出,删除设备标签的格式是一个JSON数组,一次可按attrKey删除多组设备标签 196 */ 197 aiot_devinfo_msg_data_t delete; 198 } data; 199 } aiot_devinfo_msg_t; 200 201 /** 202 * @brief @ref aiot_devinfo_setopt 接口的option参数可选值. 203 * 204 * @details 下文每个选项中的数据类型, 指的是@ref aiot_devinfo_setopt 中, data参数的数据类型 205 * 206 * 1. data的数据类型是void *时, 以配置@ref AIOT_DEVINFOOPT_MQTT_HANDLE 为例: 207 * 208 * void *mqtt_handle = aiot_mqtt_init(); 209 * aiot_devinfo_setopt(devinfo_handle, AIOT_DEVINFOOPT_MQTT_HANDLE, mqtt_handle); 210 * 211 * 2. data的数据类型是其他数据类型时, 以配置@ref AIOT_DEVINFOOPT_DEINIT_TIMEOUT_MS 为例: 212 * 213 * uint32_t deinit_timeout_ms = 443; 214 * aiot_devinfo_setopt(devinfo_handle, AIOT_DEVINFOOPT_DEINIT_TIMEOUT_MS, (void *)&deinit_timeout_ms); 215 */ 216 typedef enum { 217 /** 218 * @brief devinfo会话 需要的MQTT句柄, 需要先建立MQTT连接, 再设置MQTT句柄 219 */ 220 AIOT_DEVINFOOPT_MQTT_HANDLE, 221 222 /** 223 * @brief 设置回调, 它在SDK收到网络报文的时候被调用, 告知用户 224 * 225 * @details 226 * 227 * 数据类型: ( @ref aiot_devinfo_recv_handler_t) 228 */ 229 AIOT_DEVINFOOPT_RECV_HANDLER, 230 231 /** 232 * @brief 设置回调, 它在SDK发生内部状态变更时被调用, 告知用户 233 * 234 * @details 235 * 236 * 数据类型: ( @ref aiot_devinfo_event_handler_t) 237 */ 238 AIOT_DEVINFOOPT_EVENT_HANDLER, 239 240 /** 241 * @brief 用户需要SDK暂存的上下文, 数据类型为(void *) 242 * 243 * @details 这个上下文指针会在 AIOT_DEVINFOOPT_RECV_HANDLER 和 AIOT_DEVINFOOPT_EVENT_HANDLER 设置的回调被调用时, 由SDK传给用户 244 */ 245 AIOT_DEVINFOOPT_USERDATA, 246 247 /** 248 * @brief 销毁devinfo实例时, 等待其他api执行完毕的时间 249 * 250 * @details 251 * 252 * 当调用@ref aiot_devinfo_deinit 销毁devinfo实例时, 若继续调用其他aiot_devinfo_xxx API, API会返回@ref STATE_USER_INPUT_EXEC_DISABLED 错误 253 * 254 * 此时, 用户应该停止调用其他aiot_devinfo_xxx API 255 * 256 * 数据类型: (uint32_t *) 默认值: (2 * 1000) ms 257 */ 258 AIOT_DEVINFOOPT_DEINIT_TIMEOUT_MS, 259 AIOT_DEVINFOOPT_MAX 260 } aiot_devinfo_option_t; 261 262 /** 263 * @brief 创建devinfo会话实例, 并以默认值配置会话参数 264 * 265 * @return void * 266 * @retval 非NULL devinfo实例的句柄 267 * @retval NULL 初始化失败, 一般是内存分配失败导致 268 * 269 */ 270 void *aiot_devinfo_init(void); 271 272 /** 273 * @brief 配置devinfo会话 274 * 275 * @param[in] handle devinfo会话句柄 276 * @param[in] option 配置选项, 更多信息请参考@ref aiot_devinfo_option_t 277 * @param[in] data 配置选项数据, 更多信息请参考@ref aiot_devinfo_option_t 278 * 279 * @return int32_t 280 * @retval <STATE_SUCCESS 参数配置失败 281 * @retval >=STATE_SUCCESS 参数配置成功 282 * 283 */ 284 int32_t aiot_devinfo_setopt(void *handle, aiot_devinfo_option_t option, void *data); 285 286 /** 287 * @brief 结束devinfo会话, 销毁实例并回收资源 288 * 289 * @param[in] handle 指向devinfo会话句柄的指针 290 * 291 * @return int32_t 292 * @retval <STATE_SUCCESS 执行失败 293 * @retval >=STATE_SUCCESS 执行成功 294 * 295 */ 296 int32_t aiot_devinfo_deinit(void **handle); 297 298 /** 299 * @brief 向devinfo服务器发送devinfo消息请求 300 * 301 * @param handle devinfo会话句柄 302 * @param msg devinfo发送给云端的删除/更新设备标签信息的报文 303 * 304 * @return int32_t 305 * @retval <STATE_SUCCESS 请求发送失败 306 * @retval >=STATE_SUCCESS 请求发送成功 307 */ 308 int32_t aiot_devinfo_send(void *handle, aiot_devinfo_msg_t *msg); 309 310 #if defined(__cplusplus) 311 } 312 #endif 313 314 #endif /* __AIOT_DEVINFO_API_H__ */ 315 316