跳到主要内容

IoTSDK接入

更新时间:2025-04-25 18:01:31

IoTSDK主要维护和服务器之间的信令连接,采用纯C实现,主要支持设备绑定、解绑、信令解析、物模型处理相关的操作。

IoTSDK-API 列表

IoTSDK 相关的 API 功能说明如下:

API 接口功能说明
xs_iot_initSDK 初始化
xs_iot_unInitSDK 反初始化
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_notifyHostStatusSDK分离模式下:用于告知 主控芯片(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_msgCallbacksdk内部消息的回调函数,设备侧收到此回调之后,直接将参数转给StreamSDK处理即可(xs_stream_inputIotMsg),不需要关心参数内容
xs_systimeCallback同步设备系统时间,SDK只负责同步主设备的系统时间,子设备的时间需要厂商自行处理
xs_logCallbackSDK日志回调
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_reportMsgCallbackxs_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;

设备上线

  1. 设备侧调用 xs_iot_open 接口创建设备资源之后,才能对该设备进行操作(目前暂时不支持子设备)
  2. 设备侧调用 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连接云端之后,会触发同步系统时间的回调,设备需要将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信息通过xs_iot_setBindToken接口传递给IoTSDK。 IoTSDK调用云平台,确认bindToken的有效性,如果有效,则云平台会通知AppSDK发起绑定请求。绑定接口异步回调(xs_bindStatusCallback)给设备,设备需要监听绑定成功返回的token并保存。

相关接口:

/**
* @brief 设置绑定令牌信息(无线绑定需要),设备从app生成的二维码或者蓝牙声波等信息中提取出此字段,
* 连接wifi成功之后,通过此接口塞给sdk,绑定成功后,设备会收到 xs_deviceStatusCallback 的回调
* @param [IN] bindToken: app生成的临时绑定token
* @return 0:成功, 其他值:错误码
*/
xs_int32 xs_iot_setBindToken(const char* bindToken);

设备绑定结果回调通知如下:

/**
* @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);

注意点:

  1. 设备需要记录绑定状态,DEVICE_STATUS_BIND、DEVICE_STATUS_UNBIND 状态在设备每次启动或者重连的时候都会回调出来,设备需要自行判断当前状态,并做相应的控制。另外设备绑定成功的时候也会回调 DEVICE_STATUS_BIND
  2. 绑定失败或者绑定超时后,需要重新进入绑定流程

另外绑定成功后,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信息

物模型

物模型是对设备是什么,能做什么的描述,包括设备的属性(properties)、服务(services)、事件(events)等。RTCX-IOT 通过定义一种物的描述语言来描述物模型,称之为 TSL(即 Thing Specification Language)。

功能类型
说明
属性(Property)
用于描述设备运行时具体信息和状态。例如,环境监测设备所读取的当前环境温度、智能灯开关状态、电风扇风力等级等。属性可分为读写和只读两种类型。读写类型支持读取和设置属性值,只读类型仅支持读取属性值。
服务(Service)
指设备可供外部调用的指令或方法。服务调用中可设置输入和输出参数。输入参数是服务执行时的参数,输出参数是服务执行后的结果。相比于属性,服务可通过一条指令实现更复杂的业务逻辑,例如执行某项特定的任务。服务分为异步和同步两种调用方式。
事件(Event)
设备运行时,主动上报给云端的信息,一般包含需要被外部感知和处理的信息、告警和故障。事件中可包含多个输出参数。例如,某项任务完成后的通知信息;设备发生故障时的温度、时间信息;设备告警时的运行状态等。事件可以被订阅和推送。

接入客户可以在控制台管理页面配置和导出物模型定义,具体细节参考其他文档。

设备端、服务器、客户端交互的时候,必须严格按照物模型定义的参数和类型进行通信,否则会出现类型不匹配的问题,导致异常或者崩溃等问题

属性

SDK 提供了物模型属性的设置和上报接口,具体如下:

修改物模型参数

服务器或客户端修改物模型属性参数,会触发以下回调函数:

/**
* @brief 设置物模型属性的回调
* @param [IN] devId: 设备ID,xs_iot_open接口返回的ID,目前仅支持主设备
* @param [IN] property: 物模型属性,json字符串,支持同时修改多个属性,格式和物模型定义中的格式匹配
* @param [IN] propertyLength: 字符串长度
* @return 0:成功, 其他值:错误码
*/
typedef xs_int32(*xs_setPropertyCallback)(xs_int32 devId, const xs_char* property, xs_uint32 propertyLength);

参数格式说明

设备收到的property字段格式为json字符串,包含要修改的参数的key和value,举例如下:

{
"VoiceDetectionSensitivity": {
"value": 2
},
"SoundDetectionSensitivity": {
"value": 3
}
}

物模型属性上报

以下情况设备需要上报物模型参数到平台:

  1. 设备收到上述设置请求之后,修改对应参数值并且修改成功
  2. 设备启动后,或者设备绑定成功后

上报接口定义( msgType = XS_IOT_MSG_POST_PROPERTY):

/**
* @brief 上报消息到云端(主要包括物模型属性消息、事件消息、OTA相关消息)
* @param [IN] devId: xs_iot_open 接口返回的 deviceId
* @param [IN] msgType: 上报的消息类型
* @param [IN] payload: 消息内容,物模型中定义的带结束符(\0)的json格式字符串,格式参考文档定义
* @param [IN] payloadLen: 消息长度,不能超过4096字节
* @param [OUT] serviceId: 本地上报消息生成的serviceId,和回调(xs_reportMsgCallback)中的serviceId对应
* @return 0:成功, 其他值:错误码
* @note
* 1. 此接口需要设备已绑定且在线的情况下才能调用成功,否则会返回失败,返回失败后
* 2. 此接口为异步接口,调用成功仅代表塞入到本地消息队列中,不表示上报成功
* 3. 上报结果通过 xs_reportMsgCallback 回调函数通知
* 3. 如果内部上报失败,会有重传机制,一直重传失败(3次),会抛出上传失败的回调
*/
xs_int32 xs_iot_report(xs_int32 devId, xs_iotReportMsgType_en msgType, const xs_char* payload, xs_uint32 payloadLen, xs_uint32* serviceId);

参数格式说明

设备上报的payload参数为json格式,目前支持两种上报格式:

格式一:key/value/time格式:注意需要包含上报的参数的key以及value和time字段,举例如下:

{
"VoiceDetectionSensitivity": {
"value": 2,
"time":"1732691271662"
},
"SoundDetectionSensitivity": {
"value": 3,
"time":"1732691271662"
}
}

注意value值需要和物模型定义的格式保持一致,time字段为参数修改时的utc时间戳(毫秒)

格式二(建议采用):精简格式,支持按照 属性:值的格式进行上报,格式如下:

{
"VoiceDetectionSensitivity": 2,
"SoundDetectionSensitivity": 3,
"time": "1732691271662"
}

上面两种上报格式是相同的效果。

注意:

如果设备参数之间有互斥行为(比如人脸检测功能和车牌检测功能不能同时打开),设备自行处理互斥行为,并将修改后的其他参数值通过上述接口一并上报到平台。

另外,设备绑定成功或设备重启后,建议将所有属性打包一起上报到服务器,后续通过增量方式上报更新

事件

SDK支持通过下面2种方式上报自定义事件消息(例如开锁消息,传感器消息等),平台会保存用户上报的消息列表。

方式一:

xs_iot_report 接口:和上报接口和物模型属性的上报接口相同,区别是 上报的时候 msgType 值为 XS_IOT_MSG_POST_TSL_MSG

typedef enum {
...
XS_IOT_MSG_POST_TSL_MSG = 4, //上报自定义物模型IOT事件消息
} xs_iotReportMsgType_en;

上报数据的格式(payload)举例说明如下:

{
"LockAllEvent": [{
"value": {
"lockEvent": [-59],
"type": 9
},
"time": "1736919345687"
}]
}

其中,"LockAllEvent"为用户在控制台自定义的物模型消息类型(event Identifier),"value" 和 "time"为必填项,value的值为用户定义的消息参数结构体,time为事件发生的utc毫秒时间戳。

方式二:

xs_iot_report_event 接口:对xs_iot_report 接口进行了二次封装,达到和 xs_iot_report 接口相同的效果,区别是 xs_iot_report_event 是一次只能上报一种类型的事件,但是使用起来更加简单方便。


/**
* @brief 上报自定义事件消息到云端
* @param [IN] devId: xs_iot_open 接口返回的 deviceId
* @param [IN] eventId: 物模型中定义的事件类型, eventIdentifier
* @param [IN] utcms: utc时间戳,毫秒,如果填0, SDK内部会使用当前系统时间
* @param [IN] payload: 消息内容,物模型中定义的带结束符(\0)的json格式字符串,格式参考文档定义
* @param [IN] payloadLen: 消息长度,不能超过4096字节
* @return 0:成功, 其他值:错误码
* @note
* 1. 使用xs_iot_report 接口(msgType = XS_IOT_MSG_POST_TSL_MSG)也可以达到和此接口相同的效果,区别是使用此接口上报更加简单一些
* 2. 其他注意事项同 xs_iot_report 接口
*/
xs_int32 xs_iot_report_event(xs_int32 devId, const xs_char* eventId, xs_uint64 utcms, const xs_char* payload, xs_uint32 payloadLen, xs_uint32* 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);
}

