Sfoglia il codice sorgente

tmp:interconnect_route_modules: new interconnectroute module

Richard Good 11 anni fa
parent
commit
1821adaf93

+ 17 - 0
modules/interconnectroute/Makefile

@@ -0,0 +1,17 @@
+# $Id: Makefile,v 1.6 2003/05/23 15:43:43 andrei Exp $
+#
+# carrierroute Makefile
+#
+# WARNING: do not run this directly, it should be run by the master Makefile
+
+include ../../Makefile.defs
+
+auto_gen=
+NAME=interconnectroute.so
+
+DEFS+=-DKAMAILIO_MOD_INTERFACE
+
+SERLIBPATH=../../lib
+SER_LIBS+=$(SERLIBPATH)/trie/trie $(SERLIBPATH)/srdb1/srdb1 $(SERLIBPATH)/kmi/kmi $(SERLIBPATH)/kcore/kcore
+
+include ../../Makefile.modules

+ 14 - 0
modules/interconnectroute/config.h

@@ -0,0 +1,14 @@
+/* 
+ * File:   config.h
+ * Author: jaybeepee
+ *
+ * Created on 15 October 2014, 3:14 PM
+ */
+
+#ifndef CONFIG_H
+#define	CONFIG_H
+
+#define DEFAULT_IXDB_URL "mysql://root:[email protected]/scscf"
+
+#endif	/* CONFIG_H */
+

+ 165 - 0
modules/interconnectroute/db.c

