2
0
Эх сурвалжийг харах

add new module "matrix" for array lookups

Marius Bucur 15 жил өмнө
parent
commit
1fb1997b63

+ 13 - 0
lib/srdb1/schema/kamailio-matrix.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE database PUBLIC "-//kamailio.org//DTD DBSchema V1.1//EN"
+  "http://kamailio.org/pub/kamailio/dbschema/dtd/1.1/dbschema.dtd" [
+
+<!ENTITY % entities SYSTEM "entities.xml">
+%entities;
+
+]>
+
+<database xmlns:xi="http://www.w3.org/2001/XInclude">
+    <name>Route Matrix</name>
+    <xi:include href="matrix.xml"/>
+</database>

+ 45 - 0
lib/srdb1/schema/matrix.xml

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE table PUBLIC "-//kamailio.org//DTD DBSchema V1.1//EN" 
+  "http://kamailio.org/pub/kamailio/dbschema/dtd/1.1/dbschema.dtd" [
+
+<!ENTITY % entities SYSTEM "entities.xml">
+%entities;
+
+]>
+
+<table id="matrix" xmlns:db="http://docbook.org/ns/docbook">
+    <name>matrix</name>
+    <version>1</version>
+    <type db="mysql">&MYSQL_TABLE_TYPE;</type>
+    <description>
+        <db:para>This table is used by the matrix module.
+        </db:para>
+    </description>
+
+    <column id="first">
+        <name>first</name>
+        <type>int</type>
+        <size>&table_id_len;</size>
+        <description>The row id in the matrix</description>
+    </column>
+
+    <column id="second">
+        <name>second</name>
+        <type>short</type>
+        <size>&table_id_len;</size>
+        <description>The column id in the matrix</description>
+    </column>
+
+    <column id="res">
+        <name>res</name>
+        <type>int</type>
+        <size>&table_id_len;</size>
+        <description>The resource element in the matrix</description>
+    </column>
+
+    <index>
+        <name>matrix_idx</name>
+        <colref linkend="first"/>
+        <colref linkend="second"/>
+    </index>
+</table>

+ 13 - 0
modules/matrix/Makefile

@@ -0,0 +1,13 @@
+# WARNING: do not run this directly, it should be run by the master Makefile
+
+include ../../Makefile.defs
+auto_gen=
+NAME=matrix.so
+LIBS=
+
+DEFS+=-DOPENSER_MOD_INTERFACE
+
+SERLIBPATH=../../lib
+SER_LIBS+=$(SERLIBPATH)/kmi/kmi
+SER_LIBS+=$(SERLIBPATH)/srdb1/srdb1
+include ../../Makefile.modules

+ 313 - 0
modules/matrix/README

@@ -0,0 +1,313 @@
+matrix Module
+
+Hardy Kahl
+
+   1&1 Internet AG
+
+Edited by
+
+Henning Westerholt
+
+   1&1 Internet AG
+   <[email protected]>
+
+   Copyright © 2008 1&1 Internet AG
+   Revision History
+   Revision $Revision: 4863 $ $Date: 2008-09-05 13:11:33 +0200 (Fri, 05
+                              Sep 2008) $
+     __________________________________________________________________
+
+   Table of Contents
+
+   1. Admin Guide
+
+        1. Overview
+        2. Dependencies
+
+              2.1. Kamailio Modules
+              2.2. External Libraries or Applications
+
+        3. Exported Parameters
+
+              3.1. db_url (string)
+              3.2. matrix_table (string)
+              3.3. matrix_first_col (string)
+              3.4. matrix_second_col (string)
+              3.5. matrix_res_col (string)
+
+        4. Exported Functions
+
+              4.1. matrix (string first, string second, string dstavp)
+
+        5. MI Commands
+
+              5.1. reload_matrix
+
+        6. Installation and Running
+
+              6.1. Database setup
+
+   2. Module parameter for database access.
+
+        1. db_url (String)
+        2. matrix_table (String)
+        3. matrix_first_col (string)
+        4. matrix_second_col (string)
+        5. matrix_res_col (string)
+
+   List of Examples
+
+   1.1. Set db_url parameter
+   1.2. Set matrix_table parameter
+   1.3. Set matrix_first_col parameter
+   1.4. Set matrix_second_col parameter
+   1.5. Set matrix_res_col parameter
+   1.6. matrix usage
+   1.7. reload_matrix usage
+   1.8. Example database content - matrix table
+   2.1. Set db_url parameter
+   2.2. Set matrix_table parameter
+   2.3. Set matrix_first_col parameter
+   2.4. Set matrix_second_col parameter
+   2.5. Set matrix_res_col parameter
+
+Chapter 1. Admin Guide
+
+   Table of Contents
+
+   1. Overview
+   2. Dependencies
+
+        2.1. Kamailio Modules
+        2.2. External Libraries or Applications
+
+   3. Exported Parameters
+
+        3.1. db_url (string)
+        3.2. matrix_table (string)
+        3.3. matrix_first_col (string)
+        3.4. matrix_second_col (string)
+        3.5. matrix_res_col (string)
+
+   4. Exported Functions
+
+        4.1. matrix (string first, string second, string dstavp)
+
+   5. MI Commands
+
+        5.1. reload_matrix
+
+   6. Installation and Running
+
+        6.1. Database setup
+
+1. Overview
+
+   The matrix module can be used to arbitrary lookup operations over an
+   array. One possible usecase is to define which routing tree should be
+   used depending on the preferred carrier of the source number and the
+   carrier id of the destination number. The matrix cells are read from a
+   database and can be reloaded using a FIFO command. You do not have to
+   define all matrix cells. The matrix can be sparse. Currently, the
+   implementation is designed for a small number of columns (they are
+   stored in a linked list). This does not scale well and has to be
+   replaced by more an efficient data data structure when needed.
+
+2. Dependencies
+
+   2.1. Kamailio Modules
+   2.2. External Libraries or Applications
+
+2.1. Kamailio Modules
+
+   The module depends on the following modules (in the other words the
+   listed modules must be loaded before this module):
+     * none
+
+2.2. External Libraries or Applications
+
+   The following libraries or applications must be installed before
+   running Kamailio with this module loaded:
+     * none
+
+3. Exported Parameters
+
+   3.1. db_url (string)
+   3.2. matrix_table (string)
+   3.3. matrix_first_col (string)
+   3.4. matrix_second_col (string)
+   3.5. matrix_res_col (string)
+
+3.1. db_url (string)
+
+   The URL for the database connection.
+
+   Default value is "mysql://openserro:openserro@localhost/openser".
+
+   Example 1.1. Set db_url parameter
+...
+modparam("matrix", "db_url", "mysql://openserro:openserro@localhost/openser")
+...
+
+3.2. matrix_table (string)
+
+   The name of the table containing the matrix data.
+
+   Default value is "matrix".
+
+   Example 1.2. Set matrix_table parameter
+...
+modparam("matrix", "matrix_table", "matrix")
+...
+
+3.3. matrix_first_col (string)
+
+   The name of the column containing the first row in the matrix.
+
+   Default value is "first".
+
+   Example 1.3. Set matrix_first_col parameter
+...
+modparam("matrix", "matrix_first_col", "first")
+...
+
+3.4. matrix_second_col (string)
+
+   The name of the column containing the second row in the matrix.
+
+   Default value is "second".
+
+   Example 1.4. Set matrix_second_col parameter
+...
+modparam("matrix", "matrix_second_col", "second")
+...
+
+3.5. matrix_res_col (string)
+
+   The name of the column containing the result ID to be used.
+
+   Default value is "res".
+
+   Example 1.5. Set matrix_res_col parameter
+...
+modparam("matrix", "matrix_res_col", "res")
+...
+
+4. Exported Functions
+
+   4.1. matrix (string first, string second, string dstavp)
+
+4.1.  matrix (string first, string second, string dstavp)
+
+   Looks up the desired result ID in the matrix for the given column and
+   value and saves the result in dstavp. Returns false if the cell is not
+   defined or when an error occured. Pseudo-variables or AVPs can be used
+   for first and second.
+
+   Example 1.6. matrix usage
+...
+if (!matrix("$avp(first)", "$(second)", "$avp(route_tree)"))
+  $avp(route_tree) = $avp(frst); # default routing as defined for source number
+}
+cr_route("$avp(route_tree)", "$rd", "$rU", "$rU", "call_id");
+...
+
+5. MI Commands
+
+   5.1. reload_matrix
+
+5.1.  reload_matrix
+
+   Reloads the internal matrix representation from the database. This is
+   necessary after entries in the database have been changed.
+
+   Example 1.7. reload_matrix usage
+...
+kamctl fifo reload_matrix
+...
+
+6. Installation and Running
+
+   6.1. Database setup
+
+6.1. Database setup
+
+   Before running Kamailio with matrix, you have to setup the database
+   table where the module will read the matrix data. For that, if the
+   table was not created by the installation script or you choose to
+   install everything by yourself you can use the matrix-create.sql SQL
+   script in the database directories in the kamailio/scripts folder as
+   template. Database, table, and column names can be set with module
+   parameters so they can be changed. You can also find the complete
+   database documentation on the project webpage,
+   http://www.kamailio.org/docs/db-tables/kamailio-db-devel.html.
+
+   Example 1.8. Example database content - matrix table
+...
++---------+--------------+---------+
+|  first  |    second    |   res   |
++---------+--------------+---------+
+|       1 |            9 |       2 |
+|       2 |           69 |       1 |
+|       2 |           13 |       3 |
++---------+--------------+---------+
+...
+
+Chapter 2. Module parameter for database access.
+
+   Table of Contents
+
+   1. db_url (String)
+   2. matrix_table (String)
+   3. matrix_first_col (string)
+   4. matrix_second_col (string)
+   5. matrix_res_col (string)
+
+1. db_url (String)
+
+   URL to the database containing the data.
+
+   Default value is "mysql://openserro:openserro@localhost/openser".
+
+   Example 2.1. Set db_url parameter
+...
+modparam("matrix", "db_url", "dbdriver://username:password@dbhost/dbname")
+...
+
+2. matrix_table (String)
+
+   Name of the matrix table for the matrix module.
+
+   Default value is "matrix".
+
+   Example 2.2. Set matrix_table parameter
+...
+modparam("matrix", "matrix_table", "matrix")
+...
+
+3. matrix_first_col (string)
+
+   The row index in the matrix
+
+   Example 2.3. Set matrix_first_col parameter
+...
+modparam("matrix", "matrix_first_col", "first")
+...
+
+4. matrix_second_col (string)
+
+   The column index in the matrix
+
+   Example 2.4. Set matrix_second_col parameter
+...
+modparam("matrix", "matrix_second_col", "second")
+...
+
+5. matrix_res_col (string)
+
+   The resource contained in the matrix
+
+   Example 2.5. Set matrix_res_col parameter
+...
+modparam("matrix", "matrix_res_col", "res")
+...