其他视频相关的智能报警事件的上报主要是通过 StreamSDK 接口进行上报,可以参考 StreamSDK 的报警推送接口 xs_stream_postIntelligentAlarm

服务

物模型服务的回调函数如下,通过此回调可以控制设备 PTZ 操作,SD 卡格式化,容量查询、设备抓图等操作,具体支持的服务种类以用户定义的物模型模板为准:

/**
* @brief 设置物模型服务的回调,注意:回调完成后,SDK内部会用free函数释放response
* @param [IN] devId: 设备ID,xs_iot_open接口返回的ID,目前仅支持主设备
* @param [IN] serviceid: 物模型中定义的服务类型ID
* @param [IN] serviceidLen: serviceid的长度
* @param [IN] request: 物模型服务对应的json参数信息,格式参考物模型定义中的inputData
* @param [IN] request_len: 参数信息的长度
* @param [OUT] response: 返回的response,格式参考物模型定义中的outputData,如果没有返回值,则不需要处理此字段
* @param [OUT] responseLen: 返回的response的长度
* @return 0:成功, 其他值:错误码
*/
typedef xs_int32(*xs_serviceCallback)(xs_int32 devId, const xs_char *serviceid, const xs_uint32 serviceidLen,
const xs_char *request, const xs_uint32 request_len,
xs_char **response, xs_uint32 *responseLen);