@@ -0,0 +1,165 @@
+#include "db.h"
+#include "route_data.h"
+
+db1_con_t * interconnectroute_dbh = NULL;
+db_func_t interconnectroute_dbf;
+
+static char *query_fmt = "select N.OPERATOR_KEY, T.TRUNK_ID, T.PRIORITY, T.IPV4, T.EXTERNAL_TRUNK_ID "
+	"from operator_number N left join operator_trunk T on N.OPERATOR_KEY=T.OPERATOR_KEY "
+	"where %.*s >= CAST(NUMBER_START AS UNSIGNED) and %.*s <= CAST(NUMBER_END AS UNSIGNED) ORDER BY T.PRIORITY DESC";
+static char query[QUERY_LEN];
+
+str interconnectnumber_table = str_init("operator_number");
+
+/* table version */
+const unsigned int interconnectroute_version = 1;
+
+str interconnecttrunk_table = str_init("operator_trunk");
+
+/*
+ * Closes the DB connection.
+ */
+void interconnectroute_db_close(void) {
+    if (interconnectroute_dbh) {
+	interconnectroute_dbf.close(interconnectroute_dbh);
+	interconnectroute_dbh = NULL;
+    }
+}
+
+
+int interconnectroute_db_init(void) {
+    if (!interconnectroute_db_url.s || !interconnectroute_db_url.len) {
+	LM_ERR("you have to set the db_url module parameter.\n");
+	return -1;
+    }
+    if (db_bind_mod(&interconnectroute_db_url, &interconnectroute_dbf) < 0) {
+	LM_ERR("can't bind database module.\n");
+	return -1;
+    }
+    if ((interconnectroute_dbh = interconnectroute_dbf.init(&interconnectroute_db_url)) == NULL) {
+	LM_ERR("can't connect to database using [%.*s]\n", interconnectroute_db_url.len, interconnectroute_db_url.s);
+	return -1;
+    }
+    if (
+	    (db_check_table_version(&interconnectroute_dbf, interconnectroute_dbh, &interconnectnumber_table, interconnectroute_version) < 0) ||
+	    (db_check_table_version(&interconnectroute_dbf, interconnectroute_dbh, &interconnecttrunk_table, interconnectroute_version) < 0)) {
+	LM_ERR("during table version check.\n");
+	interconnectroute_db_close();
+	return -1;
+    }
+    interconnectroute_db_close();
+    return 0;
+}
+
+
+int interconnectroute_db_open(void) {
+    if (interconnectroute_dbh) {
+	interconnectroute_dbf.close(interconnectroute_dbh);
+    }
+    if ((interconnectroute_dbh = interconnectroute_dbf.init(&interconnectroute_db_url)) == NULL) {
+	LM_ERR("can't connect to database.\n");
+	return -1;
+    }
+    return 0;
+}
+
+int get_routes(str* dst_number, route_data_t** route_data) {
+    int i,n, priority;
+    db1_res_t* route_rs;
+    db_row_t* route_row;
+    db_val_t* route_vals;
+    str query_s, operator_key, trunk_id, external_trunk_id, gateway_ipv4;
+    route_data_t* new_route;
+    ix_route_list_t* route_list = new_route_list();
+    int num_rows;
+    
+
+    if (strlen(query_fmt) + dst_number->len > QUERY_LEN) {
+	LM_ERR("query too big\n");
+	return -1;
+    }
+    snprintf(query, QUERY_LEN, query_fmt, dst_number->len, dst_number->s, dst_number->len, dst_number->s);
+    query_s.s = query;
+    query_s.len = strlen(query);
+
+    LM_DBG("QUERY IS: [%s]\n", query);
+
+    if (interconnectroute_dbf.raw_query(interconnectroute_dbh, &query_s, &route_rs) != 0) {
+	LM_ERR("Unable to query DB for interconnect routes with number [%.*s]\n", dst_number->len, dst_number->s);
+	interconnectroute_dbf.free_result(interconnectroute_dbh, route_rs);
+    }
+
+    LM_DBG("Received route results [%d]\n", RES_ROW_N(route_rs));
+    if (RES_ROW_N(route_rs) <= 0) {
+	LM_DBG("No routes found for number [%.*s]\n", dst_number->len, dst_number->s);
+	return -1;
+    } else {
+	n = 0;
+	do {
+	    n++;
+	    LM_DBG("looping through route recordset [%d]\n", n);
+	    for (i = 0; i < RES_ROW_N(route_rs); i++) {
+		route_row = RES_ROWS(route_rs) + i;
+		route_vals = ROW_VALUES(route_row);
+
+		if (!VAL_NULL(route_vals)) {
+		    operator_key.s = (char*) VAL_STRING(route_vals);
+		    operator_key.len = strlen(operator_key.s);
+		    LM_DBG("Received route for operator key: [%.*s]\n", operator_key.len, operator_key.s);
+		}
+		if (!VAL_NULL(route_vals+1)) {
+		    trunk_id.s = (char*) VAL_STRING(route_vals+1);
+		    trunk_id.len = strlen(trunk_id.s);
+		    LM_DBG("Trunk is: [%.*s]\n", trunk_id.len, trunk_id.s);
+		}
+		if (!VAL_NULL(route_vals+2)) {
+		    priority = VAL_INT(route_vals+2);
+		    LM_DBG("Priority is: [%d]\n", priority);
+		}
+		if (!VAL_NULL(route_vals+3)) {
+		    gateway_ipv4.s = (char*) VAL_STRING(route_vals+3);
+		    gateway_ipv4.len = strlen(gateway_ipv4.s);
+		    LM_DBG("Gateway IP for trunk to this operator is: [%.*s]\n", gateway_ipv4.len, gateway_ipv4.s);
+		}
+		if (!VAL_NULL(route_vals+4)) {
+		    external_trunk_id.s = (char*) VAL_STRING(route_vals+4);
+		    external_trunk_id.len = strlen(external_trunk_id.s);
+		    LM_DBG("External trunk ID: [%.*s]\n", external_trunk_id.len, external_trunk_id.s);
+		}
+		
+		new_route = new_route_data(&operator_key, &trunk_id, priority, &gateway_ipv4, &external_trunk_id);
+		if (!new_route) {
+		    LM_DBG("Could not get new route... continuing\n");
+		    continue;
+		}
+		
+		if (!add_route(route_list, new_route)) {
+		    LM_DBG("unable to add route.....\n");
+		    continue;
+		}
+		
+		LM_DBG("route list now has %d elements\n", route_list->count);
+		
+		
+	    }
+	    if (DB_CAPABILITY(interconnectroute_dbf, DB_CAP_FETCH)) {
+		if (interconnectroute_dbf.fetch_result(interconnectroute_dbh, &route_rs, 2000/*ul_fetch_rows*/) < 0) {
+		    LM_ERR("fetching rows failed\n");
+		    interconnectroute_dbf.free_result(interconnectroute_dbh, route_rs);
+		    return -1;
+		}
+	    } else {
+		break;
+	    }
+	} while (RES_ROW_N(route_rs) > 0);
+	interconnectroute_dbf.free_result(interconnectroute_dbh, route_rs);
+    }
+    
+    *route_data = new_route;
+    num_rows = route_list->count;//RES_ROW_N(route_rs);
+    interconnectroute_dbf.free_result(interconnectroute_dbh, route_rs);
+    LM_DBG("Returning %d rows\n", num_rows);
+    return num_rows;
+}
+
+

