Wi-Fi SDK适配文档

  • 天猫精灵IoT开放平台是阿里巴巴人工智能实验室(Alibaba A.I.Labs)面向品牌商、方案商、模组商、芯片商以及个人开发者推出的,将IoT物联网技术(蓝牙Mesh协议、Wi-Fi协议、天猫精灵IoT云服务)和AI(天猫精灵ASR语音识别、NLP自然语言处理、TTS语音合成)等对外输出的开放式平台。

  • IoTConnect Kit提供了包括开放通信协议、连接标准、SDK、模组、开发板和芯片库、产品库、方案库,以及产品规范、认证规范、安全规范等在内的“全栈式”智能家居连接平台的服务能力。IoTConnect Kit能够为厂商提供更多样化的选择,更便捷、高效和先进的智能家居接入服务。

  • Wi-Fi SDK是面向模组厂,个人开发者推出的,通过Wi-Fi对接天猫精灵及IoT云服务的软件开发工具包,目的是帮助模组厂,个人开发者快速接入天猫精灵生态。

  • 本文首先介绍了如何将Wi-Fi SDK移植到运行一个新平台上,接着说明了怎样使用Wi-Fi SDK提供的API,最后对Wi-Fi品类如何对接进行了简单说明。

Wi-Fi SDK介绍

IoTConnect Kit-Wi-Fi SDK - 图2

  • 上图中天猫精灵,IoT设备,精灵云是天猫精灵生态系统中的典型组成部分。IoT设备出厂后没办法直接连接路由器并使用精灵云的服务。

  • Wi-Fi SDK就是为Wi-Fi IoT设备提供自动配网能力及连接精灵云服务的软件开发包。配网功能目前支持天猫精灵“找队友”以及天猫精灵APP“添加智能设备”两种方式。通过天猫精灵或天猫精灵APP配网成功之后,Wi-Fi SDK会自动连接精灵云服务,连接精灵云服务成功之后,用户便可感受智能家居体验了。

整个过程如下图所示(1或1’二选一即可):
IoTConnect Kit-Wi-Fi SDK - 图3

Wi-Fi SDK适配说明

Wi-Fi SDK在IoT设备软件框图中,位置如下:
IoTConnect Kit-Wi-Fi SDK - 图4

Wi-Fi SDK为上层应用程序提供配网开始/结束、连接精灵云服务(透过MQTT协议)、断开云端连接、上报设备状态等接口服务。需要OS、Network、MQTT、SNTP、JSON等模块提供接口满足配网及连接云服务功能。

Wi-Fi SDK移植到新平台

Wi-Fi SDK所依赖的API

芯片商/平台商必须实现下面的API才能让Wi-Fi SDK成功运行起来。

