first draft and patch for module oriented API.

Harrie Hazewinkel <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <5452159.1022581436@localhost>
HI All,

Attached is a document slightly explaining a module oriented API
and a patch assoicated for it.

I would people like to invite to make comments and in perticular those
who made additional modules that need always patching the core.
I understand it is not complete yet, but that is why I invite comments.

Harrie

Internet Management Consulting
tel: +39-3474932300
mailto:[email protected]                http ://www.mod-snmp.com/
modules.patch (application/octet-stream, 24.8 KB)
diff -rNu ../../gateway/gw/bearerbox.c ./gw/bearerbox.c
--- ../../gateway/gw/bearerbox.c	Mon May 27 10:16:18 2002
+++ ./gw/bearerbox.c	Mon May 27 10:44:05 2002
@@ -22,6 +22,8 @@
 #include "shared.h"
 #include "dlr.h"
 
+#include "bearerbox_modules.h"
+
 /* global variables; included to other modules as needed */
 
 List *incoming_sms;
diff -rNu ../../gateway/gw/bearerbox_modules.h ./gw/bearerbox_modules.h
--- ../../gateway/gw/bearerbox_modules.h	Wed Dec 31 16:00:00 1969
+++ ./gw/bearerbox_modules.h	Mon May 27 10:44:05 2002
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2002 Harrie Hazewinkel, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by Harrie Hazewinkel."
+ *
+ * 4. The name of the Copyright holder must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 5. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Harrie Hazewinkel"
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+#ifndef __BEARER_MODULES_H__
+#define __BEARER_MODULES_H__
+
+#include "gwlib/modules.h"
+
+kannel_module *module_array[] = {
+};
+
+int module_array_size = sizeof(module_array)/sizeof(kannel_module*);
+#endif /* __BEARER_MODULES_H__ */
diff -rNu ../../gateway/gw/mod_heartbeat.c ./gw/mod_heartbeat.c
--- ../../gateway/gw/mod_heartbeat.c	Wed Dec 31 16:00:00 1969
+++ ./gw/mod_heartbeat.c	Mon May 27 10:44:05 2002
@@ -0,0 +1,155 @@
+/*
+ * heartbeat.c - thread for sending heartbeat Msgs to bearerbox
+ */
+
+#include <signal.h>
+
+#include "gwlib/gwlib.h"
+#include "msg.h"
+#include "shared.h"
+#include "gwlib/modules.h"
+#include "mod_heartbeat.h"
+
+/*
+ * Each running heartbeat gets one of these.  They are collected in
+ * the heartbeats List.
+ */
+struct hb_info {
+    long thread;
+    double freq;
+    send_func_t *send_func;
+    load_func_t *load_func;
+    volatile sig_atomic_t running;
+};
+
+/* List of struct hb_info. */
+static List *heartbeats;
+/* The heartbeat frequentie. */
+static int heartbeat_freq = DEFAULT_HEARTBEAT;
+
+
+/*
+ * Look for a hb_info in a list, by thread number.
+ */
+static int find_hb(void *item, void *pattern)
+{
+    long *threadnrp;
+    struct hb_info *info;
+
+    info = item;
+    threadnrp = pattern;
+
+    return info->thread == *threadnrp;
+}
+
+static void heartbeat_thread(void *arg)
+{
+    struct hb_info *info;
+    time_t last_hb;
+
+    info = arg;
+    last_hb = 0;
+
+    while (info->running) {
+        Msg *msg;
+
+        gwthread_sleep(info->freq);
+
+        /*
+         * Because the sleep can be interrupted, we might end up sending
+         * heartbeats faster than the configured heartbeat frequency.
+         * This is not bad unless we send them way too fast.  Make sure
+         * our frequency is not more than twice the configured one.
+         */
+        if (difftime(last_hb, time(NULL)) < info->freq / 2)
+            continue;
+
+        msg = msg_create(heartbeat);
+        msg->heartbeat.load = info->load_func();
+        info->send_func(msg);
+        last_hb = time(NULL);
+    }
+}
+
+static long
+heartbeat_start(send_func_t *send_func,
+                     load_func_t *load_func)
+{
+    struct hb_info *info;
+
+    debug("mod_heartbeat", GW_DEBUG, "Start heartbeat");
+    info = gw_malloc(sizeof(*info));
+    info->send_func = send_func;
+    info->freq = heartbeat_freq;
+    info->load_func = load_func;
+    info->running = 1;
+    info->thread = gwthread_create(heartbeat_thread, info);
+    if (info->thread >= 0) {
+	if (heartbeats == NULL)
+	    heartbeats = list_create();
+	list_append(heartbeats, info);
+        return 0;
+    } else {
+        gw_free(info);
+        return -1;
+    }
+}
+
+static void
+heartbeat_stop(void)
+{
+    struct hb_info *info;
+
+    debug("mod_heartbeat", GW_DEBUG, "STOP heartbeat");
+
+    while (list_len(heartbeats)) {
+        debug("mod_heartbeat", GW_DEBUG, "yep");
+        info = list_extract_first(heartbeats);
+        if (info) {
+            info->running = 0;
+            gwthread_wakeup(info->thread);
+            gwthread_join(info->thread);
+        }
+         gw_free(info);
+    }
+    list_destroy(heartbeats, NULL);
+    heartbeats = NULL;
+}
+
+static int
+heartbeat_init(void)
+{
+    return 0;
+}
+
+static int
+heartbeat_log(void)
+{
+/* the hook in the core is not implemented yet */
+}
+
+static void
+heartbeat_exit(void)
+{
+
+}
+
+kannel_config config_parms[] = {
+    { "heartbeat", "smsbox", NULL },
+    NULL
+};
+
+kannel_module mod_heartbeat = {
+    1,                /* api version                                */
+    "heartbeat",      /* module identification                      */
+    config_parms,     /* module specific configuration parameters.  */
+                      /* For the moment not done, needs big rewrite */
+                      /* of existing configuration handling.        */
+    heartbeat_init,   /* module initialization                      */
+    heartbeat_start,  /* module start                               */
+    heartbeat_stop,   /* module start                               */
+    heartbeat_log,    /* module log           (not implemented yet) */
+    heartbeat_exit    /* module exit/cleanup  (not implemented yet) */
+    /* other */
+};
+
diff -rNu ../../gateway/gw/mod_heartbeat.h ./gw/mod_heartbeat.h
--- ../../gateway/gw/mod_heartbeat.h	Wed Dec 31 16:00:00 1969
+++ ./gw/mod_heartbeat.h	Mon May 27 10:44:05 2002
@@ -0,0 +1,15 @@
+/*
+ * heartbeat.h - thread for sending heartbeat Msgs to bearerbox
+ */
+
+#ifndef __MOD_HEARTBEAT_H__
+#define __MOD_HEARTBEAT_H__
+
+#include "gwlib/gwlib.h"
+#include "msg.h"
+
+#define DEFAULT_HEARTBEAT    30
+
+extern kannel_module mod_heartbeat;
+
+#endif /* __MOD_HEARTBEAT_H__ */
diff -rNu ../../gateway/gw/shared.h ./gw/shared.h
--- ../../gateway/gw/shared.h	Tue May 14 04:05:08 2002
+++ ./gw/shared.h	Mon May 27 10:44:05 2002
@@ -64,6 +64,10 @@
  * Send an Msg to the bearerbox, and destroy the Msg.
  */
 void write_to_bearerbox(Msg *msg);