+ 112 - 0
modules/matrix/db_matrix.c

@@ -0,0 +1,112 @@
+
+/*!
+ * \file
+ * \ingroup db
+ * \brief Database support for modules.
+ *
+ * Database support functions for modules.
+ *
+ * @cond
+ * WARNING:
+ * This file was autogenerated from the XML source file
+ * ../../modules/matrix/kamailio-matrix.xml.
+ * It can be regenerated by running 'make modules' in the db/schema
+ * directory of the source code. You need to have xsltproc and
+ * docbook-xsl stylesheets installed.
+ * ALL CHANGES DONE HERE WILL BE LOST IF THE FILE IS REGENERATED
+ * @endcond
+ */
+
+#include "db_matrix.h"
+
+/* database variables */
+/* TODO assign read-write or read-only URI, introduce a parameter in XML */
+
+//extern str matrix_db_url;
+db1_con_t * matrix_dbh = NULL;
+db_func_t matrix_dbf;
+
+str matrix_table = str_init("matrix");
+
+/* column names */
+str matrix_first_col = str_init("first");
+str matrix_second_col = str_init("second");
+str matrix_res_col = str_init("res");
+
+/* table version */
+const unsigned int matrix_version = 1;
+
+
+/*
+ * Closes the DB connection.
+ */
+void matrix_db_close(void) {
+	if (matrix_dbh) {
+		matrix_dbf.close(matrix_dbh);
+		matrix_dbh = NULL;
+	}
+}
+
+
+/*!
+ * Initialises the DB API, check the table version and closes the connection.
+ * This should be called from the mod_init function.
+ *
+ * \return 0 means ok, -1 means an error occured.
+ */
+int matrix_db_init(void) {
+	if (!matrix_db_url.s || !matrix_db_url.len) {
+		LM_ERR("you have to set the db_url module parameter.\n");
+		return -1;
+	}
+	if (db_bind_mod(&matrix_db_url, &matrix_dbf) < 0) {
+		LM_ERR("can't bind database module.\n");
+		return -1;
+	}
+	if ((matrix_dbh = matrix_dbf.init(&matrix_db_url)) == NULL) {
+		LM_ERR("can't connect to database.\n");
+		return -1;
+	}
+	if (
+	(db_check_table_version(&matrix_dbf, matrix_dbh, &matrix_table, matrix_version) < 0)
+	) {
+		LM_ERR("during table version check.\n");
+		matrix_db_close();
+		return -1;
+	}
+	matrix_db_close();
+	return 0;
+}
+
+
+/*!
+ * Initialize the DB connection without checking the table version and DB URL.
+ * This should be called from child_init. An already existing database
+ * connection will be closed, and a new one created.
+ *
+ * \return 0 means ok, -1 means an error occured.
+ */
+int matrix_db_open(void) {
+	if (matrix_dbh) {
+		matrix_dbf.close(matrix_dbh);
+	}
+	if ((matrix_dbh = matrix_dbf.init(&matrix_db_url)) == NULL) {
+		LM_ERR("can't connect to database.\n");
+		return -1;
+	}
+	return 0;
+}
+
+
+/*!
+ * Update the variable length after eventual assignments from the config script.
+ * This is necessary because we're using the 'str' type.
+ */
+void matrix_db_vars(void) {
+	if (matrix_db_url.s) matrix_db_url.len = strlen(matrix_db_url.s);
+	matrix_table.len = strlen(matrix_table.s);
+	matrix_first_col.len = strlen(matrix_first_col.s);
+	matrix_second_col.len = strlen(matrix_second_col.s);
+	matrix_res_col.len = strlen(matrix_res_col.s);
+}
+

+ 85 - 0
modules/matrix/db_matrix.h

@@ -0,0 +1,85 @@
+
+/*!
+ * \file
+ * \ingroup db
+ * \brief Database support for modules.
+ *
+ * Database support functions for modules.
+ *
+ * @cond
+ * WARNING:
+ * This file was autogenerated from the XML source file
+ * ../../modules/matrix/kamailio-matrix.xml.
+ * It can be regenerated by running 'make modules' in the db/schema
+ * directory of the source code. You need to have xsltproc and
+ * docbook-xsl stylesheets installed.
+ * ALL CHANGES DONE HERE WILL BE LOST IF THE FILE IS REGENERATED
+ * @endcond
+ */
+
+#ifndef db_matrix_h
+#define db_matrix_h
+
+
+/* necessary includes */
+#include "../../lib/srdb1/db.h"
+#include "../../str.h"
+#include "../../ut.h"
+
+#include <string.h>
+
+
+/* database variables */
+
+extern str matrix_db_url;
+extern db1_con_t * matrix_dbh;
+extern db_func_t matrix_dbf;
+
+#define matrix_DB_URL { "db_url", STR_PARAM, &matrix_db_url.s },
+
+#define matrix_DB_TABLE { "matrix_table", STR_PARAM, &matrix_table.s },
+
+extern str matrix_table;
+
+/* column names */
+extern str matrix_first_col;
+extern str matrix_second_col;
+extern str matrix_res_col;
+#define matrix_DB_COLS \
+{ "matrix_first_col", STR_PARAM, &matrix_first_col.s }, \
+{ "matrix_second_col", STR_PARAM, &matrix_second_col.s }, \
+{ "matrix_res_col", STR_PARAM, &matrix_res_col.s }, \
+
+/* table version */
+extern const unsigned int matrix_version;
+
+
+/*
+ * Closes the DB connection.
+ */
+void matrix_db_close(void);
+
+/*!
+ * Initialises the DB API, check the table version and closes the connection.
+ * This should be called from the mod_init function.
+ *
+ * \return 0 means ok, -1 means an error occured.
+ */
+int matrix_db_init(void);
+
+/*!
+ * Initialize the DB connection without checking the table version and DB URL.
+ * This should be called from child_init. An already existing database
+ * connection will be closed, and a new one created.
+ *
+ * \return 0 means ok, -1 means an error occured.
+ */
+int matrix_db_open(void);
+
+/*!
+ * Update the variable length after eventual assignments from the config script.
+ * This is necessary because we're using the 'str' type.
+ */
+void matrix_db_vars(void);
+
+#endif

+ 4 - 0
modules/matrix/doc/Makefile

@@ -0,0 +1,4 @@
+docs = matrix.xml
+
+docbook_dir = ../../../docbook
+include $(docbook_dir)/Makefile.module

+ 874 - 0
modules/matrix/doc/matrix.html

