Chapter 5. Plug-ins

5.1. Plug-in API

Siproxd plug-ins are dynamic loadable libraries and must provide 3 functions towards siproxd. As we make use of some libltdl features we do some internal macor magic - the PLUGIN_xxx funcation names are actually CPP macros that will expand in unique names. Th have this working properly the PLUGIN_NAME must be #defined before the plugins.h header file is included:

#define PLUGIN_NAME     plugin_myplugin
#include "plugins.h"
[...]
int  PLUGIN_INIT(plugin_def_t *plugin_def);
int  PLUGIN_PROCESS(int stage, sip_ticket_t *ticket);
int  PLUGIN_END(plugin_def_t *plugin_def);

The PLUGIN_INIT function is called when the plug-in is loaded during startup of siproxd. The plug-in must define the following 4 fields of the plugin_def structure:

  1. api_version

  2. name

  3. desc

  4. exe_mask

Example code fragment:

/* API version number of siproxd that this plug-in is built against.
 * This constant will change whenever changes to the API are made
 * that require adaptions in the plug-in. */
plugin_def->api_version=SIPROXD_API_VERSION;

/* Name and descriptive text of the plug-in. Those item MUST NOT be
   on the stack but either allocated via malloc (and then freed
   of course) or a static string in the plug-in. */
plugin_def->name=strdup("plugin_demo");
plugin_def->desc=strdup("This is just a demo plugin without any purpose");

/* Execution mask - during what stages of SIP processing shall
 * the plug-in be called. */
plugin_def->exe_mask=PLUGIN_DETERMINE_TARGET|PLUGIN_PRE_PROXY;

The PLUGIN_PROCESS function is called at the requested SIP processing stages (see 'execution mask'). Your processing will be done here.

The PLUGIN_END function is called at shutdown of siproxd and gives the plug-in the opportunity to clean up and properly shutdown itself.

Note: The previously allocated 'name' and 'desc' must be freed by the plug-in. If you did use a static string then of course you must not try to free() anything.

Minimum required clean up procedure:

int  PLUGIN_END(plugin_def_t *plugin_def){
   /* free my allocated rescources (if allocated via malloc only) */
   if (plugin_def->name) {free(plugin_def->name); plugin_def->name=NULL;}
   if (plugin_def->desc) {free(plugin_def->desc); plugin_def->desc=NULL;}
   return STS_SUCCESS;
}

For a simple example refer to the simple demonstration plug-in plugin_demo.

Each plug-in can have its own set of configuration parameters in siproxd.conf. The plug-in has to define a cfgopts_t structure and call read_config during its initialization. Look at plugin_demo for a simple example. The naming of the config parameters is by definition plugin_name_option.