+ 34 - 0
modules/interconnectroute/db.h

@@ -0,0 +1,34 @@
+/* 
+ * File:   db.h
+ * Author: jaybeepee
+ *
+ * Created on 14 October 2014, 5:48 PM
+ */
+
+#ifndef DB_H
+#define	DB_H
+
+#include "../../lib/srdb1/db.h"
+#include "../../str.h"
+#include "../../ut.h"
+#include "route_data.h"
+
+#include <string.h>
+
+#define QUERY_LEN 2048
+
+extern str interconnectroute_db_url;
+extern str interconnectnumber_table;
+extern str interconnecttrunk_table;
+
+extern db1_con_t * interconnectroute_dbh;
+extern db_func_t interconnectroute_dbf;
+
+void interconnectroute_db_close(void);
+int interconnectroute_db_init(void);
+int interconnectroute_db_open(void);
+
+int get_routes(str* dst_number, route_data_t** route_data);
+
+#endif	/* DB_H */
+

+ 14 - 0
modules/interconnectroute/fixups.c

@@ -0,0 +1,14 @@
+#include "fixups.h"
+
+
+int uri_fixup(void ** param) {
+
+    return 0;
+}
+int ix_trunk_query_fixup(void ** param, int param_no) {
+	if (param_no == 1) {
+	    return fixup_var_str_12(param, param_no);
+	}
+
+	return 0;
+}

+ 16 - 0
modules/interconnectroute/fixups.h

@@ -0,0 +1,16 @@
+/* 
+ * File:   fixups.h
+ * Author: jaybeepee
+ *
+ * Created on 14 October 2014, 3:51 PM
+ */
+
+#ifndef FIXUPS_H
+#define	FIXUPS_H
+
+#include "../../mod_fix.h"
+
+int ix_trunk_query_fixup(void ** param, int param_no);
+
+#endif	/* FIXUPS_H */
+

+ 1 - 0
modules/interconnectroute/interconnect_data.c

@@ -0,0 +1 @@
+

+ 14 - 0
modules/interconnectroute/interconnect_data.h

@@ -0,0 +1,14 @@
+/* 
+ * File:   interconnect_data.h
+ * Author: jaybeepee
+ *
+ * Created on 14 October 2014, 5:44 PM
+ */
+
+#ifndef INTERCONNECT_DATA_H
+#define	INTERCONNECT_DATA_H
+
+typedef struct  
+
+#endif	/* INTERCONNECT_DATA_H */
+

+ 95 - 0
modules/interconnectroute/interconnectroute.c

@@ -0,0 +1,95 @@
+#include "interconnectroute.h"
+#include "../../sr_module.h"
+#include "fixups.h"
+#include "query.h"
+#include "db.h"
+#include "config.h"
+
+MODULE_VERSION
+
+str interconnectroute_db_url = str_init(DEFAULT_IXDB_URL);
+	
+static int mod_init(void);
+static int child_init(int);
+static int mi_child_init(void);
+static void mod_destroy(void);
+
+/************* Module Exports **********************************************/
+static cmd_export_t cmds[]={
+	{"ix_trunk_query",  (cmd_function)ix_trunk_query,  1, ix_trunk_query_fixup, 0, REQUEST_ROUTE | FAILURE_ROUTE },
+	{0, 0, 0, 0, 0, 0}
+};
+
+static param_export_t params[]= {
+    { "db_url", PARAM_STR, &interconnectroute_db_url },
+    { "numbertable", PARAM_STR, &interconnectnumber_table },
+    { "trunktable", PARAM_STR, &interconnecttrunk_table },
+    {0,0,0}
+};
+
+static rpc_export_t rpc_methods[];
+
+struct module_exports exports = {
+	"carrierroute",
+	DEFAULT_DLFLAGS, /* dlopen flags */
+	cmds,       /* Exported functions */
+	params,     /* Export parameters */
+	0,          /* exported statistics */
+	0,    /* exported MI functions */
+	0,          /* exported pseudo-variables */
+	0,          /* extra processes */
+	mod_init,   /* Module initialization function */
+	0,          /* Response function */
+	mod_destroy,/* Destroy function */
+	child_init  /* Child initialization function */
+};
+
+/************* Interface Functions *****************************************/
+
+/**
+ *
+ * @return 0 on success, -1 on failure
+ */
+static int mod_init(void) {
+    
+    if (interconnectroute_db_init() != 0) {
+	LM_ERR("Failed to initialise DB connection\n");
+	return -1;
+    };
+    return 0;
+}
+
+static int child_init(int rank) {
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
+		return 0; /* do nothing for the main process */
+
+	return interconnectroute_db_open();
+}
+
+
+static int mi_child_init(void) {
+//	if(mode == CARRIERROUTE_MODE_DB){
+//		return carrierroute_db_open();
+//	}
+	return 0;
+}
+
+static void mod_destroy(void) {
+//	if(mode == CARRIERROUTE_MODE_DB){
+//		carrierroute_db_close();
+//	}
+//	destroy_route_data();
+}
+
+static const char *rpc_cr_reload_routes_doc[2] = {
+	"Reload routes", 0
+};
+
+static void rpc_cr_reload_routes(rpc_t *rpc, void *c) {
+
+}
+
+static rpc_export_t rpc_methods[] = {
+//	{ "cr.reload_routes",  rpc_cr_reload_routes, rpc_cr_reload_routes_doc, 0},
+	{0, 0, 0, 0}
+};