函数原型 const device_info_t* aick_wlan_get_device_info(void)
参数
返回值 指向device_info_t的指针
说明 获取设备信息,SDK初始化过程中需要获取设备中存放的三元组信息;每台IoT设备的三元组信息都是独一无二的,详情请参考deviceinfo_t的声明。三元组信息中不含VID,VID固定取1000。
typedef struct _device_info_t
{
u8 mac[6]; / MAC地址 /
u32 vid; / 厂商ID /
u32 pid; / 产品ID /
char secret[33]; / 秘钥 /
}device_info_t;
函数原型 network_config_t* aick_wlan_get_network_config(void)
参数
返回值 指向网络配置信息变量的指针
说明 开机需用全局变量保存此网络配置信息;
如果已经配网成功,此信息保存在设备中只读安全区域中,系统重新启动再从只读安全区域中读取到全局变量中并确保此变量在整个系统运行过程中不会被修改
typedef struct network_kconfig_t{
char ssid[MAX_SSID_LEN]; / 路由器SSID /
char password[MAX_PASSWD_LEN]; / 路由器密码 /
u8 bssid_set; / 是否连接到BSSID/
u8 bssid[MAC_LEN]; / 路由器MAC地址 /
char usrid[MAX_USRID_LEN]; / 用户ID /
char token[MAX_TOKEN_LEN]; / 只用于SmartConfig绑定环节 /
} network_config_t;
函数原型 product_info_t* aick_wlan_get_product_info(void)
参数
返回值 product_info_t*
产品配置信息
说明 需用全局变量保存此产品配置信息
typedef struct product_info_t{
char signature; / 产品信息签名 /
char uuid[9]; / UUID /
char puid[13]; / PUID /
char manufacturer[30]; / “Ali A.I. Labs IoT center” /
char mode[30]; / “Alioutlet_0101” /
char type[30]; / 产品类型/
char traits[62]; / 产品属性 /
char host[32]; / 目标网址 /
char groupid[32]; / 组ID /
STA_CONFIG_STATUS sta_cfg_status; / 设备配网状态信息 /
}product_info_t;
函数原型 void aick_wlan_set_channel(u8 channel)
参数 channel:Wi-Fi信道ID, 取值范围[0,13]
返回值
说明 控制Wi-Fi芯片切换到特定信道
函数原型 bool aick_wlan_reg_pkt_rx_cb(aick_pkt_rx_handler_t cb)
参数 cb:wlan sniff mode rx data handler
返回值 回调函数注册成功,返回true;否则,返回false
说明 SDK处于待配网状态会开启Wi-Fi芯片混杂模式,并注册处理802.11数据包的回调函数,buf应指向标准802.11数据包包头,len为整个802.11数据包长度
typedef void ( aick_pkt_rx_handler_t)(u8 buf, u16 len)
函数原型 void aick_wlan_promis_enable(bool enable)
参数 enable:使能/关闭Wi-Fi芯片的混杂模式
返回值
说明 控制Wi-Fi芯片进入/退出混杂模式
函数原型 bool aick_wlan_send_pkt(u8 *buf, u16 len, bool sys_seq)
参数 buf:数据包缓冲区
len:数据包长度
sys_seq:Wi-Fi数据包SN是否使用系统SN
返回值 数据包成功发送到空中返回true;否则,返回false
说明 将buf指向的802.11数据包发送到空中
函数原型 bool aick_wlan_sta_disconnect(void)
参数
返回值 与路由器断线成功,返回true;否则,返回false
说明 断开与路由器的连线
函数原型 bool aick_wlan_set_sta_config(network_config_t *config)
参数 config:目标路由器SSID/Password信息
返回值 保存目标路由器SSID/Password信息成功,返回true;否则,返回false
说明 Wi-Fi SDK配网成功后,获取到目标路由器SSID/Password后呼叫此函数,应用层用此配置信息启动连接路由器过程
函数原型 bool aick_wlan_reg_event_cb(aick_wlan_event_handler_t cb)
参数 cb:Wi-Fi事件(扫描、连线、断线、DHCP开始、结束等)回调函数
返回值 回调函数注册成功,返回true;否则,返回false
说明 SDK需要在底层Wi-Fi状态发生变化时得到消息通知。
与路由器连线完成,断线,获取到IP地址三种状态,必须通过cb通知Wi-Fi SDK,其余事件也建议通知到Wi-Fi SDK
typedef enum {
AWLAN_SCAN_DONE = 0, / 扫描结束 /
AWLAN_CONNECTED, / 连接路由器成功 /
AWLAN_DISCONNECTED, / 路由器连线断开 /
AWLAN_AUTHMODE_CHANGE, / 路由器安全方式发生变化 /
AWLAN_GOT_IP, / 获取到IP地址 /
AWLAN_DHCP_TIMEOUT, / DHCP过程超时 /
AWLAN_EVENT_MAXID
} AWLAN_EVENT_ID;
函数原型 bool aick_wlan_ip_obtained(void)
参数
返回值 从路由器获取到IP地址,返回true;否则,返回false
说明 查询是否从路由器获取到IP地址
函数原型 void aick_wlan_set_awlan_error_code(AWLAN_ERROR_CODE err)
参数 err:错误码
返回值
说明 设置Wi-Fi错误码信息
状态指示灯的状态需要根据Wi-Fi错误码的变化而变化
函数原型 void flash_save_product_info(product_info_t *p_product)
参数 p_product:指向product_info_t的指针
返回值
说明 将产品信息保存到安全区域
函数原型 bool flash_save_network_config(network_config_t *p_config)
参数 p_config:网络配置信息指针
返回值 保存成功,返回true;否则,返回false
说明 保存网络配置信息到安全区域
函数原型 bool flash_get_network_config(network_config_t *p_config)
参数 p_config:网络配置信息指针
返回值 获取成功,返回true;否则,返回false
说明 从安全区域获取网络配置信息
函数原型 bool flash_clear_network_config(void)
参数
返回值 网络配置信息清除成功,返回true;否则,返回false
说明 从安全区域清除网络配置信息
函数原型 u32 aick_osal_get_time_ms(void)
参数
返回值 返回系统时间
说明 获取系统时间,单位:ms
函数原型 u64 aick_osal_random(void)
参数
返回值 随机数
说明 返回随机数,64比特
函数原型 bool aick_osal_delayed_reboot (u32 ms)
参数 ms:系统重启前等待的时间
单位:毫秒
返回值 触发系统重启动作成功,返回true;否则,返回false
说明 系统在等待ms时间之后重新启动
函数原型 void user_sntp_init(void)
参数
返回值
说明 SNTP系统初始化
SNTP:简单网络时间协议(Simple Network Time Protocol)
启动SNTP协议,需定期的与SNTP服务器进行时间同步
函数原型 u32 sntp_get_current_timestamp(void)
参数
返回值 SNTP东八时区时间对应的相对时间
单位:秒
说明 与SNTP服务器进行时间同步之前,返回0
函数原型 s32 aick_ssl_connect(aick_ssl_network *p_asn)
参数 p_asn:指向aick_ssl_network的指针
返回值 SSL连线成功,返回0;否则,返回错误码
说明 SSL连线要求进行双向验证 sslset_authmode(&ssl, SSL_VERIFY_REQUIRED ) mbedtls_ssl_conf_authmode(n->conf, MBEDTLS_SSL_VERIFY_REQUIRED)任何情况下,每次连线本地端口需随机选择,连续采用相同的本地端口进行连线请求,会被服务器拒绝
typedef struct _aick_ssl_network
{
Network n; / Network结构体/
char root_ca; / 服务器根证书 /
char
client_ca; / 设备端根证书 /
char cliient_pk; / 设备端 /
char
address; / SSL 服务器地址 /
u32 port; / SSL 服务器端口号 /
bool connected; / SSL 连线状态 /
} aick_ssl_network;
函数原型 s32 aick_ssl_disconnect(aick_ssl_network *p_asn)
参数 p_asn:指向aick_ssl_network的指针,详情请参考函数说明
返回值 SSL断线成功,返回0;否则,返回错误码
说明
函数原型 void aick_wlan_netconfig_state_notify(AWLAN_STATE_TYPE state)
参数 state:网络配置当前状态
返回值
说明 未配网设备在配网阶段发生状态切换,会呼叫此函数通知应用层
应用层需根据配网状态变化调整状态指示灯的状态,指示灯具体状态请参考设备认证规范
typedef enum {
AWLAN_STATE_INIT = 0, / 初始状态 /
AWLAN_STATE_WAIT_COFNIG, / 待配网状态 /
AWLAN_STATE_ZEROCONFIGING, / 零配开始 /
AWLAN_STATE_SMARTCONFIGURING, / SmartConfigure开始/
AWLAN_STATE_CONFIG_TIMEOUT, / 配网超时 /
AWLAN_STATE_CONFIGURED, / 收到网络配置信息 /
AWLAN_STATE_DHCP_START, / DHCP 开始 /
AWLAN_STATE_GOT_IP, / 获取到IP地址 /
AWLAN_STATE_MQTT_CONNECTING, / MQTT 连线进行中 /
AWLAN_STATE_MQTT_CONNECTED, / MQTT 连线完成 /
AWLAN_STATE_MAX
} AWLAN_STATE_TYPE;

