From d07ca258fb115016c64418bdcd540e0dd4d4627b Mon Sep 17 00:00:00 2001 From: Fabricio Santolin da Silva Date: Tue, 13 Sep 2022 16:18:19 +0200 Subject: [PATCH] MT#33005 Allow search uri of speed dial by customer Previously all speed dials were related to subscribers. This modification allows having large speed dial numbers (like *999) related to a customer/domain. Change-Id: I082bd41ca25af8fabd8017f4c42c47bbc079cf77 --- debian/patches/series | 2 + .../patches/sipwise/bigger_short_codes.patch | 351 ++++++++++++++++++ 2 files changed, 353 insertions(+) create mode 100644 debian/patches/sipwise/bigger_short_codes.patch diff --git a/debian/patches/series b/debian/patches/series index 5af67d914..c317eb3bd 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -67,6 +67,8 @@ upstream/pv_headers-use-tm.t_find-API.patch upstream/tm-added-t_unset-intermodule-API-function.patch upstream/pv_headers-use-t_unset-based-on-vref-instead-of-rese.patch sipwise/pv_headers-rework-pvh_remove_header_param-take-two.patch +sipwise/bigger_short_codes.patch + # ### Don't just put stuff in any order ### use gbp pq import/export tooling to help maintain patches diff --git a/debian/patches/sipwise/bigger_short_codes.patch b/debian/patches/sipwise/bigger_short_codes.patch new file mode 100644 index 000000000..4c33fee52 --- /dev/null +++ b/debian/patches/sipwise/bigger_short_codes.patch @@ -0,0 +1,351 @@ +--- a/src/modules/speeddial/sdlookup.c ++++ b/src/modules/speeddial/sdlookup.c +@@ -58,6 +58,44 @@ static inline int rewrite_ruri(struct si + return 0; + } + ++int process_result(db1_res_t* db_res, str *ret, char *buffer) ++{ ++ ret->s=buffer+4; ++ if (RES_ROW_N(db_res) > 1) ++ { ++ LM_WARN("too many similar results, returning first result\n"); ++ } ++ switch(RES_ROWS(db_res)[0].values[0].type) ++ { ++ case DB1_STRING: ++ strcpy(ret->s, ++ (char*)RES_ROWS(db_res)[0].values[0].val.string_val); ++ ret->len = strlen(ret->s); ++ break; ++ case DB1_STR: ++ strncpy(ret->s, ++ (char*)RES_ROWS(db_res)[0].values[0].val.str_val.s, ++ RES_ROWS(db_res)[0].values[0].val.str_val.len); ++ ret->len = RES_ROWS(db_res)[0].values[0].val.str_val.len; ++ ret->s[ret->len] = '\0'; ++ break; ++ case DB1_BLOB: ++ strncpy(ret->s, ++ (char*)RES_ROWS(db_res)[0].values[0].val.blob_val.s, ++ RES_ROWS(db_res)[0].values[0].val.blob_val.len); ++ ret->len = RES_ROWS(db_res)[0].values[0].val.blob_val.len; ++ ret->s[ret->len] = '\0'; ++ break; ++ default: ++ LM_ERR("unknown type of DB new_uri column\n"); ++ if (db_funcs.free_result(db_handle, db_res) < 0) { ++ LM_DBG("failed to free result of query\n"); ++ } ++ return -1; ++ } ++ return 1; ++} ++ + /** + * + */ +@@ -175,34 +213,127 @@ int sd_lookup_owner(sip_msg_t* _msg, str + return -1; + } + +- user_s.s = useruri_buf+4; +- switch(RES_ROWS(db_res)[0].values[0].type) ++ if(process_result(db_res, &user_s, useruri_buf) < 0) + { +- case DB1_STRING: +- strcpy(user_s.s, +- (char*)RES_ROWS(db_res)[0].values[0].val.string_val); +- user_s.len = strlen(user_s.s); +- break; +- case DB1_STR: +- strncpy(user_s.s, +- (char*)RES_ROWS(db_res)[0].values[0].val.str_val.s, +- RES_ROWS(db_res)[0].values[0].val.str_val.len); +- user_s.len = RES_ROWS(db_res)[0].values[0].val.str_val.len; +- user_s.s[user_s.len] = '\0'; +- break; +- case DB1_BLOB: +- strncpy(user_s.s, +- (char*)RES_ROWS(db_res)[0].values[0].val.blob_val.s, +- RES_ROWS(db_res)[0].values[0].val.blob_val.len); +- user_s.len = RES_ROWS(db_res)[0].values[0].val.blob_val.len; +- user_s.s[user_s.len] = '\0'; +- break; +- default: +- LM_ERR("unknown type of DB new_uri column\n"); +- if (db_funcs.free_result(db_handle, db_res) < 0) { +- LM_DBG("failed to free result of query\n"); +- } +- goto err_server; ++ LM_DBG("failed to process result\n"); ++ return -1; ++ } ++ ++ /* check 'sip:' */ ++ if(user_s.len<4 || strncmp(user_s.s, "sip:", 4)) ++ { ++ memcpy(useruri_buf, "sip:", 4); ++ user_s.s -= 4; ++ user_s.len += 4; ++ } ++ ++ /** ++ * Free the result because we don't need it anymore ++ */ ++ if (db_funcs.free_result(db_handle, db_res) < 0) { ++ LM_DBG("failed to free result of query\n"); ++ } ++ ++ /* set the URI */ ++ LM_DBG("URI of sd from R-URI [%s]\n", user_s.s); ++ if(rewrite_ruri(_msg, user_s.s)<0) ++ { ++ LM_ERR("failed to replace the R-URI\n"); ++ goto err_server; ++ } ++ ++ return 1; ++ ++err_server: ++ return -1; ++} ++ ++ ++int sd_lookup_group(sip_msg_t* _msg, str* stable, str* sgroup) ++{ ++ str user_s, table_s; ++ int nr_keys; ++ db_key_t db_keys[3]; ++ db_val_t db_vals[3]; ++ db_key_t db_cols[1]; ++ db1_res_t* db_res = NULL; ++ ++ if(stable==NULL || stable->s==NULL || stable->len<=0) ++ { ++ LM_ERR("invalid table parameter"); ++ return -1; ++ } ++ table_s = *stable; ++ ++ if(sgroup==NULL || sgroup->s==NULL || sgroup->len<=0) ++ { ++ LM_ERR("invalid group parameter"); ++ return -1; ++ } ++ ++ /* init */ ++ nr_keys = 0; ++ db_cols[0]=&new_uri_column; ++ ++ /* take sd from r-uri */ ++ if (parse_sip_msg_uri(_msg) < 0) ++ { ++ LM_ERR("failed to parsing Request-URI\n"); ++ goto err_server; ++ } ++ ++ db_keys[nr_keys]=&sd_user_column; ++ db_vals[nr_keys].type = DB1_STR; ++ db_vals[nr_keys].nul = 0; ++ db_vals[nr_keys].val.str_val.s = _msg->parsed_uri.user.s; ++ db_vals[nr_keys].val.str_val.len = _msg->parsed_uri.user.len; ++ nr_keys++; ++ ++ if(use_domain>=2) ++ { ++ db_keys[nr_keys]=&sd_domain_column; ++ db_vals[nr_keys].type = DB1_STR; ++ db_vals[nr_keys].nul = 0; ++ db_vals[nr_keys].val.str_val.s = _msg->parsed_uri.host.s; ++ db_vals[nr_keys].val.str_val.len = _msg->parsed_uri.host.len; ++ ++ if (dstrip_s.s!=NULL && dstrip_s.len>0 ++ && dstrip_s.len<_msg->parsed_uri.host.len ++ && strncasecmp(_msg->parsed_uri.host.s,dstrip_s.s,dstrip_s.len)==0) ++ { ++ db_vals[nr_keys].val.str_val.s += dstrip_s.len; ++ db_vals[nr_keys].val.str_val.len -= dstrip_s.len; ++ } ++ nr_keys++; ++ } ++ ++ ++ db_keys[nr_keys]=&group_column; ++ db_vals[nr_keys].type = DB1_STR; ++ db_vals[nr_keys].nul = 0; ++ db_vals[nr_keys].val.str_val = *sgroup; ++ nr_keys++; ++ ++ db_funcs.use_table(db_handle, &table_s); ++ if(db_funcs.query(db_handle, db_keys, NULL, db_vals, db_cols, ++ nr_keys /*no keys*/, 1 /*no cols*/, NULL, &db_res)!=0 || db_res==NULL) ++ { ++ LM_ERR("failed to query database\n"); ++ goto err_server; ++ } ++ ++ if(RES_ROW_N(db_res) <= 0 || RES_ROWS(db_res)[0].values[0].nul != 0) { ++ LM_DBG("no sip address found for R-URI\n"); ++ if(db_funcs.free_result(db_handle, db_res) < 0) { ++ LM_DBG("failed to free result of query\n"); ++ } ++ goto err_server; ++ } ++ ++ if(process_result(db_res, &user_s, useruri_buf) < 0) ++ { ++ LM_DBG("failed to process result\n"); ++ goto err_server; + } + + /* check 'sip:' */ +@@ -259,3 +390,24 @@ int w_sd_lookup(struct sip_msg* _msg, ch + + return sd_lookup_owner(_msg, &table_s, NULL); + } ++ ++/** ++ * ++ */ ++int w_sd_lookup_group(struct sip_msg* _msg, char* _table, char* _group) ++{ ++ str table_s, group_s; ++ ++ if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0) ++ { ++ LM_ERR("invalid table parameter"); ++ return -1; ++ } ++ ++ if(_group==NULL ||fixup_get_svalue(_msg, (gparam_p)_group, &group_s)!=0) ++ { ++ LM_ERR("invalid group parameter"); ++ return -1; ++ } ++ return sd_lookup_group(_msg, &table_s, &group_s); ++} +--- a/src/modules/speeddial/speeddial.c ++++ b/src/modules/speeddial/speeddial.c +@@ -54,6 +54,8 @@ str domain_column = str_init("domain" + str sd_user_column = str_init("sd_username"); + str sd_domain_column = str_init("sd_domain"); + str new_uri_column = str_init("new_uri"); ++str attribute_column = str_init("attribute"); ++str group_column = str_init("group_id"); + int use_domain = 0; + static str domain_prefix = {NULL, 0}; + +@@ -70,6 +72,8 @@ static cmd_export_t cmds[] = { + REQUEST_ROUTE}, + {"sd_lookup", (cmd_function)w_sd_lookup, 2, fixup_spve_spve, 0, + REQUEST_ROUTE}, ++ {"sd_lookup_group", (cmd_function)w_sd_lookup_group, 2, fixup_spve_spve, 0, ++ REQUEST_ROUTE}, + {0, 0, 0, 0, 0, 0} + }; + +@@ -180,6 +184,11 @@ static sr_kemi_t sr_kemi_speeddial_expor + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, ++ { str_init("speeddial"), str_init("lookup_group"), ++ SR_KEMIP_INT, sd_lookup_group, ++ { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, ++ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } ++ }, + + { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } + }; +--- a/src/modules/speeddial/speeddial.h ++++ b/src/modules/speeddial/speeddial.h +@@ -20,25 +20,25 @@ + * + */ + +- + #ifndef _SPEEDDIAL_H_ + #define _SPEEDDIAL_H_ + + #include "../../lib/srdb1/db.h" + #include "../../core/parser/msg_parser.h" + +- + /* Module parameters variables */ + +-extern str user_column; /* 'username' column name */ +-extern str domain_column; /* 'domain' column name */ +-extern str sd_user_column; /* 'sd_username' column name */ +-extern str sd_domain_column; /* 'sd_domain' column name */ +-extern str new_uri_column; /* 'new_uri' column name */ +-extern int use_domain; /* use or not the domain for sd lookup */ +-extern str dstrip_s; ++extern str user_column; /* 'username' column name */ ++extern str domain_column; /* 'domain' column name */ ++extern str sd_user_column; /* 'sd_username' column name */ ++extern str sd_domain_column; /* 'sd_domain' column name */ ++extern str new_uri_column; /* 'new_uri' column name */ ++extern str attribute_column; /* 'attribute' column name */ ++extern str group_column; /* 'group' column name */ ++extern int use_domain; /* use or not the domain for sd lookup */ ++extern str dstrip_s; + + extern db_func_t db_funcs; /* Database functions */ +-extern db1_con_t* db_handle; /* Database connection handle */ ++extern db1_con_t* db_handle; /* Database connection handle */ + + #endif /* _SPEEDDIAL_H_ */ +--- a/src/modules/speeddial/doc/speeddial_admin.xml ++++ b/src/modules/speeddial/doc/speeddial_admin.xml +@@ -252,6 +252,40 @@ if(uri=~"sip:[0-9]{2}@.*") + + + ++
++ ++ <function moreinfo="none">sd_lookup_group(table , group)</function> ++ ++ ++ The function lookups the short dial number from the group defined in the 'table' and replaces the R-URI with associated address. ++ ++ Meaning of the parameters is as follows: ++ ++ ++ table - The name of the table storing the ++ speed dial records. ++ ++ ++ ++ group - The group that has the ++ short dialing codes. ++ ++ ++ ++ ++ This function can be used from REQUEST_ROUTE. ++ ++ ++ <function>sd_lookup_group</function> usage ++ ++... ++# 'speed_dial' is the default table name created by kamailio db script ++if(uri=~"sip:[0-9]{2}@.*") ++ sd_lookup("speed_dial", "group_id"); ++... ++ ++ ++
+ +
+ Installation and Running +--- a/src/modules/speeddial/sdlookup.h ++++ b/src/modules/speeddial/sdlookup.h +@@ -27,6 +27,8 @@ + #include "../../core/parser/msg_parser.h" + + int w_sd_lookup(struct sip_msg* _msg, char* _table, char* _owner); ++int w_sd_lookup_group(struct sip_msg* _msg, char* _table, char* _group); + int sd_lookup_owner(struct sip_msg* _msg, str* _stable, str* _sowner); ++int sd_lookup_group(struct sip_msg* _msg, str* _stable, str* _sgroup); + + #endif /* _SDLOOKUP_H_ */