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:
api_version
name
desc
exe_mask
/* 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.