OS相关:

函数原型 void *aick_osal_malloc(unsigned int size)
参数 size:要申请的内存大小,单位:bytes
返回值 指向申请到的内存的指针
说明 申请size bytes的内存
返回值非0代表申请成功;否则代表申请内存失败
函数原型 void aick_osal_free(void *ptr)
参数 ptr:指向要释放内存的指针
返回值
说明 释放ptr指向的内存
函数原型 char aick_osal_strdup(const char str)
参数 str:指向源字串指针
返回值 指向新字串的指针
说明 复制一个字串,并返回指向新字串的指针
函数原型 void aick_osal_dump_memory8(char description, char buf, int len)
参数 description:指向此buf的描述字串
buf:指向目标缓存的指针
len:要打印的缓存长度,单位:byte
返回值
说明 打印buf指向内存的内容
函数原型 void aick_osal_timer_del(aick_timer_t *ptimer)
参数 ptimer:指向要删除定时器的指针
返回值
说明 删除ptimer指向的定时器
删除定时器之前,需确保呼叫过aick_osal_timer_add将定时器添加到系统中
函数原型 void aick_osal_timer_set_handle(aick_timer_t ptimer, aick_timer_func_t pfunc, void *parg)
参数 ptimer:指向要修改的定时器的指针
pfunc:定时器handler
parg:定时器handler参数指针
返回值
说明 parg是否可以被正确传递到pfunc中依赖于系统实现,目前FreeRTOS平台parg无法作为参数传递到pfunc中
函数原型 void aick_osal_timer_add(aick_timer_t *ptimer, unsigned int msec, bool repeat)
参数 ptimer:指向要修改的定时器的指针
msec:定时器超时时间,单位:毫秒
repeat:定时器是否到期自动重启
返回值
说明 定时器是否可以到期自动重启依赖于系统实现,目前FreeRTOS平台定时器无法自动重新启动
函数原型 unsigned int aick_osal_get_free_mem_size(void)
参数
返回值 返回内存大小
说明 返回值单位依赖于系统实现;
FreeRTOS平台单位:byte
函数原型 void aick_osal_msleep(unsigned int ms)
参数 ms:毫秒
返回值
说明 睡眠制定时间并返回
函数原型 void aick_osal_sha256(
const unsigned char *in, size_t len,
unsigned char out[32], int is224)
参数 in:输入数据
len:数据长度
out:经过解密计算之后的数据
is224:是否使用224比特模式
返回值
说明 对输入数据进行SHA256计算
函数原型 int aick_osal_aes_crypt_cfb128(
size_t len,
unsigned char key
size_t
iv_off,
unsigned char iv[16],
const unsigned char input,
unsigned char
output)
参数 len:数据长度
key:解密用的秘钥
iv_off:初始化向量偏移值
iv:初始化向量
input:需要解密的数据
output:经过解密计算之后的数据
返回值
说明 AES CFB128位模式加密/解密,输入输出数据区可以重叠
函数原型 void aick_osal_hex2str(unsigned char src, char dst, int len)
参数 src:指向十六进制数据的指针
dst:用于存放转换后字串内存的指针
len:要转换的十六进制数据长度,单位:字节
返回值
说明 将指定的十六进制数据转换成字串