+/*
+ * Associated typedef for send function.
+ */
+typedef void send_func_t(Msg *msg);
 
 /*
  * Validates an OSI date.
diff -rNu ../../gateway/gw/sms_modules.h ./gw/sms_modules.h
--- ../../gateway/gw/sms_modules.h	Wed Dec 31 16:00:00 1969
+++ ./gw/sms_modules.h	Mon May 27 10:44:05 2002
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2002 Harrie Hazewinkel, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by Harrie Hazewinkel."
+ *
+ * 4. The name of the Copyright holder must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 5. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Harrie Hazewinkel"
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+#ifndef __SMS_MODULES_H__
+#define __SMS_MODULES_H__
+
+#include "gwlib/modules.h"
+#include "mod_heartbeat.h"
+
+extern kannel_module mod_heartbeat;
+
+kannel_module *module_array[] = {
+    &mod_heartbeat
+};
+
+int module_array_size = sizeof(module_array)/sizeof(kannel_module*);
+#endif /* __SMS_MODULES_H__ */
diff -rNu ../../gateway/gw/smsbox.c ./gw/smsbox.c
--- ../../gateway/gw/smsbox.c	Mon May 20 07:12:56 2002
+++ ./gw/smsbox.c	Mon May 27 10:44:05 2002
@@ -13,7 +13,6 @@
 #include "sms.h"
 #include "bb.h"
 #include "shared.h"