用法示例:

/*处理物模型服务的消息回调,设备按照物模型中定义的Id 和参数进行解析*/
static xs_int32 handleServiceCallback(xs_int32 devId, const xs_char *serviceid, const xs_uint32 serviceidLen,
const xs_char *request, const xs_uint32 request_len,
xs_char **response, xs_uint32 *responseLen)
{
LOG_PRINT("handle service callback| devId:%d | serviceId:%s | request:%s\n",
devId, serviceid, request);

/* 此处需解析serviceId以及对应的输入参数
* 以开始操作PTZ转动为例(StartPTZAction), 设备收到的回调中:
* serviceId= "StartPTZAction", request = "{\"ActionType\":1,\"Speed\":2}"
*/
return XSIOT_EC_SUCCESS;
}

*注意:返回值中 response 如果不为 NULL,SDK 内部会调用 free 函数将其释放

OTA 固件在线升级

OTA固件升级功能,一般按照如下步骤操作:

  1. 设备上报版本号和对应模块信息
  2. 控制台配置升级包信息,和测试设备信息,并上传升级包到控制台
  3. APP检测到升级,点击升级按钮触发升级
  4. 设备收到固件升级的回调通知(upgradeCb 回调)
  5. 设备开始下载升级包、并安装,升级过程中需要上报下载和升级进度。

详细描述如下:

版本号上报

首先,设备端需上报版本号到平台。一般在设备首次上线后,通过 xs_iot_report 接口上报,具体可参考 Demo 的 testOtaInform 函数

/*设备上报版本号*/
void testOtaInform()
{
const char* inform = "{\"version\": \"1.1.0\",\"module\": \"default\"}";
xs_iot_report(g_devId, XS_IOT_MSG_OTA_INFORM, inform, strlen(inform));
}

设备端上报的内容为 Json 字符串,各字段含义如下

字段名称
是否必需
类型
说明
version

String
OTA 模块版本。
module

String
升级包所属的模块名。默认(default)模块

注意:消息中的 module 字段为模块名,一定要和控制台配置的升级包模块名一致,否则在控制台无法检测到升级包信息,如果设备有多个模块升级包,需要上报多次

固件升级

当固件升级包部署到平台,可以通过 App 发起 OTA 升级,此时设备端会收到 upgradeCb 回调,参数 upgradeInfo 为升级信息,其格式为 Json 字符串,各字段含义如下

