... | ... |
@@ -168,6 +168,7 @@ void dlg_clean_timer_exec(unsigned int ticks, void* param); |
168 | 168 |
static int fixup_profile(void** param, int param_no); |
169 | 169 |
static int fixup_get_profile2(void** param, int param_no); |
170 | 170 |
static int fixup_get_profile3(void** param, int param_no); |
171 |
+static int fixup_dlg_get_matches(void** param, int param_no); |
|
171 | 172 |
static int w_set_dlg_profile(struct sip_msg*, char*, char*); |
172 | 173 |
static int w_unset_dlg_profile(struct sip_msg*, char*, char*); |
173 | 174 |
static int w_is_in_profile(struct sip_msg*, char*, char*); |
... | ... |
@@ -192,6 +193,8 @@ static int fixup_dlg_bridge(void** param, int param_no); |
192 | 193 |
static int w_dlg_get(struct sip_msg*, char*, char*, char*); |
193 | 194 |
static int w_is_known_dlg(struct sip_msg *); |
194 | 195 |
static int w_dlg_set_ruri(sip_msg_t *, char *, char *); |
196 |
+static int w_dlg_get_matches1(struct sip_msg*, char*, char*, char*, char*); |
|
197 |
+static int w_dlg_get_matches2(struct sip_msg*, char*, char*, char*, char*, char*); |
|
195 | 198 |
static int w_dlg_db_load_callid(sip_msg_t *msg, char *ci, char *p2); |
196 | 199 |
static int w_dlg_db_load_extra(sip_msg_t *msg, char *p1, char *p2); |
197 | 200 |
static int fixup_dlg_get_var(void** param, int param_no); |
... | ... |
@@ -257,6 +260,10 @@ static cmd_export_t cmds[]={ |
257 | 260 |
0, ANY_ROUTE }, |
258 | 261 |
{"dlg_set_ruri", (cmd_function)w_dlg_set_ruri, 0, NULL, |
259 | 262 |
0, ANY_ROUTE }, |
263 |
+ {"dlg_get_matches", (cmd_function)w_dlg_get_matches1, 4, fixup_dlg_get_matches, |
|
264 |
+ 0, ANY_ROUTE }, |
|
265 |
+ {"dlg_get_matches", (cmd_function)w_dlg_get_matches2, 5, fixup_dlg_get_matches, |
|
266 |
+ 0, ANY_ROUTE }, |
|
260 | 267 |
{"dlg_db_load_callid", (cmd_function)w_dlg_db_load_callid, 1, fixup_spve_null, |
261 | 268 |
0, ANY_ROUTE }, |
262 | 269 |
{"dlg_db_load_extra", (cmd_function)w_dlg_db_load_extra, 0, 0, |
... | ... |
@@ -448,6 +455,48 @@ static int fixup_get_profile3(void** param, int param_no) |
448 | 455 |
return 0; |
449 | 456 |
} |
450 | 457 |
|
458 |
+static int fixup_dlg_get_matches(void **param, int param_no) |
|
459 |
+{ |
|
460 |
+ str s; |
|
461 |
+ |
|
462 |
+ s.s = (char *)(*param); |
|
463 |
+ s.len = strlen(s.s); |
|
464 |
+ if(s.len == 0) { |
|
465 |
+ LM_ERR("param %d is empty string!\n", param_no); |
|
466 |
+ return E_CFG; |
|
467 |
+ } |
|
468 |
+ |
|
469 |
+ //Match key |
|
470 |
+ if(param_no == 1) { |
|
471 |
+ if(strncmp(s.s, "ruri", s.len) != 0 |
|
472 |
+ && strncmp(s.s, "turi", s.len) != 0 |
|
473 |
+ && strncmp(s.s, "furi", s.len) != 0 |
|
474 |
+ && strncmp(s.s, "callid", s.len) != 0 |
|
475 |
+ && strncmp(s.s, "start_ts", s.len) != 0) { |
|
476 |
+ LM_ERR("param %d must be 'ruri', 'turi', 'furi', 'callid' or 'start_ts'.\n", |
|
477 |
+ param_no); |
|
478 |
+ return E_CFG; |
|
479 |
+ } |
|
480 |
+ // Match operator |
|
481 |
+ } else if(param_no == 2) { |
|
482 |
+ if(strncmp(s.s, "eq", s.len) != 0 |
|
483 |
+ && strncmp(s.s, "sw", s.len) != 0 |
|
484 |
+ && strncmp(s.s, "re", s.len) != 0 |
|
485 |
+ && strncmp(s.s, "gt", s.len) != 0 |
|
486 |
+ && strncmp(s.s, "lt", s.len) != 0) { |
|
487 |
+ LM_ERR("param %d must be 'eq', 'sw', 're', 'gt' or 'lt'.\n", param_no); |
|
488 |
+ return E_CFG; |
|
489 |
+ } |
|
490 |
+ //No extra validation for param 3 |
|
491 |
+ |
|
492 |
+ //XAVP result variable |
|
493 |
+ } else if(param_no == 4) { |
|
494 |
+ /* We don't to evaluate the variable, just accept a string name to use as the XAVP class name. |
|
495 |
+ * no further validation needed. |
|
496 |
+ */ |
|
497 |
+ } |
|
498 |
+ return 0; |
|
499 |
+} |
|
451 | 500 |
|
452 | 501 |
|
453 | 502 |
int load_dlg( struct dlg_binds *dlgb ) |
... | ... |
@@ -2784,6 +2833,611 @@ static int w_dlg_set_ruri(sip_msg_t *msg, char *p1, char *p2) |
2784 | 2833 |
return dlg_set_ruri(msg); |
2785 | 2834 |
} |
2786 | 2835 |
|
2836 |
+/*! |
|
2837 |
+ * \brief Helper function that outputs ptrs to matching dialogs in an array to be used elsewhere. |
|
2838 |
+ * |
|
2839 |
+ * \param list Ptr to hold array of dlg_cell_match_t struct ptrs to return results in. |
|
2840 |
+ * \param mkey The dlg field to match against |
|
2841 |
+ * \param mop The matching operation to use |
|
2842 |
+ * \param mval The value to match against |
|
2843 |
+ * \param max_results The max amount of results to return, or 0 if no limit |
|
2844 |
+ * |
|
2845 |
+ * \return -1 if error, or otherwise the number of matches returned in the array. |
|
2846 |
+ */ |
|
2847 |
+static int dlg_list_matches(dlg_cell_match_t **list, str mkey, str mop, str mval, int max_results) |
|
2848 |
+{ |
|
2849 |
+ dlg_cell_t *dlg = NULL; |
|
2850 |
+ int i = 0; |
|
2851 |
+ str sval = {NULL, 0}; |
|
2852 |
+ unsigned int ival = 0; |
|
2853 |
+ unsigned int mival = 0; |
|
2854 |
+ int matches = 0; |
|
2855 |
+ int vkey = 0; |
|
2856 |
+ int vop = 0; |
|
2857 |
+ int matched = 0; |
|
2858 |
+ regex_t mre; |
|
2859 |
+ regmatch_t pmatch; |
|
2860 |
+ size_t arr_size = 0; //Start at 0 as shm for array is allocated below. |
|
2861 |
+ |
|
2862 |
+ if(mkey.s==NULL || mkey.len<=0 || mop.s==NULL || mop.len<=0 |
|
2863 |
+ || mval.s==NULL || mval.len<=0) { |
|
2864 |
+ LM_ERR("invalid parameters\n"); |
|
2865 |
+ return -1; |
|
2866 |
+ } |
|
2867 |
+ if(mkey.len==4 && strncmp(mkey.s, "ruri", mkey.len)==0) { |
|
2868 |
+ vkey = 0; |
|
2869 |
+ } else if(mkey.len==4 && strncmp(mkey.s, "furi", mkey.len)==0) { |
|
2870 |
+ vkey = 1; |
|
2871 |
+ } else if(mkey.len==4 && strncmp(mkey.s, "turi", mkey.len)==0) { |
|
2872 |
+ vkey = 2; |
|
2873 |
+ } else if(mkey.len==6 && strncmp(mkey.s, "callid", mkey.len)==0) { |
|
2874 |
+ vkey = 3; |
|
2875 |
+ } else if(mkey.len==8 && strncmp(mkey.s, "start_ts", mkey.len)==0) { |
|
2876 |
+ vkey = 4; |
|
2877 |
+ } else { |
|
2878 |
+ LM_ERR("invalid key %.*s\n", mkey.len, mkey.s); |
|
2879 |
+ return -1; |
|
2880 |
+ } |
|
2881 |
+ if(mop.len!=2) { |
|
2882 |
+ LM_ERR("invalid matching operator %.*s\n", mop.len, mop.s); |
|
2883 |
+ return -1; |
|
2884 |
+ |
|
2885 |
+ } |
|
2886 |
+ if(strncmp(mop.s, "eq", 2)==0) { |
|
2887 |
+ vop = 0; |
|
2888 |
+ } else if(strncmp(mop.s, "re", 2)==0) { |
|
2889 |
+ vop = 1; |
|
2890 |
+ memset(&mre, 0, sizeof(regex_t)); |
|
2891 |
+ if (regcomp(&mre, mval.s, REG_EXTENDED|REG_ICASE|REG_NEWLINE)!=0) { |
|
2892 |
+ LM_ERR("failed to compile regex: %.*s\n", mval.len, mval.s); |
|
2893 |
+ return -1; |
|
2894 |
+ } |
|
2895 |
+ } else if(strncmp(mop.s, "sw", 2)==0) { |
|
2896 |
+ vop = 2; |
|
2897 |
+ } else if(strncmp(mop.s, "gt", 2)==0) { |
|
2898 |
+ vop = 3; |
|
2899 |
+ } else if(strncmp(mop.s, "lt", 2)==0) { |
|
2900 |
+ vop = 4; |
|
2901 |
+ } else { |
|
2902 |
+ LM_ERR("invalid matching operator %.*s\n", mop.len, mop.s); |
|
2903 |
+ return -1; |
|
2904 |
+ } |
|
2905 |
+ |
|
2906 |
+ if (vkey == 4 && vop <= 2) { |
|
2907 |
+ LM_ERR("Matching operator %.*s not supported with start_ts key\n", mop.len, mop.s); |
|
2908 |
+ goto error; |
|
2909 |
+ } |
|
2910 |
+ |
|
2911 |
+ if (vkey != 4 && vop >= 3) { |
|
2912 |
+ LM_ERR("Matching operator %.*s not supported with key %.*s\n", mop.len, mop.s, mkey.len, mkey.s); |
|
2913 |
+ return -1; |
|
2914 |
+ } |
|
2915 |
+ |
|
2916 |
+ for(i=0; i<d_table->size; i++) { |
|
2917 |
+ dlg_lock(d_table, &(d_table->entries[i])); |
|
2918 |
+ for(dlg=d_table->entries[i].first; dlg!=NULL; dlg=dlg->next) { |
|
2919 |
+ matched = 0; |
|
2920 |
+ switch(vkey) { |
|
2921 |
+ case 0: |
|
2922 |
+ sval = dlg->req_uri; |
|
2923 |
+ break; |
|
2924 |
+ case 1: |
|
2925 |
+ sval = dlg->from_uri; |
|
2926 |
+ break; |
|
2927 |
+ case 2: |
|
2928 |
+ sval = dlg->to_uri; |
|
2929 |
+ break; |
|
2930 |
+ case 3: |
|
2931 |
+ sval = dlg->callid; |
|
2932 |
+ break; |
|
2933 |
+ case 4: |
|
2934 |
+ ival = dlg->start_ts; |
|
2935 |
+ break; |
|
2936 |
+ } |
|
2937 |
+ switch(vop) { |
|
2938 |
+ case 0: |
|
2939 |
+ /* string comparison */ |
|
2940 |
+ if(mval.len==sval.len |
|
2941 |
+ && strncmp(mval.s, sval.s, mval.len)==0) { |
|
2942 |
+ matched = 1; |
|
2943 |
+ } |
|
2944 |
+ break; |
|
2945 |
+ case 1: |
|
2946 |
+ /* regexp matching */ |
|
2947 |
+ if(regexec(&mre, sval.s, 1, &pmatch, 0)==0) { |
|
2948 |
+ matched = 1; |
|
2949 |
+ } |
|
2950 |
+ break; |
|
2951 |
+ case 2: |
|
2952 |
+ /* starts with */ |
|
2953 |
+ if(mval.len<=sval.len |
|
2954 |
+ && strncmp(mval.s, sval.s, mval.len)==0) { |
|
2955 |
+ matched = 1; |
|
2956 |
+ } |
|
2957 |
+ break; |
|
2958 |
+ case 3: |
|
2959 |
+ /* greater than */ |
|
2960 |
+ if (str2int(&mval, &mival) == 0 && ival > mival) { |
|
2961 |
+ matched = 1; |
|
2962 |
+ } |
|
2963 |
+ break; |
|
2964 |
+ case 4: |
|
2965 |
+ if (str2int(&mval, &mival) == 0 && ival < mival) { |
|
2966 |
+ matched = 1; |
|
2967 |
+ } |
|
2968 |
+ break; |
|
2969 |
+ } |
|
2970 |
+ if (matched==1) { |
|
2971 |
+ matches++; |
|
2972 |
+ if (matches > arr_size) { |
|
2973 |
+ arr_size = (arr_size == 0 ? 1 : arr_size * 2); |
|
2974 |
+ if (arr_size == 1) { |
|
2975 |
+ *list = (dlg_cell_match_t *)shm_malloc(arr_size * sizeof(dlg_cell_match_t)); |
|
2976 |
+ } else { |
|
2977 |
+ *list = (dlg_cell_match_t *)shm_realloc(*list, arr_size * sizeof(dlg_cell_match_t)); |
|
2978 |
+ } |
|
2979 |
+ if (*list == NULL) { |
|
2980 |
+ LM_ERR("no more shm mem (%ld)\n", arr_size * sizeof(dlg_cell_match_t)); |
|
2981 |
+ dlg_unlock(d_table, &(d_table->entries[i])); |
|
2982 |
+ goto error; |
|
2983 |
+ } |
|
2984 |
+ LM_DBG("Re-sized matches array in shm (%ld): %p\n", arr_size * sizeof(dlg_cell_match_t), *list); |
|
2985 |
+ } |
|
2986 |
+ LM_DBG("Adding dlg match[%d] at %p = dlg ptr %p with entry %u\n", matches-1, (*list + (matches - 1)), dlg, i); |
|
2987 |
+ dlg_cell_match_t *dlg_match = (*list + (matches-1)); |
|
2988 |
+ dlg_match->dlg = dlg; |
|
2989 |
+ dlg_match->entry = i; |
|
2990 |
+ |
|
2991 |
+ if(max_results > 0 && matches == max_results) { |
|
2992 |
+ break; |
|
2993 |
+ } |
|
2994 |
+ } |
|
2995 |
+ } |
|
2996 |
+ dlg_unlock(d_table, &(d_table->entries[i])); |
|
2997 |
+ if(max_results > 0 && matches == max_results) { |
|
2998 |
+ break; |
|
2999 |
+ } |
|
3000 |
+ } |
|
3001 |
+ if(vop == 1) { |
|
3002 |
+ regfree(&mre); |
|
3003 |
+ } |
|
3004 |
+ |
|
3005 |
+ return matches; |
|
3006 |
+ |
|
3007 |
+error: |
|
3008 |
+ if (vop == 1) { |
|
3009 |
+ regfree(&mre); |
|
3010 |
+ } |
|
3011 |
+ return -1; |
|
3012 |
+} |
|
3013 |
+ |
|
3014 |
+ |
|
3015 |
+ |
|
3016 |
+ |
|
3017 |
+/*! |
|
3018 |
+ * \brief Helper function that adds a given dialog's values to a given XAVP. |
|
3019 |
+ * |
|
3020 |
+ * \param xavp XAVP array to add dialog values |
|
3021 |
+ * \param dlg Pointer to a dialog to get values from |
|
3022 |
+ * \return Returns 1 on success or 0 on failure. |
|
3023 |
+ */ |
|
3024 |
+static int dlg_get_matches_xavp_helper(sr_xavp_t **xavp, dlg_cell_t *dlg) |
|
3025 |
+{ |
|
3026 |
+ str xname_h_entry = str_init("h_entry"); |
|
3027 |
+ str xname_h_id = str_init("h_id"); |
|
3028 |
+ str xname_ref = str_init("ref"); |
|
3029 |
+ str xname_callid = str_init("callid"); |
|
3030 |
+ str xname_from_uri = str_init("from_uri"); |
|
3031 |
+ str xname_to_uri = str_init("to_uri"); |
|
3032 |
+ str xname_state = str_init("state"); |
|
3033 |
+ str xname_start_ts = str_init("start_ts"); |
|
3034 |
+ str xname_init_ts = str_init("init_ts"); |
|
3035 |
+ str xname_end_ts = str_init("end_ts"); |
|
3036 |
+ str xname_duration = str_init("duration"); |
|
3037 |
+ str xname_timeout = str_init("timeout"); |
|
3038 |
+ str xname_lifetime = str_init("lifetime"); |
|
3039 |
+ str xname_dflags = str_init("dflags"); |
|
3040 |
+ str xname_sflags = str_init("sflags"); |
|
3041 |
+ str xname_iflags = str_init("iflags"); |
|
3042 |
+ str xname_caller_tag = str_init("caller_tag"); |
|
3043 |
+ str xname_caller_contact = str_init("caller_contact"); |
|
3044 |
+ str xname_caller_cseq = str_init("caller_cseq"); |
|
3045 |
+ str xname_caller_route_set = str_init("caller_route_set"); |
|
3046 |
+ str xname_caller_socket = str_init("caller_socket"); |
|
3047 |
+ str xname_callee_tag = str_init("callee_tag"); |
|
3048 |
+ str xname_callee_contact = str_init("callee_contact"); |
|
3049 |
+ str xname_callee_cseq = str_init("callee_cseq"); |
|
3050 |
+ str xname_callee_route_set = str_init("callee_route_set"); |
|
3051 |
+ str xname_callee_socket = str_init("callee_socket"); |
|
3052 |
+ |
|
3053 |
+ sr_xval_t xval; |
|
3054 |
+ dlg_profile_link_t *pl; |
|
3055 |
+ dlg_var_t *var; |
|
3056 |
+ |
|
3057 |
+ if(dlg == NULL) { |
|
3058 |
+ LM_ERR("Null dialog was passed.\n"); |
|
3059 |
+ return 0; |
|
3060 |
+ } |
|
3061 |
+ |
|
3062 |
+ time_t tnow; |
|
3063 |
+ int tdur; |
|
3064 |
+ |
|
3065 |
+ tnow = time(NULL); |
|
3066 |
+ if(dlg->end_ts) { |
|
3067 |
+ tdur = (int)(dlg->end_ts - dlg->start_ts); |
|
3068 |
+ } else if(dlg->start_ts) { |
|
3069 |
+ tdur = (int)(tnow - dlg->start_ts); |
|
3070 |
+ } else { |
|
3071 |
+ tdur = 0; |
|
3072 |
+ } |
|
3073 |
+ |
|
3074 |
+ //h_entry |
|
3075 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3076 |
+ xval.type = SR_XTYPE_INT; |
|
3077 |
+ xval.v.i = dlg->h_entry; |
|
3078 |
+ xavp_add_value(&xname_h_entry, &xval, xavp); |
|
3079 |
+ |
|
3080 |
+ //h_id |
|
3081 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3082 |
+ xval.type = SR_XTYPE_INT; |
|
3083 |
+ xval.v.i = dlg->h_id; |
|
3084 |
+ xavp_add_value(&xname_h_id, &xval, xavp); |
|
3085 |
+ |
|
3086 |
+ //ref |
|
3087 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3088 |
+ xval.type = SR_XTYPE_INT; |
|
3089 |
+ xval.v.i = dlg->ref; |
|
3090 |
+ xavp_add_value(&xname_ref, &xval, xavp); |
|
3091 |
+ |
|
3092 |
+ //callid |
|
3093 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3094 |
+ xval.type = SR_XTYPE_STR; |
|
3095 |
+ xval.v.s = dlg->callid; |
|
3096 |
+ xavp_add_value(&xname_callid, &xval, xavp); |
|
3097 |
+ |
|
3098 |
+ //from_uri |
|
3099 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3100 |
+ xval.type = SR_XTYPE_STR; |
|
3101 |
+ xval.v.s = dlg->from_uri; |
|
3102 |
+ xavp_add_value(&xname_from_uri, &xval, xavp); |
|
3103 |
+ |
|
3104 |
+ //to_uri |
|
3105 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3106 |
+ xval.type = SR_XTYPE_STR; |
|
3107 |
+ xval.v.s = dlg->to_uri; |
|
3108 |
+ xavp_add_value(&xname_to_uri, &xval, xavp); |
|
3109 |
+ |
|
3110 |
+ //state |
|
3111 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3112 |
+ xval.type = SR_XTYPE_INT; |
|
3113 |
+ xval.v.i = dlg->state; |
|
3114 |
+ xavp_add_value(&xname_state, &xval, xavp); |
|
3115 |
+ |
|
3116 |
+ //start_ts |
|
3117 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3118 |
+ xval.type = SR_XTYPE_INT; |
|
3119 |
+ xval.v.i = dlg->start_ts; |
|
3120 |
+ xavp_add_value(&xname_start_ts, &xval, xavp); |
|
3121 |
+ |
|
3122 |
+ //init_ts |
|
3123 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3124 |
+ xval.type = SR_XTYPE_INT; |
|
3125 |
+ xval.v.i = dlg->init_ts; |
|
3126 |
+ xavp_add_value(&xname_init_ts, &xval, xavp); |
|
3127 |
+ |
|
3128 |
+ //end_ts |
|
3129 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3130 |
+ xval.type = SR_XTYPE_INT; |
|
3131 |
+ xval.v.i = dlg->end_ts; |
|
3132 |
+ xavp_add_value(&xname_end_ts, &xval, xavp); |
|
3133 |
+ |
|
3134 |
+ //duration |
|
3135 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3136 |
+ xval.type = SR_XTYPE_INT; |
|
3137 |
+ xval.v.i = tdur; |
|
3138 |
+ xavp_add_value(&xname_duration, &xval, xavp); |
|
3139 |
+ |
|
3140 |
+ //timeout |
|
3141 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3142 |
+ xval.type = SR_XTYPE_INT; |
|
3143 |
+ xval.v.i = dlg->tl.timeout ? tnow + dlg->tl.timeout - get_ticks() : 0; |
|
3144 |
+ xavp_add_value(&xname_timeout, &xval, xavp); |
|
3145 |
+ |
|
3146 |
+ //lifetime |
|
3147 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3148 |
+ xval.type = SR_XTYPE_INT; |
|
3149 |
+ xval.v.i = dlg->lifetime; |
|
3150 |
+ xavp_add_value(&xname_lifetime, &xval, xavp); |
|
3151 |
+ |
|
3152 |
+ //dflags |
|
3153 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3154 |
+ xval.type = SR_XTYPE_INT; |
|
3155 |
+ xval.v.i = dlg->dflags; |
|
3156 |
+ xavp_add_value(&xname_dflags, &xval, xavp); |
|
3157 |
+ |
|
3158 |
+ //sflags |
|
3159 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3160 |
+ xval.type = SR_XTYPE_INT; |
|
3161 |
+ xval.v.i = dlg->sflags; |
|
3162 |
+ xavp_add_value(&xname_sflags, &xval, xavp); |
|
3163 |
+ |
|
3164 |
+ //iflags |
|
3165 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3166 |
+ xval.type = SR_XTYPE_INT; |
|
3167 |
+ xval.v.i = dlg->iflags; |
|
3168 |
+ xavp_add_value(&xname_iflags, &xval, xavp); |
|
3169 |
+ |
|
3170 |
+ //caller_tag |
|
3171 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3172 |
+ xval.type = SR_XTYPE_STR; |
|
3173 |
+ xval.v.s = dlg->tag[DLG_CALLER_LEG]; |
|
3174 |
+ xavp_add_value(&xname_caller_tag, &xval, xavp); |
|
3175 |
+ |
|
3176 |
+ //caller_contact |
|
3177 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3178 |
+ xval.type = SR_XTYPE_STR; |
|
3179 |
+ xval.v.s = dlg->contact[DLG_CALLER_LEG]; |
|
3180 |
+ xavp_add_value(&xname_caller_contact, &xval, xavp); |
|
3181 |
+ |
|
3182 |
+ //caller_cseq |
|
3183 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3184 |
+ xval.type = SR_XTYPE_STR; |
|
3185 |
+ xval.v.s = dlg->cseq[DLG_CALLER_LEG]; |
|
3186 |
+ xavp_add_value(&xname_caller_cseq, &xval, xavp); |
|
3187 |
+ |
|
3188 |
+ //caller_route_set |
|
3189 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3190 |
+ xval.type = SR_XTYPE_STR; |
|
3191 |
+ xval.v.s = dlg->route_set[DLG_CALLER_LEG]; |
|
3192 |
+ xavp_add_value(&xname_caller_route_set, &xval, xavp); |
|
3193 |
+ |
|
3194 |
+ //caller_socket |
|
3195 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3196 |
+ xval.type = SR_XTYPE_STR; |
|
3197 |
+ xval.v.s = dlg->bind_addr[DLG_CALLER_LEG] |
|
3198 |
+ ? dlg->bind_addr[DLG_CALLER_LEG]->sock_str |
|
3199 |
+ : empty_str; |
|
3200 |
+ xavp_add_value(&xname_caller_socket, &xval, xavp); |
|
3201 |
+ |
|
3202 |
+ //callee_tag |
|
3203 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3204 |
+ xval.type = SR_XTYPE_STR; |
|
3205 |
+ xval.v.s = dlg->tag[DLG_CALLEE_LEG]; |
|
3206 |
+ xavp_add_value(&xname_callee_tag, &xval, xavp); |
|
3207 |
+ |
|
3208 |
+ //callee_contact |
|
3209 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3210 |
+ xval.type = SR_XTYPE_STR; |
|
3211 |
+ xval.v.s = dlg->contact[DLG_CALLEE_LEG]; |
|
3212 |
+ xavp_add_value(&xname_callee_contact, &xval, xavp); |
|
3213 |
+ |
|
3214 |
+ //callee_cseq |
|
3215 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3216 |
+ xval.type = SR_XTYPE_STR; |
|
3217 |
+ xval.v.s = dlg->cseq[DLG_CALLEE_LEG]; |
|
3218 |
+ xavp_add_value(&xname_callee_cseq, &xval, xavp); |
|
3219 |
+ |
|
3220 |
+ //callee_route_set |
|
3221 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3222 |
+ xval.type = SR_XTYPE_STR; |
|
3223 |
+ xval.v.s = dlg->route_set[DLG_CALLEE_LEG]; |
|
3224 |
+ xavp_add_value(&xname_callee_route_set, &xval, xavp); |
|
3225 |
+ |
|
3226 |
+ //callee_socket |
|
3227 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3228 |
+ xval.type = SR_XTYPE_STR; |
|
3229 |
+ xval.v.s = dlg->bind_addr[DLG_CALLEE_LEG] |
|
3230 |
+ ? dlg->bind_addr[DLG_CALLEE_LEG]->sock_str |
|
3231 |
+ : empty_str; |
|
3232 |
+ xavp_add_value(&xname_callee_socket, &xval, xavp); |
|
3233 |
+ |
|
3234 |
+ for(pl = dlg->profile_links; pl && (dlg->state < DLG_STATE_DELETED); pl = pl->next) { |
|
3235 |
+ //Prefix profile XAVPs with prf_ |
|
3236 |
+ //prefix + name + NULL |
|
3237 |
+ int buflen = 4 + pl->profile->name.len + 1; |
|
3238 |
+ char buf[buflen]; |
|
3239 |
+ snprintf(buf, buflen, "prf_%s", pl->profile->name.s); |
|
3240 |
+ str s; |
|
3241 |
+ s.s = buf; |
|
3242 |
+ s.len = strlen(buf); |
|
3243 |
+ |
|
3244 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3245 |
+ xval.type = SR_XTYPE_STR; |
|
3246 |
+ |
|
3247 |
+ if(pl->profile->has_value) { |
|
3248 |
+ xval.v.s = pl->hash_linker.value; |
|
3249 |
+ } else { |
|
3250 |
+ xval.v.s = empty_str; |
|
3251 |
+ } |
|
3252 |
+ xavp_add_value(&s, &xval, xavp); |
|
3253 |
+ } |
|
3254 |
+ |
|
3255 |
+ for(var = dlg->vars; var && (dlg->state < DLG_STATE_DELETED); var = var->next) { |
|
3256 |
+ //Prefix dlg var XAVPs with var_ |
|
3257 |
+ //prefix + key + NULL |
|
3258 |
+ int buflen = 4 + var->key.len + 1; |
|
3259 |
+ char buf[buflen]; |
|
3260 |
+ snprintf(buf, buflen, "var_%s", var->key.s); |
|
3261 |
+ str s; |
|
3262 |
+ s.s = buf; |
|
3263 |
+ s.len = strlen(buf); |
|
3264 |
+ |
|
3265 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3266 |
+ xval.type = SR_XTYPE_STR; |
|
3267 |
+ xval.v.s = var->value; |
|
3268 |
+ xavp_add_value(&s, &xval, xavp); |
|
3269 |
+ } |
|
3270 |
+ return 1; |
|
3271 |
+} |
|
3272 |
+ |
|
3273 |
+ |
|
3274 |
+/*! |
|
3275 |
+ * \brief Function matches against dialogs based on the provided mkey, mop and mval, |
|
3276 |
+ * then stores results in an XAVP variable. |
|
3277 |
+ * |
|
3278 |
+ * \param msg SIP message |
|
3279 |
+ * \param mkey Field of dialogs to match against |
|
3280 |
+ * \param mop Type of matching to perform |
|
3281 |
+ * \param mval String value to match against, can contain a pvar. |
|
3282 |
+ * \param xavp_name String name of an XAVP variable to store results in. |
|
3283 |
+ * \param max_results Integer with max results to return, returns all if 0. |
|
3284 |
+ * \return Count of matching dialogs, or -1 if no matches found. |
|
3285 |
+ */ |
|
3286 |
+static int internal_dlg_get_matches(struct sip_msg *msg, char *mkey, char *mop, |
|
3287 |
+ char *mval, char *xavp_name, int max_results) |
|
3288 |
+{ |
|
3289 |
+ dlg_cell_match_t *dlg_matches = NULL; //Ptr for array to store dlg matches. |
|
3290 |
+ int i = 0; |
|
3291 |
+ int matches = 0; //Count of matches returned. |
|
3292 |
+ sr_xavp_t **xavp = NULL; //XAVP to store fields |
|
3293 |
+ sr_xavp_t *list = NULL; //Ptr to existing XAVP with "xavp_name" if one exists. |
|
3294 |
+ sr_xavp_t *new_xavp = NULL; |
|
3295 |
+ |
|
3296 |
+ str mkey_s; |
|
3297 |
+ mkey_s.s = mkey; |
|
3298 |
+ mkey_s.len = strlen(mkey); |
|
3299 |
+ |
|
3300 |
+ str mop_s; |
|
3301 |
+ mop_s.s = mop; |
|
3302 |
+ mop_s.len = strlen(mop); |
|
3303 |
+ |
|
3304 |
+ str mval_sraw; |
|
3305 |
+ mval_sraw.s = mval; |
|
3306 |
+ mval_sraw.len = strlen(mval); |
|
3307 |
+ |
|
3308 |
+ str xavp_name_s = {0, 0}; |
|
3309 |
+ str xavp_name_sraw; |
|
3310 |
+ xavp_name_sraw.s = xavp_name; |
|
3311 |
+ xavp_name_sraw.len = strlen(xavp_name); |
|
3312 |
+ |
|
3313 |
+ LM_DBG("Looking for matches against: %s\n", mval_sraw.s); |
|
3314 |
+ //Convert the mval with any PVs to a string. |
|
3315 |
+ pv_elem_t *xmodel = NULL; |
|
3316 |
+ str mval_s = {0, 0}; |
|
3317 |
+ |
|
3318 |
+ if(pv_parse_format(&mval_sraw, &xmodel) < 0) { |
|
3319 |
+ LM_ERR("error in parsing evaluated mval parameter\n"); |
|
3320 |
+ return -1; |
|
3321 |
+ } |
|
3322 |
+ |
|
3323 |
+ if(pv_printf_s(msg, xmodel, &mval_s) != 0) { |
|
3324 |
+ LM_ERR("cannot eval reparsed value of mval parameter\n"); |
|
3325 |
+ pv_elem_free_all(xmodel); |
|
3326 |
+ return -1; |
|
3327 |
+ } |
|
3328 |
+ pv_elem_free_all(xmodel); |
|
3329 |
+ LM_DBG("Evaluated mval to: %s\n", mval_s.s); |
|
3330 |
+ |
|
3331 |
+ if(pv_parse_format(&xavp_name_sraw, &xmodel) < 0) { |
|
3332 |
+ LM_ERR("error in parsing evaluated xavp_name parameter\n"); |
|
3333 |
+ return -1; |
|
3334 |
+ } |
|
3335 |
+ |
|
3336 |
+ if(pv_printf_s(msg, xmodel, &xavp_name_s) != 0) { |
|
3337 |
+ LM_ERR("cannot eval reparsed value of xavp_name parameter\n"); |
|
3338 |
+ pv_elem_free_all(xmodel); |
|
3339 |
+ return -1; |
|
3340 |
+ } |
|
3341 |
+ pv_elem_free_all(xmodel); |
|
3342 |
+ LM_DBG("Evaluated xavp_name to: %s\n", xavp_name_s.s); |
|
3343 |
+ |
|
3344 |
+ if(xavp_name_s.s == NULL || xavp_name_s.len <= 0) { |
|
3345 |
+ LM_ERR("XAVP name not provided.\n"); |
|
3346 |
+ return -1; |
|
3347 |
+ } |
|
3348 |
+ |
|
3349 |
+ LM_DBG("Storing name for XAVP: %s\n", xavp_name_s.s); |
|
3350 |
+ //Find existing XAVP for this xavp_name, if there is one. |
|
3351 |
+ //Use the existing XAVP to append new XAVPs to the list. |
|
3352 |
+ //If none exists, we'll add it to the root list later. |
|
3353 |
+ list = xavp_get(&xavp_name_s, NULL); |
|
3354 |
+ xavp = list ? &list->val.v.xavp : &new_xavp; |
|
3355 |
+ |
|
3356 |
+ //Get list of matches |
|
3357 |
+ matches = dlg_list_matches(&dlg_matches, mkey_s, mop_s, mval_s, max_results); |
|
3358 |
+ |
|
3359 |
+ if (matches < 0) { |
|
3360 |
+ LM_ERR("dlg_list_matches returned an error.\n"); |
|
3361 |
+ return -1; |
|
3362 |
+ } |
|
3363 |
+ |
|
3364 |
+ for (i = 0; i < matches; i++) { |
|
3365 |
+ //Add fields to XAVP for this dialog. |
|
3366 |
+ //The XAVP structure is such that multiple calls to this |
|
3367 |
+ //will add each set of fields under their own index on |
|
3368 |
+ //the XAVP list. |
|
3369 |
+ unsigned int entry = dlg_matches[i].entry; |
|
3370 |
+ |
|
3371 |
+ dlg_lock(d_table, &(d_table->entries[entry])); |
|
3372 |
+ if (!dlg_get_matches_xavp_helper(xavp, dlg_matches[i].dlg)) { |
|
3373 |
+ shm_free(dlg_matches); |
|
3374 |
+ dlg_unlock(d_table, &(d_table->entries[entry])); |
|
3375 |
+ LM_ERR("Failed to add matching dialog to XAVP.\n"); |
|
3376 |
+ return -1; |
|
3377 |
+ } |
|
3378 |
+ dlg_unlock(d_table, &(d_table->entries[entry])); |
|
3379 |
+ } |
|
3380 |
+ |
|
3381 |
+ shm_free(dlg_matches); |
|
3382 |
+ |
|
3383 |
+ //Add to root list at the end, so the xavp points to last |
|
3384 |
+ //field added before adding to root list. |
|
3385 |
+ if(list == NULL && matches > 0) { |
|
3386 |
+ // If list is null there was no xavp of name xavp_name in root list - add it |
|
3387 |
+ LM_DBG("Adding new xavp to root list: %s\n", xavp_name_s.s); |
|
3388 |
+ sr_xval_t xval; |
|
3389 |
+ memset(&xval, 0, sizeof(sr_xval_t)); |
|
3390 |
+ xval.type = SR_XTYPE_XAVP; |
|
3391 |
+ xval.v.xavp = *xavp; |
|
3392 |
+ if(xavp_add_value(&xavp_name_s, &xval, NULL) == NULL) { |
|
3393 |
+ LM_ERR("cannot add xavp to root list\n"); |
|
3394 |
+ xavp_destroy_list(xavp); |
|
3395 |
+ return -1; |
|
3396 |
+ } |
|
3397 |
+ } |
|
3398 |
+ |
|
3399 |
+ if(matches == 0) { |
|
3400 |
+ LM_DBG("No matches found.\n"); |
|
3401 |
+ //Apparently returning 0 will stop execution of the calling script. So return -1. |
|
3402 |
+ return -1; |
|
3403 |
+ } |
|
3404 |
+ return matches; |
|
3405 |
+} |
|
3406 |
+ |
|
3407 |
+static int w_dlg_get_matches1( |
|
3408 |
+ struct sip_msg *msg, char *mkey, char *mop, char *mval, char *xavp_name) |
|
3409 |
+{ |
|
3410 |
+ return internal_dlg_get_matches(msg, mkey, mop, mval, xavp_name, 0); |
|
3411 |
+} |
|
3412 |
+ |
|
3413 |
+static int w_dlg_get_matches2(struct sip_msg *msg, char *mkey, char *mop, |
|
3414 |
+ char *mval, char *xavp_name, char *max_results) |
|
3415 |
+{ |
|
3416 |
+ //Convert the max_results with any PVs to a string. |
|
3417 |
+ pv_elem_t *xmodel = NULL; |
|
3418 |
+ str max_results_s; |
|
3419 |
+ max_results_s.s = max_results; |
|
3420 |
+ max_results_s.len = strlen(max_results); |
|
3421 |
+ str val = {0, 0}; |
|
3422 |
+ |
|
3423 |
+ if(pv_parse_format(&max_results_s, &xmodel) < 0) { |
|
3424 |
+ LM_ERR("error in parsing evaluated max_results parameter\n"); |
|
3425 |
+ return -1; |
|
3426 |
+ } |
|
3427 |
+ |
|
3428 |
+ if(pv_printf_s(msg, xmodel, &val) != 0) { |
|
3429 |
+ LM_ERR("cannot eval reparsed value of max_results parameter\n"); |
|
3430 |
+ pv_elem_free_all(xmodel); |
|
3431 |
+ return -1; |
|
3432 |
+ } |
|
3433 |
+ pv_elem_free_all(xmodel); |
|
3434 |
+ LM_DBG("Evaluated max_results to: %s\n", val.s); |
|
3435 |
+ |
|
3436 |
+ int max = atoi(val.s); |
|
3437 |
+ |
|
3438 |
+ return internal_dlg_get_matches(msg, mkey, mop, mval, xavp_name, max); |
|
3439 |
+} |
|
3440 |
+ |
|
2787 | 3441 |
static const char *rpc_print_dlgs_doc[2] = { |
2788 | 3442 |
"Print all dialogs", 0 |
2789 | 3443 |
}; |
... | ... |
@@ -3143,21 +3797,13 @@ static void rpc_dlg_stats_active(rpc_t *rpc, void *c) |
3143 | 3797 |
*/ |
3144 | 3798 |
static void rpc_dlg_list_match_ex(rpc_t *rpc, void *c, int with_context) |
3145 | 3799 |
{ |
3146 |
- dlg_cell_t *dlg = NULL; |
|
3800 |
+ dlg_cell_match_t *dlg_matches = NULL; |
|
3147 | 3801 |
int i = 0; |
3148 | 3802 |
str mkey = {NULL, 0}; |
3149 | 3803 |
str mop = {NULL, 0}; |
3150 | 3804 |
str mval = {NULL, 0}; |
3151 |
- str sval = {NULL, 0}; |
|
3152 |
- unsigned int ival = 0; |
|
3153 |
- unsigned int mival = 0; |
|
3154 | 3805 |
int n = 0; |
3155 | 3806 |
int m = 0; |
3156 |
- int vkey = 0; |
|
3157 |
- int vop = 0; |
|
3158 |
- int matched = 0; |
|
3159 |
- regex_t mre; |
|
3160 |
- regmatch_t pmatch; |
|
3161 | 3807 |
|
3162 | 3808 |
i = rpc->scan(c, "SSS", &mkey, &mop, &mval); |
3163 | 3809 |
if (i < 3) { |
... | ... |
@@ -3171,134 +3817,25 @@ static void rpc_dlg_list_match_ex(rpc_t *rpc, void *c, int with_context) |
3171 | 3817 |
rpc->fault(c, 500, "Invalid parameters"); |
3172 | 3818 |
return; |
3173 | 3819 |
} |
3174 |
- if(mkey.len==4 && strncmp(mkey.s, "ruri", mkey.len)==0) { |
|
3175 |
- vkey = 0; |
|
3176 |
- } else if(mkey.len==4 && strncmp(mkey.s, "furi", mkey.len)==0) { |
|
3177 |
- vkey = 1; |
|
3178 |
- } else if(mkey.len==4 && strncmp(mkey.s, "turi", mkey.len)==0) { |
|
3179 |
- vkey = 2; |
|
3180 |
- } else if(mkey.len==6 && strncmp(mkey.s, "callid", mkey.len)==0) { |
|
3181 |
- vkey = 3; |
|
3182 |
- } else if(mkey.len==8 && strncmp(mkey.s, "start_ts", mkey.len)==0) { |
|
3183 |
- vkey = 4; |
|
3184 |
- } else { |
|
3185 |
- LM_ERR("invalid key %.*s\n", mkey.len, mkey.s); |
|
3186 |
- rpc->fault(c, 500, "Invalid matching key parameter"); |
|
3187 |
- return; |
|
3188 |
- } |
|
3189 |
- if(mop.len!=2) { |
|
3190 |
- LM_ERR("invalid matching operator %.*s\n", mop.len, mop.s); |
|
3191 |
- rpc->fault(c, 500, "Invalid matching operator parameter"); |
|
3192 |
- return; |
|
3193 |
- |
|
3194 |
- } |
|
3195 |
- if(strncmp(mop.s, "eq", 2)==0) { |
|
3196 |
- vop = 0; |
|
3197 |
- } else if(strncmp(mop.s, "re", 2)==0) { |
|
3198 |
- vop = 1; |
|
3199 |
- memset(&mre, 0, sizeof(regex_t)); |
|
3200 |
- if (regcomp(&mre, mval.s, REG_EXTENDED|REG_ICASE|REG_NEWLINE)!=0) { |
|
3201 |
- LM_ERR("failed to compile regex: %.*s\n", mval.len, mval.s); |
|
3202 |
- rpc->fault(c, 500, "Invalid matching value parameter"); |
|
3203 |
- return; |
|
3204 |
- } |
|
3205 |
- } else if(strncmp(mop.s, "sw", 2)==0) { |
|
3206 |
- vop = 2; |
|
3207 |
- } else if(strncmp(mop.s, "gt", 2)==0) { |
|
3208 |
- vop = 3; |
|
3209 |
- } else if(strncmp(mop.s, "lt", 2)==0) { |
|
3210 |
- vop = 4; |
|
3211 |
- } else { |
|
3212 |
- LM_ERR("invalid matching operator %.*s\n", mop.len, mop.s); |
|
3213 |
- rpc->fault(c, 500, "Invalid matching operator parameter"); |
|
3214 |
- return; |
|
3215 |
- } |
|
3216 | 3820 |
if(rpc->scan(c, "*d", &n)<1) { |
3217 | 3821 |
n = 0; |
3218 | 3822 |
} |
3219 | 3823 |
|
3220 |
- if (vkey == 4 && vop <= 2) { |
|
3221 |
- LM_ERR("Matching operator %.*s not supported with start_ts key\n", mop.len, mop.s); |
|
3222 |
- rpc->fault(c, 500, "Matching operator not supported with start_ts key"); |
|
3223 |
- return; |
|
3224 |
- } |
|
3824 |
+ m = dlg_list_matches(&dlg_matches, mkey, mop, mval, n); |
|
3225 | 3825 |
|
3226 |
- if (vkey != 4 && vop >= 3) { |
|
3227 |
- LM_ERR("Matching operator %.*s not supported with key %.*s\n", mop.len, mop.s, mkey.len, mkey.s); |
|
3228 |
- rpc->fault(c, 500, "Matching operator not supported"); |
|
3826 |
+ if (m < 0) { |
|
3827 |
+ LM_ERR("invalid parameters, see earlier log entry.\n"); |
|
3828 |
+ rpc->fault(c, 500, "Invalid parameters, see logs for details."); |
|
3229 | 3829 |
return; |
3230 | 3830 |
} |
3231 | 3831 |
|
3232 |
- for(i=0; i<d_table->size; i++) { |
|
3233 |
- dlg_lock(d_table, &(d_table->entries[i])); |
|
3234 |
- for(dlg=d_table->entries[i].first; dlg!=NULL; dlg=dlg->next) { |
|
3235 |
- matched = 0; |
|
3236 |
- switch(vkey) { |
|
3237 |
- case 0: |
|
3238 |
- sval = dlg->req_uri; |
|
3239 |
- break; |
|
3240 |
- case 1: |
|
3241 |
- sval = dlg->from_uri; |
|
3242 |
- break; |
|
3243 |
- case 2: |
|
3244 |
- sval = dlg->to_uri; |
|
3245 |
- break; |
|
3246 |
- case 3: |
|
3247 |
- sval = dlg->callid; |
|
3248 |
- break; |
|
3249 |
- case 4: |
|
3250 |
- ival = dlg->start_ts; |
|
3251 |
- break; |
|
3252 |
- } |
|
3253 |
- switch(vop) { |
|
3254 |
- case 0: |
|
3255 |
- /* string comparison */ |
|
3256 |
- if(mval.len==sval.len |
|
3257 |
- && strncmp(mval.s, sval.s, mval.len)==0) { |
|
3258 |
- matched = 1; |
|
3259 |
- } |
|
3260 |
- break; |
|
3261 |
- case 1: |
|
3262 |
- /* regexp matching */ |
|
3263 |
- if(regexec(&mre, sval.s, 1, &pmatch, 0)==0) { |
|
3264 |
- matched = 1; |
|
3265 |
- } |
|
3266 |
- break; |
|
3267 |
- case 2: |
|
3268 |
- /* starts with */ |
|
3269 |
- if(mval.len<=sval.len |
|
3270 |
- && strncmp(mval.s, sval.s, mval.len)==0) { |
|
3271 |
- matched = 1; |
|
3272 |
- } |
|
3273 |
- break; |
|
3274 |
- case 3: |
|
3275 |
- /* greater than */ |
|
3276 |
- if (str2int(&mval, &mival) == 0 && ival > mival) { |
|
3277 |
- matched = 1; |
|
3278 |
- } |
|
3279 |
- break; |
|
3280 |
- case 4: |
|
3281 |
- if (str2int(&mval, &mival) == 0 && ival < mival) { |
|
3282 |
- matched = 1; |
|
3283 |
- } |
|
3284 |
- break; |
|
3285 |
- } |
|
3286 |
- if (matched==1) { |
|
3287 |
- m++; |
|
3288 |
- internal_rpc_print_dlg(rpc, c, dlg, with_context); |
|
3289 |
- if(n>0 && m==n) { |
|
3290 |
- break; |
|
3291 |
- } |
|
3292 |
- } |
|
3293 |
- } |
|
3294 |
- dlg_unlock(d_table, &(d_table->entries[i])); |
|
3295 |
- if(n>0 && m==n) { |
|
3296 |
- break; |
|
3297 |
- } |
|
3298 |
- } |
|
3299 |
- if(vop == 1) { |
|
3300 |
- regfree(&mre); |
|
3832 |
+ for (i = 0; i < m; i++) { |
|
3833 |
+ unsigned int entry = dlg_matches[i].entry; |
|
3834 |
+ dlg_lock(d_table, &(d_table->entries[entry])); |
|
3835 |
+ internal_rpc_print_dlg(rpc, c, dlg_matches[i].dlg, with_context); |
|
3836 |
+ dlg_unlock(d_table, &(d_table->entries[entry])); |
|
3301 | 3837 |
} |
3838 |
+ shm_free(dlg_matches); |
|
3302 | 3839 |
|
3303 | 3840 |
if(m==0) { |
3304 | 3841 |
rpc->fault(c, 404, "Not found"); |
... | ... |
@@ -165,6 +165,11 @@ typedef struct dlg_ka { |
165 | 165 |
struct dlg_ka *next; |
166 | 166 |
} dlg_ka_t; |
167 | 167 |
|
168 |
+typedef struct dlg_cell_match { |
|
169 |
+ struct dlg_cell *dlg; |
|
170 |
+ unsigned int entry; |
|
171 |
+} dlg_cell_match_t; |
|
172 |
+ |
|
168 | 173 |
/*! global dialog table */ |
169 | 174 |
extern dlg_table_t *d_table; |
170 | 175 |
|
... | ... |
@@ -2541,6 +2541,100 @@ dlg_reset_property("timeout-noreset"); |
2541 | 2541 |
</programlisting> |
2542 | 2542 |
</example> |
2543 | 2543 |
</section> |
2544 |
+ |
|
2545 |
+ <section id="dialog.f.dlg_get_matches"> |
|
2546 |
+ <title> |
|
2547 |
+ <function moreinfo="none">dlg_get_matches(key, op, value, xavp_name[, max_results])</function> |
|
2548 |
+ </title> |
|
2549 |
+ <para> |
|
2550 |
+ Returns a list of matching dialog entries into a given XAVP name. The return value of the function |
|
2551 |
+ is -1 if there is an error, or otherwise the number of matches found. |
|
2552 |
+ |
|
2553 |
+ Matches are based on the specified dialog field (key), match type (op) and matching value. |
|
2554 |
+ Matches can optionally be limited to a specified value, or unlimited if the value is 0 or |
|
2555 |
+ not specified. |
|
2556 |
+ </para> |
|
2557 |
+ <para>Meaning of the parameters is as follows:</para> |
|
2558 |
+ <itemizedlist> |
|
2559 |
+ <listitem> |
|
2560 |
+ <para> |
|
2561 |
+ <emphasis>key</emphasis> - the name of the dialog field to match against. |
|
2562 |
+ It can be: |
|
2563 |
+ <itemizedlist> |
|
2564 |
+ <listitem> |
|
2565 |
+ 'ruri' - R-URI of dialog |
|
2566 |
+ </listitem> |
|
2567 |
+ <listitem> |
|
2568 |
+ 'turi' - To Header of dialog |
|
2569 |
+ </listitem> |
|
2570 |
+ <listitem> |
|
2571 |
+ 'furi' - From Header of dialog |
|
2572 |
+ </listitem> |
|
2573 |
+ <listitem> |
|
2574 |
+ 'callid' - Call-Id of dialog |
|
2575 |
+ </listitem> |
|
2576 |
+ <listitem> |
|
2577 |
+ 'start_ts' - match against start timestamp of dialog. Only works with gt, lt. |
|
2578 |
+ </listitem> |
|
2579 |
+ </itemizedlist> |
|
2580 |
+ |
|
2581 |
+ </para> |
|
2582 |
+ </listitem> |
|
2583 |
+ <listitem> |
|
2584 |
+ <para> |
|
2585 |
+ <emphasis>op</emphasis> - the type of match operation to use. It can be: |
|
2586 |
+ <itemizedlist> |
|
2587 |
+ <listitem> |
|
2588 |
+ 'eq' - Match if string comparison equals. |
|
2589 |
+ </listitem> |
|
2590 |
+ <listitem> |
|
2591 |
+ 're' - Match using regular expression. |
|
2592 |
+ </listitem> |
|
2593 |
+ <listitem> |
|
2594 |
+ 'sw' - Match using string starts with (prefix) comparison. |
|
2595 |
+ </listitem> |
|
2596 |
+ <listitem> |
|
2597 |
+ 'gt' - Match using integer greater than comparison. Only works with 'start_ts' key. |
|
2598 |
+ </listitem> |
|
2599 |
+ <listitem> |
|
2600 |
+ 'lt' - Match using integer less than comparison. Only works with 'start_ts' key. |
|
2601 |
+ </listitem> |
|
2602 |
+ </itemizedlist> |
|
2603 |
+ </para> |
|
2604 |
+ </listitem> |
|
2605 |
+ <listitem> |
|
2606 |
+ <para> |
|
2607 |
+ <emphasis>value</emphasis> - value to match dialog against. |
|
2608 |
+ This can be a pvar. |
|
2609 |
+ </para> |
|
2610 |
+ </listitem> |
|
2611 |
+ <listitem> |
|
2612 |
+ <para> |
|
2613 |
+ <emphasis>xavp_name</emphasis> - the name of the xavp to store |
|
2614 |
+ results in. This can be a pvar. |
|
2615 |
+ </para> |
|
2616 |
+ </listitem> |
|
2617 |
+ <listitem> |
|
2618 |
+ <para> |
|
2619 |
+ <emphasis>max_results</emphasis> - the max number of results to return |
|
2620 |
+ in the xavp. If the value is 0 or not provided, there is no limit. This can be a pvar. |
|
2621 |
+ </para> |
|
2622 |
+ </listitem> |
|
2623 |
+ </itemizedlist> |
|
2624 |
+ <para> |
|
2625 |
+ This function can be used from ANY_ROUTE. |
|
2626 |
+ </para> |
|
2627 |
+ <example> |
|
2628 |
+ <title><function>dlg_get_matches</function> usage</title> |
|
2629 |
+ <programlisting format="linespecific"> |
|
2630 |
+... |
|
2631 |
+dlg_get_matches("furi", "sw", "sip:$var(ext)@", "dlg_matches"); |
|
2632 |
+dlg_get_matches("furi", "sw", "sip:$var(ext)@", "$var(name)", 2); |
|
2633 |
+... |
|
2634 |
+ |
|
2635 |
+</programlisting> |
|
2636 |
+ </example> |
|
2637 |
+ </section> |
|
2544 | 2638 |
</section> |
2545 | 2639 |
|
2546 | 2640 |
|