Skip to content

Program Code

1. Initialize QuecThing

QuecOpen SDK provides APIs for reading and writing device information and corresponding reference implementation, which can be adapted based on actual scenarios. When the device sends bootstrap authentication operations, Developer Center will authenticate the PK and PS. If the authentication succeeds, Developer Center will issue the required information to the device. Finally, the device carries this information to establish a connection with Developer Center.

c
/* Initialize QuecThing SDK. */
Ql_iotInit();
/* Register callback function for interaction event between the device and Developer Center. */
Ql_iotConfigSetEventCB(Ql_iotEventCB);
/* Configure product information.*/
Ql_iotConfigSetProductinfo("p1xxxS", "VnhyxxxxxxxxSTFh");
/* Configure the connection mode between the device and Developer Center. */
Ql_iotConfigSetConnmode(1);

2. Event Callback Function

In short, an event callback function is to add a listening task Ql_iotEventCB() to an event source (component). When you trigger some event, the listener will take over the event and you can perform different operations according to different events. The data template sample Ql_iotMain.c has implemented a generic framework for processing data events, and you can develop business logic based on this sample.

The event callback function can judge the event code and then enter the corresponding logic processing program. You only need to specifically process it in Ql_iotEventCB(). The event callback function can be divided into eight main events: bootstrap authentication, access, subscription, data sending, data receiving, de-registration, OTA, and Developer Center events. Specific descriptions are as follows:

  • Bootstrap Authentication Event

This event returns the result of device bootstrap authentication. You can check whether the device authentication is successful or not and view some error codes for connection failure, which facilitates developers to handle the errors according to the corresponding error codes.

  • Access Event

This event returns whether the device accesses Developer Center successfully. When a device accesses Developer Center, there may be errors such as incorrect DeviceKey or abnormal network. Developers can handle these errors according to the error codes.

  • Subscription Event

This event returns whether subscribing to the MQTT topic is successful.

  • Data Sending Event

This event returns the result of sending data, such as sending TSL data, transparent transmission data and positioning data.

  • Data Receiving Event

This event indicates that the transparent transmission data or downlink TSL data (service call and issuing writable property) or querying TSL (reading operations in device debug) is received. Developers can interact with Developer Center according to this event.

  • Deregistration Event

This event indicates successful de-registration (disconnection), that is, the device disconnects from Developer Center.

  • OTA Event

This event returns OTA upgrade operations. For example, if there is a new OTA upgrade task, the developer can determine whether to enable the OTA upgrade according to the configuration in event arguments and check the OTA upgrade progress, including "There is an upgrade task", "Device starts to download firmware package", "The firmware package is being downloaded", "The firmware package is downloaded successfully", "The firmware package is being upgraded", "The firmware package is upgraded successfully" and "Firmware upgrade failure".

  • Developer Center Event

    This event indicates the Developer Center's current limit when the device sends or receives messages, for example, the number of activations or requests of a device exceeds the requirement.

For example, when the device sends TSL data to Developer Center, the callback function informs {event:4,errcode:10210}, which indicates the device has successfully sent TSL data to Developer Center. Then the developer can process the event under the event callback function, as shown below:

c
/**************************************************************************
** Function	@brief: Event callback
** Input   	@param : event: Main event 
** Input   	@param : errcode: Event code (subset)
** Input   	@param : value: Property data
** Input   	@param : valLen: Property data length
** Output  	@retval: NULL
***************************************************************************/
void Ql_iotEventCB(quint32_t event, qint32_t errcode, const void *value, quint32_t valLen)
{
	/* Determine the callback event. */
	switch (event)
	{
		/* Send data. */
		case 4:
		  if(10210 == errcode)
	      {
	      	/* code */
	      	printf("Sending object model succeeded\r\n");
	      }
	 		break;
	  	default:
	        break;
	}
}

Note: See Events Related to Interaction Between the Device and Developer Center for details.

3. Develop Application Logic

1) Define Variable (Optional)

A structure is a special compound data type defined by users. Developers can define it according to the TSL template on Developer Center, which will make the program structure clearer in the code project. In addition, you can add the structure type variable to the function in this way as needed.

  • Sample Code

    c
    typedef struct 
    {
        float         OilsCurrentCapacity;  /* The remaining content of essential oil. Unit: ML.*/
        quint32_t     ReportFrequency;		/* Frequency of regular reporting. Unit: s.*/
        qbool         PowerSwitch;			/* On/Off status 0: Off; 1: On.*/
        qbool         OilsLackWarning;		/* Alert to lack of essential oil. Report the event to Developer Center when the essential oil is insufficient.*/
        quint32_t     WorkPattern;			/* Set working mode.*/
    }AromaDiffuser_type;  
    
    AromaDiffuser_type g_AromaDiffuser_st;