-#include "heartbeat.h"
 #include "html.h"
 #include "urltrans.h"
 #include "ota_prov_attr.h"
@@ -24,6 +23,7 @@
 #include <security/pam_appl.h>
 #endif
 
+#include "sms_modules.h"
 
 /*
  * Maximum number of octets in an SMS message. Note that this is 8 bit
@@ -46,7 +46,6 @@
 static Octstr *xmlrpc_url = NULL;
 static Octstr *bb_host;
 static char *pid_file;
-static int heartbeat_freq;
 static Octstr *accepted_chars = NULL;
 static int only_try_http = 0;
 static URLTranslationList *translations = NULL;
@@ -2692,7 +2691,6 @@
     bb_port = BB_DEFAULT_SMSBOX_PORT;
     bb_ssl = 0;
     bb_host = octstr_create(BB_DEFAULT_HOST);
-    heartbeat_freq = BB_DEFAULT_HEARTBEAT;
     logfile = NULL;
     lvl = 0;
 
@@ -2837,6 +2835,8 @@
     octstr_destroy(http_proxy_username);
     octstr_destroy(http_proxy_password);
     list_destroy(http_proxy_exceptions, octstr_destroy_item);
+
+    run_init();
 }
 
 
@@ -2853,7 +2853,6 @@
 int main(int argc, char **argv)
 {
     int cf_index;
-    long heartbeat_thread;
     Octstr *cfg_name;
 
     gwlib_init();
@@ -2897,14 +2896,15 @@
     connect_to_bearerbox(bb_host, bb_port, bb_ssl, NULL /* bb_our_host */);
 	/* XXX add our_host if required */
 
-    heartbeat_thread = heartbeat_start(write_to_bearerbox, heartbeat_freq,
-				       outstanding_requests);
+    run_start_thread(write_to_bearerbox,
+                                       outstanding_requests);
 
     read_messages_from_bearerbox();
 
     info(0, GW_NAME " smsbox terminating.");
 
-    heartbeat_stop(heartbeat_thread);
+    run_stop_thread();
+
     http_close_all_ports();
     gwthread_join_every(sendsms_thread);
     list_remove_producer(smsbox_requests);
diff -rNu ../../gateway/gw/smskannel.conf ./gw/smskannel.conf
--- ../../gateway/gw/smskannel.conf	Thu May  2 21:02:26 2002
+++ ./gw/smskannel.conf	Mon May 27 10:44:05 2002
@@ -53,7 +53,7 @@
 #log-file = "/tmp/smsbox.log"
 #log-level = 0
 #access-log = "access.log"
-
+heartbeat  = 50
 
 # SEND-SMS USERS
 
