All Products
Search
Document Center

IoT Platform:Verify and connect a device

Last Updated:Nov 07, 2023

This topic describes how to initialize Link SDK for Java to connect a device to IoT Platform.

Prerequisites

  • A product and a device are created. For more information, see Create a product and device.

  • The verification information of the device and the endpoint to which you want to connect the device are obtained.

Background information

  • Link SDK for Java allows you to use only DeviceSecrets to verify the identities of devices. The following table describes the verification methods that are supported by the SDK.

    Verification method

    Registration method

    Description

    Unique-certificate-per-device verification

    N/A

    A device certificate that includes a ProductKey, a DeviceName, and a DeviceSecret is burned to each device.

    Unique-certificate-per-product verification

    Pre-registration

    • A product certificate that includes a ProductKey and a ProductSecret is burned to all devices of a product.

    • You must enable the dynamic registration feature for the product.

    • Dynamic registration allows a device to obtain a DeviceSecret.

    Preregistration-free

    • A product certificat that includes a ProductKey and a ProductSecret is burned to all devices of a product.

    • You must enable the dynamic registration feature for the product.

    • Dynamic registration allows devices to obtain a combination of the ClientID and the DeviceToken.

    Note

    For information about the differences between pre-registration unique-certificate-per-product verification and preregistration-free unique-certificate-per-product verification, see Differences between the verification methods.

  • For information about the parameters of Link SDK for Java, see LinkKitInitParams.

Unique-certificate-per-device verification

Sample code for unique-certificate-per-device verification

String productKey = "${YourProductKey}";
String deviceName = "${YourDeviceName}";
String deviceSecret = "${YourDeviceSecret}";

LinkKitInitParams params = new LinkKitInitParams();

/**
 * Step 1: Configure the required parameters for Message Queuing Telemetry Transport (MQTT) initialization.
 */
IoTMqttClientConfig config = new IoTMqttClientConfig();

MqttConfigure.mqttHost = "{YourInstanceId}.mqtt.iothub.aliyuncs.com:8883";

/*
 * Specify whether to receive offline messages.
 * This parameter corresponds to the cleanSession parameter of an MQTT connection.
 */
config.receiveOfflineMsg = false;
params.mqttClientConfig = config;

/**
 * Step 2: Specify the verification information that is required to initialize a device.
 */
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.productKey = productKey;
deviceInfo.deviceName = deviceName;
deviceInfo.deviceSecret = deviceSecret;
params.deviceInfo = deviceInfo;

/**
 * Step 3: Specify the username, token, and clientId of the device.
 * This step is required only if you use the preregistration-free unique-certificate-per-product verification method to verify a device.
 * By default, this step is skipped.
 */
 // MqttConfigure.deviceToken="${YourDeviceToken}";
 // MqttConfigure.clientId="${YourClientId}";


LinkKit.getInstance().init(params, new ILinkKitConnectListener() {
    public void onError(AError aError) {
        ALog.e(TAG, "Init Error error= "+aError);
    }
    public void onInitDone(InitResult initResult) {
        ALog.i(TAG, "onInitDone result=" + initResult);
    }
});
Note
  • If onInitDone is returned after you send an initialization request, the initialization is successful. If onError is returned, the initialization failed.

  • If the initialization fails, you can configure the required parameter to re-initialize the device based on your business requirements. Link SDK for Java does not automatically reconnect the device to IoT Platform.

  • If the initialization is successful and the device is disconnected from IoT Platform, Link SDK for Java automatically reconnects the device to IoT Platform.

Dynamic registration