The device can detect and process data property based on service scenarios. For example, the device can read the remaining content of essential oil into the structure by connecting the sensor of the smart aromatherapy diffuser through a serial port. The module needs to upload the remaining content of essential oil read at this moment to Developer Center.

  • Sample Code

    c
    while (1)
    {
        /*Report the remaining content of essential oil every 30 seconds.*/ 
        void *ttlvHead = NULL;   
        /*The remaining content of essential oil*/  
        Ql_iotTtlvIdAddFloat(&ttlvHead, 1, g_AromaDiffuser_st.OilsCurrentCapacity);
        /*The first argument is QoS, and when it is equal to or greater than 1, there will be an event callback response.*/
        Ql_iotCmdBusPhymodelReport(1, ttlvHead);
        Ql_iotTtlvFree(&ttlvHead);
        sleep(30); 
    }

    Note: After adding or calling TSL nodes, call Ql_iotTtlvFree() which releases a block of memory pointed to by the pointer, thus avoiding problems such as memory leakage.

QuecThing SDK has simplified the development process for downlink data by parsing TTLV data based on the data template protocol. TSL is a template structure that uses the product data templates from Developer Center to define member variables. You can easily access property data from the parsed downlink data to add business logic in the downlink logic processing function.

  • Sample Code

    c
    void Ql_iotEventCB(quint32_t event, qint32_t errcode, const void *value, quint32_t valLen)
    {
    	/* Determine callback event. */
    	switch (event)
    	{
    	    /* Receive data. */
    	    case QIOT_ATEVENT_TYPE_RECV:
    	        printf("data recv event,code:%d\r\n",errcode);
    	        /* Receive transparent transmission data. */
    	        if(10200 == errcode)
    	        {
    	            printf("pass data:%.*s\r\n",valLen,(char *)value);
    	            /* Test: Send the received transparent transmission data back to Developer Center. */
    	            Ql_iotCmdBusPassTransSend(1,(unsigned char *)value,valLen);
    	        }
    	        /* Receive TSL data (service or writable property) issued by Developer Center. */
    	        else if(10210 == errcode)
    	        {
    	            /* Test: Send the received TSL data back to Developer Center. */
    	            Ql_iotCmdBusPhymodelReport(1,value);
    	            /* Parse the TSL data (You can process the issued service in the function).*/
    	            Ql_iotTtlvHandle(value);
    	        }
    	        /* Receive the request for TSL data (Developer Center reads the data). */
    	        else if(10211 == errcode && value)
    	        {
    	            quint16_t pkgId = *(quint16_t *)value;
    	            quint16_t *ids = (quint16_t *)(value+sizeof(quint16_t));
    	            void *ttlvHead = NULL;
    	            printf("model read event,pkgid:%d\r\n",pkgId);
    	            quint32_t i = 0;
    	            for(i=0;i<valLen;i++)
    	            {
    	                quint16_t modelId = ids[i];
    	                printf("modelId:%d\r\n",modelId);
    	                /* id1:Float id2:int id3:Bool */
    	                switch (modelId)
    	                {
    	               	 case 1:
    	                    Ql_iotTtlvIdAddFloat(&ttlvHead, modelId, g_AromaDiffuser_st.OilsCurrentCapacity);/* The remaining content of essential oil. Unit: ML.*/
    	                    break;
    	              	  case 2:
    	                    Ql_iotTtlvIdAddInt(&ttlvHead, modelId, g_AromaDiffuser_st.ReportFrequency);/* Frequency of regular reporting. Unit: s. */
    	                    break;
    	              	  case 3:
    	                   Ql_iotTtlvIdAddBool(&ttlvHead, modelId, g_AromaDiffuser_st.PowerSwitch);/* On/Off status. */
    	                    break;
    	              	  default:
    	                    break;
    	                }
    	            }
    	            Ql_iotCmdBusPhymodelAck(1,pkgId,ttlvHead);/* Respond to the requested TSL data to Developer Center. */
    	           	Ql_iotTtlvFree(&ttlvHead);/* Releases TTLV resources. */
    	        }
    	        break;
    	          	default:
    	        break;
    	}
    }

4. Compile

This part takes EC600N-CNLC module as an example to introduce the compilation procedure.

1) Install Toolchain

The SDK has embedded an armcc toolchain . You only need to double-click build. bat to run the script to complete the installation.

2) Create a Terminal

What we need to do first is to open or create an integrated terminal. The simplest way is to press Ctrl + Shift+` or click Terminal > Create Terminal on the toolbar.

3) Compile

Note: This compilation is based on the environment of  EC600N\LTE01R03A23_C_SDK_A_SDK\ql-sdk.
img

a. Compile Application File

./build.bat app

b. Generate Firmware

./build.bat firmware A target folder, which contains LTEXXX_C_SDK_A.ZIP, will be automatically generated in the current path after a successful compilation.

5. Download

This part takes EC600N-CNLC module as an example to introduce how to use a burning tool to download a program into the module.

1) Download Burning Tool Enter the "Module Development" page, select the specified module to enter the corresponding download page, find the burning tool, QFlash, and download it.
Note: In Windows 10, after QFlash is downloaded successfully, right-click QFlash.exe and select "Run as Administrator" to run QFlash.

2) Connect PC to the Device Connect your PC to Acceleronix Download Port of the module with a MicroUSB cable.

3) Use the Burning Tool Open QFlash and download the execution file LTEXXX_C_SDK_A.ZIP into the module, as shown below.
Note: The storage path of tools and firmware packages should not contain any spaces or Chinese characters. The storage/loading path of firmware packages should be a local path rather than a USB flash disk or network disk path.

img

Select the COM Port and Baudrate used to connect the module.
Click Load FW Files to open the generated execution file.
Click Start to download the program.