Receiving Push Message and Delaying Command Execution

You can set a callback function for checking received push messages in the SDK. If the confirmed message is a command, you can delay its execution. Your application must handle the pending commands appropriately. Once a command is pended, the SDK will not process it unless it is resent from the server.

If the command execution is not delayed, the SDK will handle the command appropriately. See Executing Commands to check how the command is handled.

Callback function for checking push message

A prototype of a callback function for checking push message is as follows:

typedef tio_bool_t (*TIO_CB_PUSH)(
        const char* message,
        size_t message_length,
        void* userdata);

You will define the callback function on the basis of this prototype.

tio_bool_t tio_cb_push (
        const char* message,
        size_t message_length,
        void* userdata)
{
    /* Do something. */

    return KII_FALSE;
}

If the content passed in message is a command, you can delay its execution. Return KII_TRUE if you want to delay the execution. Return KII_FALSE otherwise.

Set this callback function using the setter function when you initialize the tio_handler_t instance.

tio_handler_set_cb_push(&handler, tio_cb_push, &cb_push_userdata);

This callback function is optional. You only need to set it when you need it.

Here is a simple sample for delaying the command execution.

void message_enqueue(const char* msg, size_t len);

tio_bool_t tio_cb_push(
        const char* message,
        size_t message_length,
        void* userdata)
{
    if (strstr(message, "\"commandID\"") != NULL) {
        message_enqueue(message, message_length);
        return KII_TRUE;
    }
    return KII_FALSE;
}

You just need to save the content passed in message in some way (a message queue, as shown in this example) and return KII_TRUE. Note that this sample code only uses the existence of commandID for judging if the content is a command or not. You might want to use a more appropriate method.

Executing commands

We use the tio_handler_parse_command API for executing commands. You can execute each action in the command by setting the command string and the callback function for passing the parsed result. Do not forget to save the action execution result so that you can later return the result to the server.

A prototype of a callback function for notifying the parsed result per action is as follows:

typedef void (*TIO_CB_PARSED_ACTION)(
        char* command_id,
        tio_action_t* action,
        void* userdata);

You will define the callback function on the basis of this prototype.

void cb_parsed_action(
        char* command_id,
        tio_action_t* action,
        void* userdata)
{
   // DO action and memory result.
}

You will execute the tio_handler_parse_command as follows:

tio_code_t res = tio_handler_parse_command(
        handler,
        command,
        command_length,
        cb_parsed_action,
        cb_parsed_action_userdata);

if (res != TIO_ERR_OK) {
    // error handle.
}

In the TIO_CB_PARSED_ACTION callback function, use the action parameters for each action to execute the requested actions.

Before start parsing the JSON, please check the following:

  • Check the alias parameter.

    Check if the value matches with a known trait name. You can check its length with the alias_length parameter.

Then, identify and execute the designated action as follows.

  • Check the action_name parameter

    Identify the target action by checking the string in the action_name parameter. You can check its length with the alias_length parameter. The action name specified in the trait definition is stored in the action_name parameter. For example, the string like turnPower and setPresetTemperature are contained in the parameter. By making the string comparison, the action handler can determine which action to execute.

  • Check the action_value parameter

    Parse the parameter and execute the requested action. The action_value stores the tio_action_value_t union containing various values.

It is probably a good idea to save the action results in the alias and action_name pairs. In some cases, you may also need to sort the action results by command_id. If this is the case, you should use the command_id value.

Sending command execution result

Use the tio_handler_handle_command API to send the command execution result. You can send the execution result to the server by setting the command string and the callback function for setting the execution result per action in this API.

A prototype of the callback function for setting the execution result per action is as follows:

typedef void (*TIO_CB_ACTION)(
        tio_action_t* action,
        tio_action_err_t* err,
        tio_action_result_data_t* data,
        void* userdata);

You will define the callback function on the basis of this prototype.

tio_bool_t cb_action_result(
        tio_action_t* action,
        tio_action_err_t* err,
        tio_action_result_data_t* data,
        void* userdata)
{
    // Set result of parsed_action_cb.
    return KII_TRUE/* or KII_FALSE */;
}

The callback should return KII_TRUE when the action specified in action is successfully executed. Otherwise, it should return KII_FALSE. In case when the action execution failed, you can put an error message in theerr. You can also put an arbitrary message in the data regardless of if the action execution succeeded or failed.

You will execute the tio_handler_handle_command as follows:

tio_code_t res = tio_handler_handle_command(
        handler,
        command,
        command_length,
        cb_action_result,
        cb_action_result_userdata);

if (res != TIO_ERR_OK) {
    // error handle.
}

Sample code

Here is a sample code of the delayed command execution. In this sample, we assume that commands are stored in a message queue by the push callback function. The app creates a task to execute the commands in the queue.

void other_application_task(tio_handler_t* handler) {
   char msg_buff[MAX_MSG_SIZE];

   while(1) {
       size_t msg_len = message_dequeue(msg_buff, MAX_MSG_SIZE);
       if (msg_len > 0) {
           tio_code_t res = tio_handler_parse_command(
                   handler,
                   msg_buff,
                   msg_len,
                   cb_parsed_action,
                   cb_parsed_action_userdata);

           if (res != TIO_ERR_OK) {
               // error handle.
           }

           res = tio_handler_handle_command(
                   handler,
                   msg_buff,
                   msg_len,
                   cb_action_result,
                   cb_action_result_userdata);

           if (res != TIO_ERR_OK) {
               // error handle.
           }
       }
       sleep(1);
   }
}

The code gets a command string from the message queue. If the string is valid, actions in the command are executed with the tio_handler_parse_command method. The command execution result is sent to the server with the tio_handler_handle_command method.