Browse code

tmp:interconnect_route_modules: new interconnectroute module

Richard Good authored on 05/11/2014 15:31:57
Showing 14 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,17 @@
1
+# $Id: Makefile,v 1.6 2003/05/23 15:43:43 andrei Exp $
2
+#
3
+# carrierroute Makefile
4
+#
5
+# WARNING: do not run this directly, it should be run by the master Makefile
6
+
7
+include ../../Makefile.defs
8
+
9
+auto_gen=
10
+NAME=interconnectroute.so
11
+
12
+DEFS+=-DKAMAILIO_MOD_INTERFACE
13
+
14
+SERLIBPATH=../../lib
15
+SER_LIBS+=$(SERLIBPATH)/trie/trie $(SERLIBPATH)/srdb1/srdb1 $(SERLIBPATH)/kmi/kmi $(SERLIBPATH)/kcore/kcore
16
+
17
+include ../../Makefile.modules
0 18
new file mode 100644
... ...
@@ -0,0 +1,14 @@
1
+/* 
2
+ * File:   config.h
3
+ * Author: jaybeepee
4
+ *
5
+ * Created on 15 October 2014, 3:14 PM
6
+ */
7
+
8
+#ifndef CONFIG_H
9
+#define	CONFIG_H
10
+
11
+#define DEFAULT_IXDB_URL "mysql://root:changeme@10.0.1.157/scscf"
12
+
13
+#endif	/* CONFIG_H */
14
+
0 15
new file mode 100644
... ...
@@ -0,0 +1,165 @@
1
+#include "db.h"
2
+#include "route_data.h"
3
+
4
+db1_con_t * interconnectroute_dbh = NULL;
5
+db_func_t interconnectroute_dbf;
6
+
7
+static char *query_fmt = "select N.OPERATOR_KEY, T.TRUNK_ID, T.PRIORITY, T.IPV4, T.EXTERNAL_TRUNK_ID "
8
+	"from operator_number N left join operator_trunk T on N.OPERATOR_KEY=T.OPERATOR_KEY "
9
+	"where %.*s >= CAST(NUMBER_START AS UNSIGNED) and %.*s <= CAST(NUMBER_END AS UNSIGNED) ORDER BY T.PRIORITY DESC";
10
+static char query[QUERY_LEN];
11
+
12
+str interconnectnumber_table = str_init("operator_number");
13
+
14
+/* table version */
15
+const unsigned int interconnectroute_version = 1;
16
+
17
+str interconnecttrunk_table = str_init("operator_trunk");
18
+
19
+/*
20
+ * Closes the DB connection.
21
+ */
22
+void interconnectroute_db_close(void) {
23
+    if (interconnectroute_dbh) {
24
+	interconnectroute_dbf.close(interconnectroute_dbh);
25
+	interconnectroute_dbh = NULL;
26
+    }
27
+}
28
+
29
+
30
+int interconnectroute_db_init(void) {
31
+    if (!interconnectroute_db_url.s || !interconnectroute_db_url.len) {
32
+	LM_ERR("you have to set the db_url module parameter.\n");
33
+	return -1;
34
+    }
35
+    if (db_bind_mod(&interconnectroute_db_url, &interconnectroute_dbf) < 0) {
36
+	LM_ERR("can't bind database module.\n");
37
+	return -1;
38
+    }
39
+    if ((interconnectroute_dbh = interconnectroute_dbf.init(&interconnectroute_db_url)) == NULL) {
40
+	LM_ERR("can't connect to database using [%.*s]\n", interconnectroute_db_url.len, interconnectroute_db_url.s);
41
+	return -1;
42
+    }
43
+    if (
44
+	    (db_check_table_version(&interconnectroute_dbf, interconnectroute_dbh, &interconnectnumber_table, interconnectroute_version) < 0) ||
45
+	    (db_check_table_version(&interconnectroute_dbf, interconnectroute_dbh, &interconnecttrunk_table, interconnectroute_version) < 0)) {
46
+	LM_ERR("during table version check.\n");
47
+	interconnectroute_db_close();
48
+	return -1;
49
+    }
50
+    interconnectroute_db_close();
51
+    return 0;
52
+}
53
+
54
+
55
+int interconnectroute_db_open(void) {
56
+    if (interconnectroute_dbh) {
57
+	interconnectroute_dbf.close(interconnectroute_dbh);
58
+    }
59
+    if ((interconnectroute_dbh = interconnectroute_dbf.init(&interconnectroute_db_url)) == NULL) {
60
+	LM_ERR("can't connect to database.\n");
61
+	return -1;
62
+    }
63
+    return 0;
64
+}
65
+
66
+int get_routes(str* dst_number, route_data_t** route_data) {
67
+    int i,n, priority;
68
+    db1_res_t* route_rs;
69
+    db_row_t* route_row;
70
+    db_val_t* route_vals;
71
+    str query_s, operator_key, trunk_id, external_trunk_id, gateway_ipv4;
72
+    route_data_t* new_route;
73
+    ix_route_list_t* route_list = new_route_list();
74
+    int num_rows;
75
+    
76
+
77
+    if (strlen(query_fmt) + dst_number->len > QUERY_LEN) {
78
+	LM_ERR("query too big\n");
79
+	return -1;
80
+    }
81
+    snprintf(query, QUERY_LEN, query_fmt, dst_number->len, dst_number->s, dst_number->len, dst_number->s);
82
+    query_s.s = query;
83
+    query_s.len = strlen(query);
84
+
85
+    LM_DBG("QUERY IS: [%s]\n", query);
86
+
87
+    if (interconnectroute_dbf.raw_query(interconnectroute_dbh, &query_s, &route_rs) != 0) {
88
+	LM_ERR("Unable to query DB for interconnect routes with number [%.*s]\n", dst_number->len, dst_number->s);
89
+	interconnectroute_dbf.free_result(interconnectroute_dbh, route_rs);
90
+    }
91
+
92
+    LM_DBG("Received route results [%d]\n", RES_ROW_N(route_rs));
93
+    if (RES_ROW_N(route_rs) <= 0) {
94
+	LM_DBG("No routes found for number [%.*s]\n", dst_number->len, dst_number->s);
95
+	return -1;
96
+    } else {
97
+	n = 0;
98
+	do {
99
+	    n++;
100
+	    LM_DBG("looping through route recordset [%d]\n", n);
101
+	    for (i = 0; i < RES_ROW_N(route_rs); i++) {
102
+		route_row = RES_ROWS(route_rs) + i;
103
+		route_vals = ROW_VALUES(route_row);
104
+
105
+		if (!VAL_NULL(route_vals)) {
106
+		    operator_key.s = (char*) VAL_STRING(route_vals);
107
+		    operator_key.len = strlen(operator_key.s);
108
+		    LM_DBG("Received route for operator key: [%.*s]\n", operator_key.len, operator_key.s);
109
+		}
110
+		if (!VAL_NULL(route_vals+1)) {
111
+		    trunk_id.s = (char*) VAL_STRING(route_vals+1);
112
+		    trunk_id.len = strlen(trunk_id.s);
113
+		    LM_DBG("Trunk is: [%.*s]\n", trunk_id.len, trunk_id.s);
114
+		}
115
+		if (!VAL_NULL(route_vals+2)) {
116
+		    priority = VAL_INT(route_vals+2);
117
+		    LM_DBG("Priority is: [%d]\n", priority);
118
+		}
119
+		if (!VAL_NULL(route_vals+3)) {
120
+		    gateway_ipv4.s = (char*) VAL_STRING(route_vals+3);
121
+		    gateway_ipv4.len = strlen(gateway_ipv4.s);
122
+		    LM_DBG("Gateway IP for trunk to this operator is: [%.*s]\n", gateway_ipv4.len, gateway_ipv4.s);
123
+		}
124
+		if (!VAL_NULL(route_vals+4)) {
125
+		    external_trunk_id.s = (char*) VAL_STRING(route_vals+4);
126
+		    external_trunk_id.len = strlen(external_trunk_id.s);
127
+		    LM_DBG("External trunk ID: [%.*s]\n", external_trunk_id.len, external_trunk_id.s);
128
+		}
129
+		
130
+		new_route = new_route_data(&operator_key, &trunk_id, priority, &gateway_ipv4, &external_trunk_id);
131
+		if (!new_route) {
132
+		    LM_DBG("Could not get new route... continuing\n");
133
+		    continue;
134
+		}
135
+		
136
+		if (!add_route(route_list, new_route)) {
137
+		    LM_DBG("unable to add route.....\n");
138
+		    continue;
139
+		}
140
+		
141
+		LM_DBG("route list now has %d elements\n", route_list->count);
142
+		
143
+		
144
+	    }
145
+	    if (DB_CAPABILITY(interconnectroute_dbf, DB_CAP_FETCH)) {
146
+		if (interconnectroute_dbf.fetch_result(interconnectroute_dbh, &route_rs, 2000/*ul_fetch_rows*/) < 0) {
147
+		    LM_ERR("fetching rows failed\n");
148
+		    interconnectroute_dbf.free_result(interconnectroute_dbh, route_rs);
149
+		    return -1;
150
+		}
151
+	    } else {
152
+		break;
153
+	    }
154
+	} while (RES_ROW_N(route_rs) > 0);
155
+	interconnectroute_dbf.free_result(interconnectroute_dbh, route_rs);
156
+    }
157
+    
158
+    *route_data = new_route;
159
+    num_rows = route_list->count;//RES_ROW_N(route_rs);
160
+    interconnectroute_dbf.free_result(interconnectroute_dbh, route_rs);
161
+    LM_DBG("Returning %d rows\n", num_rows);
162
+    return num_rows;
163
+}
164
+
165
+
0 166
new file mode 100644
... ...
@@ -0,0 +1,34 @@
1
+/* 
2
+ * File:   db.h
3
+ * Author: jaybeepee
4
+ *
5
+ * Created on 14 October 2014, 5:48 PM
6
+ */
7
+
8
+#ifndef DB_H
9
+#define	DB_H
10
+
11
+#include "../../lib/srdb1/db.h"
12
+#include "../../str.h"
13
+#include "../../ut.h"
14
+#include "route_data.h"
15
+
16
+#include <string.h>
17
+
18
+#define QUERY_LEN 2048
19
+
20
+extern str interconnectroute_db_url;
21
+extern str interconnectnumber_table;
22
+extern str interconnecttrunk_table;
23
+
24
+extern db1_con_t * interconnectroute_dbh;
25
+extern db_func_t interconnectroute_dbf;
26
+
27
+void interconnectroute_db_close(void);
28
+int interconnectroute_db_init(void);
29
+int interconnectroute_db_open(void);
30
+
31
+int get_routes(str* dst_number, route_data_t** route_data);
32
+
33
+#endif	/* DB_H */
34
+
0 35
new file mode 100644
... ...
@@ -0,0 +1,14 @@
1
+#include "fixups.h"
2
+
3
+
4
+int uri_fixup(void ** param) {
5
+
6
+    return 0;
7
+}
8
+int ix_trunk_query_fixup(void ** param, int param_no) {
9
+	if (param_no == 1) {
10
+	    return fixup_var_str_12(param, param_no);
11
+	}
12
+
13
+	return 0;
14
+}
0 15
\ No newline at end of file
1 16
new file mode 100644
... ...
@@ -0,0 +1,16 @@
1
+/* 
2
+ * File:   fixups.h
3
+ * Author: jaybeepee
4
+ *
5
+ * Created on 14 October 2014, 3:51 PM
6
+ */
7
+
8
+#ifndef FIXUPS_H
9
+#define	FIXUPS_H
10
+
11
+#include "../../mod_fix.h"
12
+
13
+int ix_trunk_query_fixup(void ** param, int param_no);
14
+
15
+#endif	/* FIXUPS_H */
16
+
0 17
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+
0 2
new file mode 100644
... ...
@@ -0,0 +1,14 @@
1
+/* 
2
+ * File:   interconnect_data.h
3
+ * Author: jaybeepee
4
+ *
5
+ * Created on 14 October 2014, 5:44 PM
6
+ */
7
+
8
+#ifndef INTERCONNECT_DATA_H
9
+#define	INTERCONNECT_DATA_H
10
+
11
+typedef struct  
12
+
13
+#endif	/* INTERCONNECT_DATA_H */
14
+
0 15
new file mode 100644
... ...
@@ -0,0 +1,95 @@
1
+#include "interconnectroute.h"
2
+#include "../../sr_module.h"
3
+#include "fixups.h"
4
+#include "query.h"
5
+#include "db.h"
6
+#include "config.h"
7
+
8
+MODULE_VERSION
9
+
10
+str interconnectroute_db_url = str_init(DEFAULT_IXDB_URL);
11
+	
12
+static int mod_init(void);
13
+static int child_init(int);
14
+static int mi_child_init(void);
15
+static void mod_destroy(void);
16
+
17
+/************* Module Exports **********************************************/
18
+static cmd_export_t cmds[]={
19
+	{"ix_trunk_query",  (cmd_function)ix_trunk_query,  1, ix_trunk_query_fixup, 0, REQUEST_ROUTE | FAILURE_ROUTE },
20
+	{0, 0, 0, 0, 0, 0}
21
+};
22
+
23
+static param_export_t params[]= {
24
+    { "db_url", PARAM_STR, &interconnectroute_db_url },
25
+    { "numbertable", PARAM_STR, &interconnectnumber_table },
26
+    { "trunktable", PARAM_STR, &interconnecttrunk_table },
27
+    {0,0,0}
28
+};
29
+
30
+static rpc_export_t rpc_methods[];
31
+
32
+struct module_exports exports = {
33
+	"carrierroute",
34
+	DEFAULT_DLFLAGS, /* dlopen flags */
35
+	cmds,       /* Exported functions */
36
+	params,     /* Export parameters */
37
+	0,          /* exported statistics */
38
+	0,    /* exported MI functions */
39
+	0,          /* exported pseudo-variables */
40
+	0,          /* extra processes */
41
+	mod_init,   /* Module initialization function */
42
+	0,          /* Response function */
43
+	mod_destroy,/* Destroy function */
44
+	child_init  /* Child initialization function */
45
+};
46
+
47
+/************* Interface Functions *****************************************/
48
+
49
+/**
50
+ *
51
+ * @return 0 on success, -1 on failure
52
+ */
53
+static int mod_init(void) {
54
+    
55
+    if (interconnectroute_db_init() != 0) {
56
+	LM_ERR("Failed to initialise DB connection\n");
57
+	return -1;
58
+    };
59
+    return 0;
60
+}
61
+
62
+static int child_init(int rank) {
63
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
64
+		return 0; /* do nothing for the main process */
65
+
66
+	return interconnectroute_db_open();
67
+}
68
+
69
+
70
+static int mi_child_init(void) {
71
+//	if(mode == CARRIERROUTE_MODE_DB){
72
+//		return carrierroute_db_open();
73
+//	}
74
+	return 0;
75
+}
76
+
77
+static void mod_destroy(void) {
78
+//	if(mode == CARRIERROUTE_MODE_DB){
79
+//		carrierroute_db_close();
80
+//	}
81
+//	destroy_route_data();
82
+}
83
+
84
+static const char *rpc_cr_reload_routes_doc[2] = {
85
+	"Reload routes", 0
86
+};
87
+
88
+static void rpc_cr_reload_routes(rpc_t *rpc, void *c) {
89
+
90
+}
91
+
92
+static rpc_export_t rpc_methods[] = {
93
+//	{ "cr.reload_routes",  rpc_cr_reload_routes, rpc_cr_reload_routes_doc, 0},
94
+	{0, 0, 0, 0}
95
+};
0 96
\ No newline at end of file
1 97
new file mode 100644
... ...
@@ -0,0 +1,16 @@
1
+/* 
2
+ * File:   interconnectroute.h
3
+ * Author: jaybeepee
4
+ *
5
+ * Created on 14 October 2014, 2:58 PM
6
+ */
7
+
8
+#ifndef INTERCONNECTROUTE_H
9
+#define	INTERCONNECTROUTE_H
10
+
11
+#include "../../str.h"
12
+#include "../../usr_avp.h"
13
+
14
+
15
+#endif	/* INTERCONNECTROUTE_H */
16
+
0 17
new file mode 100644
... ...
@@ -0,0 +1,89 @@
1
+#include "query.h"
2
+#include "db.h"
3
+#include "../../parser/parse_uri.h"
4
+#include "../../sr_module.h"
5
+
6
+int create_response_avp_string(char* name, str* val) {
7
+    int rc;
8
+    int_str avp_val, avp_name;
9
+    avp_name.s.s = name;
10
+    avp_name.s.len = strlen(name);
11
+
12
+    avp_val.s = *val;
13
+
14
+    rc = add_avp(AVP_NAME_STR|AVP_VAL_STR, avp_name, avp_val);
15
+
16
+    if (rc < 0)
17
+        LM_ERR("couldnt create AVP\n");
18
+    else
19
+        LM_INFO("created AVP successfully : [%.*s] - [%.*s]\n", avp_name.s.len, avp_name.s.s, val->len, val->s);
20
+
21
+    return 1;
22
+}
23
+
24
+int create_avps(route_data_t* route_data) {
25
+    create_response_avp_string("ix_trunk_id", &route_data->trunk_id);
26
+    create_response_avp_string("ix_trunk_gw", &route_data->ipv4);
27
+    create_response_avp_string("ix_external_trunk_id", &route_data->external_trunk_id);
28
+}
29
+
30
+int isonlydigits(str* s) {
31
+    int i;
32
+
33
+    for (i = 0; i < s->len; i++) {
34
+	if (!isdigit(s->s[i]))
35
+	    return 0;
36
+    }
37
+
38
+    return 1;
39
+}
40
+
41
+int ix_trunk_query(struct sip_msg* msg, char* uri) {
42
+    str uri_number_s, number;
43
+    sip_uri_t* sip_uri;
44
+    route_data_t* route_data;
45
+    
46
+    if (get_str_fparam(&uri_number_s, msg, (fparam_t*) uri) < 0) {
47
+	    LM_ERR("failed to get URI or number\n");
48
+	    return -1;
49
+    }
50
+    number.s = uri_number_s.s;
51
+    number.len = uri_number_s.len;
52
+    
53
+    LM_DBG("IX Route: searching for URI: <%.*s>\n", number.len, number.s);
54
+    
55
+    if (number.len < 4 || (strncmp(number.s, "sip:", 4) && strncmp(number.s, "tel:", 4))) {
56
+	LM_DBG("no leading tel: or sip: [%.*s] - assuming number passed in... will check => \n", number.len, number.s);
57
+    } else {
58
+	//need to clean uri to extract "user" portion - which should be a number...
59
+	if (parse_uri(uri_number_s.s, number.len, sip_uri) != 0) {
60
+	    LM_ERR("Failed to parse URI [%.*s]\n", number.len, number.s);
61
+	    return -1;
62
+	}
63
+	number = sip_uri->user;
64
+    }
65
+    
66
+    if (number.len > 0 && number.s[0]=='+') {
67
+	LM_DBG("stripping off leading +\n");
68
+	number.s = number.s + 1;
69
+	number.len -= 1;
70
+    }
71
+
72
+    /* check this is a number? */
73
+    if (!isonlydigits(&number)) {
74
+	LM_WARN("not a number and not a URI... aborting\n");
75
+	return -1;
76
+    } 
77
+
78
+    LM_DBG("number to be searched: [%.*s]\n", number.len, number.s);
79
+    int res = get_routes(&number, &route_data);
80
+    
81
+    if (res <= 0) {
82
+	return -1;
83
+    }
84
+    
85
+    LM_DBG("Received route for operator key: [%.*s]\n", route_data->operator_key.len, route_data->operator_key.s);
86
+    create_avps(route_data);
87
+
88
+    return 1;
89
+}
0 90
\ No newline at end of file
1 91
new file mode 100644
... ...
@@ -0,0 +1,16 @@
1
+/* 
2
+ * File:   query.h
3
+ * Author: jaybeepee
4
+ *
5
+ * Created on 14 October 2014, 3:50 PM
6
+ */
7
+
8
+#ifndef QUERY_H
9
+#define	QUERY_H
10
+
11
+#include "../../parser/msg_parser.h"
12
+
13
+int ix_trunk_query(struct sip_msg* msg, char* uri);
14
+
15
+#endif	/* QUERY_H */
16
+
0 17
new file mode 100644
... ...
@@ -0,0 +1,75 @@
1
+#include <string.h>
2
+#include "route_data.h"
3
+
4
+#include "../../mem/mem.h"
5
+
6
+/* creates a new structure to hold route data in pkg memory 
7
+   NB: remember to free when done!
8
+ */
9
+route_data_t* new_route_data(str* operator_key, str* trunk_id, int priority, str* gw_ip, str* external_trunk_id) {
10
+    struct route_data* route_data;
11
+    char *p;
12
+    int len = sizeof(struct route_data) + operator_key->len + trunk_id->len + gw_ip->len + external_trunk_id->len;
13
+    route_data = (struct route_data*)pkg_malloc(len);
14
+    if (!route_data) {
15
+	LM_ERR("no more pkg memory\n");
16
+	return NULL;
17
+    }
18
+    
19
+    memset(route_data, 0, len);
20
+    
21
+    route_data->priority = priority;
22
+    p = (char*)(route_data + 1);
23
+    
24
+    route_data->operator_key.s = p;
25
+    route_data->operator_key.len = operator_key->len;
26
+    memcpy(p, operator_key->s, operator_key->len);
27
+    p+=operator_key->len;
28
+    
29
+    route_data->trunk_id.s = p;
30
+    memcpy(p, trunk_id->s, trunk_id->len);
31
+    route_data->trunk_id.len = trunk_id->len;
32
+    p+= trunk_id->len;
33
+    
34
+    route_data->ipv4.s = p;
35
+    memcpy(p, gw_ip->s, gw_ip->len);
36
+    route_data->ipv4.len = gw_ip->len;
37
+    p+=gw_ip->len;
38
+    
39
+    route_data->external_trunk_id.s = p;
40
+    memcpy(p, external_trunk_id->s, external_trunk_id->len);
41
+    route_data->external_trunk_id.len = external_trunk_id->len;
42
+    p+=external_trunk_id->len;  
43
+    
44
+    if (p != (((char*) route_data) + len)) {
45
+        LM_CRIT("buffer overflow\n");
46
+        pkg_free(route_data);
47
+        return 0;
48
+    }
49
+    
50
+    return route_data;
51
+}
52
+
53
+ix_route_list_t* new_route_list() {
54
+    ix_route_list_t* route_list = pkg_malloc(sizeof(ix_route_list_t));
55
+    
56
+    memset(route_list, 0, sizeof(ix_route_list_t));
57
+    
58
+    return route_list;
59
+}
60
+
61
+int add_route(struct ix_route_list* list, struct route_data* route) 
62
+{
63
+    if (list->count == 0) {
64
+	list->first = list->last = route;
65
+	list->count++;
66
+	return 1;
67
+    }
68
+    
69
+    route->prev = list->last;
70
+    list->last->next = route;
71
+    list->last = route;
72
+    list->count++;
73
+    
74
+    return 1;
75
+}
0 76
\ No newline at end of file
1 77
new file mode 100644
... ...
@@ -0,0 +1,34 @@
1
+/* 
2
+ * File:   route_data.h
3
+ * Author: jaybeepee
4
+ *
5
+ * Created on 15 October 2014, 4:51 PM
6
+ */
7
+
8
+#ifndef ROUTE_DATA_H
9
+#define	ROUTE_DATA_H
10
+
11
+#include "../../str.h"
12
+
13
+typedef struct route_data {
14
+    str     operator_key;
15
+    str     trunk_id;
16
+    str     external_trunk_id;
17
+    str     ipv4;
18
+    int     priority;
19
+    struct route_data* next;
20
+    struct route_data* prev;
21
+} route_data_t;
22
+
23
+typedef struct ix_route_list {
24
+    route_data_t* first;
25
+    route_data_t* last;
26
+    int count;
27
+} ix_route_list_t;
28
+
29
+route_data_t* new_route_data(str* operator_key, str* trunk_id, int priority, str* gw_ip, str* external_trunk_id);
30
+ix_route_list_t* new_route_list();
31
+int add_route(struct ix_route_list* list, struct route_data* route);
32
+
33
+#endif	/* ROUTE_DATA_H */
34
+