Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
development:write-module [2007/02/22 15:50] – added definition of childInit 193.170.48.50 | development:write-module [2012/03/22 12:33] (current) – removed spam 80.250.1.245 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Writing OpenSER module ====== | ||
+ | |||
+ | |||
+ | My interest is mostly in writing new Modules for OpenSER at this time. I could not find a lot of information about it, so I started this page set. Please if you find I am going down the wrong path, correct me and these pages. I will try to only include correct information, | ||
+ | |||
+ | ====== Introduction ====== | ||
+ | |||
+ | |||
+ | The code and APIs are based off the current 1.1.x source base. | ||
+ | |||
+ | When starting a new module, there are a few things you must do. Listed below will get you started with the template module structured code example: | ||
+ | |||
+ | |||
+ | |||
+ | ===== Template Module ===== | ||
+ | |||
+ | <code @C> | ||
+ | #include " | ||
+ | |||
+ | MODULE_VERSION/ | ||
+ | |||
+ | static int mod_init(void); | ||
+ | static void mod_destroy(void); | ||
+ | static int child_init(int); | ||
+ | |||
+ | /* | ||
+ | * Script commands we export. | ||
+ | */ | ||
+ | static cmd_export_t cmds[]={ | ||
+ | {0,0,0,0,0} | ||
+ | }; | ||
+ | |||
+ | /* | ||
+ | * Script parameters | ||
+ | */ | ||
+ | static param_export_t mod_params[]={ | ||
+ | { 0,0,0 } | ||
+ | }; | ||
+ | |||
+ | /* | ||
+ | * Export the statistics we have | ||
+ | */ | ||
+ | static stat_export_t mod_stats[] = { | ||
+ | {0,0,0} | ||
+ | }; | ||
+ | |||
+ | struct module_exports exports= { | ||
+ | " | ||
+ | cmds, /* exported functions */ | ||
+ | mod_params, | ||
+ | mod_stats, | ||
+ | modInit, | ||
+ | 0, /* reply processing function FIXME Not sure when this is used */ | ||
+ | modDestroy, | ||
+ | childInit | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * @return 0 to continue to load the OpenSER, -1 to stop the loading | ||
+ | * and abort OpenSER. | ||
+ | */ | ||
+ | static int modInit(void) { | ||
+ | return(0); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Called only once when OpenSER is shuting down to clean up module | ||
+ | * resources. | ||
+ | */ | ||
+ | static void modDestroy() { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * The rank will be o for the main process calling this function, | ||
+ | * or 1 through n for each listener process. The rank can have a negative | ||
+ | * value if it is a special process calling the child init function. | ||
+ | * Other then the listeners, the rank will equal one of these values: | ||
+ | * PROC_MAIN | ||
+ | * PROC_TIMER | ||
+ | * PROC_FIFO | ||
+ | * PROC_TCP_MAIN -4 TCP main process | ||
+ | * PROC_UNIXSOCK -5 Unix domain socket server processes | ||
+ | * | ||
+ | * If this function returns a nonzero value the loading of OpenSER will | ||
+ | * stop. | ||
+ | */ | ||
+ | static int childInit(int rank) { | ||
+ | int rtn = 0; | ||
+ | |||
+ | return(rtn); | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | * The // | ||
+ | * You must include the // | ||
+ | * Declare your local initialization and destructor functions. | ||
+ | * Fill out the following data structures to export the modules functionality. | ||
+ | * cmd_export_t - This structure is where you export the script functions. (more on it later) | ||
+ | * param_export_t structure is used to export the modules parameters that can be set in the script (openser.cfg) | ||
+ | * stat_export_t If your module wants to track statistics this is where you declare and export them. | ||
+ | * module_exports - This is where you tie all the exported information together to define your new Module. | ||
+ | * The module name. A //char *// that uniquely identifies your module. | ||
+ | * The pointer to the cmd_export_t (or NULL if none defined) | ||
+ | * The pointer to the param_export_t (or NULL if none defined) | ||
+ | * The pointer to the stat_export_t (or NULL if none defined) | ||
+ | * The module initialization function pointer. FIXME Function prototype needed here. (rw) | ||
+ | * FIXME Need more information on this function pointer. | ||
+ | * The module destroy function pointer. FIXME Need prototype here. (rw) | ||
+ | * FIXME Need the child init function explained and included in the example. (rw) | ||
+ | |||
+ | You should be able to cut and paste the code above into your first module " | ||
+ | |||
+ | ===== Module export structure ===== | ||
+ | |||
+ | ==== cmd_export_t ==== | ||
+ | |||
+ | <code c> | ||
+ | struct cmd_export_t { | ||
+ | char* name; /* null terminated command name */ | ||
+ | cmd_function function; | ||
+ | int param_no; | ||
+ | fixup_function fixup; | ||
+ | | ||
+ | int flags; | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | * **name** //char *// - A null terminated command name. | ||
+ | * **function** //int (*cmd_function)(struct sip_msg*, char*, char*)// - The C function pointer to bind to the named script function. | ||
+ | * **param_no** //int// - The number of parameters to pass to the C function (the function argument count) | ||
+ | * **fixup** //int (*fixup_function)(void * * param, int param_no);// | ||
+ | * **flags** //int// - Can't have a structure without flags! The flags tell the script when it is legal to call the function. The flag values can be " | ||
+ | * **REQUEST_ROUTE** - The function can be called in the request route section of the openser.cfg script. | ||
+ | * **FAILURE_ROUTE** - The function can be called in the failure route section of the openser.cfg script. | ||
+ | * **ONREPLY_ROUTE** - The function can be called in the reply route section of the openser.cfg script. | ||
+ | * **BRANCH_ROUTE** | ||
+ | |||
+ | === Hints & Tips === | ||
+ | |||
+ | Because the module is written in " | ||
+ | |||
+ | ===== Licensing of Modules ===== | ||
+ | |||
+ | The relevant part of the GPL concerning distribution of proprietary modules is the bottom of section 2, here quoted: | ||
+ | |||
+ | // | ||
+ | These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work **based on** the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. | ||
+ | |||
+ | Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. | ||
+ | |||
+ | In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. | ||
+ | // | ||
+ | |||
+ | |||
+ | So, if you are writing a closed module that washes the dog, walks the dishes, and controls the light in your aquarium within the larger context of the openSER framework, without modifying the framework, directing people who wish source code to the openSER web site to obtain the GPL'd portions of a proprietary and commercial VOIP-controlled dog-washing, | ||
+ | dishes, and pet fish -- is not the main focus of openSER, and although your module plugs into the openSER framework, it could just as well plug into some other framework instead of openSER. | ||
+ | |||
+ | The GPL would not force distribution of your trade secrets involved in your dog/ | ||
+ | |||
+ | Addition of a module does not constitute a modification of openSER, nor does selection of openSER as a product' | ||
+ | |||
+ | Said home automation system would not be "based on" openSER. | ||
+ | |||
+ | Adherence to the provided and documented module API fulfills the " | ||