dialplan: added dp_match() and dp_replace() functions
authorDaniel-Constantin Mierla <miconda@gmail.com>
Tue, 25 Jul 2017 17:06:05 +0000 (19:06 +0200)
committerDaniel-Constantin Mierla <miconda@gmail.com>
Tue, 25 Jul 2017 17:41:05 +0000 (19:41 +0200)
- alternatives to dp_translate() with dedicated required parameters
  (avoiding second parameter of two variables separated by '/')
- dp_match(dpid, inval)
- dp_replace(dpid, inval, outvar)
- dpid can be interger or variable
- inval can be a static or dynamic (with vars) string
- outvar has to be a writable variable

src/modules/dialplan/dialplan.c
src/modules/dialplan/dialplan.h
src/modules/dialplan/dp_repl.c

index 7fd6245..cac1df7 100644 (file)
@@ -49,6 +49,7 @@
 #include "../../core/action.h"
 #include "../../core/pvar.h"
 #include "../../core/dset.h"
+#include "../../core/mod_fix.h"
 #include "../../core/mem/mem.h"
 #include "../../core/parser/parse_to.h"
 #include "../../core/rpc.h"
@@ -70,9 +71,14 @@ static int dialplan_init_rpc(void);
 static int dp_translate_f(struct sip_msg* msg, char* str1, char* str2);
 static int dp_trans_fixup(void ** param, int param_no);
 static int dp_reload_f(struct sip_msg* msg);
+static int w_dp_replace(sip_msg_t* msg, char* pid, char* psrc, char* pdst);
+static int w_dp_match(sip_msg_t* msg, char* pid, char* psrc);
+
+int dp_replace_fixup(void** param, int param_no);
+int dp_replace_fixup_free(void** param, int param_no);
 
 str attr_pvar_s = STR_NULL;
-pv_spec_t * attr_pvar = NULL;
+pv_spec_t *attr_pvar = NULL;
 
 str default_param_s = str_init(DEFAULT_PARAM);
 dp_param_p default_par2 = NULL;
@@ -104,6 +110,10 @@ static cmd_export_t cmds[]={
                ANY_ROUTE},
        {"dp_reload",(cmd_function)dp_reload_f, 0, 0,  0,
                ANY_ROUTE},
+       {"dp_match",(cmd_function)w_dp_match,   2,      fixup_igp_spve,
+               fixup_free_igp_spve, ANY_ROUTE},
+       {"dp_replace",(cmd_function)w_dp_replace,       2,      dp_replace_fixup,
+               dp_replace_fixup_free, ANY_ROUTE},
        {0,0,0,0,0,0}
 };
 
@@ -235,7 +245,7 @@ static int dp_get_svalue(struct sip_msg * msg, pv_spec_t *spec, str* val)
 }
 
 