MQTT/网络相关API:

函数原型 s32 aick_ ssl_connect(aick_ssl_network *p_asn)
参数 p_asn:指向SSL network结构体
返回值 SSL连线成功返回0;失败返回错误码
说明 typedef struct aick_ssl_network {
Network n; / network变量 /
char root_ca; / 根证书 /
char
client_ca; / 客户端证书 /
char cliient_pk; / 客户端私钥 /
char
address; / SSL服务器网址 /
u32 port; / SSL服务器端口号 /
bool connected; / SSL连线状态 /
} aick_ssl_network;
从安全的角度考虑,SSL连线要求使用双向认证的方式进行。
函数原型 s32 aick_ ssl_disconnect(aick_ssl_network *p_asn)
参数 p_asn:指向SSL network结构体
返回值 SSL断线成功返回0;失败返回错误码
说明 断开SSL连线
函数原型 s32 aick_mqtt_ssl_connect(aick_ssl_network *p_asn)
参数 p_asn:指向SSL network结构体
返回值 SSL连线成功返回0;失败返回错误码
说明 建立到MQTT server的安全连接(SSL)
可直接呼叫aick_ssl_connect
函数原型 s32 aick_mqtt_ssl_disconnect(aick_ssl_network *p_asn)
参数 p_asn:指向SSL network结构体
返回值 SSL断线成功返回0;失败返回错误码
说明 断开MQTT server的安全连接(SSL)
可直接呼叫aick_ssl_disconnect
函数原型 s32 aick_mqtt_init(mqtt_client *cli)
参数 cli:指向MQTT client的指针
返回值 MQTT客户端初始化成功返回0;初始化失败返回负数
说明 初始化MQTT客户端
函数原型 s32 aick_mqtt_reg_rx_cb(mqtt_client *cli, mqtt_rx_cb handler)
参数 cli:指向MQTT 客户端的指针
handler:MQTT消息处理函数
返回值 注册成功返回0;注册失败返回负数
说明 注册MQTT消息处理函数
函数原型 s32 aick_mqtt_connect(mqtt_client cli, aick_mqtt_creditional cred)
参数 cli:指向MQTT 客户端的指针
cred:MQTT连线所需信息
返回值
说明 typedef struct aick_mqtt_creditional {
char user; / 用户名/
char
password; / 密码/
char client_id; / 客户端ID */
} aick_mqtt_creditional;
函数原型 s32 aick_mqtt_pub(mqtt_client cli, char topic, mqtt_message* message)
参数 cli:指向MQTT client的指针
topic:指向要发布的主题的指针
message:指向要发布的消息的指针
返回值 返回0代表消息发布成功;否则代表消息发布失败
说明 发布消息到MQTT服务器
typedef struct mqtt_message {
enum QoS qos; / 要发布的消息类型,跟MQTT协议匹配 /
void payload; / 指向发布的消息的指针 /
u32 payload_len; /
要发布的消息的长度 */
} mqtt_message;
函数原型 s32 aick_mqtt_sub(mqtt_client cli, char topic, enum QoS qos)
参数 cli:指向MQTT client的指针
topic:指向要注册的主题的指针
qos:此主题消息使用的qos数值
返回值 注册成功返回0;失败返回错误码
说明 cli->handler作为接收注册主题的消息
cli->handler=aick_mqtt_message_handler
函数原型 s32 aick_mqtt_yield(mqtt_client *cli)
参数 cli:指向MQTT client的指针
返回值 返回负数代表MQTT连线异常;返回0代表MQTT连线正常
说明 阻塞MQTT_MAX_YIELD_PERIOD_MS时间,并尝试去读取MQTT数据
函数原型 bool aick_mqtt_is_connected(mqtt_client *cli)
参数 cli:指向要查询的MQTT client指针
返回值 返回true代表MQTT client处于正常连线状态;false代表MQTT client处于断线状态
说明 查询MQTT client是否处于连线状态

