Skip to content

Release v0.4.0

Choose a tag to compare

@heshaoqiong-tuya heshaoqiong-tuya released this 27 Aug 09:48
· 55 commits to master since this release
238045b

Added

  • iot-client — device-initiated reset (iot_client_reset), for a device that
    unbinds itself instead of waiting to be removed from the app(#27).
    • OPRT_OK destroys the client; any other code leaves it usable so the call
      can be retried.
    • iot_reset_scope_t chooses how much the cloud clears(#28):
      IOT_RESET_UNBIND_ONLY drops the binding and keeps the device's cloud-side
      data, IOT_RESET_FACTORY also discards that data and cannot be undone.
    • The optional error_code out-param carries the cloud's rejection reason —
      needed to tell a terminal GATEWAY_NOT_EXISTS (wipe credentials, re-pair)
      from a retryable REMOTE_API_RUN_UNKNOW_FAILED.
    • It does not erase persisted credentials/DP state/schema; that stays the
      app's job. Shown in pair/api-activate --release.
  • iot-client — iot_client_get_session_token_ex() reports why the cloud
    refused an agent token(#29). The refusals need opposite handling — a terminal
    GATEWAY_NOT_EXISTS (device removed; re-pair) versus retryable ones — and the
    plain function cannot tell them apart.
  • iot-client — iot_client_connect() / iot_client_disconnect() are public(#26).
    A reconnect loop previously had to reach into src/iot_client_message.h,
    which is not installed.
  • iot-client — generic ATOP call (iot_atop_call), for cloud interfaces the SDK
    does not wrap by name(#19).
    • New public header iot_atop.h: pass an api name, its version and a JSON
      body; get the envelope's result back as a JSON string plus the cloud's
      errorCode / errorMsg. Activated devices only.
    • docs-site/docs/guides/atop-generic-call.md lists the named wrappers and
      when to promote an interface to one.
  • iot-client — cloud device-remove (protocol 11) callback(#18).
    • New iot_reset_callback_t / iot_reset_type_t; registering it makes the
      SDK consume protocol-11 notices instead of passing them to
      message_callback.
  • iot-client — OTA firmware digest verification (iot_ota_verify_*)(#17).
    • Streaming verifier (init / update / finish / abort) so a download can
      be checked without buffering the image.
  • common — coreMQTT and coreHTTP Error/Warn logs are routed into the SDK log
    facade (common/core_{mqtt,http}_config.h)(#24, #25).
    • A refused CONNECT now names the reason (Connection refused: bad user name or password.) instead of a bare MQTT_Connect failed: 6, and an oversized
      ATOP response says insufficient space: responseBufferLen=....
    • mqtt.c's own log lines print the symbolic MQTTStatus_t name alongside the
      number. docs-site/docs/reference/iot-client.md gains status and CONNACK
      tables for reading older logs.
    • Do not set MQTT_DO_NOT_USE_CUSTOM_CONFIG / HTTP_DO_NOT_USE_CUSTOM_CONFIG
      again — in either build path — or the reasons go silent.
  • iot-client — APP-confirmed OTA notice (protocol 15) callback(#21).
    • New iot_ota_confirm_callback_t on both config structs: the cloud pushes it
      once the user confirms the upgrade in the app, with the firmware channel.
      Registering it makes the SDK consume protocol-15 notices.
  • Examples — device-unbind demo (unbind_demo)(#18).
  • Examples — agent trigger demo (tai_agent_trigger_demo)(#22).
  • Examples — music play demo (tai_music_play_demo)(#12).
  • rtc-tcp-client — send an image and streamed audio as ONE multimodal event
    (tai_send_image_audio_start() / _chunk() / _end())(#20).
  • rtc-tcp-client — per-connection custom parameters on EventStart via
    tai_config_t.event_custom_param_json(#20).
  • rtc-tcp-client — tai_set_event_params() changes event parameters per turn,
    for devices that alternate between turn kinds(#20).

Changed

  • BREAKING iot-client — MQTT auto-connect is on by default;
    mqtt_auto_connect becomes mqtt_disable_auto_connect on both config
    structs(#26).
    • Migration: .mqtt_auto_connect = false → .mqtt_disable_auto_connect = true;
      .mqtt_auto_connect = true can be deleted. The rename means old code fails
      to compile rather than silently changing behaviour.
    • A failed auto-connect still returns NULL from iot_client_init(). Devices
      that may boot without a network, or that use ATOP over HTTP with no broker,
      must now opt out and drive the link themselves.
  • BREAKING iot-client — iot_get_qrcode_info and iot_get_ca_certificate
    write into caller-provided buffers; iot_qrcode_response_t is removed(#10).
  • BREAKING Examples — every POSIX example binary is named after its source
    file. The rtc-client (prebuilt UDP lib) demos gain a udp_ prefix:
    chat_demo / edu_camera_demo become udp_chat_demo / udp_edu_camera_demo.
  • Docs — the cloud-VAD turn boundary is TAI_EVT_CHAT_BREAK, not
    TAI_EVT_SERVER_VAD.
    • The cloud no longer sends TAI_EVT_SERVER_VAD (type 5) in cloud-VAD mode; it
      ends a user turn with an inbound TAI_EVT_CHAT_BREAK (type 4). The constant
      is kept for protocol compatibility but marked legacy.
  • Observability — diagnostic logging on previously-silent error paths (core
    modules + PAL)(#11). PAL logs errno on socket failures; tls_read/tls_write
    log the raw mbedTLS cause instead of collapsing to TLS_ERR_NET.
  • Examples — the rtc-tcp-client POSIX demos share their parsing helpers
    (demo_json.h, demo_text.h)(#14).

Fixed

  • iot-client — a cloud-rejected ATOP call reported success(#19). A success: false
    envelope logged errorCode / errorMsg, dropped them and returned OPRT_OK;
    it now returns OPRT_ATOP_BUSINESS_ERROR uniformly, with both strings on the
    response. Callers needing per-code policy branch on error_code.
  • iot-client — a peer that closed a non-TLS MQTT connection went unnoticed until
    the 60 s keepalive expired(#26): transport_recv() passed a 0 (EOF per pal.h)
    straight to coreMQTT, which reads it as "no data yet".
  • iot-client — tearing down an already-dead link no longer pushes a DISCONNECT
    into a socket that cannot carry it(#26). Only MQTTRecvFailed / MQTTSendFailed /
    MQTTKeepAliveTimeout count as dead; a completed exchange clears the flag.
  • iot-client — iot_client_deinit() wipes the client before freeing it(#27). devid,
    secret_key and local_key are plaintext in iot_client_t, and an embedded
    allocator hands the block to whatever mallocs next.
  • iot-client — US-East (UEAZ) and West-Europe (WEAZ) never resolved an MQTT
    broker(#15). iot_region_to_string() sent the enum name where the service
    expects the two-letter activation-token prefix.
  • iot-client — an ATOP response larger than the buffer reported a generic
    communication error(#23). REQUEST_HEADER_BUFFER_SIZE and
    RESPONSE_BUFFER_SIZE are now #ifndef-guarded so an application can size
    them with -D, and HTTPInsufficientMemory logs what was needed versus what
    the buffer holds. A product whose schema came back at contentLength 6558
    against the 4096 default looked like a network fault.
  • iot-client — SG region no longer falls back to the China ATOP host(#9).
  • iot-client — US region renamed to AZ(#7). The DNS region string and token
    prefix for US West (Oregon) is AZ, not US.
  • common/tls — a TLS 1.3 NewSessionTicket tore the session down(#20).
    MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET is a non-fatal "read again"
    signal that tls_read() treated as an error.
  • Examples — unbind-demo --reset no longer requires a working MQTT connection(#27).
    Reset travels over ATOP HTTPS, and gating it on CONNECT disabled the flag in
    the one case it exists for: a device the cloud has already unbound.
  • Examples — audio_chat_demo could not parse its session token on hosts where
    /opt/homebrew/include holds mbedtls 4.x headers: that directory lands first
    on this one target's include path (via find_path(opus)), shadowing the
    vendored 3.6.6 headers.
  • Examples — audio_chat_demo sends its one-shot file audio under the device-VAD
    attributes it actually implements (asr.enableVad).
  • Examples — the tool-less rtc-tcp-client demos answer MCP requests correctly:
    each reply now echoes the request id instead of a hardcoded "id":1(#14).
  • Examples — text streams that cannot be reassembled are reported, not dropped
    silently(#14).
  • Examples — NLG prose is unescaped before printing(#14).
  • Examples — a value too long for a display-only field truncates instead of
    being emptied(#14).
  • Examples — out-of-bounds read on received text: tai_text_msg_t.text is a
    borrowed, non-NUL-terminated slice(#14).
  • Examples — stack overflow from over-long argv credentials(#14).