@@ -0,0 +1,874 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <title>matrix Module</title>
+    <link rel="stylesheet" href="/css/sr-doc.css" type="text/css" />
+    <meta name="generator" content="DocBook XSL Stylesheets V1.75.1" />
+    <link rel="home" href="#id2523209" title="matrix Module" />
+    <link rel="next" href="#id2815512" title="Chapter 1. Admin Guide" />
+  </head>
+  <body>
+    <div class="book" title="matrix Module">
+      <div class="titlepage">
+        <div>
+          <div>
+            <h1 class="title"><a id="id2523209"></a>matrix Module</h1>
+          </div>
+          <div>
+            <div class="authorgroup">
+              <div class="author">
+                <h3 class="author"><span class="firstname">Hardy</span> <span class="surname">Kahl</span></h3>
+                <div class="affiliation">
+                  <span class="orgname">1&amp;1 Internet AG<br /></span>
+                </div>
+              </div>
+              <div class="editor">
+                <h4 class="editedby">Edited by</h4>
+                <h3 class="editor"><span class="firstname">Henning</span> <span class="surname">Westerholt</span></h3>
+                <div class="affiliation">
+                  <span class="orgname">1&amp;1 Internet AG<br /></span>
+                </div>
+                <code class="email">&lt;<a class="email" href="mailto:[email protected]">[email protected]</a>&gt;</code>
+              </div>
+            </div>
+          </div>
+          <div>
+            <p class="copyright">Copyright © 2008 1&amp;1 Internet AG</p>
+          </div>
+          <div>
+            <div class="revhistory">
+              <table border="1" width="100%" summary="Revision history">
+                <tr>
+                  <th align="left" valign="top" colspan="2">
+                    <b>Revision History</b>
+                  </th>
+                </tr>
+                <tr>
+                  <td align="left">Revision $Revision: 4863 $</td>
+                  <td align="left">$Date: 2008-09-05 13:11:33 +0200 (Fri, 05 Sep 2008) $</td>
+                </tr>
+              </table>
+            </div>
+          </div>
+        </div>
+        <hr />
+      </div>
+      <div class="toc">
+        <p>
+          <b>Table of Contents</b>
+        </p>
+        <dl>
+          <dt>
+            <span class="chapter">
+              <a href="#id2815512">1. Admin Guide</a>
+            </span>
+          </dt>
+          <dd>
+            <dl>
+              <dt>
+                <span class="section">
+                  <a href="#id2816214">1. Overview</a>
+                </span>
+              </dt>
+              <dt>
+                <span class="section">
+                  <a href="#id2808060">2. Dependencies</a>
+                </span>
+              </dt>
+              <dd>
+                <dl>
+                  <dt>
+                    <span class="section">
+                      <a href="#id2811981">2.1. Kamailio Modules</a>
+                    </span>
+                  </dt>
+                  <dt>
+                    <span class="section">
+                      <a href="#id2818364">2.2. External Libraries or Applications</a>
+                    </span>
+                  </dt>
+                </dl>
+              </dd>
+              <dt>
+                <span class="section">
+                  <a href="#id2822133">3. Exported Parameters</a>
+                </span>
+              </dt>
+              <dd>
+                <dl>
+                  <dt>
+                    <span class="section">
+                      <a href="#id2815765">3.1. <code class="varname">db_url</code> (string)</a>
+                    </span>
+                  </dt>
+                  <dt>
+                    <span class="section">
+                      <a href="#id2828576">3.2. <code class="varname">matrix_table</code> (string)</a>
+                    </span>
+                  </dt>
+                  <dt>
+                    <span class="section">
+                      <a href="#id2830755">3.3. <code class="varname">matrix_first_col</code> (string)</a>
+                    </span>
+                  </dt>
+                  <dt>
+                    <span class="section">
+                      <a href="#id2831495">3.4. <code class="varname">matrix_second_col</code> (string)</a>
+                    </span>
+                  </dt>
+                  <dt>
+                    <span class="section">
+                      <a href="#id2811302">3.5. <code class="varname">matrix_res_col</code> (string)</a>
+                    </span>
+                  </dt>
+                </dl>
+              </dd>
+              <dt>
+                <span class="section">
+                  <a href="#id2793468">4. Exported Functions</a>
+                </span>
+              </dt>
+              <dd>
+                <dl>
+                  <dt>
+                    <span class="section">
+                      <a href="#id2831283">4.1. 
+			<code class="function">matrix (string first, string second, string dstavp)</code>
+		</a>
+                    </span>
+                  </dt>
+                </dl>
+              </dd>
+              <dt>
+                <span class="section">
+                  <a href="#id2824842">5. <acronym class="acronym">MI</acronym> Commands</a>
+                </span>
+              </dt>
+              <dd>
+                <dl>
+                  <dt>
+                    <span class="section">
+                      <a href="#id2833119">5.1. 
+				<code class="function">reload_matrix</code>
+	    </a>
+                    </span>
+                  </dt>
+                </dl>
+              </dd>
+              <dt>
+                <span class="section">
+                  <a href="#id2807231">6. Installation and Running</a>
+                </span>
+              </dt>
+              <dd>
+                <dl>
+                  <dt>
+                    <span class="section">
+                      <a href="#id2832406">6.1. Database setup</a>
+                    </span>
+                  </dt>
+                </dl>
+              </dd>
+            </dl>
+          </dd>
+          <dt>
+            <span class="chapter">
+              <a href="#id2786765">2. Module parameter for database access.</a>
+            </span>
+          </dt>
+          <dd>
+            <dl>
+              <dt>
+                <span class="section">
+                  <a href="#id2786706">1. <code class="varname">db_url</code> (String)</a>
+                </span>
+              </dt>
+              <dt>
+                <span class="section">
+                  <a href="#id2828349">2. <code class="varname">matrix_table</code> (String)</a>
+                </span>
+              </dt>
+              <dt>
+                <span class="section">
+                  <a href="#id2802229">3. <code class="varname">matrix_first_col</code> (string)</a>
+                </span>
+              </dt>
+              <dt>
+                <span class="section">
+                  <a href="#id2779839">4. <code class="varname">matrix_second_col</code> (string)</a>
+                </span>
+              </dt>
+              <dt>
+                <span class="section">
+                  <a href="#id2831629">5. <code class="varname">matrix_res_col</code> (string)</a>
+                </span>
+              </dt>
+            </dl>
+          </dd>
+        </dl>
+      </div>
+      <div class="list-of-examples">
+        <p>
+          <b>List of Examples</b>
+        </p>
+        <dl>
+          <dt>1.1. <a href="#id2815079">Set <code class="varname">db_url</code> parameter</a></dt>
+          <dt>1.2. <a href="#id2811495">Set <code class="varname">matrix_table</code> parameter</a></dt>
+          <dt>1.3. <a href="#id2795600">Set <code class="varname">matrix_first_col</code> parameter</a></dt>
+          <dt>1.4. <a href="#id2794507">Set <code class="varname">matrix_second_col</code> parameter</a></dt>
+          <dt>1.5. <a href="#id2814720">Set <code class="varname">matrix_res_col</code> parameter</a></dt>
+          <dt>1.6. <a href="#id2815666"><code class="function">matrix</code> usage</a></dt>
+          <dt>1.7. <a href="#id2818370"><code class="function">reload_matrix</code> usage</a></dt>
+          <dt>1.8. <a href="#id2805497">Example database content - matrix table</a></dt>
+          <dt>2.1. <a href="#id2786762">Set <code class="varname">db_url</code> parameter</a></dt>
+          <dt>2.2. <a href="#id2784686">Set <code class="varname">matrix_table</code> parameter</a></dt>
+          <dt>2.3. <a href="#id2823757">Set <code class="varname">matrix_first_col</code> parameter</a></dt>
+          <dt>2.4. <a href="#id2824081">Set <code class="varname">matrix_second_col</code> parameter</a></dt>
+          <dt>2.5. <a href="#id2784890">Set <code class="varname">matrix_res_col</code> parameter</a></dt>
+        </dl>
+      </div>
+      <div class="chapter" title="Chapter 1. Admin Guide">
+        <div class="titlepage">
+          <div>
+            <div>
+              <h2 class="title"><a id="id2815512"></a>Chapter 1. Admin Guide</h2>
+            </div>
+          </div>
+        </div>
+        <div class="toc">
+          <p>
+            <b>Table of Contents</b>
+          </p>
+          <dl>
+            <dt>
+              <span class="section">
+                <a href="#id2816214">1. Overview</a>
+              </span>
+            </dt>
+            <dt>
+              <span class="section">
+                <a href="#id2808060">2. Dependencies</a>
+              </span>
+            </dt>
+            <dd>
+              <dl>
+                <dt>
+                  <span class="section">
+                    <a href="#id2811981">2.1. Kamailio Modules</a>
+                  </span>
+                </dt>
+                <dt>
+                  <span class="section">
+                    <a href="#id2818364">2.2. External Libraries or Applications</a>
+                  </span>
+                </dt>
+              </dl>
+            </dd>
+            <dt>
+              <span class="section">
+                <a href="#id2822133">3. Exported Parameters</a>
+              </span>
+            </dt>
+            <dd>
+              <dl>
+                <dt>
+                  <span class="section">
+                    <a href="#id2815765">3.1. <code class="varname">db_url</code> (string)</a>
+                  </span>
+                </dt>
+                <dt>
+                  <span class="section">
+                    <a href="#id2828576">3.2. <code class="varname">matrix_table</code> (string)</a>
+                  </span>
+                </dt>
+                <dt>
+                  <span class="section">
+                    <a href="#id2830755">3.3. <code class="varname">matrix_first_col</code> (string)</a>
+                  </span>
+                </dt>
+                <dt>
+                  <span class="section">
+                    <a href="#id2831495">3.4. <code class="varname">matrix_second_col</code> (string)</a>
+                  </span>
+                </dt>
+                <dt>
+                  <span class="section">
+                    <a href="#id2811302">3.5. <code class="varname">matrix_res_col</code> (string)</a>
+                  </span>
+                </dt>
+              </dl>
+            </dd>
+            <dt>
+              <span class="section">
+                <a href="#id2793468">4. Exported Functions</a>
+              </span>
+            </dt>
+            <dd>
+              <dl>
+                <dt>
+                  <span class="section">
+                    <a href="#id2831283">4.1. 
+			<code class="function">matrix (string first, string second, string dstavp)</code>
+		</a>
+                  </span>
+                </dt>
+              </dl>
+            </dd>
+            <dt>
+              <span class="section">
+                <a href="#id2824842">5. <acronym class="acronym">MI</acronym> Commands</a>
+              </span>
+            </dt>
+            <dd>
+              <dl>
+                <dt>
+                  <span class="section">
+                    <a href="#id2833119">5.1. 
+				<code class="function">reload_matrix</code>
+	    </a>
+                  </span>
+                </dt>
+              </dl>
+            </dd>
+            <dt>
+              <span class="section">
+                <a href="#id2807231">6. Installation and Running</a>
+              </span>
+            </dt>
+            <dd>
+              <dl>
+                <dt>
+                  <span class="section">
+                    <a href="#id2832406">6.1. Database setup</a>
+                  </span>
+                </dt>
+              </dl>
+            </dd>
+          </dl>
+        </div>
+        <div class="section" title="1. Overview">
+          <div class="titlepage">
+            <div>
+              <div>
+                <h2 class="title"><a id="id2816214"></a>1. Overview</h2>
+              </div>
+            </div>
+          </div>
+          <p>
+	The matrix module can be used to arbitrary lookup operations over an array.
+	One possible usecase is to define which routing tree should
+  	be used depending on the preferred carrier of the source number and
+  	the carrier id of the destination number.
+
+  	The matrix cells are read from a database and can be reloaded using
+  	a FIFO command.
+
+  	You do not have to define all matrix cells. The matrix can be sparse.
+
+  	Currently, the implementation is designed for a small number of
+  	columns (they are stored in a linked list). This does
+  	not scale well and has to be replaced by more an efficient data
+  	data structure when needed.
+
+	</p>
+        </div>
+        <div class="section" title="2. Dependencies">
+          <div class="titlepage">
+            <div>
+              <div>
+                <h2 class="title"><a id="id2808060"></a>2. Dependencies</h2>
+              </div>
+            </div>
+          </div>
+          <div class="section" title="2.1. Kamailio Modules">
+            <div class="titlepage">
+              <div>
+                <div>
+                  <h3 class="title"><a id="id2811981"></a>2.1. Kamailio Modules</h3>
+                </div>
+              </div>
+            </div>
+            <p>
+			The module depends on the following modules (in the other words 
+			the listed modules must be loaded before this module):
+			</p>
+            <div class="itemizedlist">
+              <ul class="itemizedlist">
+                <li class="listitem">
+                  <p>
+                    <span class="emphasis">
+                      <em>none</em>
+                    </span>
+                  </p>
+                </li>
+              </ul>
+            </div>
+          </div>
+          <div class="section" title="2.2. External Libraries or Applications">
+            <div class="titlepage">
+              <div>
+                <div>
+                  <h3 class="title"><a id="id2818364"></a>2.2. External Libraries or Applications</h3>
+                </div>
+              </div>
+            </div>
+            <p>
+			The following libraries or applications must be installed 
+			before running Kamailio with this module loaded:
+			</p>
+            <div class="itemizedlist">
+              <ul class="itemizedlist">
+                <li class="listitem">
+                  <p>
+                    <span class="emphasis">
+                      <em>none</em>
+                    </span>
+                  </p>
+                </li>
+              </ul>
+            </div>
+          </div>
+        </div>
+        <div class="section" title="3. Exported Parameters">
+          <div class="titlepage">
+            <div>
+              <div>
+                <h2 class="title"><a id="id2822133"></a>3. Exported Parameters</h2>
+              </div>
+            </div>
+          </div>
+          <div class="section" title="3.1. db_url (string)">
+            <div class="titlepage">
+              <div>
+                <div>
+                  <h3 class="title"><a id="id2815765"></a>3.1. <code class="varname">db_url</code> (string)</h3>
+                </div>
+              </div>
+            </div>
+            <p>
+			The URL for the database connection.
+	  </p>
+            <p>
+			<span class="emphasis"><em>
+				Default value is <span class="quote">“<span class="quote">mysql://openserro:openserro@localhost/openser</span>”</span>.
+		  </em></span>
+	  </p>
+            <div class="example">
+              <a id="id2815079"></a>
+              <p class="title">
+                <b>Example 1.1. Set <code class="varname">db_url</code> parameter</b>
+              </p>
+              <div class="example-contents">
+                <pre class="programlisting">...
+modparam("matrix", "db_url", "mysql://openserro:openserro@localhost/openser")
+...</pre>
+              </div>
+            </div>
+            <br class="example-break" />
+          </div>
+          <div class="section" title="3.2. matrix_table (string)">
+            <div class="titlepage">
+              <div>
+                <div>
+                  <h3 class="title"><a id="id2828576"></a>3.2. <code class="varname">matrix_table</code> (string)</h3>
+                </div>
+              </div>
+            </div>
+            <p>
+			The name of the table containing the matrix data.
+	  </p>
+            <p>
+			<span class="emphasis"><em>
+				Default value is <span class="quote">“<span class="quote">matrix</span>”</span>.
+		  </em></span>
+	  </p>
+            <div class="example">
+              <a id="id2811495"></a>
+              <p class="title">
+                <b>Example 1.2. Set <code class="varname">matrix_table</code> parameter</b>
+              </p>
+              <div class="example-contents">
+                <pre class="programlisting">...
+modparam("matrix", "matrix_table", "matrix")
+...</pre>
+              </div>
+            </div>
+            <br class="example-break" />
+          </div>
+          <div class="section" title="3.3. matrix_first_col (string)">
+            <div class="titlepage">
+              <div>
+                <div>
+                  <h3 class="title"><a id="id2830755"></a>3.3. <code class="varname">matrix_first_col</code> (string)</h3>
+                </div>
+              </div>
+            </div>
+            <p>
+			The name of the column containing the first row in the matrix.
+	  </p>
+            <p>
+			<span class="emphasis"><em>
+				Default value is <span class="quote">“<span class="quote">first</span>”</span>.
+		  </em></span>
+	  </p>
+            <div class="example">
+              <a id="id2795600"></a>
+              <p class="title">
+                <b>Example 1.3. Set <code class="varname">matrix_first_col</code> parameter</b>
+              </p>
+              <div class="example-contents">
+                <pre class="programlisting">...
+modparam("matrix", "matrix_first_col", "first")
+...</pre>
+              </div>
+            </div>
+            <br class="example-break" />
+          </div>
+          <div class="section" title="3.4. matrix_second_col (string)">
+            <div class="titlepage">
+              <div>
+                <div>
+                  <h3 class="title"><a id="id2831495"></a>3.4. <code class="varname">matrix_second_col</code> (string)</h3>
+                </div>
+              </div>
+            </div>
+            <p>
+			The name of the column containing the second row in the matrix.
+	  </p>
+            <p>
+			<span class="emphasis"><em>
+				Default value is <span class="quote">“<span class="quote">second</span>”</span>.
+		  </em></span>
+	  </p>
+            <div class="example">
+              <a id="id2794507"></a>
+              <p class="title">
+                <b>Example 1.4. Set <code class="varname">matrix_second_col</code> parameter</b>
+              </p>
+              <div class="example-contents">
+                <pre class="programlisting">...
+modparam("matrix", "matrix_second_col", "second")
+...</pre>
+              </div>
+            </div>
+            <br class="example-break" />
+          </div>
+          <div class="section" title="3.5. matrix_res_col (string)">
+            <div class="titlepage">
+              <div>
+                <div>
+                  <h3 class="title"><a id="id2811302"></a>3.5. <code class="varname">matrix_res_col</code> (string)</h3>
+                </div>
+              </div>
+            </div>
+            <p>
+			The name of the column containing the result ID to be used.
+	  </p>
+            <p>
+			<span class="emphasis"><em>
+				Default value is <span class="quote">“<span class="quote">res</span>”</span>.
+		  </em></span>
+	  </p>
+            <div class="example">
+              <a id="id2814720"></a>
+              <p class="title">
+                <b>Example 1.5. Set <code class="varname">matrix_res_col</code> parameter</b>
+              </p>
+              <div class="example-contents">
+                <pre class="programlisting">...
+modparam("matrix", "matrix_res_col", "res")
+...</pre>
+              </div>
+            </div>
+            <br class="example-break" />
+          </div>
+        </div>
+        <div class="section" title="4. Exported Functions">
+          <div class="titlepage">
+            <div>
+              <div>
+                <h2 class="title"><a id="id2793468"></a>4. Exported Functions</h2>
+              </div>
+            </div>
+          </div>
+          <div class="section" title="4.1.  matrix (string first, string second, string dstavp)">
+            <div class="titlepage">
+              <div>
+                <div>
+                  <h3 class="title"><a id="id2831283"></a>4.1. 
+			<code class="function">matrix (string first, string second, string dstavp)</code>
+		</h3>
+                </div>
+              </div>
+            </div>
+            <p>
+			Looks up the desired result ID in the matrix for the given column
+			and value and saves the result in dstavp. Returns false if the cell
+      			is not defined or when an error occured.
+			
+			Pseudo-variables or AVPs can be used for first and second.
+	  </p>
+            <div class="example">
+              <a id="id2815666"></a>
+              <p class="title">
+                <b>Example 1.6. <code class="function">matrix</code> usage</b>
+              </p>
+              <div class="example-contents">
+                <pre class="programlisting">...
+if (!matrix("$avp(first)", "$(second)", "$avp(route_tree)"))
+  $avp(route_tree) = $avp(frst); # default routing as defined for source number
+}
+cr_route("$avp(route_tree)", "$rd", "$rU", "$rU", "call_id");
+...</pre>
+              </div>
+            </div>
+            <br class="example-break" />
+          </div>
+        </div>
+        <div class="section" title="5. MI Commands">
+          <div class="titlepage">
+            <div>
+              <div>
+                <h2 class="title"><a id="id2824842"></a>5. <acronym class="acronym">MI</acronym> Commands</h2>
+              </div>
+            </div>
+          </div>
+          <div class="section" title="5.1.  reload_matrix">
+            <div class="titlepage">
+              <div>
+                <div>
+                  <h3 class="title"><a id="id2833119"></a>5.1. 
+				<code class="function">reload_matrix</code>
+	    </h3>
+                </div>
+              </div>
+            </div>
+            <p>
+				Reloads the internal matrix representation from the database.
+				This is necessary after entries in the database have been changed.
+	    </p>
+            <div class="example">
+              <a id="id2818370"></a>
+              <p class="title">
+                <b>Example 1.7. <code class="function">reload_matrix</code> usage</b>
+              </p>
+              <div class="example-contents">
+                <pre class="programlisting">...
+kamctl fifo reload_matrix
+...</pre>
+              </div>
+            </div>
+            <br class="example-break" />
+          </div>
+        </div>
+        <div class="section" title="6. Installation and Running">
+          <div class="titlepage">
+            <div>
+              <div>
+                <h2 class="title"><a id="id2807231"></a>6. Installation and Running</h2>
+              </div>
+            </div>
+          </div>
+          <div class="section" title="6.1. Database setup">
+            <div class="titlepage">
+              <div>
+                <div>
+                  <h3 class="title"><a id="id2832406"></a>6.1. Database setup</h3>
+                </div>
+              </div>
+            </div>
+            <p>
+				Before running Kamailio with matrix, you have to setup the database 
+				table where the module will read the matrix data. For that, if 
+				the table was not created by the installation script or you choose
+				to install everything by yourself you can use the matrix-create.sql
+				<acronym class="acronym">SQL</acronym> script in the database directories in the 
+				kamailio/scripts folder as template. 
+				Database, table, and column names can be set with module parameters so they
+				can be changed.
+				You can also find the complete database documentation on the
+				project webpage, http://www.kamailio.org/docs/db-tables/kamailio-db-devel.html.
+			</p>
+            <div class="example">
+              <a id="id2805497"></a>
+              <p class="title">
+                <b>Example 1.8. Example database content - matrix table</b>
+              </p>
+              <div class="example-contents">
+                <pre class="programlisting">...
++---------+--------------+---------+
+|  first  |    second    |   res   |
++---------+--------------+---------+
+|       1 |            9 |       2 |
+|       2 |           69 |       1 |
+|       2 |           13 |       3 |
++---------+--------------+---------+
+...</pre>
+              </div>
+            </div>
+            <br class="example-break" />
+          </div>
+        </div>
+      </div>
+      <div class="chapter" title="Chapter 2. Module parameter for database access.">
+        <div class="titlepage">
+          <div>
+            <div>
+              <h2 class="title"><a id="id2786765"></a>Chapter 2. Module parameter for database access.</h2>
+            </div>
+          </div>
+        </div>
+        <div class="toc">
+          <p>
+            <b>Table of Contents</b>
+          </p>
+          <dl>
+            <dt>
+              <span class="section">
+                <a href="#id2786706">1. <code class="varname">db_url</code> (String)</a>
+              </span>
+            </dt>
+            <dt>
+              <span class="section">
+                <a href="#id2828349">2. <code class="varname">matrix_table</code> (String)</a>
+              </span>
+            </dt>
+            <dt>
+              <span class="section">
+                <a href="#id2802229">3. <code class="varname">matrix_first_col</code> (string)</a>
+              </span>
+            </dt>
+            <dt>
+              <span class="section">
+                <a href="#id2779839">4. <code class="varname">matrix_second_col</code> (string)</a>
+              </span>
+            </dt>
+            <dt>
+              <span class="section">
+                <a href="#id2831629">5. <code class="varname">matrix_res_col</code> (string)</a>
+              </span>
+            </dt>
+          </dl>
+        </div>
+        <div class="section" title="1. db_url (String)">
+          <div class="titlepage">
+            <div>
+              <div>
+                <h2 class="title"><a id="id2786706"></a>1. <code class="varname">db_url</code> (String)</h2>
+              </div>
+            </div>
+          </div>
+          <p>URL to the database containing the data.</p>
+          <p>
+      <span class="emphasis"><em>Default value is <span class="quote">“<span class="quote">mysql://openserro:openserro@localhost/openser</span>”</span>.</em></span>
+    </p>
+          <div class="example">
+            <a id="id2786762"></a>
+            <p class="title">
+              <b>Example 2.1. Set <code class="varname">db_url</code> parameter</b>
+            </p>
+            <div class="example-contents">
+              <pre class="programlisting">...
+modparam("matrix", "db_url", "dbdriver://username:password@dbhost/dbname")
+...</pre>
+            </div>
+          </div>
+          <br class="example-break" />
+        </div>
+        <div class="section" title="2. matrix_table (String)">
+          <div class="titlepage">
+            <div>
+              <div>
+                <h2 class="title"><a id="id2828349"></a>2. <code class="varname">matrix_table</code> (String)</h2>
+              </div>
+            </div>
+          </div>
+          <p>Name of the matrix table for the matrix module.</p>
+          <p>
+      <span class="emphasis"><em>Default value is <span class="quote">“<span class="quote">matrix</span>”</span>.</em></span>
+    </p>
+          <div class="example">
+            <a id="id2784686"></a>
+            <p class="title">
+              <b>Example 2.2. Set <code class="varname">matrix_table</code> parameter</b>
+            </p>
+            <div class="example-contents">
+              <pre class="programlisting">...
+modparam("matrix", "matrix_table", "matrix")
+...</pre>
+            </div>
+          </div>
+          <br class="example-break" />
+        </div>
+        <div class="section" title="3. matrix_first_col (string)">
+          <div class="titlepage">
+            <div>
+              <div>
+                <h2 class="title"><a id="id2802229"></a>3. <code class="varname">matrix_first_col</code> (string)</h2>
+              </div>
+            </div>
+          </div>
+          <p>The row index in the matrix</p>
+          <div class="example">
+            <a id="id2823757"></a>
+            <p class="title">
+              <b>Example 2.3. Set <code class="varname">matrix_first_col</code> parameter</b>
+            </p>
+            <div class="example-contents">
+              <pre class="programlisting">...
+modparam("matrix", "matrix_first_col", "first")
+...</pre>
+            </div>
+          </div>
+          <br class="example-break" />
+        </div>
+        <div class="section" title="4. matrix_second_col (string)">
+          <div class="titlepage">
+            <div>
+              <div>
+                <h2 class="title"><a id="id2779839"></a>4. <code class="varname">matrix_second_col</code> (string)</h2>
+              </div>
+            </div>
+          </div>
+          <p>The column index in the matrix</p>
+          <div class="example">
+            <a id="id2824081"></a>
+            <p class="title">
+              <b>Example 2.4. Set <code class="varname">matrix_second_col</code> parameter</b>
+            </p>
+            <div class="example-contents">
+              <pre class="programlisting">...
+modparam("matrix", "matrix_second_col", "second")
+...</pre>
+            </div>
+          </div>
+          <br class="example-break" />
+        </div>
+        <div class="section" title="5. matrix_res_col (string)">
+          <div class="titlepage">
+            <div>
+              <div>
+                <h2 class="title"><a id="id2831629"></a>5. <code class="varname">matrix_res_col</code> (string)</h2>
+              </div>
+            </div>
+          </div>
+          <p>The resource contained in the matrix</p>
+          <div class="example">
+            <a id="id2784890"></a>
+            <p class="title">
+              <b>Example 2.5. Set <code class="varname">matrix_res_col</code> parameter</b>
+            </p>
+            <div class="example-contents">
+              <pre class="programlisting">...
+modparam("matrix", "matrix_res_col", "res")
+...</pre>
+            </div>
+          </div>
+          <br class="example-break" />
+        </div>
+      </div>
+    </div>
+  </body>
+</html>

