Gateway C ABI
Loading...
Searching...
No Matches
Gateway's C Plugin SDK

This SDK provides a C ABI to interact with the core gateway. Every plugin must use this ABI to interact with the core.

To create a C plugin, the user is responsible for implementing the following exported functions:

The following is the simplest example of a subscriber plugin without any configuration.

#include abi.h
#include <stdlib.h>
#include <stdio.h>
typedef struct {
GCPluginInterface interface;
} ExamplePlugin;
ExamplePlugin* instance = malloc(sizeof(ExamplePlugin));
if (instance == NULL) {
gcSystemLog(interface, ERROR, "Failed to allocate memory for plugin instance");
return NULL;
}
instance->interface = interface;
return instance;
}
free(instance);
}
static struct sGCPluginInfo info = { "ExamplePlugin", "0.1.0", "0", 0 };
return &info;
}
ExamplePlugin* plugin = (ExamplePlugin*)instance;
// Handle incoming datapoint. Example: print the value
switch (dataValue->type) {
gcSystemLog(plugin->interface, INFO, "Received datapoint value: %d", dataValue->value.i32);
break;
// Handle other types as needed...
default:
gcSystemLog(plugin->interface, WARNING, "Received unsupported datapoint type");
}
plugin->interface->publishDatapointValueCallback(plugin->interface->ctx, dataValue);
gcReleaseDatapointValue(plugin->interface, dataValue);
return true;
}
void gc_plugin_shutdown(GCInstanceHandle instance)
Safely shuts down the plugin instance.
GCPluginInfo gc_plugin_get_info()
Retrieves the plugin information.
bool gc_plugin_receive_datapoint(GCInstanceHandle instance, const GCDatapointValue dataValue)
Receives a datapoint value.
GCInstanceHandle gc_plugin_init(GCPluginInterface interface)
Initializes the plugin.
@ ERROR
Definition abi.h:170
@ INFO
Definition abi.h:172
@ WARNING
Definition abi.h:171
void gcSystemLog(GCPluginInterface interface, GCLogLevel level, const char *message,...)
Logs a message to the system log.
void * GCInstanceHandle
The handle to the plugin instance.
Definition abi.h:228
void gcReleaseDatapointValue(GCPluginInterface interface, GCDatapointValue dataValue)
Releases a datapoint value This function is a wrapper around the releaseDatapointValueCallback callba...
@ GCOS_DATAPOINT_TYPE_INT32
Definition datapoint_value.h:40
The value of a datapoint.
Definition datapoint_value.h:57
int32_t i32
Definition datapoint_value.h:74
union sGCDatapointValue::@0 value
The value of the datapoint.
GCDatapointValueType type
The type of the datapoint value This type depends on the datapoint's value field.
Definition datapoint_value.h:64
Plugin version information The information that the core uses to register a new plugin....
Definition abi.h:182
The plugin interface.
Definition abi.h:273

This plugin will log the value of an INT32 datapoint to the system log.

  • The gc_plugin_init function will be responsible for initializing the plugin instance. This function receives the sGCPluginInterface which contains all the callbacks that the plugin can use to interact with the core. It should return a handle to the plugin instance. This handle will be passed to all other plugin exported functions.
  • The gc_plugin_shutdown function is called by the core when the plugin instance needs to be shutdown. It is crucial to release all resources allocated in the gc_plugin_init function (check gc_plugin_shutdown for insights in the shutdown procedure).
  • The gc_plugin_get_info function returns a sGCPluginInfo struct which contains information about the plugin.
  • The gc_plugin_receive_datapoint function is called when a datapoint the plugin is subscribed to receives a new value. The example code demonstrates handling an INT32 datapoint and logging its value. Be sure to handle all expected datapoint types. Critically, this function must call the sGCPluginInterface::releaseDatapointValueCallback function from the provided interface to release the received dataValue after processing it.

Concurrency

A plugin may have multiple instances running inside the same process and thus functions maybe called from multiple threads simultaneously. Keep this in mind as it can affect the overall functionality (e.g., handling global, static variables and race conditions). Head over to gc_plugin_shutdown for more insights about the plugin shutdown procedure which are important in a concurrent environment.

Parsing plugin configuration

Given a plugin instance with the following specific configuration:

{
"host": "abc",
"arr_example": [
0,
{
"arr_el": 4001
}
]
}
Note
The plugin plugin_specific_config is any config provided by the user in the configuration (Head over to plugin configuration for more information).

Below is an example of how to parse the plugin own configuration using the provided JSON callbacks.

GCPluginInterface* interface...; // GCPluginInterface yield by gc_plugin_init
GCJsonCallbacks json_callbacks = interface->config.pluginJsonConfig;
GCJsonObject root = json_callbacks->data;
// Retrieves the host field
GCJsonObject host_value = json_callbacks->getObjectField(root, "host", &result);
assert(result == GC_JSON_OK && "Failed to get host field");
const char* host = json_callbacks->getString(host_value, &result);
assert(result == GC_JSON_OK && "Failed to get ethernet_interface value");
assert(strcmp(host, "eth0") == 0 && "ethernet_interface value is not eth0");
json_callbacks->freeString((void*)host); // Important to always free the string if not used
// Retrieves arr_example field and size
GCJsonObject arr_obj = json_callbacks->getObjectField(root, "arr_example", &result);
assert(result == GC_JSON_OK && "Failed to get arr_example field");
uint64_t arr_length = json_callbacks->getArrayLength(arr_obj, &result);
assert(result == GC_JSON_OK && arr_length==2 && "Failed to get arr_example length");
// Retrieve arr_el
GCJsonObject arr_el_parent_obj = json_callbacks->getArrayIdx(arr_obj, 1, &result);
assert(result == GC_JSON_OK && "Failed to arr_el_parent_obj field");
GCJsonObject arr_el_obj = json_callbacks->getObjectField(arr_el_parent_obj, "arr_el", &result);
assert(result == GC_JSON_OK && "Failed to get arr_el field");
int64_t arr_el = json_callbacks->getInt(arr_el_obj, &result);
assert(result == GC_JSON_OK && arr_el==4001 && "Failed to get arr_el value");
enum eResultCallback GCResultCallback
Definition json.h:29
@ GC_JSON_ERROR
Definition json.h:27
@ GC_JSON_OK
Definition json.h:26
The JSON configuration data and parsing callbacks.
Definition json.h:65
tJsonObjectGetInt getInt
Parse an integer from a JSON object.
Definition json.h:80
tJsonObjectGetObjectField getObjectField
Get a field from a JSON object.
Definition json.h:128
tJsonObjectGetArrayIdx getArrayIdx
Get an element from a JSON array.
Definition json.h:109
tFreeSring freeString
Free a string.
Definition json.h:148
const GCJsonObject data
The plugin specific configuration.
Definition json.h:155
tJsonObjectGetArrayLength getArrayLength
Get the length of a JSON array.
Definition json.h:118
tJsonObjectGetString getString
Parse a string from a JSON object.
Definition json.h:99
The JSON object.
Definition json.h:37
const GCPluginConfig config
Configuration and related functions.
Definition abi.h:321
const GCJsonCallbacks pluginJsonConfig
Definition abi.h:246

Essentially any JSON object can be parsed and is important that all strings returned by the JSON callbacks are freed using the freeString callback. All json callbacks (with the exception of the freeString) return a result as the last argument, that should be checked to ensure the operation was successful.

Additional plugin examples

For an example of a plugin that creates a new thread and publishes values, check the datapoint_generator plugin.

Testing

The SDK provides a testing library that can be used to test the plugin configuration parsing. More information can be found in the json_testing.h header file.