diff -rNu ../../gateway/gw/wap_modules.h ./gw/wap_modules.h
--- ../../gateway/gw/wap_modules.h	Wed Dec 31 16:00:00 1969
+++ ./gw/wap_modules.h	Mon May 27 10:44:05 2002
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2002 Harrie Hazewinkel, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by Harrie Hazewinkel."
+ *
+ * 4. The name of the Copyright holder must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 5. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Harrie Hazewinkel"
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+#ifndef __WAP_MODULES_H__
+#define __WAP_MODULES_H__
+
+#include "gwlib/modules.h"
+#include "mod_heartbeat.h"
+
+extern kannel_module mod_heartbeat;
+
+kannel_module *module_array[] = {
+    &mod_heartbeat
+};
+
+int module_array_size = sizeof(module_array)/sizeof(kannel_module*);
+#endif /* __WAP_MODULES_H__ */
diff -rNu ../../gateway/gw/wapbox.c ./gw/wapbox.c
--- ../../gateway/gw/wapbox.c	Tue May 14 04:05:08 2002
+++ ./gw/wapbox.c	Mon May 27 10:44:05 2002
@@ -22,6 +22,8 @@
 #include "bb.h"
 #include "sms.h"
 
+#include "wap_modules.h"
+
 #ifdef HAVE_WTLS_OPENSSL
 #include <openssl/x509.h>
 #include "wap/wtls.h"
diff -rNu ../../gateway/gwlib/cfg.c ./gwlib/cfg.c
--- ../../gateway/gwlib/cfg.c	Mon Apr 29 18:11:34 2002
+++ ./gwlib/cfg.c	Mon May 27 10:44:05 2002
@@ -6,6 +6,8 @@
 
 
 #include "gwlib/gwlib.h"