字段名称
是否必需
类型
说明
version

String
设备升级包的版本信息
signMethod

String
签名方法。取值:SHA256MD5
files


多个升级包文件的信息列表。
-fileSize

Long
升级包文件大小,单位字节
-fileName

String
升级包文件的名称
-fileUrl

String
升级包下载链接
-fileSign

String
OTA 升级包文件的签名
module

String
升级包所属的模块名。默认(default)模块
extData

Object
升级批次标签列表和推送给设备的自定义信息。_package_udi 表示自定义信息的字段。单个标签格式:"key":"value"。

具体例子如下:

{
"version": "2.0.0",
"signMethod": "MD5",
"files": [
{
"fileSize": 123568,
"fileName": "ota-file1-name",
"fileUrl": "https://***1.tar.gz?Expires=1502955804&OSSAccessKeyId=***&Signature=***&security-token=***",
"fileSign": "******"
},
{
"fileSize": 235687,
"fileName": "ota-file2-name",
"fileUrl": "https://***2.tar.gz?Expires=1502955804&OSSAccessKeyId=***&Signature=***&security-token=***",
"fileSign": "******"
}
],
"module": "MCU",
"extData": {
"key1": "value1",
"key2": "value2",
"_package_udi": "{\"ota_notice\":\"升级底层摄像头驱动。\"}"
}
}

设备端解析得到升级包下载链接等信息,就可以下载升级包,并进行固件升级

进度上报

升级过程需上报升级进度到平台,通过 xs_iot_report 接口上报,具体可参考 Demo 的 testOtaProgress 函数

/*设备上报升级进度*/
void testOtaProgress()
{
const char* progress = "{\"step\":\"-1\",\"desc\":\"OTA升级失败。\",\"module\":\"default\"}";
xs_iot_report(g_devId, XS_IOT_MSG_OTA_PROGRESS, progress, strlen(progress));
}

设备端上报的内容为 Json 字符串,各字段含义如下

字段名称
是否必需
类型
说明
step

String

OTA 升级进度,小于 0 表示升级失败的情况,大于 0 表示升级状态-1:升级失败。-2:下载失败。-3:校验失败。-4:烧写失败。3:文件下载成功。4:升级中。5:升级成功
desc


String
当前步骤的描述信息,长度不超过 128 个字符。如果发生异常,此字段可承载错误信息。
module

String
升级包所属的模块名。默认(default)模块

海外时区设置

国内设备建议将设备时区固定为东八区,不需要处理时区设置功能。

海外设备时区设置,需要客户端APP修改标准物模型属性中的 TimezoneOffset 属性,SDK内部不做处理,需要设备侧自行处理物模型设置。

由于某些区域会有夏令时切换机制,因此当设备侧检测到时区修改之后,需要将时区的zoneId传入SDK,SDK内部判断是否需要切换夏令时,并触发相应回调。

  1. 设备启动后,或者用户修改了时区后,需要调用此API接口通知SDK
/**
* @brief 设置时区信息,海外设备需要使用此接口,SDK内部会根据设置的时区信息处理夏令时切换机制,如果该时区支持夏令时切换,会触发xs_timezoneCallback 的回调,反之则不会
* @param zoneId : 时区名称,例如Asia/Shanghai
* @note 初始化之后调用(如果有),以及时区修改的时候调用(app可以通过物模型(TimezoneOffset)修改时区),注意,sdk不会修改设备时区,此接口sdk内部处理夏令时切换机制
*/
xs_int32 xs_iot_set_timezone(const xs_char* zoneId);
  1. SDK通过云端接口判断此时区是否有夏令时、非夏令时切换逻辑,如果有,触发下面的回调,反之则不会触发此回调
/**
* @brief 时区和偏移量信息回调
* @param [IN] timezone: 时区信息,例如 "Asia/Shanghai",参考时区信息表
* @param [IN] offset: 时区偏移量,格式类似 "GMT+08:00" 或者 "GMT+8:00" 或者零时区 "GMTZ"
* @return 0:成功, 其他值:错误码
* @note 建议厂商将时区信息保存下来,每次启动之后先用保存的。如果收到SDK回调的,就将本地的覆盖掉。海外时区和夏令时切换机制SDK内部处理掉了,夏令时和非夏令时切换的时候会触发此回调
*/
typedef xs_int32(*xs_timezoneCallback)(const xs_char* timezone, const char* offset);