Wi-Fi SDK提供的API

SDK提供的API供模组厂/品牌商使用。

函数列表

函数原型 const char *aick_get_sdk_version(void)
参数 获取SDK版本信息
返回值 指向SDK版本信息的字符串
说明
函数原型 bool aick_set_dev_version(char *ver)
参数 ver:设置Device端版本信息到SDK
返回值 SDK成果功能保存设备信息,返回true;否则返回false
说明 OTA升级会参考此版本信息决定设备是否需要升级
函数原型 bool aick_wlan_netcfg_start(void)
参数
返回值 配网过程成功开始,返回true;否则,返回false
说明 未配网状态通知SDK进入配网状态
函数原型 void aick_wlan_netcfg_stop(void)
参数
返回值
说明 通知SDK退出配网状态
函数原型 bool aick_wlan_netcfg_get_data(network_config_t *result)
参数 result:指向配网配置信息结构体的指针
返回值 获取望楼配置信息成功,返回false;否则,返回false
说明 从SDK获取配网信息
函数原型 bool aick_mqtt_client_start(void)
参数
返回值 此函数不会返回
说明 下面2个条件下SDK会触发与MQTT服务器的连接。
1. Wi-Fi连线成功或获取到IP地址之后(aick_wlan_ip_obtained)
2. 成功获取到SNTP时间(user_sntp_init -> sntp_get_current_timestamp)
函数原型 bool aick_mqtt_client_init(void)
参数
返回值 MQTT模块初始化成功,返回true;否则,返回false
说明 此函数会通过aick_wlan_get_product_info/ aick_wlan_get_device_info获取设备及产品信息,并完成MQTT模块初始化
函数原型 bool aick_mqtt_pub_msg(aick_mqtt_msg *p_msg)
参数 p_msg:指向MQTT消息的指针
返回值 MQTT消息publish成功,返回true;否则,返回false
说明 此过程为异步操作,此函数返回之后p_msg指针所指向的结构体会被复制一份并通知MQTT任务所在线程进行消息发布
函数原型 bool aick_mqtt_reg_op_cb(const char *key, aick_mqtt_op_cb cb)
参数 key:关键事件字符串
cb:接收关键事件消息的回调函数
返回值 注册成功,返回true;否则,返回false
说明 key请从下面关键字之一:
“control”:接收设备控制信息

