You can use Cloud Connector to receive data from Remote Manager, also known as receiving Device Requests. Transfers are initiated from a Web Services client connected to Remote Manager, which hosts the device. This transfer is used to send data to the device or trigger actions in the device. The device may also return a response.

Device Requests are composed of:

  • Target: A unique name which specifies which part of the application is in charge of attending this request.

  • Data: Arbitrary data sent to the device.

On the device, when Cloud Connector receives the request, it looks into the user-registered targets. If a match is found, then it is automatically accepted and the appropriate handlers called. If no match is found, Cloud Connector returns a standard error response to Remote Manager.

Digi Embedded Yocto includes a Device Request example demonstrating how to receive device requests from Remote Manager.

For a list of possible errors receiving device request from Remote Manager, see Description of errors.

1. Register a target

In order to make your application aware of Device Requests sent to the device, you must register a handler for each new target. The ccapi_receive_add_target() function allows you to register specific targets.

ccapi_receive_error_t ccapi_receive_add_target(char const * const target, ccapi_receive_data_cb_t const data_cb,
					       ccapi_receive_status_cb_t const status_cb, size_t const max_request_size)
Parameter Description

target

Name of the target to register. It must be unique.

data_cb

Callback called when new data for target is received. This function performs the request and optionally returns a response to Remote Manager.

status_cb

Callback called when the receive process has completed. This function checks status and free resources.

This may be NULL if no status callback is required.

max_request_size

Maximum length of the data to be received in a request from Remote Manager for this target.

If the data received exceeds this value, data_cb will not be called, only status_cb.

The following subset of ccapi_receive_error_t errors can be returned by ccapi_receive_add_target():

  • CCAPI_RECEIVE_ERROR_NONE

  • CCAPI_RECEIVE_ERROR_CCAPI_NOT_RUNNING

  • CCAPI_RECEIVE_ERROR_NO_RECEIVE_SUPPORT

  • CCAPI_RECEIVE_ERROR_INSUFFICIENT_MEMORY

  • CCAPI_RECEIVE_ERROR_INVALID_TARGET

  • CCAPI_RECEIVE_ERROR_TARGET_ALREADY_ADDED

  • CCAPI_RECEIVE_ERROR_INVALID_DATA_CB

  • CCAPI_RECEIVE_ERROR_LOCK_FAILED

See Description of errors for more information.

If you want to stop listening for any specific Device Request, you can remove the target with ccapi_receive_remove_target() function.

ccapi_receive_error_t ccapi_receive_remove_target(char const * const target);
Parameter Description

target

Name of the target to remove. It must be unique.

Registering a target
int main (void)
{
	[...]

	init_error = init_cloud_connection(NULL);

	[...]
	receive_error = ccapi_receive_add_target("increment_counter", increment_counter_cb,
						 increment_counter_status_cb, DESIRED_MAX_REQUEST_SIZE);
	if (receive_error != CCAPI_RECEIVE_ERROR_NONE) {
		log_error("Cannot register target 'increment_counter', error %d", receive_error);
	}

	[...]

	start_error = start_cloud_connection();

	[...]
}

The following subset of ccapi_receive_error_t errors can be returned by ccapi_receive_remove_target():

  • CCAPI_RECEIVE_ERROR_NONE

  • CCAPI_RECEIVE_ERROR_CCAPI_NOT_RUNNING

  • CCAPI_RECEIVE_ERROR_NO_RECEIVE_SUPPORT

  • CCAPI_RECEIVE_ERROR_INSUFFICIENT_MEMORY

  • CCAPI_RECEIVE_ERROR_INVALID_TARGET

  • CCAPI_RECEIVE_ERROR_TARGET_NOT_ADDED

  • CCAPI_RECEIVE_ERROR_LOCK_FAILED

See Description of errors for more information.

2. Define receive callbacks

Custom receive callbacks are required when registering a new target with ccapi_receive_add_target() : a data callback to perform the requested operation, and an optional status callback to check the status of the process. In the example above, increment_counter_cb and increment_counter_status_cb callbacks are those custom callbacks:

Data callback

Input and output callback where the application performs the necessary operations to attend the request and optionally creates and returns a response to Remote Manager.

The callback typically follows this scheme:

  1. Analyze the input data from the request.

  2. Perform any necessary operations on the device.

  3. Provide a response to Remote Manager. The callback cannot return a response if Remote Manager made the request without requesting a response.

typedef void (*ccapi_receive_data_cb_t)(char const * const target,
	      ccapi_transport_t const transport,
	      ccapi_buffer_info_t const * const request_buffer_info,
	      ccapi_buffer_info_t * const response_buffer_info)
Parameter Description

target

Name of the received target.

transport

The transport used to received the request.

Always CCAPI_TRANSPORT_TCP.

request_buffer_info

Data sent from Remote Manager to the device.

It may be empty if no data is required to process the target.

response_buffer_info

Device response to Remote Manager after processing the request.

Status callback

Cloud Connector calls status user callback (if provided) when the receive process is complete.

This callback provides overall error status. Users should check status and free all possible resources allocated during the receive process, including the memory allocated to provide a response within the data callback.

