Reference for C Device SDK
You can use the C interface of the Device SDK to integrate your Devices with the Spotflow IoT Platform.
Requirements
You don't need to install additional software to run the Device SDK library on any supported operating system. The example projects use the following tools to compile the sample code that uses the Device SDK library:
- Linux
- Windows
Feel free to use any other toolchain that you're familiar with.
Installation
Download the latest version of the Spotflow Device SDK library for your operating system and processor architecture:
If you need the library compiled for a different operating system or processor architecture, please contact us.
Extract the archive to a directory of your choice.
You can now include the header file include/spotflow.h
into your code.
Then, link the static library file to your project or add the dynamic library file to your project's runtime path.
See the details for each operating system below:
- Linux
- Windows
You'll see the following directory structure:
Directory | Content |
---|---|
bin | Dynamic library file libspotflow.so |
examples | Example program get_started.c that can be compiled using the provided Makefiles - one for using the dynamic library and one for using the static library |
include | Header file spotflow.h |
lib | Static library file libspotflow.a |
To try the basic example, change <Your Provisioning Token>
in examples/get_started.c
to the actual Provisioning Token from the Platform.
Then, navigate to one of the following directories:
examples/gcc_makefile_dynamic
to use the dynamic library.examples/gcc_makefile_static
to use the static library.
Run the command:
make run
This will compile the example program and run it. You should see the request to approve the Device into the Platform. See Get Started for more details on approving the Device and viewing the received data.
If you want to remove the compiled files, run:
make clean
You'll see the following directory structure:
Directory | Content |
---|---|
bin | Dynamic library file spotflow.dll |
examples | Example program get_started.c that can be compiled using the provided Makefiles - one for using the dynamic library and one for using the static library |
include | Header file spotflow.h |
lib | Static library file spotflow.lib and the import library spotflow.dll.lib |
To try the basic example, open one of the provided solutions in Visual Studio 2022:
examples/vs2022_dynamic/spotflow_example.sln
to use the dynamic library.examples/vs2022_static/spotflow_example.sln
to use the static library.
In Solution Explorer, expand Source Files and double-click get_started.c
to open it.
Change <Your Provisioning Token>
in examples/get_started.c
to the actual Provisioning Token from the Platform.
Press F5 or Debug > Start Debugging to build and run the example program.
This will compile the example program and run it. You should see the request to approve the Device into the Platform. See Get Started for more details on approving the Device and viewing the received data.
If you want to remove the compiled files, right-click the project spotflow_example in Solution Explorer and select Clean.
Basic Usage
The following code is the contents of the file examples/get_started.c
that is included in the download archive (see Installation).
It connects the Device to the Platform and starts sending simulated sensor measurements.
You need to register to the Platform and set it up before you can use the code.
See Get Started for more information on configuring the Platform, registering your Device, and viewing the received data.
Don't forget to replace <Your Provisioning Token>
with the actual Provisioning Token from the Platform.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "spotflow.h"
#ifdef _WIN32
#include <windows.h>
#define gmtime_r(timer, buf) gmtime_s(buf, timer)
#else
#include <unistd.h>
#define Sleep(x) usleep((x)*1000)
#endif
void show_last_error()
{
size_t error_size = SPOTFLOW_ERROR_MAX_LENGTH;
char* error_buffer = malloc(error_size);
spotflow_read_last_error_message(error_buffer, error_size);
printf("Error: %s\n", error_buffer);
free(error_buffer);
}
void send_data(spotflow_client_t* client)
{
spotflow_message_context_t* ctx;
spotflow_message_context_create(&ctx, "default-stream-group", "default-stream");
const size_t max_size = 1024;
char* msg = malloc(max_size);
// Your working code starts here. E.g. read data from your sensors and send it to the platform
for (int i = 0; i < 60; i++)
{
// Example: Send sample data to the platform:
time_t now_ts = time(NULL);
struct tm now;
gmtime_r(&now_ts, &now);
double temperature = 21 + (i * 0.05);
double humidity = 50 + (i * 0.1);
snprintf(
msg, max_size,
"{\"timestamp\": \"%04d-%02d-%02dT%02d:%02d:%02dZ\", \"temperatureCelsius\": %g, \"humidityPercent\": %g}",
now.tm_year + 1900, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec, temperature, humidity);
printf("%s\n", msg);
if (spotflow_client_send_message(client, ctx, NULL, NULL, (const uint8_t*)msg, strlen(msg)) != SPOTFLOW_OK)
{
show_last_error();
return;
}
// Pause till next iteration
Sleep(5000);
}
// Your working code ends here.
free(msg);
spotflow_message_context_destroy(ctx);
}
int main()
{
spotflow_client_options_t* options;
// Connect to the Platform (starts Device Provisioning if the Device is not already registered)
spotflow_client_options_create(&options, "my-device", "<Your Provisioning Token>", "spotflow.db");
spotflow_client_t* client;
if (spotflow_client_start(&client, options) != SPOTFLOW_OK)
{
show_last_error();
return 1;
}
send_data(client);
spotflow_client_destroy(client);
spotflow_client_options_destroy(options);
}
Reference
Functions
Set the verbosity level of logging (SPOTFLOW_LOG_WARN
by default).
Parameters
level | The verbosity level of logging. |
---|
SPOTFLOW_OK
if successful, SPOTFLOW_ERROR
otherwise.
Write the most recent error message into the provided buffer as a UTF-8 string, returning the number of bytes written. If successful, the error message is consumed and will not be returned again in a future call to this function.
Since the string is in the UTF-8 encoding, Windows users may need to convert it to a UTF-16 string before displaying it.
Parameters
buffer | The buffer to write the error message into. |
---|---|
buffer_length | The length of the buffer in bytes. Use SPOTFLOW_ERROR_MAX_LENGTH to be sure that it is always large enough. |
The number of bytes written into the buffer including the trailing null character. If no error has been produced yet, returns 0. If buffer or buffer_length are invalid (for example, null pointer or insufficient length), returns -1.
spotflow_result_t
spotflow_client_options_create( struct spotflow_client_options_t
** options, const char * device_id, const char * provisioning_token, const char * database_file)Create an object that stores the connection options. The created object of type spotflow_client_options_t
is managed by the Device SDK. After you configure all the options (using either this function or with the additional functions listed below), pass the address of spotflow_client_options_t
to spotflow_client_start
. Delete spotflow_client_options_t
using spotflow_client_options_destroy
.
See also
spotflow_client_options_set_database_file spotflow_client_options_set_provisioning_token spotflow_client_options_set_device_id spotflow_client_options_set_instance spotflow_client_options_set_display_provisioning_operation_callbackParameters
options | (Output) The pointer to the spotflow_client_options_t object that will be created by this function. |
---|---|
device_id | (Optional) The ID of the Device you are running the code from. Use NULL if you don't want to specify it. See spotflow_client_options_set_device_id . |
provisioning_token | The Provisioning Token that will spotflow_client_start use to start Device Provisioning. See spotflow_client_options_set_provisioning_token . |
database_file | The path to the local database file where the Device SDK stores the connection credentials and temporarily persists incoming and outgoing messages. See spotflow_client_options_set_database_file . |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid (or NULL if it's required).
spotflow_result_t
spotflow_client_options_set_database_file( struct spotflow_client_options_t
* options, const char * database_file)Set the path to the local database file where the Device SDK stores the connection credentials and temporarily persists incoming and outgoing messages. spotflow_client_start
creates the file if it doesn't exist.
The file must end with the suffix ".db", for example, "spotflow.db". If you don't use an absolute path, the file is created relative to the current working directory.
Parameters
options | The spotflow_client_options_t object. |
---|---|
database_file | The path to the local database file. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid.
spotflow_result_t
spotflow_client_options_set_provisioning_token( struct spotflow_client_options_t
* options, const char * provisioning_token)Set the Provisioning Token that will spotflow_client_start
use to start Device Provisioning.
See Get Started for instructions how to create a Provisioning Token.
Parameters
options | The spotflow_client_options_t object. |
---|---|
provisioning_token | The Provisioning Token. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid.
spotflow_result_t
spotflow_client_options_set_device_id( struct spotflow_client_options_t
* options, const char * device_id)Set the unique Device ID you are running the code from. If you don't specify it here, you'll need to either store it in the Provisioning Token, or choose it during the approval of the Provisioning Operation.
Make sure that no two Devices in the same Workspace use the same ID. Otherwise, unexpected errors can occur during the communication with the Platform.
Parameters
options | The spotflow_client_options_t object. |
---|---|
device_id | (Optional) The ID of the Device. Use NULL if you don't want to specify it. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid.
spotflow_result_t
spotflow_client_options_set_instance( struct spotflow_client_options_t
* options, const char * instance)Set the URI/hostname of the Platform instance where the Device will connect to.
If your company uses a dedicated instance of the Platform, such as acme.spotflow.io, specify it here. The default value is api.eu1.spotflow.io.
Parameters
options | The spotflow_client_options_t object. |
---|---|
instance | (Optional) The domain of the Platform instance. Use NULL if you want to keep the default value. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid.
spotflow_result_t
spotflow_client_options_set_display_provisioning_operation_callback( struct spotflow_client_options_t
* options, spotflow_display_provisioning_operation_callback_t
callback, void * context)Set the function that displays the details of the Provisioning Operation when spotflow_client_start
is performing Device Provisioning. See Get Started for hands-on experience with this process.
Parameters
options | The spotflow_client_options_t object. |
---|---|
callback | (Optional) The function that displays the details of the Provisioning Operation. Use NULL if you don't want to specify it. |
context | (Optional) The context that will be passed to callback. Use NULL if you don't want to specify it. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid.
spotflow_result_t
spotflow_client_options_set_desired_properties_updated_callback( struct spotflow_client_options_t
* options, spotflow_desired_properties_updated_callback_t
callback, void * context)Set the function that is called right after spotflow_client_start
with the current version of the Desired Properties and then whenever the Device receives their update from the Platform. The Device configuration tutorial shows how to use this option. The function is called in a separate thread, so make sure that you properly synchronize access to your shared resources. The functions working with spotflow_client_t
are thread-safe (apart from spotflow_client_destroy
), so it's safe to call them in the function.
Parameters
options | The spotflow_client_options_t object. |
---|---|
callback | (Optional) The function that is called with each update of the Desired Properties. Use NULL if you don't want to specify it. |
context | (Optional) The context that will be passed to callback. It will be used from a different thread, so make sure that it's properly synchronized. Use NULL if you don't want to specify it. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid.
Destroy the spotflow_client_options_t
object.
Parameters
options | The spotflow_client_options_t object to destroy. |
---|
spotflow_result_t
spotflow_client_start( spotflow_client_t
** client, const struct spotflow_client_options_t
* options)Start communicating with the Platform. The created object of type spotflow_client_t
is managed by the Device SDK. Delete it using spotflow_client_destroy
.
If the Device is not yet registered in the Platform, or its Registration Token is expired, this method performs Device Provisioning and waits for the approval. Get Started shows this process in practice.
If the Registration Token from the last run is still valid, this method succeeds even without the connection to the Internet. The Device SDK will store all outgoing communication in the local database file and send it once it connects to the Platform.
Parameters
client | (Output) The pointer to the spotflow_client_t object that will be created by this function. |
---|---|
options | The options that specify how to connect to the Platform. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid.
spotflow_result_t
spotflow_message_context_create( struct spotflow_message_context_t
** message_context, const char * stream_group, const char * stream)Create an object that stores the options for sending Messages to the Platform.
Initialize the spotflow_message_context_t
object: set the most important fields to the provided values and the other fields to default values. The created object of type spotflow_message_context_t
is managed by the Device SDK. You can configure the object either using this function or using the additional functions listed below. Delete it using spotflow_message_context_destroy
.
See also
spotflow_message_context_set_stream_group spotflow_message_context_set_stream spotflow_message_context_set_compressionParameters
message_context | (Output) The pointer to the spotflow_message_context_t object that will be created by this function. |
---|---|
stream_group | (Optional) The Stream Group the Message will be sent to. If NULL, the Platforms directs the Messages to the default Stream Group of the current Workspace. |
stream | (Optional) The Stream the Message will be sent to. If NULL, the Platform directs the Messages into the default Stream of the given Stream Group. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid.
spotflow_result_t
spotflow_message_context_set_stream_group( struct spotflow_message_context_t
* message_context, const char * stream_group)Set the Stream Group where Messages will be sent to.
Parameters
message_context | The spotflow_message_context_t object. |
---|---|
stream_group | The Stream Group. If NULL, the Platforms directs the Messages to the default Stream Group of the current Workspace. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid.
spotflow_result_t
spotflow_message_context_set_stream( struct spotflow_message_context_t
* message_context, const char * stream)Set the Stream where Messages will be sent to.
Parameters
message_context | The spotflow_message_context_t object. |
---|---|
stream | The Stream. If NULL, the Platform directs the Messages into the default Stream of the given Stream Group. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid.
spotflow_result_t
spotflow_message_context_set_compression( struct spotflow_message_context_t
* message_context, enum spotflow_compression_t
compression)Set the compression to use for sending Messages.
Parameters
message_context | The spotflow_message_context_t object. |
---|---|
compression | The compression to use for sending Messages. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid.
Destroy the spotflow_message_context_t
object.
Parameters
message_context | The spotflow_message_context_t object to destroy. |
---|
spotflow_result_t
spotflow_client_enqueue_message( spotflow_client_t
* client, const struct spotflow_message_context_t
* message_context, const char * batch_id, const char * message_id, const uint8_t * buffer, size_t length)Enqueue a Message to be sent to the Platform.
If the Stream doesn't have a Message ID Autofill Pattern, you must provide message_id. If the Stream groups Messages into Batches and doesn't have a Batch ID Autofill Pattern, you must provide batch_id. See User Guide for more details.
The method returns right after it saves the Message to the queue in the local database file. A background thread asynchronously sends the messages from the queue to the Platform. You can check the number of pending messages in the queue using spotflow_client_get_pending_messages_count
.
Parameters
client | The spotflow_client_t object. |
---|---|
message_context | The options that specify how to send the Message. |
batch_id | (Optional) The ID of the Batch the Message is a part of. Use NULL if you don't want to specify it. |
message_id | (Optional) The ID of the Message. Use NULL if you don't want to specify it. |
buffer | The buffer that contains the Message. |
length | The length of the buffer in bytes. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid or there is an error in persisting the message.
spotflow_result_t
spotflow_client_enqueue_message_advanced( spotflow_client_t
* client, const struct spotflow_message_context_t
* message_context, const char * batch_id, const char * batch_slice_id, const char * message_id, const char * chunk_id, const uint8_t * buffer, size_t length)Enqueue a Message to be sent to the Platform.
If the Stream doesn't have a Message ID Autofill Pattern, you must provide message_id. If the Stream groups Messages into Batches and doesn't have a Batch ID Autofill Pattern, you must provide batch_id. See User Guide for more details. Optionally, you can provide also batch_slice_id to use Batch Slices and chunk_id to use Message Chunking.
The method returns right after it saves the Message to the queue in the local database file. A background thread asynchronously sends the messages from the queue to the Platform. You can check the number of pending messages in the queue using spotflow_client_get_pending_messages_count
.
Parameters
client | The spotflow_client_t object. |
---|---|
message_context | The options that specify how to send the Message. |
batch_id | (Optional) The ID of the Batch the Message is a part of. Use NULL if you don't want to specify it. |
batch_slice_id | (Optional) The ID of the Batch Slice the Message is a part of. Use NULL if you dont' want to specify it. |
message_id | (Optional) The ID of the Message. Use NULL if you don't want to specify it. |
chunk_id | (Optional) The ID of the Chunk of the Message. Use NULL if you don't want to specify it. |
buffer | The buffer that contains the Message. |
length | The length of the buffer in bytes. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid or there is an error in persisting the message.
spotflow_result_t
spotflow_client_enqueue_batch_completion( spotflow_client_t
* client, const struct spotflow_message_context_t
* message_context, const char * batch_id)Enqueue the manual completion of the current Batch to be sent to the Platform.
The Platform also completes the previous Batch automatically when the new one starts. Therefore, you might not need to call this method at all. See User Guide for more details.
The method returns right after it saves the batch-completing Message to the queue in the local database file. A background thread asynchronously sends the messages from the queue to the Platform. You can check the number of pending messages in the queue using spotflow_client_get_pending_messages_count
.
Parameters
client | The spotflow_client_t object. |
---|---|
message_context | The options that specify how to send the batch-completing Message. |
batch_id | The ID of the Batch that will be completed. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid or there is an error in persisting the message.
spotflow_result_t
spotflow_client_enqueue_message_completion( spotflow_client_t
* client, const struct spotflow_message_context_t
* message_context, const char * batch_id, const char * message_id)Enqueue the manual completion of the current Message to be sent to the Platform. Use this methods when Message Chunking is used.
The method returns right after it saves the message-completing Message to the queue in the local database file. A background thread asynchronously sends the Messages from the queue to the Platform. You can check the number of pending messages in the queue using spotflow_client_get_pending_messages_count
.
Parameters
client | The spotflow_client_t object. |
---|---|
message_context | The options that specify how to send the message-completing Message. |
batch_id | The ID of the Batch that the Message belongs to. |
message_id | The ID of the Message. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid or there is an error in persisting the message.
Block the current thread until all the Messages that have been previously enqueued are sent to the Platform.
Parameters
client | The spotflow_client_t object. |
---|
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if the argument is invalid.
spotflow_result_t
spotflow_client_send_message( spotflow_client_t
* client, const struct spotflow_message_context_t
* message_context, const char * batch_id, const char * message_id, const uint8_t * buffer, size_t length)Send a Message to the Platform.
Warning: This method blocks the current thread until the Message (and all the Messages enqueued before it) is sent to the Platform. If your Device doesn't have a stable Internet connection, consider using spotflow_client_enqueue_message instead.
If the Stream doesn't have a Message ID Autofill Pattern, you must provide message_id. If the Stream groups Messages into Batches and doesn't have a Batch ID Autofill Pattern, you must provide batch_id. See User Guide for more details.
Parameters
client | The spotflow_client_t object. |
---|---|
message_context | The options that specify how to send the Message. |
batch_id | (Optional) The ID of the Batch the Message is a part of. Use NULL if you don't want to specify it. |
message_id | (Optional) The ID of the Message. Use NULL if you don't want to specify it. |
buffer | The buffer that contains the Message. |
length | The length of the buffer in bytes. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid or there is an error in persisting the message.
spotflow_result_t
spotflow_client_send_message_advanced( spotflow_client_t
* client, const struct spotflow_message_context_t
* message_context, const char * batch_id, const char * batch_slice_id, const char * message_id, const char * chunk_id, const uint8_t * buffer, size_t length)Send a Message to the Platform.
Warning: This method blocks the current thread until the Message (and all the Messages enqueued before it) is sent to the Platform. If your Device doesn't have a stable Internet connection, consider using spotflow_client_enqueue_message_advanced instead.
If the Stream doesn't have a Message ID Autofill Pattern, you must provide message_id. If the Stream groups Messages into Batches and doesn't have a Batch ID Autofill Pattern, you must provide batch_id. See User Guide for more details. Optionally, you can provide also batch_slice_id to use Batch Slices and chunk_id to use Message Chunking.
Parameters
client | The spotflow_client_t object. |
---|---|
message_context | The options that specify how to send the Message. |
batch_id | (Optional) The ID of the Batch the Message is a part of. Use NULL if you don't want to specify it. |
batch_slice_id | (Optional) The ID of the Batch Slice the Message is a part of. Use NULL if you dont' want to specify it. |
message_id | (Optional) The ID of the Message. Use NULL if you don't want to specify it. |
chunk_id | (Optional) The ID of the Chunk of the Message. Use NULL if you don't want to specify it. |
buffer | The buffer that contains the Message. |
length | The length of the buffer in bytes. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid or there is an error in persisting the message.
spotflow_result_t
spotflow_client_get_pending_messages_count( const spotflow_client_t
* client, size_t * count)Get the number of Messages that have been persisted in the local database file but haven't been sent to the Platform yet.
Parameters
client | The spotflow_client_t object. |
---|---|
count | (Output) The number of pending Messages. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid or there is an error in accessing the local database file.
spotflow_result_t
spotflow_client_get_workspace_id( const spotflow_client_t
* client, char * buffer, size_t buffer_length)Write the ID of the Workspace to which the Device belongs into the provided buffer.
Parameters
client | The spotflow_client_t object. |
---|---|
buffer | The buffer where the Workspace ID string including the trailing NUL character will be written to. |
buffer_length | The length of the buffer in bytes. Use SPOTFLOW_WORKSPACE_ID_MAX_LENGTH to be sure that it is always large enough. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_INSUFFICIENT_BUFFER
if the buffer is too small, SPOTFLOW_ERROR
if any argument is invalid.
spotflow_result_t
spotflow_client_get_device_id( const spotflow_client_t
* client, char * buffer, size_t buffer_length)Write the Device ID into the provided buffer. Note that the value might differ from the one requested in spotflow_client_options_set_device_id
if the technician overrides it during the approval of the Provisioning Operation.
Parameters
client | The spotflow_client_t object. |
---|---|
buffer | The buffer where the Device ID string including the trailing NUL character will be written to. |
buffer_length | The length of the buffer in bytes. Use SPOTFLOW_DEVICE_ID_MAX_LENGTH to be sure that it is always large enough. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_INSUFFICIENT_BUFFER
if the buffer is too small, SPOTFLOW_ERROR
if any argument is invalid.
Disconnect from the Platform and destroy the spotflow_client_t
object.
Parameters
client | The spotflow_client_t object. |
---|
spotflow_result_t
spotflow_client_get_desired_properties( spotflow_client_t
* client, char * buffer, size_t buffer_length, size_t * properties_length, uint64_t * properties_version)Write the current Desired Properties into the provided buffer and obtain their version. The content is a JSON string encoded in UTF-8.
Only the latest version is returned, any versions between the last obtained one and the current one will be skipped.
Parameters
client | The spotflow_client_t object. |
---|---|
buffer | The buffer to write the JSON string encoded in UTF-8 into. |
buffer_length | The length of the buffer in bytes. |
properties_length | (Output) The length of the JSON string in bytes including the trailing null character. |
properties_version | (Output) The version of the current properties. |
SPOTFLOW_OK
if the properties were written successfully, SPOTFLOW_INSUFFICIENT_BUFFER
if the buffer is too small (you can then resize it using properties_length and call the function again), SPOTFLOW_ERROR
if any argument is invalid.
spotflow_result_t
spotflow_client_get_desired_properties_if_newer( spotflow_client_t
* client, uint64_t version, char * buffer, size_t buffer_length, size_t * properties_length, uint64_t * properties_version)Write the current Desired Properties into the provided buffer and obtain their version if their version is higher than version or if version is SPOTFLOW_PROPERTIES_VERSION_ANY
. The content is a JSON string encoded in UTF-8.
Only the latest version is returned, any versions between the last obtained one and the current one will be skipped.
Parameters
client | The spotflow_client_t object. |
---|---|
version | The version of the last received properties. Only the properties with a higher version are retrieved. Use SPOTFLOW_PROPERTIES_VERSION_ANY to always retrieve the current properties. |
buffer | The buffer to write the JSON string encoded in UTF-8 into. |
buffer_length | The length of the buffer in bytes. |
properties_length | (Output) The length of the JSON string in bytes including the trailing null character. If the current version of the current version of the properties is not larger than version, 0 will be stored here. |
properties_version | (Output) The version of the current properties. If the current version of the properties is not larger than version, nothing is stored here. |
SPOTFLOW_OK
if the properties were written successfully or they were not written at all because their version wasn't higher than version, SPOTFLOW_INSUFFICIENT_BUFFER
if the buffer is too small (you can then resize it using properties_length and call the function again), SPOTFLOW_ERROR
if any argument is invalid.
spotflow_result_t
spotflow_client_update_reported_properties( const spotflow_client_t
* client, const char * properties)Enqueue an update of the Reported Properties to be sent to the Platform.
This method saves these reported properties persistently in the local database file. The update will be sent asynchronously when possible. The update may be sent later depending on Internet connectivity and other factors. To be sure that it has been sent to the Platform, call spotflow_client_get_any_pending_reported_properties_updates
.
Parameters
client | The spotflow_client_t object. |
---|---|
properties | The JSON string encoded in UTF-8 containing the desired Reported Properties. |
SPOTFLOW_OK
if the properties were updated successfully, SPOTFLOW_ERROR
if any argument is invalid or there was an error in accessing the local database file.
spotflow_result_t
spotflow_client_get_any_pending_reported_properties_updates( const spotflow_client_t
* client, bool * any)Check if there are any updates to Reported Properties that are yet to be sent to the Platform.
Parameters
client | The spotflow_client_t object. |
---|---|
any | (Output) Whether there are any updates to Reported Properties that are yet to be sent to the Platform. |
SPOTFLOW_OK
if the function succeeds, SPOTFLOW_ERROR
if any argument is invalid.
Enums
A result of a function that can fail. If a function returns a spotflow_result_t
, the caller must check that the returned value is SPOTFLOW_OK
before continuing further. If the function returns a different value, the caller can call spotflow_read_last_error_message
to retrieve the error message. Check the documentation of the particular function to see what results it can return.
The compression to use for sending Messages.
The verbosity levels of logging.
Structs
A client communicating with the Platform. This object is managed by the Device SDK. Create its instance using spotflow_client_start
and delete it using spotflow_client_destroy
.
The client stores all outgoing communication to the local database file and then sends it in a background thread asynchronously. Thanks to that, it works even when the connection is unreliable. Similarly, the client also stores all ingoing communication to the local database file and deletes it only after the application processes it.
A set of options that specify how to connect to the Platform. This object is managed by the Device SDK. Create its instance using spotflow_client_options_create
and delete it using spotflow_client_options_destroy
. After you configure all the options, pass the address of spotflow_client_options_t
to spotflow_client_start
.
A set of options for sending Messages to a Stream. This object is managed by the Device SDK. Create its instance using spotflow_message_context_create
and delete it using spotflow_message_context_destroy
.
The summary of an ongoing Provisioning Operation. This object is managed by the Device SDK and its contents must not be modified.
If you specify a custom callback to spotflow_client_options_set_display_provisioning_operation_callback
, you'll receive a pointer to spotflow_provisioning_operation_t
as its argument. The pointer is valid only for the duration of the callback.
(Don't modify) The expiration time of this Provisioning Operation. The operation is no longer valid after that.
The date/time format is RFC 3339.
Callbacks
The callback to display the details of an ongoing Provisioning Operation when the Device SDK is performing Device Provisioning. The callback is called only if you have configured it by spotflow_client_options_set_display_provisioning_operation_callback
. The callback is called on the same thread that calls spotflow_client_start
.
Parameters
operation | The summary of the Provisioning Operation. See spotflow_provisioning_operation_t for details. |
---|---|
context | The optional context that was configured by spotflow_client_options_set_display_provisioning_operation_callback . |
The callback to be called when the Desired Properties are updated. The callback is called only if you have configured it by spotflow_client_options_set_desired_properties_updated_callback
. The callback is called on a background thread.
Parameters
desired_properties | The new Desired Properties represented as a JSON string encoded in UTF-8. |
---|---|
version | The version of the new Desired Properties. |
context | The optional context that was configured by spotflow_client_options_set_desired_properties_updated_callback . |
Constants
The maximum number of bytes of any Device ID string including the trailing NUL character.
The maximum number of bytes of any Workspace ID string including the trailing NUL character.
The maximum number of bytes of any error message including the trailing null character.
A special value that instructs spotflow_client_get_desired_properties_if_newer
to always return the current version.