Unique-certificate-per-product verification is also known as dynamic registration. The feature is used to request DeviceSecrets from IoT Platform. Unique-certificate-per-product verification methods are classified into the following types: preregistration-free and pre-registration. Before you use the feature, make sure that the following prerequisites are met:

  • Dynamic registration is enabled for a product that you created in the IoT Platform console.

  • In the deviceinfo file of the demo package, the deviceSecret parameter is left empty and a value is specified for the productSecret parameter.

  • Make sure that Step 1, Step 2, and Step 3 in the following sample code are performed.

  • After dynamic registration is completed, you must close the persistent connection for dynamic registration. For more information, see the sample code in Step 4.

  • The sample code shows how to perform pre-registration unique-certificate-per-product verification. You can refer to the usage notes in Step 1 of the sample code to perform preregistration-free unique-certificate-per-product verification.

  • To ensure device security, burn a DeviceSecret to a device after you obtain the DeviceSecret by using the unique-certificate-per-product verification method. If you want to connect your device to IoT Platform, refer to the "Unique-certificate-per-device verification" section of this topic.

The following table describes the differences between the preregistration-free unique-certificate-per-product and pre-registration unique-certificate-per-product verification methods.

Item

Pre-registration

Preregistration-free

Protocols

Message Queuing Telemetry Transport (MQTT) and HTTPS

MQTT

Regions

  • MQTT-based dynamic registration is available in all regions that are supported by IoT Platform.

  • HTTPS-based dynamic registration is available only in the China (Shanghai) region. We recommend that you do not use HTTPS-based dynamic registration. The sample code does not include code for this method.

China (Shanghai) and China (Beijing)

Returned DeviceSecrets

For more information about how to use a DeviceSecret, see Step 1 in the sample code for unique-certificate-per-device verification.

Burn the ClientID and DeviceToken of a device to the device. This way, the information can be used when you use specific features, such as connecting the device to IoT Platform. For more information, see Step 3 in the sample code for unique-certificate-per-device verification.

Device registration

You must pre-register the DeviceName of a device in the IoT Platform console.

You do not need to pre-register the DeviceName of a device in the IoT Platform console.

Usage times

  • You can use a device certificate to activate only one physical device. If Device A is activated by using a DeviceName and Device B needs to use the DeviceName, you can delete Device A in the IoT Platform console and disable the DeviceSecret of Device A. This way, you can use the DeviceName to create and activate Device B.

  • If a device needs to be reactivated because the DeviceSecret is lost, you must call the ResetThing operation to set the device status to Inactive. Then, you can reactivate the device. The DeviceSecret that is issued by IoT Platform remains unchanged.

You can activate up to five physical devices by using the same ProductKey, ProductSecret, and DeviceName in the IoT Platform console at the same time. IoT Platform generates a unique ClientID and DeviceToken for each device.