+ 313 - 0
modules/matrix/doc/matrix.txt

@@ -0,0 +1,313 @@
+matrix Module
+
+Hardy Kahl
+
+   1&1 Internet AG
+
+Edited by
+
+Henning Westerholt
+
+   1&1 Internet AG
+   <[email protected]>
+
+   Copyright © 2008 1&1 Internet AG
+   Revision History
+   Revision $Revision: 4863 $ $Date: 2008-09-05 13:11:33 +0200 (Fri, 05
+                              Sep 2008) $
+     __________________________________________________________________
+
+   Table of Contents
+
+   1. Admin Guide
+
+        1. Overview
+        2. Dependencies
+
+              2.1. Kamailio Modules
+              2.2. External Libraries or Applications
+
+        3. Exported Parameters
+
+              3.1. db_url (string)
+              3.2. matrix_table (string)
+              3.3. matrix_first_col (string)
+              3.4. matrix_second_col (string)
+              3.5. matrix_res_col (string)
+
+        4. Exported Functions
+
+              4.1. matrix (string first, string second, string dstavp)
+
+        5. MI Commands
+
+              5.1. reload_matrix
+
+        6. Installation and Running
+
+              6.1. Database setup
+
+   2. Module parameter for database access.
+
+        1. db_url (String)
+        2. matrix_table (String)
+        3. matrix_first_col (string)
+        4. matrix_second_col (string)
+        5. matrix_res_col (string)
+
+   List of Examples
+
+   1.1. Set db_url parameter
+   1.2. Set matrix_table parameter
+   1.3. Set matrix_first_col parameter
+   1.4. Set matrix_second_col parameter
+   1.5. Set matrix_res_col parameter
+   1.6. matrix usage
+   1.7. reload_matrix usage
+   1.8. Example database content - matrix table
+   2.1. Set db_url parameter
+   2.2. Set matrix_table parameter
+   2.3. Set matrix_first_col parameter
+   2.4. Set matrix_second_col parameter
+   2.5. Set matrix_res_col parameter
+
+Chapter 1. Admin Guide
+
+   Table of Contents
+
+   1. Overview
+   2. Dependencies
+
+        2.1. Kamailio Modules
+        2.2. External Libraries or Applications
+
+   3. Exported Parameters
+
+        3.1. db_url (string)
+        3.2. matrix_table (string)
+        3.3. matrix_first_col (string)
+        3.4. matrix_second_col (string)
+        3.5. matrix_res_col (string)
+
+   4. Exported Functions
+
+        4.1. matrix (string first, string second, string dstavp)
+
+   5. MI Commands
+
+        5.1. reload_matrix
+
+   6. Installation and Running
+
+        6.1. Database setup
+
+1. Overview
+
+   The matrix module can be used to arbitrary lookup operations over an
+   array. One possible usecase is to define which routing tree should be
+   used depending on the preferred carrier of the source number and the
+   carrier id of the destination number. The matrix cells are read from a
+   database and can be reloaded using a FIFO command. You do not have to
+   define all matrix cells. The matrix can be sparse. Currently, the
+   implementation is designed for a small number of columns (they are
+   stored in a linked list). This does not scale well and has to be
+   replaced by more an efficient data data structure when needed.
+
+2. Dependencies
+
+   2.1. Kamailio Modules
+   2.2. External Libraries or Applications
+
+2.1. Kamailio Modules
+
+   The module depends on the following modules (in the other words the
+   listed modules must be loaded before this module):
+     * none
+
+2.2. External Libraries or Applications
+
+   The following libraries or applications must be installed before
+   running Kamailio with this module loaded:
+     * none
+
+3. Exported Parameters
+
+   3.1. db_url (string)
+   3.2. matrix_table (string)
+   3.3. matrix_first_col (string)
+   3.4. matrix_second_col (string)
+   3.5. matrix_res_col (string)
+
+3.1. db_url (string)
+
+   The URL for the database connection.
+
+   Default value is "mysql://openserro:openserro@localhost/openser".
+
+   Example 1.1. Set db_url parameter
+...
+modparam("matrix", "db_url", "mysql://openserro:openserro@localhost/openser")
+...
+
+3.2. matrix_table (string)
+
+   The name of the table containing the matrix data.
+
+   Default value is "matrix".
+
+   Example 1.2. Set matrix_table parameter
+...
+modparam("matrix", "matrix_table", "matrix")
+...
+
+3.3. matrix_first_col (string)
+
+   The name of the column containing the first row in the matrix.
+
+   Default value is "first".
+
+   Example 1.3. Set matrix_first_col parameter
+...
+modparam("matrix", "matrix_first_col", "first")
+...
+
+3.4. matrix_second_col (string)
+
+   The name of the column containing the second row in the matrix.
+
+   Default value is "second".
+
+   Example 1.4. Set matrix_second_col parameter
+...
+modparam("matrix", "matrix_second_col", "second")
+...
+
+3.5. matrix_res_col (string)
+
+   The name of the column containing the result ID to be used.
+
+   Default value is "res".
+
+   Example 1.5. Set matrix_res_col parameter
+...
+modparam("matrix", "matrix_res_col", "res")
+...
+
+4. Exported Functions
+
+   4.1. matrix (string first, string second, string dstavp)
+
+4.1.  matrix (string first, string second, string dstavp)
+
+   Looks up the desired result ID in the matrix for the given column and
+   value and saves the result in dstavp. Returns false if the cell is not
+   defined or when an error occured. Pseudo-variables or AVPs can be used
+   for first and second.
+
+   Example 1.6. matrix usage
+...
+if (!matrix("$avp(first)", "$(second)", "$avp(route_tree)"))
+  $avp(route_tree) = $avp(frst); # default routing as defined for source number
+}
+cr_route("$avp(route_tree)", "$rd", "$rU", "$rU", "call_id");
+...
+
+5. MI Commands
+
+   5.1. reload_matrix
+
+5.1.  reload_matrix
+
+   Reloads the internal matrix representation from the database. This is
+   necessary after entries in the database have been changed.
+
+   Example 1.7. reload_matrix usage
+...
+kamctl fifo reload_matrix
+...
+
+6. Installation and Running
+
+   6.1. Database setup
+
+6.1. Database setup
+
+   Before running Kamailio with matrix, you have to setup the database
+   table where the module will read the matrix data. For that, if the
+   table was not created by the installation script or you choose to
+   install everything by yourself you can use the matrix-create.sql SQL
+   script in the database directories in the kamailio/scripts folder as
+   template. Database, table, and column names can be set with module
+   parameters so they can be changed. You can also find the complete
+   database documentation on the project webpage,
+   http://www.kamailio.org/docs/db-tables/kamailio-db-devel.html.
+
+   Example 1.8. Example database content - matrix table
+...
++---------+--------------+---------+
+|  first  |    second    |   res   |
++---------+--------------+---------+
+|       1 |            9 |       2 |
+|       2 |           69 |       1 |
+|       2 |           13 |       3 |
++---------+--------------+---------+
+...
+
+Chapter 2. Module parameter for database access.
+
+   Table of Contents
+
+   1. db_url (String)
+   2. matrix_table (String)
+   3. matrix_first_col (string)
+   4. matrix_second_col (string)
+   5. matrix_res_col (string)
+
+1. db_url (String)
+
+   URL to the database containing the data.
+
+   Default value is "mysql://openserro:openserro@localhost/openser".
+
+   Example 2.1. Set db_url parameter
+...
+modparam("matrix", "db_url", "dbdriver://username:password@dbhost/dbname")
+...
+
+2. matrix_table (String)
+
+   Name of the matrix table for the matrix module.
+
+   Default value is "matrix".
+
+   Example 2.2. Set matrix_table parameter
+...
+modparam("matrix", "matrix_table", "matrix")
+...
+
+3. matrix_first_col (string)
+
+   The row index in the matrix
+
+   Example 2.3. Set matrix_first_col parameter
+...
+modparam("matrix", "matrix_first_col", "first")
+...
+
+4. matrix_second_col (string)
+
+   The column index in the matrix
+
+   Example 2.4. Set matrix_second_col parameter
+...
+modparam("matrix", "matrix_second_col", "second")
+...
+
+5. matrix_res_col (string)
+
+   The resource contained in the matrix
+
+   Example 2.5. Set matrix_res_col parameter
+...
+modparam("matrix", "matrix_res_col", "res")
+...

