diff --git a/cccs-data-request-example/Makefile b/cccs-data-request-example/Makefile
new file mode 100644
index 0000000..37c74e9
--- /dev/null
+++ b/cccs-data-request-example/Makefile
@@ -0,0 +1,40 @@
+#
+# Copyright 2023, Digi International Inc.
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+#
+
+BINARY := cccs-data-request-example
+
+CFLAGS += -Wall
+
+CFLAGS += $(shell pkg-config --cflags cccs)
+LDLIBS += $(shell pkg-config --libs --static cccs)
+
+SRCS := $(wildcard *.c)
+OBJS := $(SRCS:.c=.o)
+
+$(BINARY): $(OBJS)
+ $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+.PHONY: install
+install: $(BINARY)
+ install -d $(DESTDIR)/usr/bin
+ install -m 0755 $^ $(DESTDIR)/usr/bin/
+
+.PHONY: all
+all: $(BINARY)
+
+.PHONY: clean
+clean:
+ -rm -f *.o $(BINARY)
diff --git a/cccs-data-request-example/README.md b/cccs-data-request-example/README.md
new file mode 100644
index 0000000..10e12da
--- /dev/null
+++ b/cccs-data-request-example/README.md
@@ -0,0 +1,118 @@
+Digi ConnectCore Cloud Services Data Request Example Application
+================================================================
+
+Example application to listen to data requests from Remote Manager using
+ConnectCore Cloud Services.
+
+This application registers a `get_time` data request.
+When this request arrives the application sends back the current time.
+
+Running the application
+-----------------------
+This application requires `cccsd` (ConnectCore Cloud Services daemon) running
+on the device.
+
+Once the binary is in the target, launch the application:
+
+```
+# ./cccs-data-request-example
+cccs-data-request-example[1011]: [DEBUG] CCCSD: Connected to CCCSD (s=4)
+cccs-data-request-example[1011]: [DEBUG] CCCS daemon ready
+cccs-data-request-example[1011]: [INFO] DREQ: Registering 'get_time' data request
+cccs-data-request-example[1011]: [DEBUG] CCCSD: Connected to CCCSD (s=7)
+cccs-data-request-example[1011]: [DEBUG] CCCSD: Success from CCCSD
+Waiting for Remote Manager request...
+Press 'q' and 'Enter' to exit
+
+```
+
+Send a `get_time` data request to your device.
+To do so:
+
+1. Go to https://remotemanager.digi.com/.
+2. Login with your credentials.
+3. Get your device identifier from the **Devices** page:
+ a. Go to the **Management > Devices** tab.
+ b. 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`.
+ 3. 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.
+4. Go to the **System > API Explorer** tab. From here you can test the Web
+ Services API.
+5. Click the **Examples** combo.
+6. Select **SCI > Data Service > Send Request**.
+A request appears inside the Body text box.
+7. Modify the request to stop the sampling process on your device:
+ a. Replace the `device id` value with the copied one.
+ b. Replace the `target_name` value with `get_time`.
+ c. Remove the payload of the request.
+ The request should be similar to the following:
+
+ ```xml
+
+
+
+
+
+
+
+
+
+
+ ```
+ Where `00000000-00000000-00XXXXXX-XXXXXXXX` is the Device ID.
+8. Click **Send** to send the request to your device.
+In the **Response** text box you can review the answer from the device:
+
+ ```xml
+
+
+
+
+ Time: Fri Sep 1 11:36:33 2023
+
+
+
+
+ ```
+Where `00000000-00000000-00XXXXXX-XXXXXXXX` is the Device ID.
+
+The application prints out the received request:
+
+```
+[...]
+Waiting for Remote Manager request...
+Press 'q' and 'Enter' to exit
+cccs-data-request-example[1163]: [DEBUG] get_time_cb: target='get_time'
+cccs-data-request-example[1163]: [DEBUG] get_time_status_cb: target='get_time' - error='0' - error-hint='Success'
+```
+
+Compiling the application
+-------------------------
+This example can be compiled using a Digi Embedded Yocto based toolchain. Make
+sure to source the corresponding toolchain of the platform you are using,
+for example, for ConnectCore 6UL:
+
+```
+~$ . /environment-setup-cortexa7t2hf-neon-dey-linux-gnueabi
+~$ make
+```
+
+For more information, see the [Digi Embedded Yocto online documentation](https://github.com/digi-embedded/meta-digi).
+
+License
+-------
+Copyright 2023, Digi International Inc.
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/cccs-data-request-example/main.c b/cccs-data-request-example/main.c
new file mode 100644
index 0000000..7c0529f
--- /dev/null
+++ b/cccs-data-request-example/main.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2023, Digi International Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#if !(defined UNUSED_ARGUMENT)
+#define UNUSED_ARGUMENT(a) (void)(a)
+#endif
+
+#define TARGET_GET_TIME "get_time"
+
+/*
+ * sigaction_handler() - Handler to execute after receiving a signal
+ *
+ * @signum: Received signal.
+ */
+static void sigaction_handler(int signum)
+{
+ log_debug("%s: received signal %d", __func__, signum);
+
+ exit(0);
+}
+
+/*
+ * cleanup() - Frees all the allocated memory before exiting
+ */
+static void cleanup(void)
+{
+ cccs_resp_t resp;
+ cccs_comm_error_t ret;
+
+ ret = cccs_remove_request_target(TARGET_GET_TIME, &resp);
+ if (ret != CCCS_SEND_ERROR_NONE) {
+ log_error("%s: Cannot unregister target '%s': CCCSD error %d",
+ __func__, TARGET_GET_TIME, ret);
+ } else if (resp.code != 0) {
+ if (resp.hint)
+ log_error("%s: Cannot unregister target '%s': CCCSD error, %s (%d)",
+ __func__, TARGET_GET_TIME, resp.hint, resp.code);
+ else
+ log_error("%s: Cannot unregister target '%s': CCCSD error, %d",
+ __func__, TARGET_GET_TIME, resp.code);
+ }
+
+ free(resp.hint);
+
+ deinit_logger();
+}
+
+/*
+ * register_signals() - Registers program signals
+ */
+static void register_signals(void)
+{
+ struct sigaction new_action;
+ struct sigaction old_action;
+
+ atexit(cleanup);
+
+ new_action.sa_handler = sigaction_handler;
+ new_action.sa_flags = 0;
+ sigemptyset(&new_action.sa_mask);
+
+ sigaction(SIGINT, NULL, &old_action);
+ if (old_action.sa_handler != SIG_IGN)
+ sigaction(SIGINT, &new_action, NULL);
+
+ sigaction(SIGHUP, &old_action, NULL);
+ if (old_action.sa_handler != SIG_IGN)
+ sigaction(SIGHUP, &new_action, NULL);
+
+ sigaction(SIGTERM, &old_action, NULL);
+ if (old_action.sa_handler != SIG_IGN)
+ sigaction(SIGTERM, &new_action, NULL);
+}
+
+/*
+ * get_time_cb() - Data callback for 'get_time' data requests
+ *
+ * @target: Target ID of the data request (get_time).
+ * @req_buf_info: Buffer containing the data request.
+ * @resp_buf_info: Buffer to store the answer of the request.
+ *
+ * Logs information about the received request and executes the corresponding
+ * command.
+ *
+ * Return: 'CCCS_RECEIVE_ERROR_NONE' if success, any other value on failure.
+ */
+static cccs_receive_error_t get_time_cb(char const *const target,
+ cccs_buffer_info_t const *const req_buf_info,
+ cccs_buffer_info_t *const resp_buf_info)
+{
+ time_t t = time(NULL);
+ char *time_str = ctime(&t);
+
+ UNUSED_ARGUMENT(req_buf_info);
+ log_debug("%s: target='%s'", __func__, target);
+
+ resp_buf_info->length = snprintf(NULL, 0, "Time: %s", time_str);
+ resp_buf_info->buffer = calloc(resp_buf_info->length + 1, sizeof(char));
+ if (resp_buf_info->buffer == NULL) {
+ log_error("%s: resp_buf_info calloc error", __func__);
+
+ return CCCS_RECEIVE_ERROR_INSUFFICIENT_MEMORY;
+ }
+
+ resp_buf_info->length = sprintf(resp_buf_info->buffer, "Time: %s", time_str);
+
+ return CCCS_RECEIVE_ERROR_NONE;
+}
+
+/*
+ * get_time_status_cb() - Status callback for 'get_time' data requests
+ *
+ * @target: Target ID of the data request (get_time)
+ * @resp_buf_info: Buffer containing the response data.
+ * @receive_error: The error status of the receive process.
+ * @receive_error_hint: The error hint from the connector service.
+ *
+ * This callback is executed when the response process has finished. It doesn't
+ * matter if everything worked or there was an error during the process.
+ *
+ * Cleans and frees the response buffer.
+ */
+static void get_time_status_cb(char const *const target,
+ cccs_buffer_info_t *const resp_buf_info,
+ int receive_error,
+ const char *const receive_error_hint)
+{
+ log_debug("%s: target='%s' - error='%d' - error-hint='%s'",
+ __func__, target, receive_error, receive_error_hint);
+
+ /* Free the response buffer */
+ if (resp_buf_info != NULL)
+ free(resp_buf_info->buffer);
+}
+
+/*
+ * Use the following SCI request to test this example (insert your Device ID):
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+int main(int argc, char *argv[])
+{
+ cccs_comm_error_t ret;
+ char *name = basename(argv[0]);
+ cccs_resp_t resp;
+ int read_char;
+
+ init_logger(LOG_DEBUG, LOG_CONS | LOG_NDELAY | LOG_PID | LOG_PERROR, name);
+
+ register_signals();
+
+ if (!cccs_is_daemon_ready(CCCSD_NO_WAIT)) {
+ log_error("%s: CCCS daemon not ready... exiting", __func__);
+
+ return EXIT_FAILURE;
+ }
+
+ ret = cccs_add_request_target(TARGET_GET_TIME, get_time_cb,
+ get_time_status_cb, &resp);
+ if (ret != CCCS_SEND_ERROR_NONE) {
+ log_error("%s: Cannot register target '%s': CCCSD error %d",
+ __func__, TARGET_GET_TIME, ret);
+
+ return EXIT_FAILURE;
+ } else if (resp.code != 0) {
+ if (resp.hint)
+ log_error("%s: Cannot register target '%s': CCCSD error, %s (%d)",
+ __func__, TARGET_GET_TIME, resp.hint, resp.code);
+ else
+ log_error("%s: Cannot register target '%s': CCCSD error, %d",
+ __func__, TARGET_GET_TIME, resp.code);
+
+ return EXIT_FAILURE;
+ }
+
+ free(resp.hint);
+
+ printf("Waiting for Remote Manager request...\n");
+ printf("Press 'q' and 'Enter' to exit\n");
+ do {
+ read_char = getchar();
+ } while (read_char != 'q');
+
+ return EXIT_SUCCESS;
+}
diff --git a/cccs-examples.mk b/cccs-examples.mk
new file mode 100644
index 0000000..f5930eb
--- /dev/null
+++ b/cccs-examples.mk
@@ -0,0 +1,28 @@
+#
+# Copyright (c) 2023 Digi International Inc.
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+#
+
+SUBDIRS := \
+ cccs-data-request-example \
+ cccs-upload-data-points-example
+
+all: $(SUBDIRS)
+
+.PHONY: $(SUBDIRS)
+$(SUBDIRS):
+ $(MAKE) -C $@
+
+install clean:
+ for a in $(SUBDIRS); do $(MAKE) -C $$a $@; done
diff --git a/cccs-upload-data-points-example/Makefile b/cccs-upload-data-points-example/Makefile
new file mode 100644
index 0000000..3d9d137
--- /dev/null
+++ b/cccs-upload-data-points-example/Makefile
@@ -0,0 +1,40 @@
+#
+# Copyright 2023, Digi International Inc.
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+#
+
+BINARY := cccs-upload-data-points-example
+
+CFLAGS += -Wall
+
+CFLAGS += $(shell pkg-config --cflags cccs)
+LDLIBS += $(shell pkg-config --libs --static cccs)
+
+SRCS := $(wildcard *.c)
+OBJS := $(SRCS:.c=.o)
+
+$(BINARY): $(OBJS)
+ $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+.PHONY: install
+install: $(BINARY)
+ install -d $(DESTDIR)/usr/bin
+ install -m 0755 $^ $(DESTDIR)/usr/bin/
+
+.PHONY: all
+all: $(BINARY)
+
+.PHONY: clean
+clean:
+ -rm -f *.o $(BINARY)
diff --git a/cccs-upload-data-points-example/README.md b/cccs-upload-data-points-example/README.md
new file mode 100644
index 0000000..afe7e0b
--- /dev/null
+++ b/cccs-upload-data-points-example/README.md
@@ -0,0 +1,68 @@
+Digi ConnectCore Cloud Services Upload Data Points Example Application
+======================================================================
+
+Example application to upload data points to Remote Manager using ConnectCore
+Cloud Services.
+
+This application uploads an integer value with an incremented counter to a data
+stream called 'incremental'. The counter value is incremented every 5 seconds.
+The uploads takes place every 10 new samples, that is every 50 seconds.
+
+Running the application
+-----------------------
+This application requires `cccsd` (ConnectCore Cloud Services daemon) running
+on the device.
+
+Once the binary is in the target, launch the application:
+
+```
+# ./cccs-upload-data-points-example
+cccs-upload-data-points-example[1010]: [DEBUG] CCCSD: Connected to CCCSD (s=4)
+cccs-upload-data-points-example[1010]: [DEBUG] CCCS daemon ready
+cccs-upload-data-points-example[1090]: [INFO] Counter = 0
+cccs-upload-data-points-example[1090]: [INFO] Counter = 1
+cccs-upload-data-points-example[1090]: [INFO] Counter = 2
+cccs-upload-data-points-example[1090]: [INFO] Counter = 3
+cccs-upload-data-points-example[1090]: [INFO] Counter = 4
+cccs-upload-data-points-example[1090]: [INFO] Counter = 5
+cccs-upload-data-points-example[1090]: [INFO] Counter = 6
+cccs-upload-data-points-example[1090]: [INFO] Counter = 7
+cccs-upload-data-points-example[1090]: [INFO] Counter = 8
+cccs-upload-data-points-example[1090]: [INFO] Counter = 9
+cccs-upload-data-points-example[1090]: [INFO] Sending data sream with new incremental value
+cccs-upload-data-points-example[1090]: [INFO] DP: Sending data points to CCCSD
+cccs-upload-data-points-example[1090]: [DEBUG] CCCSD: Connected to CCCSD (s=4)
+cccs-upload-data-points-example[1090]: [DEBUG] CCCSD: Success from CCCSD
+cccs-upload-data-points-example[1090]: [INFO] Counter = 10
+cccs-upload-data-points-example[1090]: [INFO] Counter = 11
+
+```
+
+Compiling the application
+-------------------------
+This example can be compiled using a Digi Embedded Yocto based toolchain. Make
+sure to source the corresponding toolchain of the platform you are using,
+for example, for ConnectCore 6UL:
+
+```
+~$ . /environment-setup-cortexa7t2hf-neon-dey-linux-gnueabi
+~$ make
+```
+
+For more information, see the [Digi Embedded Yocto online documentation](https://github.com/digi-embedded/meta-digi).
+
+License
+-------
+Copyright 2023, Digi International Inc.
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/cccs-upload-data-points-example/main.c b/cccs-upload-data-points-example/main.c
new file mode 100644
index 0000000..a3122f8
--- /dev/null
+++ b/cccs-upload-data-points-example/main.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2023, Digi International Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define STREAM_NAME "incremental"
+
+#define DP_SLEEP_TIME 5
+#define DP_NUMBER 10
+
+static int stop_requested = 0;
+static cccs_dp_collection_handle_t dp_collection;
+
+/*
+ * destroy_data_stream() - Destroy the data collection with the included data streams
+ *
+ * @collection: Data point collection to destroy.
+ *
+ * Return: 'CCCS_DP_ERROR_NONE' if success, any other value on failure.
+ */
+static cccs_dp_error_t destroy_data_stream(cccs_dp_collection_handle_t collection)
+{
+ log_debug("%s", "Destroying data collection");
+
+ return cccs_dp_destroy_collection(collection);
+}
+
+/*
+ * sigaction_handler() - Handler to execute after receiving a signal
+ *
+ * @signum: Received signal.
+ */
+static void sigaction_handler(int signum)
+{
+ log_debug("%s: received signal %d", __func__, signum);
+
+ stop_requested = 1;
+ /* 'atexit' executes the cleanup function */
+ exit(0);
+}
+
+/*
+ * cleanup() - Frees all the allocated memory before exiting
+ */
+static void cleanup(void)
+{
+ if (stop_requested)
+ destroy_data_stream(dp_collection);
+
+ deinit_logger();
+}
+
+/*
+ * register_signals() - Registers program signals
+ */
+static void register_signals(void)
+{
+ struct sigaction new_action;
+ struct sigaction old_action;
+
+ atexit(cleanup);
+
+ new_action.sa_handler = sigaction_handler;
+ new_action.sa_flags = 0;
+ sigemptyset(&new_action.sa_mask);
+
+ sigaction(SIGINT, NULL, &old_action);
+ if (old_action.sa_handler != SIG_IGN)
+ sigaction(SIGINT, &new_action, NULL);
+
+ sigaction(SIGHUP, &old_action, NULL);
+ if (old_action.sa_handler != SIG_IGN)
+ sigaction(SIGHUP, &new_action, NULL);
+
+ sigaction(SIGTERM, &old_action, NULL);
+ if (old_action.sa_handler != SIG_IGN)
+ sigaction(SIGTERM, &new_action, NULL);
+}
+
+/*
+ * get_incremental_value() - Retrieves an incremental value each time
+ *
+ * Return: The new counter value.
+ */
+static int get_incremental_value(void)
+{
+ static int counter = -1;
+
+ if (counter == INT_MAX)
+ counter = 0;
+ else
+ counter++;
+
+ log_info("Counter = %d", counter);
+
+ return counter;
+}
+
+/*
+ * init_data_stream() - Initialize a data point collection
+ *
+ * @collection: Data point collection to initialize
+ *
+ * This function creates a data point collection and adds the 'incremental'
+ * data stream to it.
+ *
+ * Return: 'CCCS_DP_ERROR_NONE' if success, any other value on failure.
+ */
+static cccs_dp_error_t init_data_stream(cccs_dp_collection_handle_t *collection)
+{
+ cccs_dp_collection_handle_t c;
+ cccs_dp_error_t dp_error;
+
+ dp_error = cccs_dp_create_collection(&c);
+ if (dp_error != CCCS_DP_ERROR_NONE) {
+ log_error("%s: error %d", __func__, dp_error);
+
+ return dp_error;
+ }
+
+ *collection = c;
+
+ dp_error = cccs_dp_add_data_stream_to_collection_extra(c,
+ STREAM_NAME, CCCS_DP_KEY_DATA_INT32, true, "counts", NULL);
+ if (dp_error != CCCS_DP_ERROR_NONE) {
+ log_error("%s: error %d", __func__, dp_error);
+ cccs_dp_destroy_collection(c);
+ *collection = NULL;
+ }
+
+ return dp_error;
+}
+
+/*
+ * add_incremental_data_point() - Add a new incremental data point to the collection
+ *
+ * @collection: Data point collection to add the new data point.
+ *
+ * Return: 'CCCS_DP_ERROR_NONE' if success, any other value on failure.
+ */
+static cccs_dp_error_t add_incremental_data_point(cccs_dp_collection_handle_t collection)
+{
+ cccs_dp_error_t dp_error;
+
+ dp_error = cccs_dp_add(collection, STREAM_NAME, get_incremental_value());
+ if (dp_error != CCCS_DP_ERROR_NONE)
+ log_error("%s: failed with error: %d", __func__, dp_error);
+
+ return dp_error;
+}
+
+/*
+ * send_data() - Send collected data to ConnectCore Cloud Services daemon
+ *
+ * @collection: Data point collection to with the data to send.
+ *
+ * Return: 0 if success, any other value on failure.
+ */
+static int send_data(cccs_dp_collection_handle_t collection)
+{
+ cccs_comm_error_t ret;
+ cccs_resp_t resp;
+
+ log_info("%s", "Sending data sream with new incremental value");
+
+ ret = cccs_send_dp_collection_tout(collection, 5, &resp);
+ if (ret != CCCS_SEND_ERROR_NONE) {
+ log_error("%s: error sending data points: CCCSD error %d", __func__, ret);
+ } else if (resp.code != 0) {
+ if (resp.hint)
+ log_error("%s: error sending data points: CCCSD error %s (%d)", __func__, resp.hint, resp.code);
+ else
+ log_error("%s: error sending data points: CCCSD error %d", __func__, resp.code);
+ }
+
+ free(resp.hint);
+
+ return ret;
+}
+
+int main(int argc, char *argv[])
+{
+ char *name = basename(argv[0]);
+ cccs_dp_error_t dp_error;
+ int i;
+
+ init_logger(LOG_DEBUG, LOG_CONS | LOG_NDELAY | LOG_PID | LOG_PERROR, name);
+
+ register_signals();
+
+ if (!cccs_is_daemon_ready(CCCSD_NO_WAIT)) {
+ log_error("%s: CCCS daemon not ready... exiting", __func__);
+
+ return EXIT_FAILURE;
+ }
+
+ dp_error = init_data_stream(&dp_collection);
+ if (dp_error != CCCS_DP_ERROR_NONE) {
+ log_error("%s: Cannot initialize data stream, error %d",
+ __func__, dp_error);
+
+ return EXIT_FAILURE;
+ }
+
+ stop_requested = 0;
+ while (!stop_requested) {
+ /* Collect DP_NUMBER data points sampled each DP_SLEEP_TIME seconds */
+ for (i = 0; i < DP_NUMBER; i++) {
+ dp_error = add_incremental_data_point(dp_collection);
+
+ if (dp_error != CCCS_DP_ERROR_NONE) {
+ log_error("%s: Cannot add data point, error %d",
+ __func__, dp_error);
+ i--;
+ }
+
+ if (i + 1 < DP_NUMBER)
+ sleep(DP_SLEEP_TIME);
+ }
+
+ /* Send the block of collected data points */
+ send_data(dp_collection);
+
+ if (i == DP_NUMBER)
+ sleep(DP_SLEEP_TIME);
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/samples-manifest.xml b/samples-manifest.xml
index 8135f23..ce97fb3 100644
--- a/samples-manifest.xml
+++ b/samples-manifest.xml
@@ -223,4 +223,51 @@ A key modifier may be used to further differentiate the key used in a particular
ccimx8mm-dvk
+
+ Digi CCCS data request Example
+
+Example application to listen to data requests from Remote Manager using
+ConnectCore Cloud Services.
+This application registers a `get_time` data request.
+When this request arrives the application sends back the current time.
+
+ cccs-data-request-example
+
+ ccimx6sbc
+ ccimx6qpsbc
+ ccimx6ulstarter
+ ccimx6ulsbc
+ ccimx8x-sbc-express
+ ccimx8x-sbc-pro
+ ccimx8mn-dvk
+ ccimx8mm-dvk
+ ccmp15-dvk
+ ccmp13-dvk
+ ccimx93-dvk
+
+
+
+ Digi CCCS upload data points Example
+
+Example application to upload data points to Remote Manager using ConnectCore
+Cloud Services.
+This application uploads an integer value with an incremented counter to a data
+stream called 'incremental'. The counter value is incremented every 5 seconds.
+The uploads takes place every 10 new samples, that is every 50 seconds.
+
+ cccs-upload-data-points-example
+
+ ccimx6sbc
+ ccimx6qpsbc
+ ccimx6ulstarter
+ ccimx6ulsbc
+ ccimx8x-sbc-express
+ ccimx8x-sbc-pro
+ ccimx8mn-dvk
+ ccimx8mm-dvk
+ ccmp15-dvk
+ ccmp13-dvk
+ ccimx93-dvk
+
+