+#include "gw/shared.h"
+#include "gwlib/modules.h"
 
 
 struct CfgGroup {
@@ -97,6 +99,10 @@
     
     groupstr = octstr_imm("group");
 
+    if (is_allowed_by_module(group, variable)) {
+        return 1;
+    }
+
     #define OCTSTR(name) \
     	if (octstr_compare(octstr_imm(#name), variable) == 0) \
 	    return 1;
@@ -122,6 +128,9 @@
 
 static int is_single_group(Octstr *query)
 {
+    if (is_single_group_by_module(query))
+        return 1;
+
     #define OCTSTR(name)
     #define SINGLE_GROUP(name, fields) \
     	if (octstr_compare(octstr_imm(#name), query) == 0) \
diff -rNu ../../gateway/gwlib/modules.c ./gwlib/modules.c
--- ../../gateway/gwlib/modules.c	Wed Dec 31 16:00:00 1969
+++ ./gwlib/modules.c	Mon May 27 10:44:05 2002
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2002 Harrie Hazewinkel, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by Harrie Hazewinkel."
+ *
+ * 4. The name of the Copyright holder must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 5. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Harrie Hazewinkel"
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <stdio.h>
+
+#include "gw/shared.h"
+
+/* Includes all modules. */
+#include "modules.h"
+
+int
+is_allowed_by_module(Octstr *group, Octstr *variable) {
+
+    if (module_array != NULL) {
+        int i = 0;
+        while (i < module_array_size) {
+            kannel_config *config = (*module_array[i]).config;
+            if (config) {
+                while (config->item) {
+                    if (octstr_str_compare(group, config->ofgroup) == 0) {
+                        if (octstr_str_compare(variable, config->item) == 0) {
+                            return 1;
+                        }
+                    }
+                    ++config;
+                }
+            }
+            i++;
+        }
+        return 0;
+    }
+}
+
+int
+is_single_group_by_module(Octstr *query) {
+
+    debug("core.modules", GW_DEBUG, "group testing '%s'", octstr_get_cstr(query));
+    return 0;
+}
+
+
+int
+run_init(void) {
+    if (module_array != NULL) {
+        int i = 0;
+        while (i < module_array_size) {
+            init_function function = (*module_array[i]).func_init;
+            if (function) {
+                if ((*function)()) {
+                    error(GW_ERROR, "Oh oh, I am in trouble");
+                    exit(0);
+                }
+            }
+            i++;
+        }
+        return 0;
+    }
+    return -1;
+}
+
+int
+run_start_thread(send_func_t *send_func,
+                                     load_func_t *load_func) {
+    if (module_array != NULL) {
+        int i = 0;
+
+        debug("core.modules", GW_DEBUG, "we have %d modules", module_array_size);
+
+        while (i < module_array_size) {
+            start_thread_function function = (*module_array[i]).func_start_thread;
+            if (function) {
+                if ((*function)(send_func, load_func)) {
+                    error(GW_ERROR, "Oh oh, I am in trouble");
+                    exit(0);
+                }
+            }
+            i++;
+        }
+        return 0;
+    }
+    return -1;
+}
+
+int
+run_stop_thread(void) {
+    if (module_array != NULL) {
+        int i = 0;
+
+        debug("core.modules", GW_DEBUG, "we have %d modules", module_array_size);
+
+        while (i < module_array_size) {
+            stop_thread_function function = (*module_array[i]).func_stop_thread;
+            if (function) {
+                (*function)();
+            }
+            i++;
+        }
+        return 0;
+    }
+    return -1;
+}
+
+int
+run_log(void) {
+    if (module_array != NULL) {
+        int i = 0;
+        while (i < module_array_size) {
+            log_function function = (*module_array[i]).func_log;
+            if (function) {
+                if ((*function)()) {
+                    error(GW_ERROR, "Oh oh, I am in trouble");
+                    exit(0);
+                }
+            }
+            i++;
+        }
+        return 0;
+    }
+    return -1;
+}
+
+int
+run_exit(void) {
+    if (module_array != NULL) {
+        int i = 0;
+        while (i < module_array_size) {
+            exit_function function = (*module_array[i]).func_exit;
+            if (function) {
+                (*function)();
+            }
+            i++;
+        }
+        return 0;
+    }
+    return -1;
+}
+
diff -rNu ../../gateway/gwlib/modules.h ./gwlib/modules.h
--- ../../gateway/gwlib/modules.h	Wed Dec 31 16:00:00 1969
+++ ./gwlib/modules.h	Mon May 27 10:44:05 2002
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2002 Harrie Hazewinkel, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by Harrie Hazewinkel."
+ *
+ * 4. The name of the Copyright holder must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 5. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by Harrie Hazewinkel"
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+#ifndef __MODULES_H__
+#define __MODULES_H__
+
+/* This is here defined, but should be in some other place; TBD */
+typedef long load_func_t(void);
+
+typedef int (*config_function) (void);
+
+/* A structure to maintian configuration specific items */
+typedef struct kannel_config_s {
+  char *item;
+  char *ofgroup;
+  config_function handler;
+} kannel_config;
+
+/* Tyepdef for the hook functions. */
+typedef int  (*init_function)         (void /* parameters */);
+typedef long (*start_thread_function) (send_func_t *send_func,
+                                       load_func_t *load_func);
+typedef void (*stop_thread_function)  (void);
+typedef int  (*log_function)          (void /* parameters */);
+typedef void (*exit_function)         (void /* parameters */);
+
+/* The module structure definition. */
+typedef struct kannel_module_s {
+    int api_version;               /* API version for compatibility check. */
+    char *module_name;             /* module identification. */
+    kannel_config *config;         /* module specific configuration parameters. */
+    init_function func_init;
+    start_thread_function func_start_thread;
+    stop_thread_function func_stop_thread;
+    log_function func_log;
+    exit_function func_exit;
+    /* other */
+} kannel_module;
+
+/* The external modules array;
+ * needs to be defined in a process specific file.
+ */
+extern kannel_module *module_array[];
+extern int module_array_size;
+
+/* The run hooks function definitions. */
+int is_allowed_by_module(Octstr *group, Octstr *variable);
+int is_single_group_by_module(Octstr *query);
+int run_init(void);
+int run_start_thread(send_func_t *send_func,
+                                     load_func_t *load_func);
+int run_stop_thread(void);
+int run_log(void);
+int run_exit(void);
+
+#endif /* __MODULES_H__ */
module_struct.txt (application/octet-stream, 6.5 KB)
Author: Harrie Hazewinkel ([email protected])
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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.