This chapter describes how to send and receive messages via MQTT topics, and how to implement a device by TSL programming methods on Ubuntu.

Background information

Install the local development environment

Install Ubuntu16.04

The compiling environment for this quick experience is Ubuntu16.04 on a 64-bit host. This environment has not been verified on other versions of Linux. We recommend that you install the release version consistent with Alibaba to avoid compatibility problems.

If you are using a Windows operating system, we recommend that you install the VMWare Virtualbox. Download Link: https://www.virtualbox.org/wiki/Downloads

Then, install the 64-bit Desktop version of Ubuntu 16.04.x LTS. Download Link: http://releases.ubuntu.com/16.04

Install the prerequisite software

The development and compiling environment of this SDK uses the following software: make-4.1, git-2.7.4, gcc-5.4.0, gcov-5.4.0, lcov-1.12, bash-4.3.48, tar-1.28, mingw-5.3.1

You can use the following command to install the necessary software:

$ sudo apt-get install -y build-essential make git gcc

Access the device using MQTT topics

Create products and devices

Use your Alibaba Cloud account to log on to the Alibaba Cloud IoT Platform to create products. Because you are implementing the product functions directly through MQTT topics, you can select “Basic version” when creating the product.After creating a product, you can add a specific device. Alibaba Cloud IoT Platform will generate identity information for the device.If you are not familiar with product creation on the cloud, please learn how to create products and devices on Alibaba Cloud IoT Platform.

Implement product functions

Understand the root directory structure of the SDK

After the Link Kit SDK has been downloaded, the top-level directory structure is as follows:

$ ls
build-rules  Config.in  examples  LICENSE   make.settings  project.mk  sdk-c.mk  win_board_conf.mk CMakeLists.txt  Config.linkkit include   makefile  prebuilt  README.txt  src  win.makefile

Enter the device trituple into the routine

Open the ./examples/mqtt/mqtt-example.c file, edit the following code snippet, and fill in the device trituple obtained after the device was created on the cloud:

#if defined(SUPPORT_ITLS)
 
...
...
 
#else
 
    #if defined(ON_DAILY)
        ...
        ...
    #else
        #define PRODUCT_KEY             "a1ExpAkj9Hi"
        #define DEVICE_NAME             "Example1"
        #define DEVICE_SECRET           "cNzcn2Lbqzh4UiXKLwW77hxI9GFmcRgb"
    #endif
 
#endif

Note: The device trituple defined above are read by the HAL functions used for obtaining ProductKey, DeviceName, and DeviceSecret in Ubuntu.

Initialize the device and establish a connection

The following code snippet briefly describes the initialization and connection establishment process of the device:

int mqtt_client(void)
{
    ...
    ...
 
 
/* Enter the device identity information before attempting to establish an MQTT connection to the server*/
 
    if (0 != IOT_SetupConnInfo(__product_key, __device_name, __device_secret, (void **)&pconn_info)) {
        EXAMPLE_TRACE("AUTH request failed!") ;
        rc = -1;
        goto do_exit;
    }
 
    /* Initialize MQTT parameter */
    ...
    ...

Attempt to establish an MQTT connection to the server

    pclient = IOT_MQTT_Construct(&mqtt_params);
    if (NULL == pclient) {
        EXAMPLE_TRACE("MQTT construct failed");
        rc = -1;
        goto do_exit;
    }

Report data to the cloud

The following topics are defined in the sample file:

/* These are pre-defined topics */
#define TOPIC_UPDATE            "/"PRODUCT_KEY"/"DEVICE_NAME"/update"
#define TOPIC_ERROR             "/"PRODUCT_KEY"/"DEVICE_NAME"/update/error"
#define TOPIC_GET               "/"PRODUCT_KEY"/"DEVICE_NAME"/get"
#define TOPIC_DATA              "/"PRODUCT_KEY"/"DEVICE_NAME"/data"
 
/* These are pre-defined topic formats*/
#define TOPIC_UPDATE_FMT            "/%s/%s/update"
#define TOPIC_ERROR_FMT             "/%s/%s/update/error"
#define TOPIC_GET_FMT               "/%s/%s/get"
#define TOPIC_DATA_FMT              "/%s/%s/data"

The following code snippets show how to send data to the topics:

/* Initialize topic information */
memset(&topic_msg, 0x0, sizeof(iotx_mqtt_topic_info_t));
strcpy(msg_pub, "update: hello! start!") ;

topic_msg.qos = IOTX_MQTT_QOS1;
topic_msg.retain = 0;
topic_msg.dup = 0;
topic_msg.payload = (void *)msg_pub;
topic_msg.payload_len = strlen(msg_pub);

rc = IOT_MQTT_Publish(pclient, TOPIC_UPDATE, &topic_msg);
if (rc < 0) {
IOT_MQTT_Destroy(&pclient);
EXAMPLE_TRACE("error occur when publish");
rc = -1;
goto do_exit;
}

EXAMPLE_TRACE("\n publish message: \n topic: %s\n payload: \%s\n rc = %d", TOPIC_UPDATE, topic_msg.payload, rc);

Subscribe and process data from the cloud

The sample program sends data to a topic, subscribes to this topic, and receives the data back from the cloud. The following code subscribes to a specified topic, and specifies the handler for the received data:

rc = IOT_MQTT_Subscribe(pclient, TOPIC_DATA, IOTX_MQTT_QOS1, _demo_message_arrive, NULL);
if (rc < 0) {
IOT_MQTT_Destroy(&pclient);
EXAMPLE_TRACE("IOT_MQTT_Subscribe() failed, rc = %d", rc);
rc = -1;
goto do_exit;
}

IOT_MQTT_Yield(pclient, 200);

HAL_SleepMs(2000);

...
...

When the sample program receives data from the cloud, it simply prints the data out:

static void _demo_message_arrive(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
{
    iotx_mqtt_topic_info_pt ptopic_info = (iotx_mqtt_topic_info_pt) msg->msg;
 
    /* print topic name and topic message */
    EXAMPLE_TRACE("----");
    EXAMPLE_TRACE("packetId: %d", ptopic_info->packet_id);
    EXAMPLE_TRACE("Topic: '%.*s' (Length: %d)",
                  ptopic_info->topic_len,
                  ptopic_info->ptopic,
                  ptopic_info->topic_len);
    EXAMPLE_TRACE("Payload: '%.*s' (Length: %d)",
                  ptopic_info->payload_len,
                  ptopic_info->payload,
                  ptopic_info->payload_len);
    EXAMPLE_TRACE("----");
}

The following code snippets attempt to send data to this topic:

do {
cnt++;
msg_len = snprintf(msg_pub, sizeof(msg_pub), "{\"attr_name\":\"temperature\", \"attr_value\":\"%d\"}", cnt);
...
...

rc = IOT_MQTT_Publish(pclient, TOPIC_DATA, &topic_msg);
if (rc < 0) {
EXAMPLE_TRACE("error occur when publish");
rc = -1;
break;
}
EXAMPLE_TRACE("packet-id=%u, publish topic msg=%s", (uint32_t)rc, msg_pub);

Compile the sample program

Run the following command in the top-level directory of the SDK:

make distclean
make

After the compilation is successfully completed, the sample program is generated in the output/release/bin directory of the current path:

$ tree output/release
output/release/
+-- bin
...
...
|   +-- mqtt-example
...
...

Observe data

Run the following command:

$ ./output/release/bin/mqtt-example

You can find the specified product in the console of Alibaba Cloud IoT Platform, and view the messages reported from the device in Log Service. You can click here to learn how to view the data reported from the device on the cloud.

You can also see the data from the cloud printed by the sample program in the Linux console:

_demo_message_arrive|166 :: ----
_demo_message_arrive|167 :: packetId: 35641
_demo_message_arrive|171 :: Topic: '/a1ExpAkj9Hi/Example1/data' (Length: 26)
_demo_message_arrive|175 :: Payload: '{"attr_name":"temperature", "attr_value":"1"}' (Length: 45)
_demo_message_arrive|176 :: ----

Access the device using TSL

Create products and devices

You can create products on Alibaba Cloud IoT Platform and multiple services provided on it. The help links for creating products on Alibaba Cloud IoT Platform are as follows:

If a product needs to be created on the Life IoT Platform (lifestyle-related services on Alibaba Cloud IoT Platform), you can log on to the Life IoT Platform to create the product.

In this example, you need to create a product that supports the following TSL:

  • Attribute LightSwitch
    • Identifier: LightSwitch
    • Data type: enum
    • Values: 0 and 1
    • Read/Write type: read and write
  • Service Custom
    • Identifier: Custom
    • Call method: Asynchronous
    • Input parameter: {Identifier: transparency, Data type: int32, Value range: 0 ~ 100}
    • Output parameter: {Identifier: Contrastratio, Data type: int32, Value range: 0 ~ 100}
  • Event
    • Identifier: Error
    • Event type: Information
    • Output parameter: {Identifier: Errorcode, Data type: enum, Value range: 0, 1}

After a TSL is defined, the cloud generates a TSL description file in JSON format for this TSL.

Implement product functions

Enter the device trituple into the routine

Replace the trituple in ./examples/linkkit/linkkit_example_solo.c with those of the device created on the cloud.

#define PRODUCT_KEY      "a1csED27mp7"
#define PRODUCT_SECRET   "VuULINCrtTAzCSzp"
#define DEVICE_NAME      "AdvExample1"
#define DEVICE_SECRET    "3xGoxtWRscxPAoMxnJnjocZbNfmCTRi0"

Compile and run a program

Run the following command in the top-level directory of the SDK:

$ make distclean
$ make

After the compilation is successfully completed, the sample program for the advanced version is generated in the output/release/bin directory of the current path, and its name is linkkit-example-solo.

Run the following command in the top-level directory of the SDK:

$ ./output/release/bin/linkkit-example-solo

Observe data

The sample program periodically reports the values of the LightSwitch attribute to the cloud. You can check and set the received attribute on the cloud, and verify that the LightSwitch attribute reported on the device side has been modified to the value that you have set.

Report attributes

This sample uses user_post_property as an example of attribute reporting. The sample cycles through reporting the payloads of various situations. You see the following prompt messages returned when incorrect payloads are reported:

void user_post_property(void)
{
static int example_index = 0;
int res = 0;
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
char *property_payload = "NULL";

if (example_index == 0) {

Typical attribute reporting

/* Typical Example */
property_payload = "{\"LightSwitch\":1}";
example_index++;
}else if(...) {
...
...
}

res = IOT_Linkkit_Report(user_example_ctx->master_devid, ITM_MSG_POST_PROPERTY,
(unsigned char *)property_payload, strlen(property_payload));

EXAMPLE_TRACE("Post Property Message ID: %d", res);
}

The logs printed during typical attribute reporting are as follows:

[inf] dm_msg_request(218): DM Send Message, URI: /sys/a1csED27mp7/AdvExample1/thing/event/property/post, Payload: {"id":"1","version":"1.0","params":{"LightSwitch":1},"method":"thing.event.property.post"}
[dbg] MQTTPublish(319): ALLOC: (160) / [224] @ 0x1da41a0
[inf] MQTTPublish(378): Upstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/event/property/post'
[inf] MQTTPublish(379): Upstream Payload:

The following message is sent to the cloud:

> {
>     "id": "1",
>     "version": "1.0",
>     "params": {
>         "LightSwitch": 1
>     },
>     "method": "thing.event.property.post"
> }

[inf] dm_client_publish(106): Publish Result: 0
[dbg] alcs_observe_notify(105): payload:{"id":"1","version":"1.0","params":{"LightSwitch":1},"method":"thing.event.property.post"}
[dbg] CoAPResourceByPath_get(176): Found the resource: /sys/a1csED27mp7/AdvExample1/thing/event/property/post
[inf] dm_server_send(76): Send Observe Notify Result 0
[dbg] dm_msg_cache_insert(79): dmc list size: 0
user_post_property. 431: Post Property Message ID: 1
[dbg] iotx_mc_cycle(1774): PUBLISH
[inf] iotx_mc_handle_recv_PUBLISH(1549): Downstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/event/property/post_reply'
[inf] iotx_mc_handle_recv_PUBLISH(1550): Downstream Payload:

The following response is received from the cloud:

< {
<     "code": 200,
<     "data": {
<     },
<     "id": "1",
<     "message": "success",
<     "method": "thing.event.property.post",
<     "version": "1.0"
< }

[dbg] iotx_mc_handle_recv_PUBLISH(1555):         Packet Ident : 00000000
[dbg] iotx_mc_handle_recv_PUBLISH(1556):         Topic Length : 60
[dbg] iotx_mc_handle_recv_PUBLISH(1560):           Topic Name : /sys/a1csED27mp7/AdvExample1/thing/event/property/post_reply
[dbg] iotx_mc_handle_recv_PUBLISH(1563):     Payload Len/Room : 104 / 4935
[dbg] iotx_mc_handle_recv_PUBLISH(1564):       Receive Buflen : 5000
[dbg] iotx_mc_handle_recv_PUBLISH(1575): delivering msg ...
[dbg] iotx_mc_deliver_message(1291): topic be matched
[inf] dm_msg_proc_thing_event_post_reply(258): Event Id: property
[dbg] dm_msg_response_parse(167): Current Request Message ID: 1
[dbg] dm_msg_response_parse(168): Current Request Message Code: 200
[dbg] dm_msg_response_parse(169): Current Request Message Data: {}
[dbg] dm_msg_response_parse(174): Current Request Message Desc: success
[dbg] dm_ipc_msg_insert(87): dm msg list size: 0, max size: 50
[dbg] dm_msg_cache_remove(142): Remove Message ID: 1
[inf] _iotx_linkkit_event_callback(219): Receive Message Type: 30
[inf] _iotx_linkkit_event_callback(221): Receive Message: {"id":1,"code":200,"devid":0,"payload":{}}
[dbg] _iotx_linkkit_event_callback(476): Current Id: 1
[dbg] _iotx_linkkit_event_callback(477): Current Code: 200
[dbg] _iotx_linkkit_event_callback(478): Current Devid: 0

The log of the callback function:

user_report_reply_event_handler. 300: Message Post Reply Received, Devid: 0, Message ID: 1, Code: 200, Reply: {}

Process an attribute-setting request

When an attribute-setting request is received in the sample code, the following callback function is triggered:

static int user_property_set_event_handler(const int devid, const char *request, const int request_len)
{
int res = 0;
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
EXAMPLE_TRACE("Property Set Received, Devid: %d, Request: %s", devid, request);

The received attribute-setting request is sent to the cloud, which updates the cloud device attributes:

res = IOT_Linkkit_Report(user_example_ctx->master_devid, ITM_MSG_POST_PROPERTY,
(unsigned char *)request, request_len);
EXAMPLE_TRACE("Post Property Message ID: %d", res);

return 0;
}

You can see the value set on the server in the device logs:

[dbg] iotx_mc_cycle(1774): PUBLISH
[inf] iotx_mc_handle_recv_PUBLISH(1549): Downstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/service/property/set'
[inf] iotx_mc_handle_recv_PUBLISH(1550): Downstream Payload:

The attribute-setting request received from the cloud is as follows:

< {
<     "method": "thing.service.property.set",
<     "id": "161430786",
<     "params": {
<         "LightSwitch": 1
<     },
<     "version": "1.0.0"
< }

[dbg] iotx_mc_handle_recv_PUBLISH(1555):         Packet Ident : 00000000
[dbg] iotx_mc_handle_recv_PUBLISH(1556):         Topic Length : 55
[dbg] iotx_mc_handle_recv_PUBLISH(1560):           Topic Name : /sys/a1csED27mp7/AdvExample1/thing/service/property/set
[dbg] iotx_mc_handle_recv_PUBLISH(1563):     Payload Len/Room : 113 / 4940
[dbg] iotx_mc_handle_recv_PUBLISH(1564):       Receive Buflen : 5000
[dbg] iotx_mc_handle_recv_PUBLISH(1575): delivering msg ...
[dbg] iotx_mc_deliver_message(1291): topic be matched
[inf] dm_msg_proc_thing_service_property_set(93): thing/service/property/set
[dbg] dm_msg_request_parse(142): Current Request Message ID: 161430786
[dbg] dm_msg_request_parse(143): Current Request Message Version: 1.0.0
[dbg] dm_msg_request_parse(144): Current Request Message Method: thing.service.property.set
[dbg] dm_msg_request_parse(145): Current Request Message Params: {"LightSwitch":1}
[dbg] dm_ipc_msg_insert(87): dm msg list size: 0, max size: 50
[inf] dm_msg_response(274): Send URI: /sys/a1csED27mp7/AdvExample1/thing/service/property/set_reply, Payload: {"id":"161430786","code":200,"data":{}}
[dbg] MQTTPublish(319): ALLOC: (100) / [164] @ 0x154f1f0
[inf] MQTTPublish(378): Upstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/service/property/set_reply'
[inf] MQTTPublish(379): Upstream Payload:

The response sent back to the cloud is as follows:

> {
>     "id": "161430786",
>     "code": 200,
>     "data": {
>     }
> }

[inf] dm_client_publish(106): Publish Result: 0
[inf] _iotx_linkkit_event_callback(219): Receive Message Type: 15
[inf] _iotx_linkkit_event_callback(221): Receive Message: {"devid":0,"payload":{"LightSwitch":1}}
[dbg] _iotx_linkkit_event_callback(339): Current Devid: 0
[dbg] _iotx_linkkit_event_callback(340): Current Payload: {"LightSwitch":1}

The following log is printed when the user_property_set_event_handler sample function receives the attribute-setting request:

user_property_set_event_handler. 160: Property Set Received, Devid: 0, Request: {"LightSwitch":1}

By now, the attribute-setting request sent from the server has reached the device.

As in the routine, after the attribute-setting request for this attribute is received, the IOT_Linkkit_Report function is called to report the attribute value to the server. The following logs are printed:

[inf] dm_msg_request(218): DM Send Message, URI: /sys/a1csED27mp7/AdvExample1/thing/event/property/post, Payload: {"id":"2","version":"1.0","params":{"LightSwitch":1},"method":"thing.event.property.post"}
[dbg] MQTTPublish(319): ALLOC: (156) / [220] @ 0x154f280
[inf] MQTTPublish(378): Upstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/event/property/post'
[inf] MQTTPublish(379): Upstream Payload:

The user_property_set_event_handler sample function sends the attribute value to the server, which updates the attribute on the cloud:

> {
>     "id": "2",
>     "version": "1.0",
>     "params": {
>         "LightSwitch": 1
>     },
>     "method": "thing.event.property.post"
> }

[inf] dm_client_publish(106): Publish Result: 0
[dbg] alcs_observe_notify(105): payload:{"id":"2","version":"1.0","params":{"LightSwitch":1},"method":"thing.event.property.post"}
[dbg] CoAPResourceByPath_get(176): Found the resource: /sys/a1csED27mp7/AdvExample1/thing/event/property/post
[inf] dm_server_send(76): Send Observe Notify Result 0
[dbg] dm_msg_cache_insert(79): dmc list size: 0
user_property_set_event_handler. 164: Post Property Message ID: 2
[dbg] iotx_mc_cycle(1774): PUBLISH
[inf] iotx_mc_handle_recv_PUBLISH(1549): Downstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/event/property/post_reply'
[inf] iotx_mc_handle_recv_PUBLISH(1550): Downstream Payload:

The response to attribute reporting is as follows:

< {
<     "code": 200,
<     "data": {
<     },
<     "id": "2",
<     "message": "success",
<     "method": "thing.event.property.post",
<     "version": "1.0"
< }

[dbg] iotx_mc_handle_recv_PUBLISH(1555):         Packet Ident : 00000000
[dbg] iotx_mc_handle_recv_PUBLISH(1556):         Topic Length : 60
[dbg] iotx_mc_handle_recv_PUBLISH(1560):           Topic Name : /sys/a1csED27mp7/AdvExample1/thing/event/property/post_reply
[dbg] iotx_mc_handle_recv_PUBLISH(1563):     Payload Len/Room : 104 / 4935
[dbg] iotx_mc_handle_recv_PUBLISH(1564):       Receive Buflen : 5000
[dbg] iotx_mc_handle_recv_PUBLISH(1575): delivering msg ...
[dbg] iotx_mc_deliver_message(1291): topic be matched
[inf] dm_msg_proc_thing_event_post_reply(258): Event Id: property
[dbg] dm_msg_response_parse(167): Current Request Message ID: 2
[dbg] dm_msg_response_parse(168): Current Request Message Code: 200
[dbg] dm_msg_response_parse(169): Current Request Message Data: {}
[dbg] dm_msg_response_parse(174): Current Request Message Desc: success
[dbg] dm_ipc_msg_insert(87): dm msg list size: 0, max size: 50
[dbg] dm_msg_cache_remove(142): Remove Message ID: 2
[inf] _iotx_linkkit_event_callback(219): Receive Message Type: 30
[inf] _iotx_linkkit_event_callback(221): Receive Message: {"id":2,"code":200,"devid":0,"payload":{}}
[dbg] _iotx_linkkit_event_callback(476): Current Id: 2
[dbg] _iotx_linkkit_event_callback(477): Current Code: 200
[dbg] _iotx_linkkit_event_callback(478): Current Devid: 0
user_report_reply_event_handler. 300: Message Post Reply Received, Devid: 0, Message ID: 2, Code: 200, Reply: {}

Note: When the actual product receives the attribute settings, you should parse the attribute and process it accordingly instead of simply sending the value back to the cloud.

Report an event

The IOT_Linkkit_TriggerEvent is used in the sample to report attributes. The sample cycles through reporting the payloads of various situations. You see the following prompt messages returned when incorrect payloads are reported:

void user_post_event(void)
{
static int example_index = 0;
int res = 0;
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
char *event_id = "Error";
char *event_payload = "NULL";

if (example_index == 0) {

Typical event reporting

/* Typical Example */
event_payload = "{\"ErrorCode\":0}";
example_index++;
} else if (...) {
...
...
}

Report the event to the cloud

res = IOT_Linkkit_TriggerEvent(user_example_ctx->master_devid, event_id, strlen(event_id),
event_payload, strlen(event_payload));
EXAMPLE_TRACE("Post Event Message ID: %d", res);
}

In the sample program, the Error event is reported every 17 seconds, and loops in each situation above. The typical reporting log is as follows:

[inf] dm_msg_request(218): DM Send Message, URI: /sys/a1csED27mp7/AdvExample1/thing/event/Error/post, Payload: {"id":"1","version":"1.0","params":{"ErrorCode":0},"method":"thing.event.Error.post"}
[dbg] MQTTPublish(319): ALLOC: (136) / [200] @ 0x1195150
[inf] MQTTPublish(378): Upstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/event/Error/post'
[inf] MQTTPublish(379): Upstream Payload:

The event reported to the cloud is as follows:

> {
>     "id": "1",
>     "version": "1.0",
>     "params": {
>         "ErrorCode": 0
>     },
>     "method": "thing.event.Error.post"
> }

[inf] dm_client_publish(106): Publish Result: 0
[dbg] alcs_observe_notify(105): payload:{"id":"1","version":"1.0","params":{"ErrorCode":0},"method":"thing.event.Error.post"}
[inf] dm_server_send(76): Send Observe Notify Result 0
[dbg] dm_msg_cache_insert(79): dmc list size: 0
user_post_event. 470: Post Event Message ID: 1
[dbg] iotx_mc_cycle(1774): PUBLISH
[inf] iotx_mc_handle_recv_PUBLISH(1549): Downstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/event/Error/post_reply'
[inf] iotx_mc_handle_recv_PUBLISH(1550): Downstream Payload:

The response received from the cloud is as follows:

< {
<     "code": 200,
<     "data": {
<     },
<     "id": "1",
<     "message": "success",
<     "method": "thing.event.Error.post",
<     "version": "1.0"
< }

[dbg] iotx_mc_handle_recv_PUBLISH(1555):         Packet Ident : 00000000
[dbg] iotx_mc_handle_recv_PUBLISH(1556):         Topic Length : 57
[dbg] iotx_mc_handle_recv_PUBLISH(1560):           Topic Name : /sys/a1csED27mp7/AdvExample1/thing/event/Error/post_reply
[dbg] iotx_mc_handle_recv_PUBLISH(1563):     Payload Len/Room : 101 / 4938
[dbg] iotx_mc_handle_recv_PUBLISH(1564):       Receive Buflen : 5000
[dbg] iotx_mc_handle_recv_PUBLISH(1575): delivering msg ...
[dbg] iotx_mc_deliver_message(1291): topic be matched
[inf] dm_msg_proc_thing_event_post_reply(258): Event Id: Error
[dbg] dm_msg_response_parse(167): Current Request Message ID: 1
[dbg] dm_msg_response_parse(168): Current Request Message Code: 200
[dbg] dm_msg_response_parse(169): Current Request Message Data: {}
[dbg] dm_msg_response_parse(174): Current Request Message Desc: success
[dbg] dm_ipc_msg_insert(87): dm msg list size: 0, max size: 50
[dbg] dm_msg_cache_remove(142): Remove Message ID: 1
[inf] _iotx_linkkit_event_callback(219): Receive Message Type: 31
[inf] _iotx_linkkit_event_callback(221): Receive Message: {"id":1,"code":200,"devid":0,"eventid":"Error","payload":"success"}
[dbg] _iotx_linkkit_event_callback(513): Current Id: 1
[dbg] _iotx_linkkit_event_callback(514): Current Code: 200
[dbg] _iotx_linkkit_event_callback(515): Current Devid: 0
[dbg] _iotx_linkkit_event_callback(516): Current EventID: Error
[dbg] _iotx_linkkit_event_callback(517): Current Message: success

The following log is printed for the user’s callback function user_trigger_event_reply_event_handler:

user_trigger_event_reply_event_handler. 310: Trigger Event Reply Received, Devid: 0, Message ID: 1, Code: 200, EventID: Error, Message: success

Service calling

In the device-side sample program, when a service-calling request is received, the following callback function is triggered:

static int user_service_request_event_handler(const int devid, const char *serviceid, const int serviceid_len,
const char *request, const int request_len,
char **response, int *response_len)
{
int contrastratio = 0, to_cloud = 0;
cJSON *root = NULL, *item_transparency = NULL, *item_from_cloud = NULL;
EXAMPLE_TRACE("Service Request Received, Devid: %d, Service ID: %.*s, Payload: %s", devid, serviceid_len,
serviceid,
request);

/* Parse Root */
root = cJSON_Parse(request);
if (root == NULL || ! cJSON_IsObject(root)) {
EXAMPLE_TRACE("JSON Parse Error");
return -1;
}

You need to process the received service with the Service ID of Custom, assign the value of the service input parameter +1 to the output parameter, and return it to the cloud.

if (strlen("Custom") == serviceid_len && memcmp("Custom", serviceid, serviceid_len) == 0) {
...
contrastratio = item_transparency->valueint + 1;

... 
HAL_Snprintf(*response, *response_len, response_fmt, contrastratio);
*response_len = strlen(*response);
} else if (strlen("SyncService") == serviceid_len && memcmp("SyncService", serviceid, serviceid_len) == 0) {
...
...
}
cJSON_Delete(root);

return 0;
}

At this point, you can see the following log on the device side:

[dbg] iotx_mc_cycle(1774): PUBLISH
[inf] iotx_mc_handle_recv_PUBLISH(1549): Downstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/service/Custom'
[inf] iotx_mc_handle_recv_PUBLISH(1550): Downstream Payload:

The following service-calling request is received from the cloud, with the input parameter transparency:

< {
<     "method": "thing.service.Custom",
<     "id": "161445548",
<     "params": {
<         "transparency": 5
<     },
<     "version": "1.0.0"
< }

[dbg] iotx_mc_handle_recv_PUBLISH(1555):         Packet Ident : 00000000
[dbg] iotx_mc_handle_recv_PUBLISH(1556):         Topic Length : 49
[dbg] iotx_mc_handle_recv_PUBLISH(1560):           Topic Name : /sys/a1csED27mp7/AdvExample1/thing/service/Custom
[dbg] iotx_mc_handle_recv_PUBLISH(1563):     Payload Len/Room : 96 / 4946
[dbg] iotx_mc_handle_recv_PUBLISH(1564):       Receive Buflen : 5000
[dbg] iotx_mc_handle_recv_PUBLISH(1575): delivering msg ...
[dbg] iotx_mc_deliver_message(1291): topic be matched
[inf] dm_msg_proc_thing_service_request(224): Service Identifier: Custom
[dbg] dm_msg_request_parse(142): Current Request Message ID: 161445548
[dbg] dm_msg_request_parse(143): Current Request Message Version: 1.0.0
[dbg] dm_msg_request_parse(144): Current Request Message Method: thing.service.Custom
[dbg] dm_msg_request_parse(145): Current Request Message Params: {"transparency":5}
[dbg] dm_ipc_msg_insert(87): dm msg list size: 0, max size: 50
[inf] _iotx_linkkit_event_callback(219): Receive Message Type: 18
[inf] _iotx_linkkit_event_callback(221): Receive Message: {"id":"161445548","devid":0,"serviceid":"Custom","payload":{"transparency":5}}
[dbg] _iotx_linkkit_event_callback(300): Current Id: 161445548
[dbg] _iotx_linkkit_event_callback(301): Current Devid: 0
[dbg] _iotx_linkkit_event_callback(302): Current ServiceID: Custom
[dbg] _iotx_linkkit_event_callback(303): Current Payload: {"transparency":5}

The user’s calling functionuser_service_request_event_handler is called:

user_service_request_event_handler. 99: Service Request Received, Devid: 0, Service ID: Custom, Payload: {"transparency":5}

user_service_request_event_handler. 116: transparency: 5
[dbg] iotx_dm_send_service_response(280): Current Service Response Payload, Length: 19, Payload: {"Contrastratio":6}
[dbg] dm_mgr_upstream_thing_service_response(1275): Current Service Name: thing/service/Custom_reply
[inf] dm_msg_response(274): Send URI: /sys/a1csED27mp7/AdvExample1/thing/service/Custom_reply, Payload: {"id":"161445548","code":200,"data":{"Contrastratio":6}}
[dbg] MQTTPublish(319): ALLOC: (111) / [175] @ 0x85a1a0
[inf] MQTTPublish(378): Upstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/service/Custom_reply'
[inf] MQTTPublish(379): Upstream Payload:

In the callback function, add 1 to the value of transparency, assign the value to Contrastratio, and then report it to the cloud:

> {
>     "id": "161445548",
>     "code": 200,
>     "data": {
>         "Contrastratio": 6
>     }
> }

[inf] dm_client_publish(106): Publish Result: 0
[dbg] alcs_observe_notify(105): payload:{"id":"161445548","code":200,"data":{"Contrastratio":6}}
[inf] dm_server_send(76): Send Observe Notify Result 0

That concludes the descriptions of services, attributes, and events in the advanced version of the single-item routine.