bool aickmqtt_op_cb (char key, aick_mqtt_msg p_msg)
typedef struct _aick_mqtt_msg
{
char p_msgid; / MQTT服务器传送此控制信息所用的标识,如此控制信息需要回复,请使用相同的标识/
struct cJSON
p_parent; / 请勿对此指针及其指向内容做任何改变 /
char key; / 此消息对应的关键事件 /
struct cJSON
p_obj; / 关键事件内容 /
} aick_mqtt_msg;
关键内容为JSON格式,JSON字串及其value属性格式请参考“阿里精灵开放平台”对品类属性的定义
函数原型 unsigned int mqtt_client_do_reset(void)
参数 复位MQTT客户端
返回值 成功,返回0;否则,返回错误码
说明 此过程为异步操作,此函数返回之后,请勿对设备进行复位操作;设备端会需要与云端同步此操作,操作完成之后会呼叫aick_osal_delay_reboot对设备进行复位操作
函数原型 void aick_wlan_set_netconfig_state(AWLAN_STATE_TYPE state)
参数 设置设备配网状态状态
返回值
说明 在对设备进行恢复出厂设置的时候需要呼叫此函数,state传入AWLAN_STATE_INIT将网络配置状态设置为初始化状态
函数原型 AWLAN_STATE_TYPE aick_wlan_get_netconfig_state(void)
参数 获取设备配网状态
返回值
说明 在对设备进行复位操作的时候需要呼叫此函数,state传入AWLAN_STATE_INIT将网络配置状态设置为初始化状态
函数原型 bool mqtt_client_get_conn_status(void)
参数 获取设备MQTT状态连线状态
返回值 MQTT处于连接状态,返回true;否则,返回false
说明
函数原型 bool aick_ol_output(u8 level, char p_module, u16 status_code, char format, …)
参数 level:日志级别,参考log.h中LOG_LEVEL_xxx的定义
p_module:模块名称,参考log.h中M_XXX的定义
status_code:状态码,参考log.h中的定义
format:日志格式
…:日志内容
返回值 日志打印成功,返回true;否则,返回false
说明 打印日志到在线日志缓存中

API使用流程

未配网状态

IoTConnect Kit-Wi-Fi SDK - 图5

成功配网后

IoTConnect Kit-Wi-Fi SDK - 图6

参考代码请参考start_sample_thread.c中的start_sample_thread做法。

void sample_start_netconfig(void)
{
product_info_t p_product_info;
printf(“awifi sdk version:%s\n”, aick_get_sdk_version());
global_parameter_init();
p_product_info = global_get_product_into();
if (p_product_info->sta_cfg_status != STA_CFG_MQTT_CONNECTED) {
sample_netconfig_entry();
} else {
extern network_config_t g_network_cfg;
extern rtw_network_info_t sample_nw_info;
flash_get_network_config(&(g_network_cfg));

strcpy((char
)sample_nw_info.ssid.val, g_network_cfg.ssid);
sample_nw_info.ssid.len = strlen(g_network_cfg.ssid);
sample_nw_info.password = g_network_cfg.password;
printf(“wifi_password =%s\n”, sample_nw_info.password);
sample_nw_info.password_len = strlen(sample_nw_info.password);
/ Connect to connect to AP /
}
aick_mqtt_client_init(); / MQTT初始化 /
aick_mqtt_reg_op_cb(“control”, sample_mqtt_control_cb); / 注册回调函数 /
/ this API won’t return, it will connect to MQTT server after IP is obtained and start MQTT loop session /
aick_mqtt_client_start(); / 启动MQTT Client /
}

恢复出厂设置

用户配网成功后如需对设备进行重新配网,则需执行下面的流程:

void user_trigger_factory_reset (void)
{
flash_clear_network_config(); //clear network config data
aick_wlan_set_netconfig_state(AWLAN_STATE_INIT); // set netconfig state to INIT state
if(mqtt_client_get_conn_status()) // if MQTT is connected
{
mqtt_client_do_reset(); //MQTT reset function, must call this operation to finish state sync with MQTT server, do not reboot system here, mqtt_client_do_reset will reset system
}
else
{
aick_osal_delayed_reboot(0); // reboot system
}
return;
}


设备状态变化上报


void device_state_change(void) {
sample_mqtt_status_update(NULL);
}

