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 |
---|---|
|
Name of the target to register. It must be unique. |
|
Callback called when new data for This function performs the request and optionally returns a response to Remote Manager. |
|
Callback called when the receive process has completed. This function checks status and free resources. This may be |
|
Number of seconds to wait for response from the daemon. |
|
Received response from CCCS daemon. Response may contain a string with the result of the operation ( |
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.
#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:
-
Analyze the input data from the request.
-
Perform any necessary operations on the device.
-
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 |
---|---|
|
Name of the received target. |
|
Data sent from Remote Manager to the device. It may be empty if no data is required to process the target. |
|
Device response to Remote Manager after processing the request. |
The maximum size of replies to device requests is 2 MB. |
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 |
---|---|
|
Name of the received target. |
|
Device response to Remote Manager after processing the request. |
|
Error code after completing the response process to Remote Manager. |
|
Error hint string after completing the response process to Remote Manager. |
This callback has a receive_error
argument indicating the final error status.
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 |
---|---|
|
Name of the target to remove. It must be unique. |
|
Number of seconds to wait for response from the daemon. |
|
Received response from CCCS daemon. Response may contain a string with the result of the operation ( |
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.
/* [...] */
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:
-
Get your device identifier from the Devices page:
-
Go to the Device Management > Devices tab.
-
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:
-
Click on the filter text box and select MAC.
-
Type the MAC address of your device and press Enter.
-
-
-
Go to the System > API Explorer tab. This tool allows you to test the web service APIs.
-
Click the Examples combo.
-
Select SCI > Data Service > Send Request.
A request appears inside the Body text box.
-
Modify the request:
-
Replace the
device id
value with the copied one. -
Replace the
target_name
value with the target to use, for exampleincrement_counter
. -
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. -
-
Click Send to send the request to your device.
In the Response text box you can review the answer from the device:
Response ofincrement_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 |
---|---|
|
Operation completed successfully. No error found. |
|
In most cases this refers to empty strings or NULL pointers in structures. |
|
CCCS encountered problems allocating memory to perform receive operations. Your system may have run out of resources. |
|
CCCS encountered problems using synchronization mechanisms. Your system may have run out of resources. |
|
Unable to connect to CCCS daemon. It is probably not running. |
|
Received bad response from CCCS daemon. |
|
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.