-static int dp_update(struct sip_msg * msg, pv_spec_t * src, pv_spec_t * dest,
+static int dp_update(struct sip_msg * msg, pv_spec_t * dest,
                str * repl, str * attrs)
 {
        int no_change;
@@ -287,7 +297,7 @@ static int dp_translate_f(struct sip_msg* msg, char* str1, char* str2)
        str input, output;
        dpl_id_p idp;
        dp_param_p id_par, repl_par;
-       str attrs, * attrs_par;
+       str attrs, *outattrs;
 
        if(!msg)
                return -1;
@@ -312,8 +322,8 @@ static int dp_translate_f(struct sip_msg* msg, char* str1, char* str2)
 
        LM_DBG("input is %.*s\n", input.len, input.s);
 
-       attrs_par = (!attr_pvar)?NULL:&attrs;
-       if (translate(msg, input, &output, idp, attrs_par)!=0){
+       outattrs = (!attr_pvar)?NULL:&attrs;
+       if (dp_translate_helper(msg, &input, &output, idp, outattrs)!=0) {
                LM_DBG("could not translate %.*s "
                                "with dpid %i\n", input.len, input.s, idp->dp_id);
                return -1;
@@ -322,8 +332,7 @@ static int dp_translate_f(struct sip_msg* msg, char* str1, char* str2)
                        input.len, input.s, idp->dp_id, output.len, output.s);
 
        /* set the output */
-       if (dp_update(msg, repl_par->v.sp[0], repl_par->v.sp[1],
-                               &output, attrs_par) !=0){
+       if (dp_update(msg, repl_par->v.sp[1], &output, outattrs) !=0){
                LM_ERR("cannot set the output\n");
                return -1;
        }
@@ -441,6 +450,96 @@ error:
        return ret;
 }
 
+static int dp_replace_helper(sip_msg_t *msg, int dpid, str *input,
+               pv_spec_t *pvd)
+{
+       dpl_id_p idp;
+       str output = STR_NULL;
+       str attrs = STR_NULL;
+       str *outattrs = NULL;
+
+       if ((idp = select_dpid(dpid)) ==0) {
+               LM_DBG("no information available for dpid %i\n", dpid);
+               return -2;
+       }
+
+       outattrs = (!attr_pvar)?NULL:&attrs;
+       if (dp_translate_helper(msg, input, &output, idp, outattrs)!=0) {
+               LM_DBG("could not translate %.*s "
+                               "with dpid %i\n", input->len, input->s, idp->dp_id);
+               return -1;
+       }
+       LM_DBG("input %.*s with dpid %i => output %.*s\n",
+                       input->len, input->s, idp->dp_id, output.len, output.s);
+
+       /* set the output */
+       if (dp_update(msg, pvd, &output, outattrs) !=0){
+               LM_ERR("cannot set the output\n");
+               return -1;
+       }
+
+       return 1;
+}
+
+static int w_dp_replace(sip_msg_t* msg, char* pid, char* psrc, char* pdst)
+{
+       int dpid = 1;
+       str src = STR_NULL;
+       pv_spec_t *pvd = NULL;
+
+       if(fixup_get_ivalue(msg, (gparam_t*)pid, &dpid)<0) {
+               LM_ERR("failed to get dialplan id value\n");
+               return -1;
+       }
+       if(fixup_get_svalue(msg, (gparam_t*)psrc, &src)<0) {
+               LM_ERR("failed to get src value\n");
+               return -1;
+       }
+       pvd = (pv_spec_t*)pdst;
+
+       return dp_replace_helper(msg, dpid, &src, pvd);
+}
+
+static int w_dp_match(sip_msg_t* msg, char* pid, char* psrc)
+{
+       int dpid = 1;
+       str src = STR_NULL;
+
+       if(fixup_get_ivalue(msg, (gparam_t*)pid, &dpid)<0) {
+               LM_ERR("failed to get dialplan id value\n");
+               return -1;
+       }
+       if(fixup_get_svalue(msg, (gparam_t*)psrc, &src)<0) {
+               LM_ERR("failed to get src value\n");
+               return -1;
+       }
+
+       return dp_replace_helper(msg, dpid, &src, NULL);
+}
+
+int dp_replace_fixup(void** param, int param_no)
+{
+       if (param_no == 1)
+               return fixup_igp_null(param, param_no);
+       else if (param_no == 2)
+               return fixup_spve_all(param, param_no);
+       else if (param_no == 3)
+               return fixup_pvar_all(param, param_no);
+       return E_UNSPEC;
+}
+
+
+int dp_replace_fixup_free(void** param, int param_no)
+{
+       if (param_no == 1)
+               return fixup_free_igp_null(param, param_no);
+       else if (param_no == 2)
+               return fixup_free_spve_all(param, param_no);
+       else if (param_no == 3)
+               return fixup_free_pvar_all(param, param_no);
+       return E_UNSPEC;
+}
+
 /**
  * trigger reload of dialplan db records from config file
  */
@@ -532,7 +631,7 @@ static void dialplan_rpc_translate(rpc_t* rpc, void* ctx)
 
        LM_DBG("trying to translate %.*s with dpid %i\n",
                        input.len, input.s, idp->dp_id);
-       if (translate(NULL, input, &output, idp, &attrs)!=0){
+       if (dp_translate_helper(NULL, &input, &output, idp, &attrs)!=0){
                LM_DBG("could not translate %.*s with dpid %i\n",
                                input.len, input.s, idp->dp_id);
                rpc->fault(ctx, 500, "No translation");
index d686f76..c47d53e 100644 (file)
@@ -96,8 +96,10 @@ dpl_id_p select_dpid(int id);
 
 struct subst_expr* repl_exp_parse(str subst);
 void repl_expr_free(struct subst_expr *se);
-int translate(struct sip_msg *msg, str user_name, str* repl_user, dpl_id_p idp, str *);
-int rule_translate(struct sip_msg *msg, str , dpl_node_t * rule, pcre *subst_comp,  str *);
+int dp_translate_helper(sip_msg_t *msg, str *user_name, str *repl_user,
+               dpl_id_p idp, str *);
+int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule,
+               pcre *subst_comp, str *);
 
 pcre *reg_ex_comp(const char *pattern, int *cap_cnt, int mtype);
 #endif
index 28d555b..06762ce 100644 (file)
@@ -384,11 +384,10 @@ error:
 }
 
 
-
 #define MAX_PHONE_NB_DIGITS            127
 static char dp_output_buf[MAX_PHONE_NB_DIGITS+1];
-int rule_translate(sip_msg_t *msg, str string, dpl_node_t * rule,
-               pcre *subst_comp, str * result)
+int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule,
+               pcre *subst_comp, str *result)
 {
        int repl_nb, offset, match_nb, rc, cap_cnt;
        struct replace_with token;
@@ -431,11 +430,11 @@ int rule_translate(sip_msg_t *msg, str string, dpl_node_t * rule,
                }
 
                /*search for the pattern from the compiled subst_exp*/
-               if (pcre_exec(subst_comp, NULL, string.s, string.len,
+               if (pcre_exec(subst_comp, NULL, instr->s, instr->len,
                                        0, 0, ovector, 3 * (MAX_REPLACE_WITH + 1)) <= 0) {
                        LM_ERR("the string %.*s matched "
-                                       "the match_exp %.*s but not the subst_exp %.*s!\n", 
-                                       string.len, string.s, 
+                                       "the match_exp %.*s but not the subst_exp %.*s!\n",
+                                       instr->len, instr->s,
                                        rule->match_exp.len, rule->match_exp.s,
                                        rule->subst_exp.len, rule->subst_exp.s);
                        return -1;
@@ -484,7 +483,7 @@ int rule_translate(sip_msg_t *msg, str string, dpl_node_t * rule,
                        case REPLACE_NMATCH:
                                /*copy from the match subexpression*/   
                                match_nb = token.u.nmatch * 2;
-                               match.s =  string.s + ovector[match_nb];
+                               match.s =  instr->s + ovector[match_nb];
                                match.len = ovector[match_nb + 1] - ovector[match_nb];
                                if(result->len + match.len >= MAX_PHONE_NB_DIGITS){
                                        LM_ERR("overflow\n");
@@ -573,7 +572,7 @@ error:
 
 #define DP_MAX_ATTRS_LEN       255
 static char dp_attrs_buf[DP_MAX_ATTRS_LEN+1];
-int translate(sip_msg_t *msg, str input, str *output, dpl_id_p idp,
+int dp_translate_helper(sip_msg_t *msg, str *input, str *output, dpl_id_p idp,
                str *attrs)
 {
        dpl_node_p rulep;
@@ -583,18 +582,18 @@ int translate(sip_msg_t *msg, str input, str *output, dpl_id_p idp,
        dpl_dyn_pcre_p re_list = NULL;
        dpl_dyn_pcre_p rt = NULL;
 
-       if(!input.s || !input.len) {
+       if(!input || !input->s || !input->len) {
                LM_WARN("invalid or empty input string to be matched\n");
                return -1;
        }
 
-       user_len = input.len;
+       user_len = input->len;
        for(indexp = idp->first_index; indexp!=NULL; indexp = indexp->next)
                if(!indexp->len || (indexp->len!=0 && indexp->len == user_len) )
                        break;
 
        if(!indexp || (indexp!= NULL && !indexp->first_rule)){
-               LM_DBG("no rule for len %i\n", input.len);
+               LM_DBG("no rule for len %i\n", input->len);
                return -1;
        }
 
@@ -604,7 +603,7 @@ search_rule:
 
                        case DP_REGEX_OP:
                                LM_DBG("regex operator testing over [%.*s]\n",
-                                               input.len, input.s);
+                                               input->len, input->s);
                                if(rulep->tflags&DP_TFLAGS_PV_MATCH) {
                                        re_list = dpl_dynamic_pcre_list(msg, &rulep->match_exp);
                                        if(re_list==NULL) {
@@ -616,7 +615,7 @@ search_rule:
                                        rez = -1;
                                        do {
                                                if(rez<0) {
-                                                       rez = pcre_exec(re_list->re, NULL, input.s, input.len,
+                                                       rez = pcre_exec(re_list->re, NULL, input->s, input->len,
                                                                        0, 0, NULL, 0);
                                                        LM_DBG("match check: [%.*s] %d\n",
                                                                re_list->expr.len, re_list->expr.s, rez);
@@ -629,7 +628,7 @@ search_rule:
                                                re_list = rt;
                                        } while(re_list);
                                } else {
-                                       rez = pcre_exec(rulep->match_comp, NULL, input.s, input.len,
+                                       rez = pcre_exec(rulep->match_comp, NULL, input->s, input->len,
                                                0, 0, NULL, 0);
                                }
                                break;
@@ -637,10 +636,10 @@ search_rule:
                        case DP_EQUAL_OP:
                                LM_DBG("equal operator testing\n");
                                if(rulep->match_exp.s==NULL
-                                               || rulep->match_exp.len != input.len) {
+                                               || rulep->match_exp.len != input->len) {
                                        rez = -1;
                                } else {
-                                       rez = strncmp(rulep->match_exp.s,input.s,input.len);
+                                       rez = strncmp(rulep->match_exp.s, input->s, input->len);
                                        rez = (rez==0)?0:-1;
                                }
                                break;
@@ -648,10 +647,10 @@ search_rule:
                        case DP_FNMATCH_OP:
                                LM_DBG("fnmatch operator testing\n");
                                if(rulep->match_exp.s!=NULL) {
-                                       b = input.s[input.len];
-                                       input.s[input.len] = '\0';
-                                       rez = fnmatch(rulep->match_exp.s, input.s, 0);
-                                       input.s[input.len] = b;
+                                       b = input->s[input->len];
+                                       input->s[input->len] = '\0';
+                                       rez = fnmatch(rulep->match_exp.s, input->s, 0);
+                                       input->s[input->len] = b;
                                        rez = (rez==0)?0:-1;
                                } else {
                                        rez = -1;