/
p_msgid = NULL; when device’s status change is triggered by user’s manual operation
p_msgid = “xxxx”; when device’s status change is triggered from cloud,
xxxx should be same as p_msg->p_msgid, where p_msg is parsed from aiot lib via rtw_mqtt_control_cbs
/
bool sample_mqtt_status_update(char p_msgid)
{
cJSON
p_obj = NULL;
aick_mqtt_msg mqtt_msg;
mqtt_msg.key = NULL; / assign key to NULL /
mqtt_msg.p_msgid = p_msgid;
mqtt_msg.p_parent = NULL; / assign key to NULL /
p_obj = cJSON_CreateObject();
if (!p_obj) {
ERR_PRINT(“create json obj failed\n”);
return false;
}
/ Should read device’s status and encapslate into p_msg /
cJSON_AddNumberToObject(p_obj, “powerstate”, 0);
mqtt_msg.p_obj = p_obj;
aick_mqtt_pub_msg(&mqtt_msg);
cJSON_Delete(p_obj); / delete the json object /
return true;
}

MQTT服务器控制指令处理

请参考Wi-Fi品类对接说明部分

Wi-Fi 品类对接说明

请先用淘宝账户登录AliGenie开发者平台,登录之后,查看开发者平台开发文档。详细阅读“快速向导”根据实际情况选择适合自己产品的接入方式。
IoTConnect Kit-Wi-Fi SDK - 图7
下面以Wi-Fi直接连接方式为例,对“直接连接 - 设备调试”章节如何对设备的“产品、事件、服务”进行调试做一个简单的说明。
在开放平台“设备调试-功能测试(图形界面)”中选择 “负离子功能”的“开启”选项,点击“发送测试”, 云端会下发红框中的JSON字串给设备。

IoTConnect Kit-Wi-Fi SDK - 图8
如果此时设备已经上线,会收到下面的消息。

[D][mqtt_unify_msg_handler-831]:len:210 msg:{“messageId”:”610b2f81-d0b0-4454-a361-dd4bdee56869”,”namespace”:”AliGenie.Iot.Device.Service.Control”,”params”:{“data”:{“anionOnOff”:1},”mac”:”78da07fca0b4”,”productKey”:”1569”,”timestamp”:0},”version”:”1.0”}

[D][mqtt_operation_handler-713]:control found, p_msg:0x10016c58, p_obj:0x10022e50
[D] operation_handler:185 - p_msg->p_msgid:610b2f81-d0b0-4454-a361-dd4bdee56869, p_msg->p_obj:{
“anionOnOff”: 1
}


SDK收到云端发送的消息之后,会将此JSON字串封装在aick_mqtt_msg结构体中,传给经aick_mqtt_reg_op_cb(“control”, cb) 注册的cb回调函数作为参数。其中p_msg-> p_msgid即为” 610b2f81-d0b0-4454-a361-dd4bdee56869”,p_msg->p_ob为{“anionOnOff”:1}。
因为“负离子功能”的传输属性为“同时上报下发”,所以设备端在收到此消息之后,应该封装一个aick_mqtt_msg消息,此消息个结构体内容如下所示,呼叫aick_mqtt_pub_msg将设备此时的负离子功能状态回传给云端。(参考示例代码的“sample_mqtt_control_cb”函数实现)

aick_mqtt_msg {
char p_msgid:”610b2f81-d0b0-4454-a361-dd4bdee56869” – 同设备收到的控制命令中的msgid
struct cJSON
p_parent:NULL
char key:NULL
struct cJSON
p_obj: { “anionOnOff”: 1} – 负离子功能在设备端的实际状态,格式同设备收到控制命令中JSON字串格式
}
  1. 对于传输类型为“只上报”的属性,设备上线以及以后每次此属性的状态发生变化的时候均需将次属性信息上报给云端,方法同样为封装aick_mqtt_msg消息透过aick_mqtt_pub_msg上报,但此时p_msgid应该填成NULL。<br />比如,如果设备从离线切换到在线状态的时候,需上报“在线状态”属性信息到云端,对需要填充的aick_mqtt_msg结构体内容如下:
aick_mqtt_msg {
char p_msgid:NULL
struct cJSON
p_parent:NULL
char key:NULL
struct cJSON
p_obj: { “onlinestate”: 1} – 设备处于在线状态
}

IoTConnect Kit-Wi-Fi SDK - 图9