From a7cecdcbc3c1d53fce22a33a3768da2a1907d64e Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Fri, 23 Sep 2022 13:17:02 +0200 Subject: [PATCH] dialog: internal api functions to get dlg variable reference or value --- src/modules/dialog/dialog.c | 9 ++--- src/modules/dialog/dlg_cb.h | 5 ++- src/modules/dialog/dlg_load.h | 3 +- src/modules/dialog/dlg_var.c | 68 +++++++++++++++++++++++------------ src/modules/dialog/dlg_var.h | 5 +-- 5 files changed, 59 insertions(+), 31 deletions(-) diff --git a/src/modules/dialog/dialog.c b/src/modules/dialog/dialog.c index 83a10b3b560..d4d2df07faf 100644 --- a/src/modules/dialog/dialog.c +++ b/src/modules/dialog/dialog.c @@ -481,7 +481,8 @@ int load_dlg( struct dlg_binds *dlgb ) dlgb->register_dlgcb = register_dlgcb; dlgb->terminate_dlg = dlg_bye_all; dlgb->set_dlg_var = set_dlg_variable; - dlgb->get_dlg_var = get_dlg_variable; + dlgb->get_dlg_varref = get_dlg_varref; + dlgb->get_dlg_varval = get_dlg_varval; dlgb->get_dlg = dlg_get_msg_dialog; dlgb->release_dlg = dlg_release; return 1; @@ -1792,7 +1793,7 @@ static str *ki_dlg_get_var_helper(sip_msg_t *msg, str *sc, str *sf, str *st, str dlg = get_dlg(sc, sf, st, &dir); if(dlg==NULL) return val; - val = get_dlg_variable(dlg, key); + val = get_dlg_varref(dlg, key); dlg_release(dlg); return val; } @@ -2462,7 +2463,7 @@ static sr_kemi_xval_t* ki_dlg_var_get_mode(sip_msg_t *msg, str *name, int rmode) sr_kemi_xval_null(&_sr_kemi_dialog_xval, rmode); return &_sr_kemi_dialog_xval; } - pval = get_dlg_variable(dlg, name); + pval = get_dlg_varref(dlg, name); if(pval==NULL || pval->s==NULL) { sr_kemi_xval_null(&_sr_kemi_dialog_xval, rmode); goto done; @@ -2523,7 +2524,7 @@ static int ki_dlg_var_is_null(sip_msg_t *msg, str *name) if(dlg==NULL) { return 1; } - pval = get_dlg_variable(dlg, name); + pval = get_dlg_varref(dlg, name); if(pval==NULL || pval->s==NULL) { return 1; } diff --git a/src/modules/dialog/dlg_cb.h b/src/modules/dialog/dlg_cb.h index bb0037c7f79..d049875308d 100644 --- a/src/modules/dialog/dlg_cb.h +++ b/src/modules/dialog/dlg_cb.h @@ -55,8 +55,11 @@ typedef int (*set_dlg_variable_f)( struct dlg_cell* dlg, str* key, str* val); /* method to get a variable from a dialog */ -typedef str* (*get_dlg_variable_f)( struct dlg_cell* dlg, +typedef str* (*get_dlg_varref_f)( struct dlg_cell* dlg, str* key); +/* method to get a variable from a dialog */ +typedef int (*get_dlg_varval_f)( struct dlg_cell* dlg, + str* key, str* val); #define CONFIRMED_DIALOG_STATE 1 diff --git a/src/modules/dialog/dlg_load.h b/src/modules/dialog/dlg_load.h index 8682a8461dd..2a3273ce847 100644 --- a/src/modules/dialog/dlg_load.h +++ b/src/modules/dialog/dlg_load.h @@ -46,7 +46,8 @@ struct dlg_binds { register_dlgcb_f register_dlgcb; terminate_dlg_f terminate_dlg; set_dlg_variable_f set_dlg_var; - get_dlg_variable_f get_dlg_var; + get_dlg_varref_f get_dlg_varref; + get_dlg_varval_f get_dlg_varval; get_dlg_f get_dlg; release_dlg_f release_dlg; }; diff --git a/src/modules/dialog/dlg_var.c b/src/modules/dialog/dlg_var.c index ef73c022d0a..4db8d84c351 100644 --- a/src/modules/dialog/dlg_var.c +++ b/src/modules/dialog/dlg_var.c @@ -279,46 +279,68 @@ void print_lists(struct dlg_cell *dlg) { } } -static str _dlg_var_strval = STR_NULL; +/** + * return reference to the dlg variable value + * - unsafe - use only when it is sure that the value is not updated + */ +str* get_dlg_varref(struct dlg_cell *dlg, str *key) +{ + str* var = NULL; + + if( !dlg || !key || key->len > strlen(key->s)) + { + LM_ERR("BUG - bad parameters\n"); + + return NULL; + } + + dlg_lock(d_table, &(d_table->entries[dlg->h_entry])); + var = get_dlg_variable_unsafe( dlg, key); + dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); + + return var; +} -str * get_dlg_variable(struct dlg_cell *dlg, str *key) +/** + * set *val to a pv buffer where the dlg value is cloned + * - safe to use immediately, before another dlg var get or other operation + * done by the same process exceeds the number of pv buffer slots + */ +int get_dlg_varval(struct dlg_cell *dlg, str *key, str *val) { - str* var = NULL; + str *var = NULL; - if( !dlg || !key || key->len > strlen(key->s)) - { + if( !dlg || !key || key->len > strlen(key->s)) { LM_ERR("BUG - bad parameters\n"); - - return NULL; + return -1; } + val->s = NULL; + val->len = 0; + dlg_lock(d_table, &(d_table->entries[dlg->h_entry])); - var = get_dlg_variable_unsafe( dlg, key); + var = get_dlg_variable_unsafe(dlg, key); if(var) { - _dlg_var_strval.len = pv_get_buffer_size(); - if(_dlg_var_strval.len < var->len+1) { + val->len = pv_get_buffer_size(); + if(val->len < var->len+1) { LM_ERR("pv buffer too small (%d) - needed %d\n", - _dlg_var_strval.len, var->len); - _dlg_var_strval.s = NULL; - _dlg_var_strval.len = 0; + val->len, var->len+1); + val->s = NULL; + val->len = 0; var = NULL; } else { - _dlg_var_strval.s = pv_get_buffer(); - strncpy(_dlg_var_strval.s, var->s, var->len); - _dlg_var_strval.len = var->len; - _dlg_var_strval.s[_dlg_var_strval.len] = '\0'; + val->s = pv_get_buffer(); + memcpy(val->s, var->s, var->len); + val->len = var->len; + val->s[val->len] = '\0'; } - } else { - _dlg_var_strval.s = NULL; - _dlg_var_strval.len = 0; } - dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); if(var) { - return &_dlg_var_strval; + return 0; } - return NULL; + return -2; } int get_dlg_variable_uintval(struct dlg_cell *dlg, str *key, unsigned int *uval) diff --git a/src/modules/dialog/dlg_var.h b/src/modules/dialog/dlg_var.h index a4b497dbd76..05060997f0d 100644 --- a/src/modules/dialog/dlg_var.h +++ b/src/modules/dialog/dlg_var.h @@ -25,7 +25,7 @@ * \ingroup dialog * Module: \ref dialog */ - + #ifndef _DLG_VAR_H_ #define _DLG_VAR_H_ @@ -59,7 +59,8 @@ typedef struct dlg_var { struct dlg_var *next; } dlg_var_t; -str* get_dlg_variable(dlg_cell_t *dlg, str *key); +str* get_dlg_varref(dlg_cell_t *dlg, str *key); +int get_dlg_varval(dlg_cell_t *dlg, str *key, str *val); int set_dlg_variable(dlg_cell_t *dlg, str *key, str *val); int get_dlg_variable_uintval(struct dlg_cell *dlg, str *key, unsigned int *uval);