+ 42 - 0
modules/matrix/doc/matrix.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding='ISO-8859-1'?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+
+<!-- Include general documentation entities -->
+<!ENTITY % docentities SYSTEM "../../../docbook/entities.xml">
+%docentities;
+
+]>
+
+<book xmlns:xi="http://www.w3.org/2001/XInclude">
+	<bookinfo>
+	<title>matrix Module</title>
+	<authorgroup>
+		<author>
+		<firstname>Hardy</firstname>
+		<surname>Kahl</surname>
+		<affiliation><orgname>1&amp;1 Internet AG</orgname></affiliation>
+		</author>
+		<editor>
+		<firstname>Henning</firstname>
+		<surname>Westerholt</surname>
+		<affiliation><orgname>1&amp;1 Internet AG</orgname></affiliation>
+		<email>[email protected]</email>
+		</editor>
+	</authorgroup>
+	<copyright>
+		<year>2008</year>
+		<holder>1&amp;1 Internet AG</holder>
+	</copyright>
+	<revhistory>
+		<revision>
+		<revnumber>$Revision: 4863 $</revnumber>
+		<date>$Date: 2008-09-05 13:11:33 +0200 (Fri, 05 Sep 2008) $</date>
+		</revision>
+	</revhistory>
+	</bookinfo>
+	<toc></toc>
+        <xi:include href="matrix_admin.xml"/>
+        <xi:include href="matrix_db.xml"/>
+
+</book>

