Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
(v4.4), `tuya.device.versions.update` (v4.1), and
`tuya.device.upgrade.status.update` (v4.1).
- `iot_ota_report_version` — reports the device's current firmware version
(also auto-called during `iot_client_init`, so the cloud can evaluate
upgrades).
(auto-called during `iot_client_init` from `iot_client_config_t.sw_ver`, so
the cloud can evaluate upgrades against the running version).
- `iot_ota_check_upgrade` — queries the cloud for a pending upgrade and
returns version, download URL (`cdnUrl` preferred, `httpsUrl` fallback),
file size, and MD5/HMAC hashes.
file size, and MD5/HMAC hashes. Takes no `sw_ver` argument — the cloud
compares against the version already reported at init.
- `iot_ota_report_status` — drives the upgrade lifecycle
(UPGRADING → FINI / EXEC / ABORT).
- **Application-supplied firmware version.** `iot_client_config_t.sw_ver` and
`iot_on_boarding_config_t.sw_ver` let the app report its own version
(`NULL` = SDK default `IOT_SDK_SW_VER`); `IOT_SDK_SW_VER` / `IOT_SDK_PV` /
`IOT_SDK_BV` are now `#ifndef`-guarded so they can also be overridden at
compile time.
- The SDK handles **only the cloud protocol**; the application owns download
and flash (e.g. ESP-IDF `esp_ota_*` or a vendor bootloader API).
- `atop_base` gains an AES-128-ECB fallback decrypt path for older (`et=1`)
cloud responses.
- Unit tests with mocked ATOP endpoints (`iot_ota_test`), a POSIX `ota-demo`,
and an ESP-IDF `ota-demo` with a two-partition OTA table.
and an ESP-IDF `ota-demo` with dual 4 MB OTA partitions on 16 MB flash
(sized for ~4 MB firmware images).

### Changed

Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- 图片理解与生成
- 设备侧 MCP(Model Context Protocol)支持
- 设备数据点(DP)管理:schema 校验、本地缓存、批量上报、下行回调、状态持久化
- OTA 固件升级:云端协议(版本上报 / 升级检查 / 状态回报),下载与烧录由应用负责
- 芯片和操作系统无关:macOS、Linux、FreeRTOS (ESP32)、MIPS、ARM
- 全球化部署,支持多数据中心区域

Expand All @@ -17,7 +18,7 @@
|------|--------|------|
| RTC TCP Client | `tuya_ai.h` | tRTC(tuya自研RTC协议) TCP 实现,开源实现,PAL 可移植 |
| RTC Client | `stm_open.h` | tRTC(tuya自研RTC协议) UDP 实现,预编译静态库形式 |
| IoT Client | `iot_client.h`、`iot_dp.h` | 设备激活、MQTT 连接、会话令牌获取;数据点(DP)管理(schema 校验 / 缓存 / 上下行 / 持久化) |
| IoT Client | `iot_client.h`、`iot_dp.h`、`iot_ota.h` | 设备激活、MQTT 连接、会话令牌获取;数据点(DP)管理(schema 校验 / 缓存 / 上下行 / 持久化);OTA 固件升级(云端协议) |
| Tuya BLE | `tuya_ble_nimble.h` | BLE 蓝牙配网(ESP-IDF) |

## 环境要求
Expand Down Expand Up @@ -64,6 +65,9 @@ cmake --build build

# 设备数据点(DP)管理
./build/dp_management_demo

