You can use ConnectCore Cloud Services to receive data from Remote Manager, also known as receiving Data 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.

Data 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 CCCS daemon 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, the daemon returns a standard error response to Remote Manager.

To send data points to Remote Manager, follow these steps:

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

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

1. Register a target

To make your application aware of Data Requests sent to the device, you must register a handler for each new target. You can use one of the following functions to register specific targets:

cccs_comm_error_t cccs_add_request_target(char const * const target,
					  cccs_request_data_cb_t data_cb,
					  cccs_request_status_cb_t status_cb,
					  cccs_resp_t *resp);
cccs_comm_error_t cccs_add_request_target_tout(char const * const target,
					       cccs_request_data_cb_t data_cb,
					       cccs_request_status_cb_t status_cb,
					       unsigned long timeout,
					       cccs_resp_t *resp);

The first one obviates the timeout parameter and it does not wait for response from the daemon if it is not ready.

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.

timeout[1]

Number of seconds to wait for response from the daemon.

resp

Received response from CCCS daemon.

Response may contain a string with the result of the operation (resp->hint). This string must be freed.

1. only for cccs_add_request_target_tout() function.

A cccs_comm_error_t error is returned by these functions, CCCS_SEND_ERROR_NONE if success. See Description of errors for more information.

Register a target
#define DATA_REQUEST_TARGET	"increment_counter"

/* [...] */

cccs_comm_error_t register_increment_counter(void)
{
	cccs_comm_error_t ret;
	cccs_resp_t resp;

	ret = cccs_add_request_target_tout(DATA_REQUEST_TARGET, increment_counter_cb,
					   increment_counter_status_cb, 5, &resp);
	if (ret != CCCS_SEND_ERROR_NONE) {
		log_error("Cannot register target '%s': Error %d",
			  DATA_REQUEST_TARGET, ret);
	} else if (resp.code != 0) {
		if (resp.hint) {
			log_error("Cannot register target '%s': Error, %s (%d)",
				  DATA_REQUEST_TARGET, resp.hint, resp.code);
		} else {
			log_error("Cannot register target '%s': Error, %d",
				  DATA_REQUEST_TARGET, resp.code);
		}
	}

	free(resp.hint);

	return ret;
}

/* [...] */

2. Define receive callbacks

Custom receive callbacks are required when registering a new target with cccs_add_request_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:

2.1. 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 cccs_receive_error_t (*cccs_request_data_cb_t)(char const * const target,
						       cccs_buffer_info_t const * const req_buf_info,
						       cccs_buffer_info_t * const resp_buf_info);
Parameter Description

target

Name of the received target.

req_buf_info

Data sent from Remote Manager to the device.

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

resp_buf_info

Device response to Remote Manager after processing the request.

The maximum size of replies to device requests is 2 MB.
Data callback
int counter = 0;

cccs_receive_error_t increment_counter_cb(char const *const target,
					  cccs_buffer_info_t const *const req_buf_info,
					  cccs_buffer_info_t *const resp_buf_info)
{
	char *request = NULL;
	long increment = 0;
	char *tmp = NULL;

	/*
	 * Request info is available at req_buf_info->buffer and is
	 * req_buf_info->length bytes long.
	 *
	 * Handle the request here.
	 *
	 * Write response to resp_buf_info.
	 */

	log_info("Received '%s': Increment counter request!", target);

	request = calloc(req_buf_info->length + 1, sizeof(*request));
	if (!request) {
		log_error("Unable to parse request '%s': Out of memory", target);

		return CCCS_RECEIVE_ERROR_INSUFFICIENT_MEMORY;
	}

	strncpy(request, req_buf_info->buffer, request_buffer_info->length + 1);

	increment = strtol(request, &tmp, 0);
	free(request);
	if (*tmp != '\0') {
		log_error("Invalid incremental value '%s'", request);

		return CCCS_RECEIVE_ERROR_INVALID_DATA_CB;
	}

	counter = counter + increment;

	resp_buf_info->buffer = calloc(DESIRED_MAX_RESPONSE_SIZE,
				       sizeof(*resp_buf_info->buffer));
	if (!resp_buf_info->buffer) {
		log_error("Unable to generate response for '%s': Out of memory", target);

		return CCCS_RECEIVE_ERROR_INSUFFICIENT_MEMORY;
	}

	resp_buf_info->length = sprintf(resp_buf_info->buffer,
					"Current value: %d", counter);

	return CCCS_RECEIVE_ERROR_NONE;
}

2.2. Status callback

CCCS call 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 (*cccs_request_status_cb_t)(char const * const target,
					 cccs_buffer_info_t * const resp_buf_info,
					 int receive_error,
					 const char * const receive_error_hint);
Parameter Description

target

Name of the received target.

resp_buf_info

Device response to Remote Manager after processing the request.

receive_error

Error code after completing the response process to Remote Manager.

receive_error_hint

