IoTSDK接入
IoTSDK主要维护和服务器之间的信令连接,采用纯C实现,主要支持设备绑定、解绑、信令解析、物模型处理相关的操作。
IoTSDK-API 列表
IoTSDK 相关的 API 功能说明如下:
API 接口 | 功能说明 |
---|---|
xs_iot_init | SDK 初始化 |
xs_iot_unInit | SDK 反初始化 |
xs_iot_setLogLevel | 设置日志级别 |
xs_iot_open | 创建设备(包含主设备和子设备) |
xs_iot_connect | 建立设备连接 |
xs_iot_disconnect | 断开设备连接 |
xs_iot_close | 销毁设备 |
xs_iot_report | 上报物模型定义的属性和状态信息 |
xs_iot_setBindInfo | 设备绑定过程中使用,设置绑定信息 |
xs_iot_handleExternalMsg | 处理外部消息(streamsdk 回调的消息) |
xs_iot_notifyHostStatus | SDK分离模式下:用于告知 主控芯片(streamsdk 运行的芯片) 的运行状态 |
xs_iot_get_version | 获取SDK版本号 |
xs_iot_set_timezone | 设置时区信息,海外设备需要使用此接口,SDK内部会根据设置的时区信息处理夏令时切换机制 |
SDK接口调用流程
以普通长电IPC为例,SDK接口调用流程以及示例代码如下:
步骤1:初始化SDK
int initSdk()
{
/*初始化iotsdk回调函数指针*/
xs_iot_callbackFun_st cbFun;
initIotCallbackFun(&cbFun);
/*设置初始化参数*/
xs_iotInitParam_st initParam;
memset(&initParam, 0, sizeof(initParam));
initParam.configPath = "/etc/config"; //设置配置文件路径,flash中可读写路径
initParam.workMode = XS_IOT_WORK_MODE_LONG_TIME_POWER;
initParam.maxSubDeviceNum = 0; //没有子设备
initParam.regionType = 0; //国内设备
initParam.heartbeatInterval = 15; //最小15
/*初始化iotsdk*/
ret = xs_iot_init(&cbFun, &initParam);
return ret;
}
步骤2:创建设备并启动连接
int connectDevice()
{
int devId = xs_iot_open(XS_IOT_DEV_TYPE_MASTER, &deviceInfo);
if (devId < 0) {
LOG_PRINT("open device failed, err=%d\n", g_devId);
return -1;
}
LOG_PRINT("open device success, id=%d\n", g_devId);
/*创建设备连接*/
ret = xs_iot_connect(g_devId);
if (ret != XSIOT_EC_SUCCESS) {
LOG_PRINT("xs_iot_connect failed, code=%d\n", ret);
return -1;
}
return ret;
}
设备上线后,会将在线状态和绑定状态回调出来,具体可以参考设备上线章节
步骤3: 绑定设备
此步骤在设备配网绑定过程中才需要触发,一般是APP生成二维码、或者通过蓝牙、局域网等方式将绑定信息传到设备端,设备端解析出绑定信息(目前有bindToken以及regionId,regionId是可选字段),然后将绑定信息传入到SDK,
int bindDevice()
{
xs_bindInfo_st bindInfo;
bindInfo.bindToken = "797B05";
bindInfo.regionId = -1; //如果没有regionId,填为 -1
xs_iot_setBindInfo(&bindInfo);
return 0;
}
绑定结果通过回调函数通知设备层,具体细节参数设备绑定章节。
步骤4: 上报物模型属性&消息&固件版本号等
注意以下上报消息的动作,必须是设备在线且已经绑定过的状态 下才能上报,否则直接返回失败
/*测试上报属性值*/
void testReportProperty()
{
/*此处模拟上报声音侦测灵敏度*/
const char* property = "{\"VoiceDetectionSensitivity\":2,\"SoundDetectionSensitivity\":3,\"time\":\"1732691271662\"}"; //time字段不填默认为当前时间
xs_uint32 serviceId = 0;
xs_iot_report(g_devId, XS_IOT_MSG_POST_PROPERTY, property, strlen(property), &serviceId);
}
/*测试上报物模型自定义的事件消息*/
void testReportTslEvent()
{
/*此处模拟上报物模型自定义事件消息*/
char* eventId = "LockAllEvent"; /*物模型中定义的event Identifier*/
char* payload = (char*)malloc(512);
strcpy(payload, "{\"lockEvent\":[-59],\"type\":9}"); /*事件内容*/
xs_uint32 serviceId = 0;
xs_iot_report_event(g_devId, eventId, getCurrentUtcMs(), payload, strlen(payload), &serviceId);
free(payload);
}
/*设备上报版本号*/
void testOtaInform()
{
const char* inform = "{\"version\": \"1.1.0\",\"module\": \"MCU\"}";
xs_uint32 serviceId = 0;
xs_iot_report(g_devId, XS_IOT_MSG_OTA_INFORM, inform, strlen(inform), &serviceId);
}
功能接口详述
设备初始化
说明:
初始化函数必须在其他函数之前调用(xs_iot_setLogLevel/xs_iot_get_version 接口除外),主要用于初始化 SDK 内部一些资源,设备侧需要实现接口中定义的回调函数指针,并做相应处理
相关接口定义:
函数定义:
/**
* @brief 初始化函数
* @param [IN] cbFun: 回调函数指针列表
* @param [IN] initParam: 初始化参数
* @return 0:成功, 其他值:错误码
*/
xs_int32 xs_iot_init(xs_iot_callbackFun_st* cbFun, xs_iotInitParam_st* initParam);
初始化过程中,需要设置回调函数列表,设备需要处理的回调函数说明:
回调函数 | 说明 |
---|---|
xs_msgCallback | sdk内部消息的回调函数,设备侧收到此回调之后,直接将参数转给StreamSDK处理即可(xs_stream_inputIotMsg),不需要关心参数内容 |
xs_systimeCallback | 同步设备系统时间,SDK只负责同步主设备的系统时间,子设备的时间需要厂商自行处理 |
xs_logCallback | SDK日志回调 |
xs_bindStatusCallback | 设备绑定状态回调,注意绑定状态绑定过程中,或者每次登录服务器成功后都会回调,设备根据绑定状 态可以控制设备自身的状态 |
xs_connectStatusCallback | 设备在线、离线状态回调 |
xs_setPropertyCallback | 设置物模型属性的回调,关于物模型属性的格式定义,详细说明请参考下面的章节 |
xs_upgradeCallback | 设备升级回调 |
xs_serviceCallback | 设置物模型服务的回调 |
xs_serverAddressCallback | 服务器地址回调,一般不需要处理,有些特殊设备需要对ip地址和端口打开白名单需要处理此消息 |
xs_wakeupHostCallback | 唤醒主控streamsdk的回调(iotsdk和streamsdk运行在不同进程的时候需要处理此回调,将streamsdk主控唤醒) |
xs_cloudTokenCallback | 设备绑定成功或解绑时会调用此接口,应用层收到此回调需要将token保存到flash中,并在启动的时候放在初始化参数中传入SDK(initParm.cloudToken) |
xs_reportMsgCallback | xs_iot_report 和 xs_iot_report_event 上报消息结果的异步回调 |
xs_timezoneCallback | 时区信息回调 |
xs_keepliveCallback | 保活信息回调(非分离模式下的低功耗保活设备使用) |
初始化参数结构体:
/*初始化信息*/
typedef struct {
xs_uint32 maxSubDeviceNum; /*最大子设备个 数,普通IPC设备填0, 网关NVR设备 > 0*/
xs_iotWorkMode_en workMode; /*工作模式,主要区分低功耗设备和长电设备*/
xs_uint32 heartbeatInterval; /*心跳间隔,小于15默认为15秒,最大不超过180秒*/
xs_char* serverHostName; /*服务器域名,NULL表示使用SDK内部默认的(正式环境域名),最长不能超过127个字符*/
xs_char* configPath; /*flash中可读写的路径(例如 /etc/config/),sdk会在此路径下创建文件,保存一些配置信息数据,如果设备系统中不支持传入可读写路径,可以填写NULL(网关NVR设备必须支持), SDK配置文件大小不超过30KB*/
xs_char* cloudToken; /*设备绑定成功后的token信息,注意:如果configPath不为空,不需要填写此参数,固定为NULL即可,SDK内部会保存token信息。
*否则需要应用层将xs_cloudTokenCallback回调函数返回的信息保存到flash中,启动的时候在初始化参数中传入,没有就传NULL。*/
xs_uint32 regionType; /*region:0 表示国内,1表示国外*/
}xs_iotInitParam_st;
设备上线
- 设备侧调用 xs_iot_open 接口创建设备资源之后,才能对该设备进行操作(目前暂时不支持子设备)
- 设备侧调用 xs_iot_connect 接口,建立和信令服务器之间的连接通道
备注:xs_iot_connect 函数在设备无网络的时候也可以调用,SDK 内部会维护重连逻辑
接口定义:
/**
* @brief 创建设备,设备启动的时候必须先创建主设备,然后再创建子设备(目前暂时不支持子设备)
* @param [IN] devType: 设备类型,标识主设备或者子设备
* @param [IN] deviceParams: 设备参数信息
* @return >=0 表示设备ID,用于后续设备操作。 <0 表示创建失败的错误码
*/
xs_int32 xs_iot_open(xs_iotDeviceType_en devType, xs_deviceInfo_st* deviceParams);
/**
* @brief 建立设备和服务器的信令连接
* @return 0:成功, 其他值:错误码
*/
xs_int32 xs_iot_connect(xs_int32 devId);
设备在线/离线状态的回调函数通知如下,设备可以根据不同的状态做不同处理:
/**
* @brief 设备在线状态回调
* @param [IN] devId: 设备ID,xs_iot_open接口返回的ID,目前仅支持主设备
* @param [IN] connectStatus: 在线状态,1表示设备在线, 0 表示设备离线
* @return 0:成功, 其他值:错误码
*/
typedef xs_int32(*xs_connectStatusCallback)(xs_int32 devId, xs_int32 connectStatus);
创建设备的时候要将设备认证信息(三元组)传入SDK,productSecret目前可以填NULL
/*设备信息*/
typedef struct {
xs_char* productKey; /*产品型号, 长度不超过64,主设备必填*/
xs_char* productSecret; /*产品秘钥,长度不超过64,目前还没有实际用途,可以填NULL*/
xs_char* deviceName; /*设备序列号,长度不超过64,主设备和子设备都必填*/
xs_char* deviceSecret; /*设备秘钥,长度不超过64,主设备必填*/
}xs_deviceInfo_st;
时间同步
SDK连接云端之后,会触发同步系统时间的回调,设备需要将utc时间戳设置到系统中。
同步成功之后,SDK内部每8个小时定时检查是否需要重新同步时间,如果需要(时间差5秒以上),还会触发此回调。
/**
* @brief 同步设备系统时间[SDK只负责同步主设备的系统时间,子设备的时间需要厂商自行处理]
* @param [IN] utcTime: utc时间戳,毫秒
* @return 0:成功, 其他值:错误码
*/
typedef xs_int32(*xs_systimeCallback)(xs_uint64 utcTime);
设备绑定
注意:SDK不处理设备配网和连接Wifi相关的工作,此部分内容由设备侧和APP自行交互处理。
设备绑定过程中,APP需要将bindToken(参考 设备绑定开发指南)通过二维码(或者蓝牙、局域网等其他方式)传递给设备,设备解析成功之后,将bindToken信息(海外设备还会有个regionId信息),通过xs_iot_setBindInfo接口传递给IoTSDK。 IoTSDK调用云平台,确认bindToken的有效性,如果有效,则云平台会通知AppSDK发起绑定请求。绑定接口异步回调(xs_bindStatusCallback)给设备,设备需要监听绑定成功返回的token并保存。
相关接口:
/**
* @brief 设备绑定过程中使用,设备从app生成的二维码或者蓝牙声波等信息中提取出相应信息,通过此接口通知SDK,绑定结果通过 xs_bindStatusCallback 回调出来
* @param [IN] bindInfo: 绑定信息,目前包括app生成的临时绑定token以及regionId信息
* @return 0:成功, 其他值:错误码
*/
xs_int32 xs_iot_setBindInfo(const xs_bindInfo_st* bindInfo);
设备绑定结果回调通知如下:
/**
* @brief 设备绑定状态回调
* @param [IN] devId: 设备ID,xs_iot_open接口返回的ID,目前仅支持主设备
* @param [IN] bindStatus: 设备状态
* @param [IN] extra: 扩展信息,deviceStatus=DEVICE_STATUS_BIND_FAILED 时有效,返回错误原因和错误码
* @return 0:成功, 其他值:错误码
*/
typedef xs_int32(*xs_bindStatusCallback)(xs_int32 devId, xs_bindStatus_en bindStatus , const xs_char* extra);
注意点:
- 设备需要记录绑定状态,DEVICE_STATUS_BIND、DEVICE_STATUS_UNBIND 状态在设备每次启动或者重连的时候都会回调出来,设备需要自行判断当前状态,并做相应的控制。另外设备绑定成功的时候也会回调 DEVICE_STATUS_BIND
- 绑定失败或者绑定超时后,需要重新进入绑定流程
另外绑定成功后,IoTSDK会将设备认证token信息回调给设备,设备应用层需要将token信息保存到flash中。并且在每次启动的时候通过初始化接口传入SDK。
回调函数接口如下:
/**
* @brief 设备绑定成功或解绑时会调用此接口,应用层收到此回调需要将token保存到flash中,并在启动的时候放在初始化参数中传入SDK
* @param [IN] token: 绑定成功后的token信息,NULL表示需要清空flash中保存的token信息
*/
typedef xs_int32 (*xs_cloudTokenCallback)(const xs_char* token);
设备解绑
设备解绑的通知也是通过上述回调函数(xs_bindStatusCallback)进行通知,设备层收到解绑通知后,建议将设备 reset(清空本地配置信息),并重启设备进入绑定模式。同时也会触发xs_cloudTokenCallback 的回调,应用层清空保存的token信息