# OTA 固件升级(云端协议)
./build/ota_demo
```

## 项目结构
Expand Down
8 changes: 6 additions & 2 deletions README_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ Multimodal device-side SDK for connecting smart hardware to the Tuya AI platform
- Image understanding and generation
- Device-side MCP (Model Context Protocol) support
- Device data point (DP) management: schema validation, local cache, batch reporting, downlink callbacks, state persistence
- OTA firmware upgrade: cloud protocol (version report / upgrade check / status report); download and flash owned by the application
- Platform and chip agnostic: macOS, Linux, FreeRTOS (ESP32), MIPS, ARM
- Global deployment with multiple data center regions

## SDK Modules

| Module | Header | Description |
|--------|--------|-------------|
| RTC TCP Client | `tuya_ai.h` | tRTC (Tuya RTC protocol), TCP implementation, fullly open sourced with PAL portability |
| RTC TCP Client | `tuya_ai.h` | tRTC (Tuya RTC protocol), TCP implementation, fully open sourced with PAL portability |
| RTC Client | `stm_open.h` | tRTC (Tuya RTC protocol), UDP implementation, pre-compiled static library |
| IoT Client | `iot_client.h`, `iot_dp.h` | Device activation, MQTT, session token; Data Point (DP) management (schema validation / cache / up- & downlink / persistence) |
| IoT Client | `iot_client.h`, `iot_dp.h`, `iot_ota.h` | Device activation, MQTT, session token; Data Point (DP) management (schema validation / cache / up- & downlink / persistence); OTA firmware upgrade (cloud protocol) |
| Tuya BLE | `tuya_ble_nimble.h` | BLE provisioning (ESP-IDF) |

## Prerequisites
Expand Down Expand Up @@ -62,6 +63,9 @@ Then run:

# Device data point (DP) management
./build/dp_management_demo

# OTA firmware upgrade (cloud protocol)
./build/ota_demo
```

## Project Structure
Expand Down
22 changes: 12 additions & 10 deletions docs-site/docs/guides/ota-upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ SDK 只提供**云端协议原语**——版本上报、升级查询、状态回

| API | 云端接口 | 用途 |
|-----|---------|------|
| `iot_ota_report_version` | `tuya.device.versions.update` (v4.1) | 上报当前固件版本(`iot_client_init` 也会自动调用) |
| `iot_ota_check_upgrade` | `tuya.device.upgrade.get` (v4.4) | 查询是否有待升级固件,返回 URL / 版本 / 大小 / 哈希 |
| `iot_ota_report_version` | `tuya.device.versions.update` (v4.1) | 上报当前固件版本(`iot_client_init` 会用 `iot_client_config_t.sw_ver` 自动调用,NULL 时用 SDK 默认 `IOT_SDK_SW_VER`) |
| `iot_ota_check_upgrade` | `tuya.device.upgrade.get` (v4.4) | 查询是否有待升级固件,返回 URL / 版本 / 大小 / 哈希(云端与已上报的版本比较,不再传版本号) |
| `iot_ota_report_status` | `tuya.device.upgrade.status.update` (v4.1) | 回报升级生命周期状态 |