Error hint string after completing the response process to Remote Manager.

This callback has a receive_error argument indicating the final error status.

Status callback
void increment_counter_status_cb(char const *const target,
				 cccs_buffer_info_t *const resp_buf_info,
				 int receive_error,
				 const char * const receive_error_hint)
{
	log_info("Error code='%d', %s", receive_error, receive_error_hint);

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

3. Remove a target

When you want to stop listening for any specific Data Request, you can remove the target with the following functions:

cccs_comm_error_t cccs_remove_request_target(char const * const target,
					     cccs_resp_t *resp);
cccs_comm_error_t cccs_remove_request_target_tout(char const * const target,
						  unsigned long timeout,
						  cccs_resp_t *resp);
Parameter Description

target

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

timeout[1]

Number of seconds to wait for response from the daemon.

resp

Received response from CCCS daemon.

Response may contain a string with the result of the operation (resp->hint). This string must be freed.

1. only for cccs_remove_request_target_tout() function.

A cccs_comm_error_t error is returned by these functions, CCCS_SEND_ERROR_NONE if success. See Description of errors for more information.

Remove a target
/* [...] */

cccs_comm_error_t remove_increment_counter(void)
{
	cccs_comm_error_t ret;
	cccs_resp_t resp;

	ret = cccs_remove_request_target_tout(DATA_REQUEST_TARGET, 5, &resp);
	if (ret != CCCS_SEND_ERROR_NONE) {
		log_error("Cannot remove target '%s': Error %d",
			  DATA_REQUEST_TARGET, ret);
	} else if (resp.code != 0) {
		if (resp.hint) {
			log_error("Cannot remove target '%s': Error, %s (%d)",
				  DATA_REQUEST_TARGET, resp.hint, resp.code);
		} else {
			log_error("Cannot remove target '%s': Error, %d",
				  DATA_REQUEST_TARGET, resp.code);
		}
	}

	free(resp.hint);

	return ret;
}

/* [...] */

4. Test implemented data request

A Data Request can be sent via Remote Manager web service APIs within the Remote Manager platform. To test your data request support, you can use API Explorer.

API Explorer is a graphical tool to send API web requests and review the answer. From here, you can test web services to list uploaded data, command requests to your devices, and much more.

To send a request use API Explorer:

  1. Get your device identifier from the Devices page:

    1. Go to the Device Management > Devices tab.

    2. Copy the Device ID of your device from the table by using the Copy Device ID button that appears next to it when you hover over the item.

      If you have more than one device, you can filter using the MAC address of your device:

      1. Click on the filter text box and select MAC.

      2. Type the MAC address of your device and press Enter.

  2. Go to the System > API Explorer tab. This tool allows you to test the web service APIs.

  3. Click the Examples combo.

  4. Select SCI > Data Service > Send Request.

    A request appears inside the Body text box.

  5. Modify the request:

    1. Replace the device id value with the copied one.

    2. Replace the target_name value with the target to use, for example increment_counter.

    3. Remove the payload of the request.

    The request should be similar to the following:

    increment_counter request
    <sci_request version="1.0">
      <data_service>
        <targets>
          <device id="00000000-00000000-00XXXXXX-XXXXXXXX" />
        </targets>
       <requests>
         <device_request target_name="increment_counter">5</device_request>
       </requests>
      </data_service>
    </sci_request>

    Where 00000000-00000000-00XXXXXX-XXXXXXXX is your device id.

  6. Click Send to send the request to your device.

    In the Response text box you can review the answer from the device:

    Response of increment_counter request
    <sci_reply version="1.0">
      <data_service>
        <device id="00000000-00000000-00XXXXXX-XXXXXXXX">
          <requests>
            <device_request target_name="increment_counter" status="0"></device_request>
          </requests>
        </device>
      </data_service>
    </sci_reply>

    Where 00000000-00000000-00XXXXXX-XXXXXXXX is your device id.

See Send data to devices for more information on how to send data using Remote Manager web service APIs.

Description of errors

cccs_comm_error_t error Description

CCCS_SEND_ERROR_NONE

Operation completed successfully. No error found.

CCCS_SEND_ERROR_INVALID_ARGUMENT

In most cases this refers to empty strings or NULL pointers in structures.

CCCS_SEND_ERROR_OUT_OF_MEMORY

CCCS encountered problems allocating memory to perform receive operations.

Your system may have run out of resources.

CCCS_SEND_ERROR_LOCK

CCCS encountered problems using synchronization mechanisms.

Your system may have run out of resources.

CCCS_SEND_UNABLE_TO_CONNECT_TO_DAEMON

Unable to connect to CCCS daemon.

It is probably not running.

CCCS_SEND_ERROR_BAD_RESPONSE

Received bad response from CCCS daemon.

CCCS_SEND_ERROR_FROM_CLOUD

Error received from Digi Remote Manager.

Data Request example

The Data Request example demonstrates how to use the CCCS 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.