The main.cpp file is the entry point for the custom driver example.  The main.cpp code does the following:

  • Create a new custom driver instance (IDI) with the underlying IDL library
  • Register the callback functions IDL will use to interact with this custom driver instance 
  • Start up and initialize the driver

In addition, in main.cpp your custom driver code will typically create any independent Linux POSIX threads that your driver might require to perform any background processing.  For example, you might need to define a thread to handle incoming, asynchronous communications packets from the protocol that your driver needs to capture. A stub example of this is included in this sample driver.

Any source files that reference or use functions or data structures defined in IDL must include the libidl.h header file.  For reference, this header file can be found on the SmartServer under the /usr/include/ directory.  In addition to including the library header file, main.cpp includes the header file for the custom driver source itself, as well as the standard POSIX <pthread.h> header file, since an example thread is created in main.cpp as well.

#include "libidl.h"
#include "example.h"
#include <pthread.h>

main.cpp starts by creating a new driver instance.  It then registers any callback functions it supports with this instance so IDL can pass data and control to the custom driver code when actions associated with this protocol occur.  This includes such actions as creating a new device that uses this protocol, provisioning a device, reading data points from a device, and so on.

Idl *idl = IdlNew(); // Create a new driver instance

/* Register the Example Driver Callback Routines with the IAP Driver Library (IDL) */

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);

main.cpp then calls a generic startup function IdiStart() located in example.cpp which provides a way for the custom driver to perform any required startup actions, such as opening a serial port or initializing some structures.  It then creates an example thread to handle background processing that might be required by the driver, and finally initializes the driver instance itself using the parameters defined in the example-idl.conf configuration file.

if (IdiStart() == 0) {
   printf("The Example IDL Driver started up...\r\n");

   /* Create any POSIX threads your driver might need before calling */
   /* IdlInit() as IdlInit() never returns. For example, this driver */
   /* creates a thread that could be used to process asynchronous */
   /* communications packets the driver needs to capture and process. */

   pthread_create( &ExampleRxThread, NULL, ExampleRxFunction, NULL);

   /* Initialize the IDL Example Driver using the parameters defined */
   /* in example-idl.conf configuration file. IdlInit() never exits. */

   IdlInit(conf_path, idl);