+ 16 - 0
modules/interconnectroute/interconnectroute.h

@@ -0,0 +1,16 @@
+/* 
+ * File:   interconnectroute.h
+ * Author: jaybeepee
+ *
+ * Created on 14 October 2014, 2:58 PM
+ */
+
+#ifndef INTERCONNECTROUTE_H
+#define	INTERCONNECTROUTE_H
+
+#include "../../str.h"
+#include "../../usr_avp.h"
+
+
+#endif	/* INTERCONNECTROUTE_H */
+

+ 89 - 0
modules/interconnectroute/query.c

@@ -0,0 +1,89 @@
+#include "query.h"
+#include "db.h"
+#include "../../parser/parse_uri.h"
+#include "../../sr_module.h"
+
+int create_response_avp_string(char* name, str* val) {
+    int rc;
+    int_str avp_val, avp_name;
+    avp_name.s.s = name;
+    avp_name.s.len = strlen(name);
+
+    avp_val.s = *val;
+
+    rc = add_avp(AVP_NAME_STR|AVP_VAL_STR, avp_name, avp_val);
+
+    if (rc < 0)
+        LM_ERR("couldnt create AVP\n");
+    else
+        LM_INFO("created AVP successfully : [%.*s] - [%.*s]\n", avp_name.s.len, avp_name.s.s, val->len, val->s);
+
+    return 1;
+}
+
+int create_avps(route_data_t* route_data) {
+    create_response_avp_string("ix_trunk_id", &route_data->trunk_id);
+    create_response_avp_string("ix_trunk_gw", &route_data->ipv4);
+    create_response_avp_string("ix_external_trunk_id", &route_data->external_trunk_id);
+}
+
+int isonlydigits(str* s) {
+    int i;
+
+    for (i = 0; i < s->len; i++) {
+	if (!isdigit(s->s[i]))
+	    return 0;
+    }
+
+    return 1;
+}
+
+int ix_trunk_query(struct sip_msg* msg, char* uri) {
+    str uri_number_s, number;
+    sip_uri_t* sip_uri;
+    route_data_t* route_data;
+    
+    if (get_str_fparam(&uri_number_s, msg, (fparam_t*) uri) < 0) {
+	    LM_ERR("failed to get URI or number\n");
+	    return -1;
+    }
+    number.s = uri_number_s.s;
+    number.len = uri_number_s.len;
+    
+    LM_DBG("IX Route: searching for URI: <%.*s>\n", number.len, number.s);
+    
+    if (number.len < 4 || (strncmp(number.s, "sip:", 4) && strncmp(number.s, "tel:", 4))) {
+	LM_DBG("no leading tel: or sip: [%.*s] - assuming number passed in... will check => \n", number.len, number.s);
+    } else {
+	//need to clean uri to extract "user" portion - which should be a number...
+	if (parse_uri(uri_number_s.s, number.len, sip_uri) != 0) {
+	    LM_ERR("Failed to parse URI [%.*s]\n", number.len, number.s);
+	    return -1;
+	}
+	number = sip_uri->user;
+    }
+    
+    if (number.len > 0 && number.s[0]=='+') {
+	LM_DBG("stripping off leading +\n");
+	number.s = number.s + 1;
+	number.len -= 1;
+    }
+
+    /* check this is a number? */
+    if (!isonlydigits(&number)) {
+	LM_WARN("not a number and not a URI... aborting\n");
+	return -1;
+    } 
+
+    LM_DBG("number to be searched: [%.*s]\n", number.len, number.s);
+    int res = get_routes(&number, &route_data);
+    
+    if (res <= 0) {
+	return -1;
+    }
+    
+    LM_DBG("Received route for operator key: [%.*s]\n", route_data->operator_key.len, route_data->operator_key.s);
+    create_avps(route_data);
+
+    return 1;
+}