Sample code for dynamic registration:

        String deviceName = "${YourDeviceName}";
        String productKey = "${YourProductKey}";
        String productSecret = "${YourProductSecret}";

        // Step 1: Check whether the unique-certificate-per-product verification method is preregistration-free or pre-registration.
        // Case 1: If you set the registerType parameter to regnwl, the preregistration-free unique-certificate-per-product verification method is used and you do not need to create a device.
        // Case 2: If you leave the registerType parameter empty or set the registerType parameter to register, the pre-registration unique-certificate-per-product verification method is used and you must create a device.
        String registerType = "register";

        // Step 2: Specify an endpoint for dynamic registration.
        MqttConfigure.mqttHost = "ssl://${YourMqttHostUrl}:8883";

        MqttInitParams initParams = new MqttInitParams(productKey, productSecret, deviceName, "",registerType);

        // Step 3: If you use a public instance of the new version or an Enterprise Edition instance, specify the instance ID that you obtained from the Instance Details page in the IoT Platform console for dynamic registration.
        initParams.instanceId = "${YourInstanceId}";

        final Object lock = new Object();
        LinkKit.getInstance().deviceDynamicRegister(initParams, new IOnCallListener() {
            @Override
            public void onSuccess(com.aliyun.alink.linksdk.channel.core.base.ARequest request, com.aliyun.alink.linksdk.channel.core.base.AResponse response) {
                try {
                    String responseData = new String((byte[]) response.data);
                    JSONObject jsonObject = JSONObject.parseObject(responseData);
                    // The output that is returned if the pre-registration unique-certificate-per-product verification method is used.
                    String deviceSecret = jsonObject.getString("deviceSecret");

                    // The output that is returned if the preregistration-free unique-certificate-per-product verification method is used.
                    String clientId = jsonObject.getString("clientId");
                    String deviceToken = jsonObject.getString("deviceToken");

                    // Save the returned credentials and proceed to Step 4. After you complete Step 4, you can use the onSuccess method to connect the device to IoT Platform.
                    
                    // Call the API operation that waits for the thread.
                    synchronized (lock){
                        lock.notify();
                    }

                } catch (Exception e) {
                }
            }

            @Override
            public void onFailed(ARequest aRequest, com.aliyun.alink.linksdk.channel.core.base.AError aError) {
                System.out.println("mqtt dynamic registration failed");
                // Call the API operation that waits for the thread.
                synchronized (lock){
                    lock.notify();
                }
            }

            @Override
            public boolean needUISafety() {
                return false;
            }
        });

        try {
            // Wait for a downstream message. In most cases, the downstream message is returned within 1 second.
            synchronized (lock){
                lock.wait(3000);
            }

            // Step 4: Disable the dynamic registration instance. 
            // Do not run the following function in the LinkKit.getInstance().deviceDynamicRegister callback. Otherwise, an error may occur.
            LinkKit.getInstance().stopDeviceDynamicRegister(2000, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken iMqttToken) {
                    System.out.println("mqtt dynamic registration success");
                    // Connect the device to IoT Platform and initialize the connection. For more information, see the "Unique-certificate-per-device verification" section of this topic.
                }

                @Override
                public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
                    System.out.println("mqtt dynamic registration failed");
                }
            });

        } catch (Exception e) {
        }

Specify an endpoint

Sample code:

// Specify an endpoint for the LinkKitInitParams parameter in an MQTT request.
IoTMqttClientConfig clientConfig = new IoTMqttClientConfig();
clientConfig.channelHost = "a18wP******.iot-as-mqtt.cn-shanghai.aliyuncs.com:8883";
linkKitInitParams.mqttClientConfig = clientConfig;           

Parameters:

Parameter

Example

Description

channelHost

a18wP******.iot-as-mqtt.cn-shanghai.aliyuncs.com:8883

Specify the endpoint to which you want to connect the device in the ${Endpoint}:${Port number} format.

  • To view the endpoint of an Enterprise Edition instance or a public instance of the new version, go to the Development Configurations panel of the Instance Details page in the IoT Platform console.

  • If you use a public instance of the previous version, the endpoint of the public instance is in the ${YourProductKey}.iot-as-mqtt.${YourRegionId}.aliyuncs.com:8883 format.

For information about public instances of the new and previous versions, Enterprise Edition instances, and endpoints, see View the endpoint of an instance.

More settings