typedef void (*ccapi_receive_status_cb_t)(char const * const target, ccapi_transport_t const transport,
					  ccapi_buffer_info_t * const response_buffer_info, ccapi_receive_error_t receive_error)
Parameter Description

target

Name of the received target.

transport

The transport used to received the request.

Always CCAPI_TRANSPORT_TCP.

response_buffer_info

Device response to Remote Manager after processing the request.

receive_error

Error code after completing the response process to Remote Manager.

This callback has a receive_error argument indicating the final error status. Following subset of ccapi_receive_error_t errors can arrive to this callback:

  • CCAPI_RECEIVE_ERROR_NONE

  • CCAPI_RECEIVE_ERROR_INSUFFICIENT_MEMORY>

  • CCAPI_RECEIVE_ERROR_INVALID_DATA_CB

  • CCAPI_RECEIVE_ERROR_USER_REFUSED_TARGET

  • CCAPI_RECEIVE_ERROR_REQUEST_TOO_BIG

  • CCAPI_RECEIVE_ERROR_STATUS_CANCEL

  • CCAPI_RECEIVE_ERROR_STATUS_TIMEOUT

  • CCAPI_RECEIVE_ERROR_STATUS_SESSION_ERROR

See Description of errors for more information.

Data and status callbacks
int counter = 0;

void increment_counter_cb(char const *const target, ccapi_transport_t const transport,
			  ccapi_buffer_info_t const *const request_buffer_info, ccapi_buffer_info_t *const response_buffer_info)
{
	char *request = NULL;
	int increment = 0;

	log_info("Increment counter request!");
	/*
	 * Request info is available at request_buffer_info->buffer
	 * and is request_buffer_info->length bytes long.
	 *
	 * Handle the request here. Write response to response_buffer_info
	 */

	request = calloc(1, sizeof (char) * (request_buffer_info->length + 1));
	strncpy(request, request_buffer_info->buffer, request_buffer_info->length + 1);

	increment = atoi(request);

	counter = counter + increment;

	response_buffer_info->buffer = calloc(1, sizeof (char) * DESIRED_MAX_RESPONSE_SIZE);
	response_buffer_info->length = sprintf(response_buffer_info->buffer, "Current value: %d", counter);
}

void increment_counter_status_cb(char const *const target, ccapi_transport_t const transport,
				 ccapi_buffer_info_t *const response_buffer_info, ccapi_receive_error_t receive_error)
{
	log_info("increment_counter_status_cb(): error code='%d'", receive_error);

	/* Free the response buffer */
	free(response_buffer_info->buffer);
}
You can register different targets using the same callback. Use the target parameter in the callback function to distinguish between them.

3. Use the API Explorer to send device requests

A Device Request can be sent via Web Services within the Remote Manager platform. If you have implemented a Device Request listener and you want to test it, follow these steps:

  1. Go to Documentation > API Explorer.

  2. Select Examples > SCI > Data Service > Send Request. Remote Manager automatically creates the necessary code.

  3. Replace the "device id" value with the ID of your device.

  4. Enter your target name and data for the device request.

    Remote Manager - API Explorer
    <sci_request version="1.0">
      <data_service>
        <targets>
          <device id="XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX"/>
        </targets>
        <requests>
          <device_request target_name="increment_counter">5</device_request>
        </requests>
      </data_service>
    </sci_request>
  5. Click Send.

Description of errors

Error Description

CCAPI_RECEIVE_ERROR_NONE

Operation completed successfully. No error found.

CCAPI_RECEIVE_ERROR_CCAPI_NOT_RUNNING

You missed calling initialize_cloud_connection() function or it failed.

CCAPI_RECEIVE_ERROR_NO_RECEIVE_SUPPORT

Receive service is not available. It probably has not been started.

CCAPI_RECEIVE_ERROR_INSUFFICIENT_MEMORY

Cloud Connector encountered problems allocating memory to perform receive operations. Your system may have run out of resources.

CCAPI_RECEIVE_ERROR_INVALID_TARGET

The target argument in ccapi_receive_add_target() or ccapi_receive_remove_target() is invalid.

CCAPI_RECEIVE_TARGET_NOT_ADDED

The ccapi_receive_remove_target() is trying to remove a target that was not previously added.

CCAPI_RECEIVE_TARGET_ALREADY_ADDED

The ccapi_receive_add_target() is trying to add a target that is already added.

CCAPI_RECEIVE_ERROR_INVALID_DATA_CB

The ccapi_receive_add_target() was called with data_cb argument set to NULL.

CCAPI_RECEIVE_ERROR_LOCK_FAILED

Cloud Connector encountered problems using synchronization mechanisms. Your system may have run out of resources.

CCAPI_RECEIVE_ERROR_REQUEST_TOO_BIG

Received request is bigger that the limit established by the user through the maximum_request_size argument in the ccapi_receive_add_target() function.

CCAPI_RECEIVE_ERROR_STATUS_TIMEOUT

Session timed out.

CCAPI_RECEIVE_ERROR_STATUS_SESSION_ERROR

Error from lower communication layer. You can check the specific error on the logging output.

Device Request example

The Device Request listener example demonstrates the usage of the Cloud Connector receive data API. In this example, a target to retrieve the system time is registered.

This example is included in Digi Embedded Yocto. Go to GitHub to look at the application source code.