+ 16 - 0
modules/interconnectroute/query.h

@@ -0,0 +1,16 @@
+/* 
+ * File:   query.h
+ * Author: jaybeepee
+ *
+ * Created on 14 October 2014, 3:50 PM
+ */
+
+#ifndef QUERY_H
+#define	QUERY_H
+
+#include "../../parser/msg_parser.h"
+
+int ix_trunk_query(struct sip_msg* msg, char* uri);
+
+#endif	/* QUERY_H */
+

+ 75 - 0
modules/interconnectroute/route_data.c

@@ -0,0 +1,75 @@
+#include <string.h>
+#include "route_data.h"
+
+#include "../../mem/mem.h"
+
+/* creates a new structure to hold route data in pkg memory 
+   NB: remember to free when done!
+ */
+route_data_t* new_route_data(str* operator_key, str* trunk_id, int priority, str* gw_ip, str* external_trunk_id) {
+    struct route_data* route_data;
+    char *p;
+    int len = sizeof(struct route_data) + operator_key->len + trunk_id->len + gw_ip->len + external_trunk_id->len;
+    route_data = (struct route_data*)pkg_malloc(len);
+    if (!route_data) {
+	LM_ERR("no more pkg memory\n");
+	return NULL;
+    }
+    
+    memset(route_data, 0, len);
+    
+    route_data->priority = priority;
+    p = (char*)(route_data + 1);
+    
+    route_data->operator_key.s = p;
+    route_data->operator_key.len = operator_key->len;
+    memcpy(p, operator_key->s, operator_key->len);
+    p+=operator_key->len;
+    
+    route_data->trunk_id.s = p;
+    memcpy(p, trunk_id->s, trunk_id->len);
+    route_data->trunk_id.len = trunk_id->len;
+    p+= trunk_id->len;
+    
+    route_data->ipv4.s = p;
+    memcpy(p, gw_ip->s, gw_ip->len);
+    route_data->ipv4.len = gw_ip->len;
+    p+=gw_ip->len;
+    
+    route_data->external_trunk_id.s = p;
+    memcpy(p, external_trunk_id->s, external_trunk_id->len);
+    route_data->external_trunk_id.len = external_trunk_id->len;
+    p+=external_trunk_id->len;  
+    
+    if (p != (((char*) route_data) + len)) {
+        LM_CRIT("buffer overflow\n");
+        pkg_free(route_data);
+        return 0;
+    }
+    
+    return route_data;
+}
+
+ix_route_list_t* new_route_list() {
+    ix_route_list_t* route_list = pkg_malloc(sizeof(ix_route_list_t));
+    
+    memset(route_list, 0, sizeof(ix_route_list_t));
+    
+    return route_list;
+}
+
+int add_route(struct ix_route_list* list, struct route_data* route) 
+{
+    if (list->count == 0) {
+	list->first = list->last = route;
+	list->count++;
+	return 1;
+    }
+    
+    route->prev = list->last;
+    list->last->next = route;
+    list->last = route;
+    list->count++;
+    
+    return 1;
+}

+ 34 - 0
modules/interconnectroute/route_data.h

@@ -0,0 +1,34 @@
+/* 
+ * File:   route_data.h
+ * Author: jaybeepee
+ *
+ * Created on 15 October 2014, 4:51 PM
+ */
+
+#ifndef ROUTE_DATA_H
+#define	ROUTE_DATA_H
+
+#include "../../str.h"
+
+typedef struct route_data {
+    str     operator_key;
+    str     trunk_id;
+    str     external_trunk_id;
+    str     ipv4;
+    int     priority;
+    struct route_data* next;
+    struct route_data* prev;
+} route_data_t;
+
+typedef struct ix_route_list {
+    route_data_t* first;
+    route_data_t* last;
+    int count;
+} ix_route_list_t;
+
+route_data_t* new_route_data(str* operator_key, str* trunk_id, int priority, str* gw_ip, str* external_trunk_id);
+ix_route_list_t* new_route_list();
+int add_route(struct ix_route_list* list, struct route_data* route);
+
+#endif	/* ROUTE_DATA_H */
+