Sub-device management
Program a gateway product by using the src/dev_model/examples/linkkit_example_gateway.c example.
Terminology
|
Term |
Description |
|
Gateway |
A device that connects directly to IoT Platform. It has sub-device management features and can act as a proxy for sub-devices to connect to the cloud. |
|
Sub-device |
A device that cannot connect directly to IoT Platform. It can only connect through a gateway. |
|
Device ID |
A device handle that identifies a specific device in a gateway scenario. It is returned when you call |
|
Topology |
The association between a sub-device and a gateway. Once established, the sub-device reuses the gateway's physical channel for data communication. |
|
Dynamic sub-device registration |
The sub-device reports its ProductKey and DeviceName to the gateway, which authenticates with the cloud on the sub-device's behalf. The cloud returns a deviceSecret used to bring the sub-device online. |
Manage sub-devices
-
Establish a connection between the gateway and the cloud.
The connection procedure for a gateway is the same as for a standalone device.
-
Call
IOT_RegisterCallbackto register callback functions for connection events, initialization completion, and property settings. The gateway and sub-devices share one set of callbacks, distinguished by the DeviceID parameter.IOT_RegisterCallback(ITE_CONNECT_SUCC, user_connected_event_handler); IOT_RegisterCallback(ITE_DISCONNECTED, user_disconnected_event_handler); IOT_RegisterCallback(ITE_PROPERTY_SET, user_property_set_event_handler); IOT_RegisterCallback(ITE_REPORT_REPLY, user_report_reply_event_handler); IOT_RegisterCallback(ITE_TIMESTAMP_REPLY, user_timestamp_reply_event_handler); IOT_RegisterCallback(ITE_INITIALIZE_COMPLETED, user_initialized); IOT_RegisterCallback(ITE_PERMIT_JOIN, user_permit_join_event_handler); -
Call
IOT_Ioctlto configure the server region and whether to use per-device certificates./* Choose Login Server */ int domain_type = IOTX_CLOUD_REGION_SHANGHAI; IOT_Ioctl(IOTX_IOCTL_SET_DOMAIN, (void *)&domain_type); /* Choose Login Method */ int dynamic_register = 0; IOT_Ioctl(IOTX_IOCTL_SET_DYNAMIC_REGISTER, (void *)&dynamic_register); -
Call
IOT_Linkkit_Openwith theIOTX_LINKKIT_DEV_TYPE_MASTERparameter to initialize the master device resources.iotx_linkkit_dev_meta_info_t master_meta_info; memset(&master_meta_info, 0, sizeof(iotx_linkkit_dev_meta_info_t)); memcpy(master_meta_info.product_key, PRODUCT_KEY, strlen(PRODUCT_KEY)); memcpy(master_meta_info.product_secret, PRODUCT_SECRET, strlen(PRODUCT_SECRET)); memcpy(master_meta_info.device_name, DEVICE_NAME, strlen(DEVICE_NAME)); memcpy(master_meta_info.device_secret, DEVICE_SECRET, strlen(DEVICE_SECRET)); /* Create Master Device Resources */ user_example_ctx->master_devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_MASTER, &master_meta_info); if (user_example_ctx->master_devid < 0) { EXAMPLE_TRACE("IOT_Linkkit_Open Failed\n"); return -1; } -
Call
IOT_Linkkit_Connectwith theIOTX_LINKKIT_DEV_TYPE_MASTERparameter to establish a connection to the cloud./* Start Connect Aliyun Server */ res = IOT_Linkkit_Connect(user_example_ctx->master_devid); if (res < 0) { EXAMPLE_TRACE("IOT_Linkkit_Connect Failed\n"); return -1; } -
In the event handler for
ITE_INITIALIZE_COMPLETED, confirm that the gateway connection is initialized. You can then proceed to add sub-devices.
NoteDo not perform operations that block threads in the callback functions registered in Step 1. Examples include calling
IOT_Linkkit_Connectto connect a sub-device or callingIOT_Linkkit_Reportto bring a sub-device online or take it offline. -
-
Add a sub-device.
This process involves four steps.
-
Call
IOT_Linkkit_Openwith theIOTX_LINKKIT_DEV_TYPE_SLAVEparameter to initialize the sub-device resources.NoteFor dynamic registration, set
device_secretto an empty string and register the sub-device's DeviceName in the IoT Platform console. -
Call
IOT_Linkkit_Connectto connect the sub-device to the cloud. This synchronous call automatically registers the sub-device and adds the topology. -
Call
IOT_Linkkit_Reportwith theITM_MSG_LOGINparameter to bring the sub-device online. -
In the event handler for
ITE_INITIALIZE_COMPLETED, confirm that the sub-device connection is initialized. The sub-device can then exchange data with the cloud.int example_add_subdev(iotx_linkkit_dev_meta_info_t *meta_info) { int res = 0, devid = -1; devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_SLAVE, meta_info); if (devid == FAIL_RETURN) { EXAMPLE_TRACE("subdev open Failed\n"); return FAIL_RETURN; } EXAMPLE_TRACE("subdev open succeeded, devid = %d\n", devid); res = IOT_Linkkit_Connect(devid); if (res == FAIL_RETURN) { EXAMPLE_TRACE("subdev connect Failed\n"); return res; } EXAMPLE_TRACE("subdev connect success: devid = %d\n", devid); res = IOT_Linkkit_Report(devid, ITM_MSG_LOGIN, NULL, 0); if (res == FAIL_RETURN) { EXAMPLE_TRACE("subdev login Failed\n"); return res; } EXAMPLE_TRACE("subdev login success: devid = %d\n", devid); return res; }
ImportantCalling
IOT_Linkkit_Openmultiple times with the sameProductKeyandDeviceNamereturns the samedevidbecause the SDK does not create duplicate resources. You can use this behavior to query thedevidof an existing sub-device by callingIOT_Linkkit_Openwith the correspondingProductKeyandDeviceName. -
-
Perform sub-device management operations.
-
Log out a sub-device.
Call
IOT_Linkkit_ReportwithITM_MSG_LOGOUTto log out the sub-device and notify IoT Platform that it is offline.res = IOT_Linkkit_Report(devid, ITM_MSG_LOGOUT, NULL, 0); if (res == FAIL_RETURN) { EXAMPLE_TRACE("subdev logout Failed\n"); return res; } EXAMPLE_TRACE("subdev logout success: devid = %d\n", devid); -
Retrieve the sub-device list.
Call
IOT_Linkkit_QuerywithITM_MSG_QUERY_TOPOLISTto retrieve all sub-devices in the topology. Results are returned in theITE_TOPOLIST_REPLYcallback. -
Delete a sub-device topology.
Call
IOT_Linkkit_ReportwithITM_MSG_DELETE_TOPOto delete the topology for the sub-device specified bydevid. The cloud then disassociates the sub-device from this gateway. -
Perform a sub-device Over-the-Air (OTA) update.
Use
IOT_Ioctlto configure OTA for the sub-device, then useIOT_Linkkit_Queryto trigger the upgrade.-
Call
IOT_RegisterCallbackto register theuser_fota_event_handlercallback function for the firmware upgrade.IOT_RegisterCallback(ITE_FOTA, user_fota_event_handler); IOT_RegisterCallback(ITE_INITIALIZE_COMPLETED, user_initialized); -
Call IOT_Linkkit_Open with the IOTX_LINKKIT_DEV_TYPE_MASTER parameter to initialize the master device resources.
iotx_linkkit_dev_meta_info_t master_meta_info; memset(&master_meta_info, 0, sizeof(iotx_linkkit_dev_meta_info_t)); memcpy(master_meta_info.product_key, PRODUCT_KEY, strlen(PRODUCT_KEY)); memcpy(master_meta_info.product_secret, PRODUCT_SECRET, strlen(PRODUCT_SECRET)); memcpy(master_meta_info.device_name, DEVICE_NAME, strlen(DEVICE_NAME)); memcpy(master_meta_info.device_secret, DEVICE_SECRET, strlen(DEVICE_SECRET)); /* Create Master Device Resources */ user_example_ctx->master_devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_MASTER, &master_meta_info); if (user_example_ctx->master_devid < 0) { EXAMPLE_TRACE("IOT_Linkkit_Open Failed\n"); return -1; } -
Call IOT_Linkkit_Connect to establish a connection to the cloud.
/* Start Connect Aliyun Server */ res = IOT_Linkkit_Connect(user_example_ctx->master_devid); if (res < 0) { EXAMPLE_TRACE("IOT_Linkkit_Connect Failed\n"); return -1; } -
Add a sub-device and perform an OTA update.
/* Add subdev */ while (user_example_ctx->subdev_index < EXAMPLE_SUBDEV_ADD_NUM) { if (user_example_ctx->master_initialized && user_example_ctx->subdev_index >= 0 && (0 == current_ota_running) && (user_example_ctx->auto_add_subdev == 1 || user_example_ctx->permit_join != 0)) { /* Add next subdev */ if (example_add_subdev((iotx_linkkit_dev_meta_info_t *)&subdevArr[user_example_ctx->subdev_index]) == SUCCESS_RETURN) { EXAMPLE_TRACE("subdev %s add succeed", subdevArr[user_example_ctx->subdev_index].device_name); } else { EXAMPLE_TRACE("subdev %s add failed", subdevArr[user_example_ctx->subdev_index].device_name); } user_example_ctx->subdev_index++; user_example_ctx->permit_join = 0; /* check each sub dev has remote ota message */ do_subdev_ota(user_example_ctx->subdev_index); /* wait remote ota message */ HAL_SleepMs(10000); } } -
Details of the
do_subdev_otafunction.Use
IOT_Ioctlto switch the OTA channel to a specific sub-device (identified by devid). After switching, only upgrade messages for that sub-device are received. CallIOT_Linkkit_Queryto query the cloud for available firmware. If a suitable version is available, the OTA process starts and triggers the user_fota_event_handler callback.void do_subdev_ota(int devid) { if (status_list[devid] == SUB_OTA_SUCCESS) { HAL_Printf("current devid is %d, its has checked remote ota message, skip\n", devid); return; } if (current_ota_running == 1) { return; } HAL_Printf("current devid running ota is %d\n", devid); int ota_result = 0; ota_result = IOT_Ioctl(IOTX_IOCTL_SET_OTA_DEV_ID, (void *)(&devid)); if (0 != ota_result) { status_list[devid] = SUB_OTA_FAILED_SET_DEV_ID; HAL_Printf("IOTX_IOCTL_SET_OTA_DEV_ID failed, id is %d\n", devid); return; } ota_result = IOT_Linkkit_Query(devid, ITM_MSG_REQUEST_FOTA_IMAGE, (unsigned char *)current_subdev_version, strlen(current_subdev_version)); HAL_Printf("current devid is %d, ITM_MSG_REQUEST_FOTA_IMAGE ret is %d\n", devid, ota_result); if (0 != ota_result) { status_list[devid] = SUB_OTA_FAILED_QUERY; return; } status_list[devid] = SUB_OTA_SUCCESS; }
-
-
-
Exchange data with the sub-device.
Data exchange between a sub-device and the cloud follows the same procedure as a standalone product. Refer to the Thing Specification Language (TSL) model programming documentation.
-
Call
IOT_Linkkit_Reportto report properties, report pass-through data, and update or delete device tags. -
Call
IOT_Linkkit_TriggerEventto proactively report an event. -
In the
ITE_RAWDATA_ARRIVEDevent callback, receive pass-through data from the cloud. -
In the
ITE_SERVICE_REQUESTevent callback, receive service requests for synchronous and asynchronous services. -
In the
ITE_PROPERTY_SETevent callback, process property settings from the cloud. -
In the
ITE_PROPERTY_GETevent callback, process requests to retrieve properties from local communication.
-
Usage notes
-
The gateway must be multi-threaded. Run
IOT_Linkkit_Yieldin a dedicated thread.void *user_dispatch_yield(void *args) { while (1){ IOT_Linkkit_Yield(USER_EXAMPLE_YIELD_TIMEOUT_MS); } return NULL; } res = HAL_ThreadCreate(&g_user_dispatch_thread, user_dispatch_yield, NULL, NULL, NULL); if (res < 0) { EXAMPLE_TRACE("HAL_ThreadCreate Failed\n"); IOT_Linkkit_Close(user_example_ctx->master_devid); return -1; } -
On the Smart Life Open Platform, add a sub-device only after receiving the ITE_PERMIT_JOIN event from the cloud.
When a user scans a QR code in the app to add a sub-device, the app sends a PermitJoin command to the cloud, which forwards it to the gateway. The ITE_PERMIT_JOIN event provides the sub-device's ProductKey and a time window (timeoutSec, typically 60 seconds). Within this window, discover and attach the sub-device, then add it and report to the cloud. The sub-device then appears in the app. Example handler:
int user_permit_join_event_handler(const char *product_key, const int time){ user_example_ctx_t *user_example_ctx = user_example_get_ctx();.EXAMPLE_TRACE(“Product Key: %s, Time: %d”, product_key, time); user_example_ctx->permit_join = 1; return 0; } ``` -
Add
FEATURE_DEVICE_MODEL_GATEWAY=yto the make.setting file in the SDK root directory, then run make to compile the gateway example.