Init Functions


Idl *IdlNew(void);

The IdlNew() function must be called as the first IDL API to allocate an instance of IDL. This instance will contain function pointers to all the callback functions that the IDI sets before initializing the IDL library.

IdlAdvOpts (Optional)

void IdlSetAdvancedOptions(IdlAdvOpts opts);

Calling IdlSetAdvancedOptions is optional, but if it is called it needs to be called prior to calling IdlInit

The IdlAdvOpts structure currently defines two flags: renewEventOnRestart and receiveTimeoutSupported. These flags are mainly used by IDI that support true event-driven monitoring. The IDI can set values 0 or 1 to these flags and pass the structure to the IDI.

The IDI can specify that event driven monitoring needs to be re-established if the engine is restarted by setting renewEventOnRestart to 1. Event-driven protocols that support receive timeouts can specify this by setting receiveTimeoutSupported to 1. This impacts the behavior of IDL when heartbeats are used with datapoints.


int IdlInit(char *confPath, Idl *idl);

The IdlInit function is the last API that the IDI must call in the main() function. The IDI needs to pass the Idl instance that was created before and the absolute path of the conf file. When this function is called, IDL starts the “event loop” provided by the libuv for processing the numerous timers that will be required for device management and datapoint polling. 

The IdlInit function never returns once it is called. Therefore:

  • IdlInit needs to be the last function IDI calls in main().
  • An IDI driver typically needs to create any other threads the driver will require for background processing before calling IdlInit.


#include "libidl.h"
#include <stdio.h>

int main(void)
    Idl *idl = NULL;                                             /* Allocate an instance of IDL */
    IdlAdvOpts opts = {0};
    idl = IdlNew();
    opts.renewEventOnRestart = 1;
    opts.receiveTimeoutSupported = 1;
    IdlSetAdvancedOptions(IdlAdvOpts opts);                      /* Pass the structure IdlAdvOpts */


    IdlDevCreateCallbackSet(idl, dev_create_cb);
    IdlDevProvisionCallbackSet(idl, dev_provision_cb);
    IdlDevDeprovisionCallbackSet(idl, dev_deprovision_cb);
    IdlDevReplaceCallbackSet(idl, dev_replace_cb);
    IdlDevDeleteCallbackSet(idl, dev_delete_cb);
    IdlDpReadCallbackSet(idl, dp_read_cb);
    IdlDpWriteCallbackSet(idl, dp_write_cb);
    IdlDpEnableEventCallbackSet(idl, dp_enable_event_cb);
    IdlDpDisableEventCallbackSet(idl, dp_disable_event_cb);

    /* Set discovery callbacks */

    IdlDevDiscoveryCallbackSet(idl, NULL, DISCOVERY_START_CALLBACK, d_start_cb);
    IdlDevDiscoveryCallbackSet(idl, NULL, DISCOVERY_STEP_CALLBACK, d_step1_cb);
    IdlDevDiscoveryCallbackSet(idl, NULL, DISCOVERY_STEP_CALLBACK, d_step2_cb);
    IdlDevDiscoveryCallbackSet(idl, NULL, DISCOVERY_STEP_CALLBACK, d_step3_cb);
    IdlDevDiscoveryCallbackSet(idl, NULL, DISCOVERY_STOP_CALLBACK, d_stop_cb);
    if (IdiStart() == 0) {

    /* INIT IDL */

    IdlInit(“/var/apollo/conf.d/modbus/idl-modbus.conf”, idl);    /* Passes idl instance and conf path */
    return 0;