You can configure the following parameters to configure additional settings that are related to device connection.

  • MQTT connection

    Item

    Description

    Sample code

    Keepalive interval

    Specify a keepalive interval for the device. This parameter specifies the period of time during which a persistent connection can be retained between the device and IoT Platform.

    MqttConfigure.setKeepAliveInterval(int interval);

    QoS level

    Specify a Quality of Service (QoS) level. A QoS level is an agreement that defines the quality level of message delivery between a device and IoT Platform. Valid values:

    • 0: Each message is delivered at most once.

    • 1: Each message is delivered at least once.

    - The qos parameter.
    MqttPublishRequest request = new MqttPublishRequest();
    // Valid values: 0 and 1. Default value: 0.
    request.qos = 0;
    request.isRPC = false;
    request.topic = topic.replace("request", "response");
    String resId = topic.substring(topic.indexOf("rrpc/request/")+13);
    request.msgId = resId;
    // Configure the preceding parameters based on your business requirements. The preceding information is provided only for reference.
    request.payloadObj = "{\"id\":\"" + resId + "\", \"code\":\"200\"" + ",\"data\":{} }";

    Offline messages

    The cleanSession parameter specifies whether to receive offline messages.

    /**
     * Configure the required parameters for MQTT initialization.
     */
    IoTMqttClientConfig config = new IoTMqttClientConfig();
    config.productKey = deviceInfoData.productKey;
    config.deviceName = deviceInfoData.deviceName;
    config.deviceSecret = deviceInfoData.deviceSecret;
    config.channelHost = pk + ".iot-as-mqtt." + deviceInfoData.region + ".aliyuncs.com:1883";
    /**
     * Specify whether to receive offline messages.
     * The following definitions correspond to the following code: receiveOfflineMsg = !cleanSession. By default, offline messages cannot be received.
     */
    config.receiveOfflineMsg = false;
    params.mqttClientConfig = config;
  • Support for logging and Log4j

    You can run the following command to obtain debugging logs:

    ALog.setLevel(ALog.LEVEL_DEBUG);

    In Link SDK for Java V1.2.3.1 and later, you can configure the log function of a global interceptor to process logs based on your business requirements. For example, you can use Log4j to store logs in persistent storage such as a file.

    Sample code:

            ALog.setLogDispatcher(new ILogDispatcher() {
                @Override
                public void log(int level, String prefix, String msg) {
                    switch (level){
                        case LEVEL_DEBUG:
                            System.out.println("debug:"+ prefix + msg);
                            break;
                        case LEVEL_INFO:
                            System.out.println("info:" + prefix + msg);
                            break;
                        case LEVEL_ERROR:
                            System.out.println("error:" + prefix + msg);
                            break;
                        case LEVEL_WARNING:
                            System.out.println("warnings:" + prefix + msg);
                            break;
                        default:
                            System.out.println("other:" + prefix + msg);
                    }
                }
            });
  • Connection status and downstream message listeners

    To listen to the connection and disconnection messages of a device and data that is sent from IoT Platform, configure the following listener:

    IConnectNotifyListener notifyListener = new IConnectNotifyListener() {
        @Override
        public void onNotify(String connectId, String topic, AMessage aMessage) {
            // The callback for downstream data from IoT Platform, such as the connectId, connection type, downstream topic from IoT Platform, and the aMessage parameter that specifies the message body sent from IoT Platform.
            //String pushData = new String((byte[]) aMessage.data);
            // pushData example:  {"method":"thing.service.test_service","id":"123374967","params":{"vv":60},"version":"1.0.0"}
            // The method parameter specifies a service type. The params parameter specifies the content of data that you want to push.    
    }
        @Override
        public boolean shouldHandle(String connectId, String topic) {
            // Specify whether to process the downstream data of a topic from IoT Platform.
            // If a topic is not processed, the onNotify listener cannot receive the downstream data of the topic from IoT Platform.
            return true; // Specify the required data processing logic for the listener based on your business scenario. 
        }
        @Override
        public void onConnectStateChange(String connectId, ConnectState connectState) {
            // The callback for the connection status change of the corresponding connection type. For information about the connection status, see ConnectState in the SDK.
            // If the SDK detects that the device is disconnected from IoT Platform due to network fluctuations, the SDK automatically reconnects the device at intervals of 1 second, 2 seconds, 4 seconds, 8 seconds, and 128 seconds. After the retry interval reaches 128 seconds, the SDK retries at an interval of 128 seconds until the device is reconnected to IoT Platform. 
        }
    }
    // Register a listener to listen to downstream data, including the status of a persistent connection and downstream data from IoT Platform.
    LinkKit.getInstance().registerOnNotifyListener(notifyListener);
                
  • Deinitialization

    The following code shows how to perform deinitialization:

    // Unregister the notifyListener listener. Make sure that you unregister the listener that you registered.
    LinkKit.getInstance().unRegisterOnNotifyListener(notifyListener);
    LinkKit.getInstance().deinit();