+ 240 - 0
modules/matrix/doc/matrix_admin.xml

@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding='ISO-8859-1'?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+
+<!-- Include general documentation entities -->
+<!ENTITY % docentities SYSTEM "../../../docbook/entities.xml">
+%docentities;
+
+]>
+<chapter>
+	<title>&adminguide;</title>
+	
+	<section>
+	<title>Overview</title>
+	<para>
+	The matrix module can be used to arbitrary lookup operations over an array.
+	One possible usecase is to define which routing tree should
+  	be used depending on the preferred carrier of the source number and
+  	the carrier id of the destination number.
+
+  	The matrix cells are read from a database and can be reloaded using
+  	a FIFO command.
+
+  	You do not have to define all matrix cells. The matrix can be sparse.
+
+  	Currently, the implementation is designed for a small number of
+  	columns (they are stored in a linked list). This does
+  	not scale well and has to be replaced by more an efficient data
+  	data structure when needed.
+
+	</para>
+	</section>
+
+	<section>
+		<title>Dependencies</title>
+		<section>
+			<title>&kamailio; Modules</title>
+			<para>
+			The module depends on the following modules (in the other words 
+			the listed modules must be loaded before this module):
+			</para>
+			<itemizedlist>
+			<listitem>
+				<para><emphasis>none</emphasis></para>
+			</listitem>
+			</itemizedlist>
+		</section>
+		<section>
+			<title>External Libraries or Applications</title>
+			<para>
+			The following libraries or applications must be installed 
+			before running &kamailio; with this module loaded:
+			</para>
+			<itemizedlist>
+				<listitem>
+				<para><emphasis>none</emphasis></para>
+				</listitem>
+			</itemizedlist>
+		</section>
+	</section>
+
+
+<section>
+	<title>Exported Parameters</title>
+	<section>
+		<title><varname>db_url</varname> (string)</title>
+	  <para>
+			The URL for the database connection.
+	  </para>
+	  <para>
+			<emphasis>
+				Default value is <quote>mysql://openserro:openserro@localhost/openser</quote>.
+		  </emphasis>
+	  </para>
+	  <example>
+		  <title>Set <varname>db_url</varname> parameter</title>
+		  <programlisting format="linespecific">
+...
+modparam("matrix", "db_url", "mysql://openserro:openserro@localhost/openser")
+...
+		  </programlisting>
+	  </example>
+  </section>
+	<section>
+		<title><varname>matrix_table</varname> (string)</title>
+	  <para>
+			The name of the table containing the matrix data.
+	  </para>
+	  <para>
+			<emphasis>
+				Default value is <quote>matrix</quote>.
+		  </emphasis>
+	  </para>
+	  <example>
+		  <title>Set <varname>matrix_table</varname> parameter</title>
+		  <programlisting format="linespecific">
+...
+modparam("matrix", "matrix_table", "matrix")
+...
+		  </programlisting>
+	  </example>
+  </section>
+	<section>
+		<title><varname>matrix_first_col</varname> (string)</title>
+	  <para>
+			The name of the column containing the first row in the matrix.
+	  </para>
+	  <para>
+			<emphasis>
+				Default value is <quote>first</quote>.
+		  </emphasis>
+	  </para>
+	  <example>
+		  <title>Set <varname>matrix_first_col</varname> parameter</title>
+		  <programlisting format="linespecific">
+...
+modparam("matrix", "matrix_first_col", "first")
+...
+		  </programlisting>
+	  </example>
+  </section>
+	<section>
+		<title><varname>matrix_second_col</varname> (string)</title>
+	  <para>
+			The name of the column containing the second row in the matrix.
+	  </para>
+	  <para>
+			<emphasis>
+				Default value is <quote>second</quote>.
+		  </emphasis>
+	  </para>
+	  <example>
+		  <title>Set <varname>matrix_second_col</varname> parameter</title>
+		  <programlisting format="linespecific">
+...
+modparam("matrix", "matrix_second_col", "second")
+...
+		  </programlisting>
+	  </example>
+  </section>
+	<section>
+		<title><varname>matrix_res_col</varname> (string)</title>
+	  <para>
+			The name of the column containing the result ID to be used.
+	  </para>
+	  <para>
+			<emphasis>
+				Default value is <quote>res</quote>.
+		  </emphasis>
+	  </para>
+	  <example>
+		  <title>Set <varname>matrix_res_col</varname> parameter</title>
+		  <programlisting format="linespecific">
+...
+modparam("matrix", "matrix_res_col", "res")
+...
+		  </programlisting>
+	  </example>
+  </section>
+</section>
+<section>
+	<title>Exported Functions</title>
+	<section>
+	  <title>
+			<function moreinfo="none">matrix (string first, string second, string dstavp)</function>
+		</title>
+		<para>
+			Looks up the desired result ID in the matrix for the given column
+			and value and saves the result in dstavp. Returns false if the cell
+      			is not defined or when an error occured.
+			
+			Pseudo-variables or AVPs can be used for first and second.
+	  </para>
+		<example>
+			<title><function>matrix</function> usage</title>
+			<programlisting format="linespecific">
+...
+if (!matrix("$avp(first)", "$(second)", "$avp(route_tree)"))
+  $avp(route_tree) = $avp(frst); # default routing as defined for source number
+}
+cr_route("$avp(route_tree)", "$rd", "$rU", "$rU", "call_id");
+...
+			</programlisting>
+	  </example>
+	</section>
+</section>
+<section>
+	<title><acronym>MI</acronym> Commands</title>
+	<section>
+	    <title>
+				<function moreinfo="none">reload_matrix</function>
+	    </title>
+	    <para>
+				Reloads the internal matrix representation from the database.
+				This is necessary after entries in the database have been changed.
+	    </para>
+			<example>
+				<title><function>reload_matrix</function> usage</title>
+				<programlisting format="linespecific">
+...
+kamctl fifo reload_matrix
+...
+				</programlisting>
+	    </example>
+	</section>
+	</section>
+  <section>
+		<title>Installation and Running</title>
+		<section>
+			<title>Database setup</title>
+			<para>
+				Before running &kamailio; with matrix, you have to setup the database 
+				table where the module will read the matrix data. For that, if 
+				the table was not created by the installation script or you choose
+				to install everything by yourself you can use the matrix-create.sql
+				<acronym>SQL</acronym> script in the database directories in the 
+				kamailio/scripts folder as template. 
+				Database, table, and column names can be set with module parameters so they
+				can be changed.
+				You can also find the complete database documentation on the
+				project webpage, &kamailiodbdocs;.
+			</para>
+
+			<example>
+				<title>Example database content - matrix table</title>
+				<programlisting format="linespecific">
+...
++---------+--------------+---------+
+|  first  |    second    |   res   |
++---------+--------------+---------+
+|       1 |            9 |       2 |
+|       2 |           69 |       1 |
+|       2 |           13 |       3 |
++---------+--------------+---------+
+...
+				</programlisting>
+			</example>
+		</section>
+	</section>
+</chapter>

+ 79 - 0
modules/matrix/doc/matrix_db.xml

@@ -0,0 +1,79 @@
+<!--
+WARNING:
+This file was autogenerated from the XML source file
+../../modules/matrix/doc/kamailio-matrix.xml.
+It can be regenerated by running 'make dbdoc' in the db/schema
+directory of the source code. You need to have xsltproc and
+docbook-xsl stylesheets installed.
+ALL CHANGES DONE HERE WILL BE LOST IF THE FILE IS REGENERATED
+-->
+
+<chapter>
+  <title>Module parameter for database access.</title>
+  <section>
+    <title><varname>db_url</varname> (String)</title>
+    <para>URL to the database containing the data.</para>
+    <para>
+      <emphasis>Default value is <quote>mysql://openserro:openserro@localhost/openser</quote>.</emphasis>
+    </para>
+    <example>
+      <title>Set <varname>db_url</varname> parameter</title>
+      <programlisting format="linespecific">
+...
+modparam("matrix", "db_url", "dbdriver://username:password@dbhost/dbname")
+...
+</programlisting>
+    </example>
+  </section>
+  <section>
+    <title><varname>matrix_table</varname> (String)</title>
+    <para>Name of the matrix table for the matrix module.</para>
+    <para>
+      <emphasis>Default value is <quote>matrix</quote>.</emphasis>
+    </para>
+    <example>
+      <title>Set <varname>matrix_table</varname> parameter</title>
+      <programlisting format="linespecific">
+...
+modparam("matrix", "matrix_table", "matrix")
+...
+</programlisting>
+    </example>
+  </section>
+  <section>
+    <title><varname>matrix_first_col</varname> (string)</title>
+    <para>The row index in the matrix</para>
+    <example>
+      <title>Set <varname>matrix_first_col</varname> parameter</title>
+      <programlisting format="linespecific">
+...
+modparam("matrix", "matrix_first_col", "first")
+...
+</programlisting>
+    </example>
+  </section>
+  <section>
+    <title><varname>matrix_second_col</varname> (string)</title>
+    <para>The column index in the matrix</para>
+    <example>
+      <title>Set <varname>matrix_second_col</varname> parameter</title>
+      <programlisting format="linespecific">
+...
+modparam("matrix", "matrix_second_col", "second")
+...
+</programlisting>
+    </example>
+  </section>
+  <section>
+    <title><varname>matrix_res_col</varname> (string)</title>
+    <para>The resource contained in the matrix</para>
+    <example>
+      <title>Set <varname>matrix_res_col</varname> parameter</title>
+      <programlisting format="linespecific">
+...
+modparam("matrix", "matrix_res_col", "res")
+...
+</programlisting>
+    </example>
+  </section>
+</chapter>