### `iot_ota_check_upgrade` 返回的升级信息
Expand All @@ -49,7 +49,7 @@ SDK 只提供**云端协议原语**——版本上报、升级查询、状态回
typedef struct {
bool has_upgrade; // 云端是否有升级
char *version; // 目标版本号
char *url; // 固件下载 URL(HTTPS
char *url; // 固件下载 URL(优先 cdnUrl,回退 httpsUrl
long file_size; // 固件大小(字节)
int channel; // 固件通道(0 = 主 MCU)
char *md5; // MD5 校验(可能为 NULL)
Expand Down Expand Up @@ -77,24 +77,24 @@ typedef enum {

### 1. 分区表

OTA 需要两个 app 分区(`ota_0` / `ota_1`)和一个 `otadata` 分区。demo 使用的 `partitions.csv`(8MB flash):
OTA 需要两个 app 分区(`ota_0` / `ota_1`)和一个 `otadata` 分区。demo 使用的 `partitions.csv`(16MB flash,每个 app 分区 4MB,可容纳约 4MB 的固件):

```csv
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
otadata, data, ota, 0x10000, 0x2000,
ota_0, app, ota_0, 0x20000, 1500K,
ota_1, app, ota_1, , 1500K,
ota_0, app, ota_0, 0x20000, 4M,
ota_1, app, ota_1, , 4M,
```

### 2. sdkconfig 关键项

```ini
# 给 TLS + HTTP + esp_ota 留够栈
CONFIG_ESP_MAIN_TASK_STACK_SIZE=16384
# 8MB flash
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
# 16MB flash(容纳双 4MB OTA 分区)
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
# 自定义分区表
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
Expand All @@ -120,12 +120,14 @@ iot_client_config_t iot_cfg = {
.env = DEFAULT_ENV,
/* mqtt_auto_connect = false: 只用 ATOP HTTP,不连 MQTT */
.mqtt_auto_connect = false,
/* 应用固件版本:init 时自动上报,供云端 OTA 比较(NULL 用 SDK 默认) */
.sw_ver = desc->version,
};
iot_client_t *iot = iot_client_init(&iot_cfg);

/* 查询升级,传入当前版本号供云端比较 */
/* 查询升级(云端与 init 时上报的 sw_ver 比较,无需再传版本号) */
iot_ota_upgrade_info_t info = {0};
int rc = iot_ota_check_upgrade(iot, 0, desc->version, &info);
int rc = iot_ota_check_upgrade(iot, 0, &info);
if (rc == OPRT_OK && info.has_upgrade) {
ESP_LOGI(TAG, "upgrade -> %s url=%s size=%ld",
info.version, info.url, info.file_size);
Expand Down
5 changes: 5 additions & 0 deletions docs-site/docs/reference/iot-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ sidebar_position: 3
| `cacert` | `const char *` | CA 证书 PEM(用于 MQTT/HTTPS/IoT-DNS TLS,调用方持有,需在 client 生命周期内有效) |
| `cert_bundle_attach` | `tls_cert_bundle_attach_fn` | 平台证书包回调(如 ESP-IDF 的 `esp_crt_bundle_attach`),NULL 表示不使用。详见 [TLS 证书验证](../guides/tls-cert-verification.md) |
| `message_callback` | `iot_message_callback_t` | MQTT 消息回调,可为 NULL |
| `schema` | `const char *` | 重启时用于恢复的 DP schema JSON(调用方持有,NULL = 不恢复 / 宽松模式) |
| `schema_id` | `const char *` | 持久化的 schema id(schema 升级查询的稳定 key,可为 NULL) |
| `dp_state` | `const char *` | 持久化的 DP 当前状态 `{"dps":{...}}`,用于恢复(不置脏、不上报,可为 NULL) |
| `sw_ver` | `const char *` | 应用固件版本号(如 `"1.2.3"`),`iot_client_init` 时自动上报供云端 OTA 比较;NULL 表示使用 SDK 默认 `IOT_SDK_SW_VER`。详见 [OTA 升级](../guides/ota-upgrade.md) |

### `iot_on_boarding_config_t`

Expand All @@ -114,6 +118,7 @@ sidebar_position: 3
| `cacert` | `const char *` | CA 证书 PEM(用于 MQTT/HTTPS/IoT-DNS TLS,调用方持有) |
| `cert_bundle_attach` | `tls_cert_bundle_attach_fn` | 平台证书包回调(如 ESP-IDF 的 `esp_crt_bundle_attach`),NULL 表示不使用。详见 [TLS 证书验证](../guides/tls-cert-verification.md) |
| `message_callback` | `iot_message_callback_t` | MQTT 消息回调 |
| `sw_ver` | `const char *` | 应用固件版本号(如 `"1.2.3"`),激活后自动上报供云端 OTA 比较;NULL 表示使用 SDK 默认 `IOT_SDK_SW_VER`。详见 [OTA 升级](../guides/ota-upgrade.md) |

### `iot_client_t`(返回实例)

Expand Down
2 changes: 1 addition & 1 deletion examples/esp-idf/ota-demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Demonstrates a complete firmware OTA upgrade flow using the agentic-kit `iot_ota

## Partition Table

Uses a custom partition table (`partitions.csv`) with two 1.5MB OTA partitions (`ota_0`, `ota_1`) on 8MB flash. The binary is ~1.1MB (WiFi + TLS + HTTP + OTA).
Uses a custom partition table (`partitions.csv`) with two 4MB OTA partitions (`ota_0`, `ota_1`) on 16MB flash, sized for firmware images up to ~4MB. The demo binary itself is ~1.1MB (WiFi + TLS + HTTP + OTA).

## How It Works

Expand Down
3 changes: 2 additions & 1 deletion examples/esp-idf/ota-demo/main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ void app_main(void)
.schema = NULL,
.schema_id = NULL,
.dp_state = NULL,
.sw_ver = desc->version,
};
memcpy((char *)iot_cfg.devid, DEFAULT_DEVID, strlen(DEFAULT_DEVID));
memcpy((char *)iot_cfg.secret_key, DEFAULT_SECRET_KEY, strlen(DEFAULT_SECRET_KEY));
Expand All @@ -317,7 +318,7 @@ void app_main(void)

/* 3. Check cloud for firmware upgrade */
iot_ota_upgrade_info_t info = {0};
int rc = iot_ota_check_upgrade(iot, 0, desc->version, &info);
int rc = iot_ota_check_upgrade(iot, 0, &info);
if (rc != OPRT_OK) {
ESP_LOGE(TAG, "iot_ota_check_upgrade failed: %d", rc);
iot_ota_upgrade_info_free(iot, &info);
Expand Down
4 changes: 2 additions & 2 deletions examples/esp-idf/ota-demo/partitions.csv
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
otadata, data, ota, 0x10000, 0x2000,
ota_0, app, ota_0, 0x20000, 1500K,
ota_1, app, ota_1, , 1500K,
ota_0, app, ota_0, 0x20000, 4M,
ota_1, app, ota_1, , 4M,
2 changes: 1 addition & 1 deletion examples/esp-idf/ota-demo/sdkconfig.defaults
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# OTA needs enough stack for TLS + HTTP + esp_ota writes
CONFIG_ESP_MAIN_TASK_STACK_SIZE=16384
CONFIG_MBEDTLS_HKDF_C=y
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_SPIRAM=y
Expand Down
23 changes: 7 additions & 16 deletions examples/posix/ota-demo/ota_demo.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ int demo_ota_run(const char *devid, const char *secret_key, const char *local_ke
.env = PROD,
.mqtt_disable_tls = false,
.mqtt_auto_connect = false,
.sw_ver = sw_ver,
};
strncpy(cfg.devid, devid, sizeof(cfg.devid) - 1);
strncpy(cfg.secret_key, secret_key, sizeof(cfg.secret_key) - 1);
Expand All @@ -108,22 +109,12 @@ int demo_ota_run(const char *devid, const char *secret_key, const char *local_ke
fprintf(stderr, "[%s] iot_client_init failed\n", TAG);
return -1;
}
printf("[%s] client initialized (devid=%s)\n", TAG, client->devid);
printf("[%s] client initialized (devid=%s, sw_ver=%s)\n", TAG, client->devid, sw_ver);

/* 2. Report current firmware version */
printf("[%s] reporting firmware version: %s\n", TAG, sw_ver);
int rc = iot_ota_report_version(client, sw_ver);
if (rc != OPRT_OK) {
fprintf(stderr, "[%s] iot_ota_report_version failed: %d\n", TAG, rc);
/* non-fatal — continue to upgrade check */
} else {
printf("[%s] version reported successfully\n", TAG);
}

/* 3. Check for firmware upgrade */
/* 2. Check for firmware upgrade */
printf("[%s] checking cloud for firmware upgrade...\n", TAG);
iot_ota_upgrade_info_t info = {0};
rc = iot_ota_check_upgrade(client, 0, sw_ver, &info);
int rc = iot_ota_check_upgrade(client, 0, &info);
if (rc != OPRT_OK) {
fprintf(stderr, "[%s] iot_ota_check_upgrade failed: %d\n", TAG, rc);
iot_ota_upgrade_info_free(client, &info);
Expand All @@ -138,7 +129,7 @@ int demo_ota_run(const char *devid, const char *secret_key, const char *local_ke
return 0;
}

/* 4. Print upgrade info */
/* 3. Print upgrade info */
printf("[%s] ===== firmware upgrade available =====\n", TAG);
printf("[%s] version : %s\n", TAG, info.version ? info.version : "?");
printf("[%s] url : %s\n", TAG, info.url);
Expand All @@ -147,14 +138,14 @@ int demo_ota_run(const char *devid, const char *secret_key, const char *local_ke
printf("[%s] md5 : %s\n", TAG, info.md5 ? info.md5 : "(none)");
printf("[%s] hmac : %s\n", TAG, info.hmac ? info.hmac : "(none)");

/* 5. Report UPGRADING status */
/* 4. Report UPGRADING status */
printf("[%s] reporting UPGRADING status...\n", TAG);
rc = iot_ota_report_status(client, info.channel, OTA_STATUS_UPGRADING);
if (rc != OPRT_OK) {
fprintf(stderr, "[%s] failed to report UPGRADING: %d\n", TAG, rc);
}

/* 6. Optionally download the firmware image */
/* 5. Optionally download the firmware image */
int result = 0;
if (auto_download && info.url) {
char out_path[256];
Expand Down
2 changes: 2 additions & 0 deletions modules/iot-client/include/iot_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ typedef struct {
const char *schema; // Persisted DP schema JSON to restore on restart (NULL = none / loose mode)
const char *schema_id; // Persisted schema id (stable key for schema upgrade query)
const char *dp_state; // Persisted DP current state {"dps":{...}} to restore (no dirty, no report)
const char *sw_ver; // Application firmware version (e.g. "1.2.3"); NULL = use SDK default IOT_SDK_SW_VER
} iot_client_config_t;

/**
Expand All @@ -121,6 +122,7 @@ typedef struct {
const char *cacert; // CA cert for all TLS (MQTT/HTTPS/IoT-DNS) (PEM, caller-owned, must outlive client)
tls_cert_bundle_attach_fn cert_bundle_attach; // Platform cert-bundle callback (NULL = none)
iot_message_callback_t message_callback; // MQTT message callback
const char *sw_ver; // Application firmware version (e.g. "1.2.3"); NULL = use SDK default IOT_SDK_SW_VER
} iot_on_boarding_config_t;


Expand Down
3 changes: 0 additions & 3 deletions modules/iot-client/include/iot_ota.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,11 @@ OTA_API int iot_ota_report_version(iot_client_t *client, const char *sw_ver);
*
* @param[in] client IoT client instance (must be initialized)
* @param[in] channel Firmware channel (0 = main MCU firmware)
* @param[in] sw_ver Current firmware version string sent to cloud for
* comparison (e.g. "1.0.0"); pass NULL to omit
* @param[out] info Output: upgrade info (caller must free with
* iot_ota_upgrade_info_free())
* @return OPRT_OK on success (including no-upgrade case), error code on failure
*/
OTA_API int iot_ota_check_upgrade(iot_client_t *client, int channel,
const char *sw_ver,
iot_ota_upgrade_info_t *info);

/**
Expand Down
3 changes: 0 additions & 3 deletions modules/iot-client/src/atop.c
Original file line number Diff line number Diff line change
Expand Up @@ -746,9 +746,6 @@ int atop_upgrade_get(const pal_t *pal, const ota_upgrade_request_t *request, ota
return OPRT_MALLOC_FAILED;
}
cJSON_AddNumberToObject(root, "type", request->channel);
if (request->sw_ver && request->sw_ver[0] != '\0') {
cJSON_AddStringToObject(root, "softVer", request->sw_ver);
}
cJSON_AddNumberToObject(root, "t", (double)timestamp);

char *post_data = cJSON_PrintUnformatted(root);
Expand Down
1 change: 0 additions & 1 deletion modules/iot-client/src/atop.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@ typedef struct {
const char *devid;
const char *key;
int channel; /**< firmware type/channel (0 = main MCU) */
const char *sw_ver; /**< current firmware version (sent as softVer for server-side comparison) */
const char *host;
uint16_t port;
const char *cacert;
Expand Down
17 changes: 14 additions & 3 deletions modules/iot-client/src/iot_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,10 @@ IOT_API iot_client_t *iot_client_init(const iot_client_config_t *config)

/* Report firmware version to cloud (enables OTA upgrade checks) */
{
int ret = iot_ota_report_version(client, IOT_SDK_SW_VER);
const char *fw_ver = (config->sw_ver && config->sw_ver[0])
? config->sw_ver
: IOT_SDK_SW_VER;
int ret = iot_ota_report_version(client, fw_ver);
if (ret != OPRT_OK) {
log_warn("iot_ota_report_version failed: %d (non-fatal)", ret);
}
Expand Down Expand Up @@ -322,7 +325,10 @@ IOT_API iot_client_t *iot_client_init_on_boarding(const iot_on_boarding_config_t
strncpy(ob_cfg.authkey, config->authkey, sizeof(ob_cfg.authkey) - 1);
strncpy(ob_cfg.product_key, config->product_key, sizeof(ob_cfg.product_key) - 1);

strncpy(ob_cfg.sw_ver, IOT_SDK_SW_VER, sizeof(ob_cfg.sw_ver) - 1);
const char *sw_ver = (config->sw_ver && config->sw_ver[0])
? config->sw_ver
: IOT_SDK_SW_VER;
strncpy(ob_cfg.sw_ver, sw_ver, sizeof(ob_cfg.sw_ver) - 1);
strncpy(ob_cfg.pv, IOT_SDK_PV, sizeof(ob_cfg.pv) - 1);
strncpy(ob_cfg.bv, IOT_SDK_BV, sizeof(ob_cfg.bv) - 1);

Expand Down Expand Up @@ -362,6 +368,7 @@ IOT_API iot_client_t *iot_client_init_on_boarding(const iot_on_boarding_config_t
client_config.cacert = config->cacert;
client_config.cert_bundle_attach = config->cert_bundle_attach;
client_config.message_callback = config->message_callback;
client_config.sw_ver = sw_ver;
/* schema / schema_id come from the activation response. iot_client_init()
* copies them and rebuilds the DP registry from the schema (dp_state is then
* initialized from the schema); first activation has no persisted DP values. */
Expand Down Expand Up @@ -413,7 +420,10 @@ IOT_API iot_client_t *iot_client_init_on_boarding_with_token(const iot_on_boardi
strncpy(ob_cfg.authkey, config->authkey, sizeof(ob_cfg.authkey) - 1);
strncpy(ob_cfg.product_key, config->product_key, sizeof(ob_cfg.product_key) - 1);

strncpy(ob_cfg.sw_ver, IOT_SDK_SW_VER, sizeof(ob_cfg.sw_ver) - 1);
const char *sw_ver = (config->sw_ver && config->sw_ver[0])
? config->sw_ver
: IOT_SDK_SW_VER;
strncpy(ob_cfg.sw_ver, sw_ver, sizeof(ob_cfg.sw_ver) - 1);
strncpy(ob_cfg.pv, IOT_SDK_PV, sizeof(ob_cfg.pv) - 1);
strncpy(ob_cfg.bv, IOT_SDK_BV, sizeof(ob_cfg.bv) - 1);

Expand Down Expand Up @@ -450,6 +460,7 @@ IOT_API iot_client_t *iot_client_init_on_boarding_with_token(const iot_on_boardi
client_config.cacert = config->cacert;
client_config.cert_bundle_attach = config->cert_bundle_attach;
client_config.message_callback = config->message_callback;
client_config.sw_ver = sw_ver;
/* schema / schema_id come from the activation response. iot_client_init()
* copies them and rebuilds the DP registry from the schema (dp_state is then
* initialized from the schema); first activation has no persisted DP values. */
Expand Down
Loading
Loading