Author: Harrie Hazewinkel (harrie@mod-snmp.com) Date: May 23, 2002. Module design for Kannel. Summary: This document provides a proposal to add a more modular based approach to the Kannel package. This apporach should enable additional modules to function with Kannel without patching the core code. 1) Introduction. Kannel is a WAP gateway that enables WAP/SMS users to access information of the Internet. Because most users want potentially different services different modules for the WAP gateway needs to be added providing the services. Besides the user oriented services there are also management/administrative oriented services. Kannel itself is open-source, however, various companies provide services/products around the open-source core. Depending on the service or product it may be neccessary to patch. This document provides a design of allowing modules to be added without patching the core. NOTE: It is recognized that the design is not complete due to various modules need different entries in the code. However, it is envisioned to have this all converging in a single module approach. NOTE2:This document does not provide information of an API for various smsc modules. That could be integrated, but is out-of-scope (for now). 2) The process cycle The following figure provides a cycle currently envisioned for the processes. The handling of each request is not yet included. startup | v reading configuration | v initialise the modules | v startup the threads | +------------------> request processing cycles | +-------------<------------+ v stop all threads | v cleanup/exit The graph above shows a simple straight forward approach. After starting up the process the configuration is read. Based on the configuration read, each modules initialize itself. At this point the server can start going into the request processing cycle by starting up the needed threads (user request handling and administartive requests). At some point the proccess needs to stop (can be caused bu sigkill) it will stop all threads and finally cleans up and exits. 2) The module structure. The module structure wil become a central piece of the design from which all actions are taken as an API. An api version: This enables to test an application whether a module is compatible with its module struct. Also allows to make changes to the api (if needed). An module name: A string based module identification. Configuration parameters A pointer to an array of configfile tokens that are used to configure the module. Therefore, also 2 additional functions needed to exists in order to provide the awareness fo these to the configuration file functionality. Those functions are: 'is_allowed_by_module' and 'is_single_group_by_module'. At this moment there is still a problem with this, since all processes use currently the same configuration file and if some process does not use a certain module it does not know its configuration parameters resulting in an error. An init function "int (*init_module)(/* parameters */);" : This function enables a module to execute any required functions before the operational phase (loop) will start. Parameters: TBD (based also on needs) Returned: integer indicating whether an error has occured. '0' == 'OK' others error. An start thread function "int (*start_thread_module)(/* parameters */);": This function enables a module to start a thread in the the operational phase (loop) will start. Parameters: TBD (based also on needs) Returned: integer indicating whether an error has occured. '0' == 'OK' others error. An stop thread function "int (*stop_thread_module)(/* parameters */);": This function enables a module to stop a thread of the the operational phase (loop) will start. Parameters: TBD (based also on needs) Returned: integer indicating whether an error has occured. '0' == 'OK' others error. An init function "int (*log_module)(/* parameters */);" : This function enables a module to add a logging function to be executed after exceuting a request (WAP/SMS). Equals some access log funcitonality. Parameters: TBD (based also on needs) Returned: integer indicating whether an error has occured. '0' == 'OK' others error. (Maybe we do not care here so much if an error happens) An init function "int (*exit_module)(/* parameters */);" : This function enables a module to execute any required functions before the the process terminates in order to clean up claimed resources, for instance. Parameters: TBD (based also on needs) --- C-code ------------ typedef struct kannel_module_s { int api_version; /* API version for compatibility check. */ char *module_name; /* module identification. */ kannel_param *config; /* module specific configuration parameters. */ int (*init_module)(/* parameters */); int (*start_thread_module)(/* parameters */); int (*stop_thread)(/* parameters */); int (*log_module(/* parameters */); void (*exit_module)(/* parameters */); /* other */ } kannel_module; ----------------------- 4) hook handling. The previous section provided some information of a potentially needed API from a module point of view. This section provides an explaination of how these module structure are to be used in the various phases. The example start from a fixed sized array that is generated during the './configure' with the required modules. This is equal to the current situation as now where a potentially patch core enables modules. for (i = o ; i < number_of_modules ; i++) { kannel_module *ptr = &(modules[i]); if (ptr->init_module(/* parameters */)) { log_error(); exit(); } } 5) extensions A extensions to this API or additional funcitonality the following could be added. - dynamically loaded modules. - missing API phases. - the request handling phases. These are currently left out in order to sollicit comments on the above described approach. It is recognized that this could potentially cause changes needed by all modules, but the result in the long turn will benefit all (I hope). 6) reference. The source code of the Apache HTTP server that implements an similar kind of interface. Copyright (c) 2002 Harrie Hazewinkel, All rights reserved.