+ 621 - 0
modules/matrix/matrix.c

@@ -0,0 +1,621 @@
+/*
+ * $Id: matrix.c 4978 2008-09-23 14:25:02Z henningw $
+ *
+ * Copyright (C) 2007 1&1 Internet AG
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <string.h>
+
+#include "../../mem/shm_mem.h"
+#include "../../sr_module.h"
+#include "../../mi/mi.h"
+#include "../../mem/mem.h"
+#include "../../usr_avp.h"
+#include "../../locking.h"
+#include "../../error.h"
+#include "../../ut.h"
+#include "../../mod_fix.h"
+
+#include "db_matrix.h"
+
+MODULE_VERSION
+
+
+
+
+#define MAXCOLS 1000
+
+
+
+
+str matrix_db_url = str_init(DEFAULT_RODB_URL);
+
+
+
+
+/**
+ * Generic parameter that holds a string, an int or an pseudo-variable
+ * @todo replace this with gparam_t
+ */
+struct multiparam_t {
+	enum {
+		MP_INT,
+		MP_STR,
+		MP_AVP,
+		MP_PVE,
+	} type;
+	union {
+		int n;
+		str s;
+		struct {
+			unsigned short flags;
+			int_str name;
+		} a;
+		pv_elem_t *p;
+	} u;
+};
+
+
+
+
+/* ---- fixup functions: */
+static int matrix_fixup(void** param, int param_no);
+
+/* ---- exported commands: */
+static int lookup_matrix(struct sip_msg *msg, struct multiparam_t *_first, struct multiparam_t *_second, struct multiparam_t *_dstavp);
+
+/* ---- module init functions: */
+static int mod_init(void);
+static int child_init(int rank);
+static int mi_child_init(void);
+static void mod_destroy(void);
+
+/* --- fifo functions */
+struct mi_root * mi_reload_matrix(struct mi_root* cmd, void* param);  /* usage: kamctl fifo reload_matrix */
+
+
+
+
+static cmd_export_t cmds[]={
+	{ "matrix", (cmd_function)lookup_matrix, 3, matrix_fixup, 0, REQUEST_ROUTE | FAILURE_ROUTE },
+	{ 0, 0, 0, 0, 0, 0}
+};
+
+
+
+
+static param_export_t params[] = {
+	matrix_DB_URL
+	matrix_DB_TABLE
+	matrix_DB_COLS
+	{ 0, 0, 0}
+};
+
+
+
+
+/* Exported MI functions */
+static mi_export_t mi_cmds[] = {
+	{ "reload_matrix", mi_reload_matrix, MI_NO_INPUT_FLAG, 0, mi_child_init },
+	{ 0, 0, 0, 0, 0}
+};
+
+
+
+
+struct module_exports exports= {
+	"matrix",
+	DEFAULT_DLFLAGS,
+	cmds,
+	params,
+	0,
+	mi_cmds,
+	0,
+	0,
+	mod_init,
+	0,
+	mod_destroy,
+	child_init
+};
+
+
+
+
+struct first_t {
+  struct first_t *next;
+	int id;
+	short int second_list[MAXCOLS+1];
+};
+
+
+
+
+struct matrix_t {
+  struct first_t *head;
+};
+
+
+
+
+static gen_lock_t *lock = NULL;
+static struct matrix_t *matrix = NULL;
+
+
+
+
+/**
+ * fixes the module functions' parameters if it is a phone number.
+ * supports string, pseudo-variables and AVPs.
+ *
+ * @param param the parameter
+ *
+ * @return 0 on success, -1 on failure
+ */
+static int mp_fixup(void ** param) {
+	pv_spec_t avp_spec;
+	struct multiparam_t *mp;
+	str s;
+
+	mp = (struct multiparam_t *)pkg_malloc(sizeof(struct multiparam_t));
+	if (mp == NULL) {
+		LM_ERR("out of pkg memory\n");
+		return -1;
+	}
+	memset(mp, 0, sizeof(struct multiparam_t));
+	
+	s.s = (char *)(*param);
+	s.len = strlen(s.s);
+
+	if (s.s[0]!='$') {
+		/* This is string */
+		mp->type=MP_STR;
+		mp->u.s=s;
+	}
+	else {
+		/* This is a pseudo-variable */
+		if (pv_parse_spec(&s, &avp_spec)==0) {
+			LM_ERR("pv_parse_spec failed for '%s'\n", (char *)(*param));
+			pkg_free(mp);
+			return -1;
+		}
+		if (avp_spec.type==PVT_AVP) {
+			/* This is an AVP - could be an id or name */
+			mp->type=MP_AVP;
+			if(pv_get_avp_name(0, &(avp_spec.pvp), &(mp->u.a.name), &(mp->u.a.flags))!=0) {
+				LM_ERR("Invalid AVP definition <%s>\n", (char *)(*param));
+				pkg_free(mp);
+				return -1;
+			}
+		} else {
+			mp->type=MP_PVE;
+			if(pv_parse_format(&s, &(mp->u.p))<0) {
+				LM_ERR("pv_parse_format failed for '%s'\n", (char *)(*param));
+				pkg_free(mp);
+				return -1;
+			}
+		}
+	}
+	*param = (void*)mp;
+
+	return 0;
+}
+
+
+
+
+/**
+ * fixes the module functions' parameters in case of AVP names.
+ *
+ * @param param the parameter
+ *
+ * @return 0 on success, -1 on failure
+ */
+static int avp_name_fixup(void ** param) {
+	pv_spec_t avp_spec;
+	struct multiparam_t *mp;
+	str s;
+
+	s.s = (char *)(*param);
+	s.len = strlen(s.s);
+	if (s.len <= 0) return -1;
+	if (pv_parse_spec(&s, &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
+		LM_ERR("Malformed or non AVP definition <%s>\n", (char *)(*param));
+		return -1;
+	}
+	
+	mp = (struct multiparam_t *)pkg_malloc(sizeof(struct multiparam_t));
+	if (mp == NULL) {
+		LM_ERR("out of pkg memory\n");
+		return -1;
+	}
+	memset(mp, 0, sizeof(struct multiparam_t));
+	
+	mp->type=MP_AVP;
+	if(pv_get_avp_name(0, &(avp_spec.pvp), &(mp->u.a.name), &(mp->u.a.flags))!=0) {
+		LM_ERR("Invalid AVP definition <%s>\n", (char *)(*param));
+		pkg_free(mp);
+		return -1;
+	}
+
+	*param = (void*)mp;
+	
+	return 0;
+}
+
+
+
+
+static int matrix_fixup(void** param, int param_no)
+{
+	if (param_no == 1) {
+		/* source id */
+		if (mp_fixup(param) < 0) {
+			LM_ERR("cannot fixup parameter %d\n", param_no);
+			return -1;
+		}
+	}
+	else if (param_no == 2) {
+		/* destination id */
+		if (mp_fixup(param) < 0) {
+			LM_ERR("cannot fixup parameter %d\n", param_no);
+			return -1;
+		}
+	}
+	else if (param_no == 3) {
+		/* destination avp name */
+		if (avp_name_fixup(param) < 0) {
+			LM_ERR("cannot fixup parameter %d\n", param_no);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+
+
+
+static void matrix_clear(void)
+{
+	struct first_t *srcitem;
+	if (matrix) {
+		while (matrix->head) {
+			srcitem = matrix->head;
+			matrix->head = srcitem->next;
+			shm_free(srcitem);
+		}
+	}
+}
+
+
+
+
+static int matrix_insert(int first, short int second, int res)
+{
+	struct first_t *srcitem;
+	int i;
+
+	if ((second<0) || (second>MAXCOLS)) {
+		LM_ERR("invalid second value %d\n", second);
+		return -1;
+	}
+	LM_DBG("searching for %d, %d\n", first, second);
+	if (matrix) {
+		srcitem = matrix->head;
+		while (srcitem) {
+			if (srcitem->id == first) {
+				srcitem->second_list[second] = res;
+				LM_DBG("inserted (%d, %d, %d)", first, second, res);
+				return 0;
+			}
+			srcitem = srcitem->next;
+		}
+		/* not found */
+		srcitem = shm_malloc(sizeof(struct first_t));
+		if (srcitem == NULL) {
+			LM_ERR("out of shared memory.");
+			return -1;
+		}
+		memset(srcitem, 0, sizeof(struct first_t));
+
+		/* Mark all new cells as empty */
+		for (i=0; i<=MAXCOLS; i++) srcitem->second_list[i] = -1;
+
+		srcitem->next = matrix->head;
+		srcitem->id = first;
+		srcitem->second_list[second] = res;
+		matrix->head = srcitem;
+	}
+
+	LM_DBG("inserted new row for (%d, %d, %d)", first, second, res);
+	return 0;
+}
+
+
+
+
+/* Returns the res id if the matrix contains an entry for the given indices, -1 otherwise.
+ */
+static int internal_lookup(int first, short int second)
+{
+	struct first_t *item;
+
+	if ((second<0) || (second>MAXCOLS)) {
+		LM_ERR("invalid second value %d\n", second);
+		return -1;
+	}
+
+	if (matrix) {
+		item = matrix->head;
+		while (item) {
+			if (item->id == first) {
+				return item->second_list[second];
+			}
+			item = item->next;
+		}
+	}
+
+	return -1;
+}
+
+
+
+
+static int lookup_matrix(struct sip_msg *msg, struct multiparam_t *_srctree, struct multiparam_t *_second, struct multiparam_t *_dstavp)
+{
+	int first;
+	int second;
+	struct usr_avp *avp;
+	int_str avp_val;
+
+	switch (_srctree->type) {
+	case MP_INT:
+		first = _srctree->u.n;
+		break;
+	case MP_AVP:
+		avp = search_first_avp(_srctree->u.a.flags, _srctree->u.a.name, &avp_val, 0);
+		if (!avp) {
+			LM_ERR("cannot find srctree AVP\n");
+			return -1;
+		}
+		if ((avp->flags&AVP_VAL_STR)) {
+			LM_ERR("cannot process string value in srctree AVP\n");
+			return -1;
+		}
+		else first = avp_val.n;
+		break;
+	default:
+		LM_ERR("invalid srctree type\n");
+		return -1;
+	}
+
+	switch (_second->type) {
+	case MP_INT:
+		second = _second->u.n;
+		break;
+	case MP_AVP:
+		avp = search_first_avp(_second->u.a.flags, _second->u.a.name, &avp_val, 0);
+		if (!avp) {
+			LM_ERR("cannot find second_value AVP\n");
+			return -1;
+		}
+		if ((avp->flags&AVP_VAL_STR)) {
+			LM_ERR("cannot process string value in second_value AVP\n");
+			return -1;
+		}
+		else second = avp_val.n;
+		break;
+	default:
+		LM_ERR("invalid second_value type\n");
+		return -1;
+	}
+	
+
+	/* critical section start: avoids dirty reads when updating d-tree */
+	lock_get(lock);
+
+	avp_val.n=internal_lookup(first, second);
+
+	/* critical section end */
+	lock_release(lock);
+
+	if (avp_val.n<0) {
+		LM_INFO("lookup failed\n");
+		return -1;
+	}
+
+	/* set avp ! */
+	if (add_avp(_dstavp->u.a.flags, _dstavp->u.a.name, avp_val)<0) {
+		LM_ERR("add AVP failed\n");
+		return -1;
+	}
+	LM_INFO("result from lookup: %d\n", avp_val.n);
+	return 1;
+}
+
+
+
+
+/**
+ * Rebuild matrix using database entries
+ * \return negative on failure, positive on success, indicating the number of matrix entries
+ */
+static int db_reload_matrix(void)
+{
+	db_key_t columns[3] = { &matrix_first_col, &matrix_second_col, &matrix_res_col };
+	db1_res_t *res;
+	int i;
+	int n = 0;
+	
+	if (matrix_dbf.use_table(matrix_dbh, &matrix_table) < 0) {
+		LM_ERR("cannot use table '%.*s'.\n", matrix_table.len, matrix_table.s);
+		return -1;
+	}
+	if (matrix_dbf.query(matrix_dbh, NULL, NULL, NULL, columns, 0, 3, NULL, &res) < 0) {
+		LM_ERR("error while executing query.\n");
+		return -1;
+	}
+
+	/* critical section start: avoids dirty reads when updating d-tree */
+	lock_get(lock);
+
+	matrix_clear();
+
+	if (RES_COL_N(res) > 2) {
+		for(i = 0; i < RES_ROW_N(res); i++) {
+			if ((!RES_ROWS(res)[i].values[0].nul) && (!RES_ROWS(res)[i].values[1].nul)) {
+				if ((RES_ROWS(res)[i].values[0].type == DB1_INT) &&
+						(RES_ROWS(res)[i].values[1].type == DB1_INT) &&
+						(RES_ROWS(res)[i].values[2].type == DB1_INT)) {
+					matrix_insert(RES_ROWS(res)[i].values[0].val.int_val, RES_ROWS(res)[i].values[1].val.int_val, RES_ROWS(res)[i].values[2].val.int_val);
+					n++;
+				}
+				else {
+					LM_ERR("got invalid result type from query.\n");
+				}
+			}
+		}
+	}
+
+	/* critical section end */
+	lock_release(lock);
+
+	matrix_dbf.free_result(matrix_dbh, res);
+
+	LM_INFO("loaded %d matrix entries.", n);
+	return n;
+}
+
+
+
+
+static int init_shmlock(void)
+{
+	lock = lock_alloc();
+	if (!lock) {
+		LM_CRIT("cannot allocate memory for lock.\n");
+		return -1;
+	}
+	if (lock_init(lock) == 0) {
+		LM_CRIT("cannot initialize lock.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+
+
+static void destroy_shmlock(void)
+{
+	if (lock) {
+		lock_destroy(lock);
+		lock_dealloc((void *)lock);
+		lock = NULL;
+	}
+}
+
+
+
+
+struct mi_root * mi_reload_matrix(struct mi_root* cmd, void* param)
+{
+	struct mi_root * tmp = NULL;
+	if(db_reload_matrix() >= 0) {
+		tmp = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
+	} else {
+		tmp = init_mi_tree( 500, "cannot reload matrix", 24);
+	}
+
+	return tmp;
+}
+
+
+
+
+static int init_matrix(void)
+{
+	matrix = shm_malloc(sizeof(struct matrix_t));
+	if (!matrix) {
+		LM_ERR("out of shared memory\n");
+		return -1;
+	}
+	memset(matrix, 0, sizeof(struct matrix_t));
+	if (db_reload_matrix() < 0) {
+		LM_ERR("cannot populate matrix\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+
+
+static void destroy_matrix(void)
+{
+	if (matrix) {
+		matrix_clear();
+		shm_free(matrix);
+	}
+}
+
+
+
+
+static int mod_init(void)
+{
+	matrix_db_vars();
+
+	if (init_shmlock() != 0) return -1;
+	if (matrix_db_init() != 0) return -1;
+	if (matrix_db_open() != 0) return -1;
+	if (init_matrix() != 0) return -1;
+	matrix_db_close();
+	return 0;
+}
+
+
+
+
+static int child_init(int rank)
+{
+	if (matrix_db_open() != 0) return -1;
+	return 0;
+}
+
+
+
+
+static int mi_child_init(void)
+{
+	if (matrix_db_open() != 0) return -1;
+	return 0;
+}
+
+
+
+
+static void mod_destroy(void)
+{
+	destroy_matrix();
+	destroy_shmlock();
+	matrix_db_close();
+}

+ 16 - 4
utils/kamctl/db_berkeley/kamailio/version

@@ -50,20 +50,30 @@ globalblacklist|
 globalblacklist|1
 globalblacklist|1
 grp|
 grp|
 grp|2
 grp|2
-gw|
-gw|10
+METADATA_DEFAULTS
+NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NULL|NIL|0|NULL
 htable|
 htable|
 htable|1
 htable|1
 imc_members|
 imc_members|
 imc_members|1
 imc_members|1
 imc_rooms|
 imc_rooms|
 imc_rooms|1
 imc_rooms|1
-lcr|
-lcr|3
+METADATA_DEFAULTS
+NIL|NIL|NULL|NULL|NIL|NIL
+lcr_gw|
+lcr_gw|1
+lcr_rule|
+lcr_rule|1
+lcr_rule_target|
+lcr_rule_target|1
 location|
 location|
 location|1004
 location|1004
+matrix|
+matrix|1
 missed_calls|
 missed_calls|
 missed_calls|3
 missed_calls|3
+mtree|
+mtree|1
 pdt|
 pdt|
 pdt|1
 pdt|1
 presentity|
 presentity|
@@ -88,6 +98,8 @@ subscriber|
 subscriber|6
 subscriber|6
 trusted|
 trusted|
 trusted|5
 trusted|5
+uacreg|
+uacreg|1
 uri|
 uri|
 uri|1
 uri|1
 userblacklist|
 userblacklist|

+ 8 - 2
utils/kamctl/dbtext/kamailio/version

@@ -20,13 +20,18 @@ dr_gw_lists:1
 dr_rules:3
 dr_rules:3
 globalblacklist:1
 globalblacklist:1
 grp:2
 grp:2
-gw:10
+id(int,auto) lcr_id(int) gw_name(string) grp_id(int) ip_addr(string) hostname(string,null) port(int,null) uri_scheme(int,null) transport(int,null) strip(int,null) tag(string,null) weight(int,null) flags(int) defunct(int,null) 
 htable:1
 htable:1
 imc_members:1
 imc_members:1
 imc_rooms:1
 imc_rooms:1
-lcr:3
+id(int,auto) lcr_id(int) prefix(string,null) from_uri(string,null) grp_id(int) priority(int) 
+lcr_gw:1
+lcr_rule:1
+lcr_rule_target:1
 location:1004
 location:1004
+matrix:1
 missed_calls:3
 missed_calls:3
+mtree:1
 pdt:1
 pdt:1
 presentity:3
 presentity:3
 pua:6
 pua:6
@@ -39,6 +44,7 @@ sip_trace:2
 speed_dial:2
 speed_dial:2
 subscriber:6
 subscriber:6
 trusted:5
 trusted:5
+uacreg:1
 uri:1
 uri:1
 userblacklist:1
 userblacklist:1
 usr_preferences:2
 usr_preferences:2

+ 9 - 0
utils/kamctl/mysql/matrix-create.sql

@@ -0,0 +1,9 @@
+INSERT INTO version (table_name, table_version) values ('matrix','1');
+CREATE TABLE matrix (
+    first INT(10) NOT NULL,
+    second SMALLINT(10) NOT NULL,
+    res INT(10) NOT NULL
+) ENGINE=MyISAM;
+
+CREATE INDEX matrix_idx ON matrix (first, second);
+

+ 17 - 0
utils/kamctl/oracle/matrix-create.sql

@@ -0,0 +1,17 @@
+INSERT INTO version (table_name, table_version) values ('matrix','1');
+CREATE TABLE matrix (
+    first NUMBER(10),
+    second NUMBER(5),
+    res NUMBER(10)
+);
+
+CREATE OR REPLACE TRIGGER matrix_tr
+before insert on matrix FOR EACH ROW
+BEGIN
+  auto_id(:NEW.id);
+END matrix_tr;
+/
+BEGIN map2users('matrix'); END;
+/
+CREATE INDEX matrix_matrix_idx  ON matrix (first, second);
+

+ 9 - 0
utils/kamctl/postgres/matrix-create.sql

@@ -0,0 +1,9 @@
+INSERT INTO version (table_name, table_version) values ('matrix','1');
+CREATE TABLE matrix (
+    first INTEGER NOT NULL,
+    second SMALLINT NOT NULL,
+    res INTEGER NOT NULL
+);
+
+CREATE INDEX matrix_matrix_idx ON matrix (first, second);
+