Browse code

dialog: internal api functions to get dlg variable reference or value

Daniel-Constantin Mierla authored on 23/09/2022 11:17:02
Showing 5 changed files
... ...
@@ -481,7 +481,8 @@ int load_dlg( struct dlg_binds *dlgb )
481 481
 	dlgb->register_dlgcb = register_dlgcb;
482 482
 	dlgb->terminate_dlg = dlg_bye_all;
483 483
 	dlgb->set_dlg_var = set_dlg_variable;
484
-	dlgb->get_dlg_var = get_dlg_variable;
484
+	dlgb->get_dlg_varref = get_dlg_varref;
485
+	dlgb->get_dlg_varval = get_dlg_varval;
485 486
 	dlgb->get_dlg = dlg_get_msg_dialog;
486 487
 	dlgb->release_dlg = dlg_release;
487 488
 	return 1;
... ...
@@ -1792,7 +1793,7 @@ static str *ki_dlg_get_var_helper(sip_msg_t *msg, str *sc, str *sf, str *st, str
1792 1793
 	dlg = get_dlg(sc, sf, st, &dir);
1793 1794
 	if(dlg==NULL)
1794 1795
 		return val;
1795
-	val = get_dlg_variable(dlg, key);
1796
+	val = get_dlg_varref(dlg, key);
1796 1797
 	dlg_release(dlg);
1797 1798
 	return val;
1798 1799
 }
... ...
@@ -2462,7 +2463,7 @@ static sr_kemi_xval_t* ki_dlg_var_get_mode(sip_msg_t *msg, str *name, int rmode)
2462 2463
 		sr_kemi_xval_null(&_sr_kemi_dialog_xval, rmode);
2463 2464
 		return &_sr_kemi_dialog_xval;
2464 2465
 	}
2465
-	pval = get_dlg_variable(dlg, name);
2466
+	pval = get_dlg_varref(dlg, name);
2466 2467
 	if(pval==NULL || pval->s==NULL) {
2467 2468
 		sr_kemi_xval_null(&_sr_kemi_dialog_xval, rmode);
2468 2469
 		goto done;
... ...
@@ -2523,7 +2524,7 @@ static int ki_dlg_var_is_null(sip_msg_t *msg, str *name)
2523 2524
 	if(dlg==NULL) {
2524 2525
 		return 1;
2525 2526
 	}
2526
-	pval = get_dlg_variable(dlg, name);
2527
+	pval = get_dlg_varref(dlg, name);
2527 2528
 	if(pval==NULL || pval->s==NULL) {
2528 2529
 		return 1;
2529 2530
 	}
... ...
@@ -55,8 +55,11 @@ typedef int (*set_dlg_variable_f)( struct dlg_cell* dlg,
55 55
                                    str* key,
56 56
                                    str* val);
57 57
 /* method to get a variable from a dialog */
58
-typedef str* (*get_dlg_variable_f)( struct dlg_cell* dlg,
58
+typedef str* (*get_dlg_varref_f)( struct dlg_cell* dlg,
59 59
                                     str* key);
60
+/* method to get a variable from a dialog */
61
+typedef int (*get_dlg_varval_f)( struct dlg_cell* dlg,
62
+                                    str* key, str* val);
60 63
 
61 64
 #define CONFIRMED_DIALOG_STATE 1
62 65
 
... ...
@@ -46,7 +46,8 @@ struct dlg_binds {
46 46
 	register_dlgcb_f  register_dlgcb;
47 47
 	terminate_dlg_f terminate_dlg;
48 48
     set_dlg_variable_f set_dlg_var;
49
-	get_dlg_variable_f get_dlg_var;
49
+	get_dlg_varref_f   get_dlg_varref;
50
+	get_dlg_varval_f   get_dlg_varval;
50 51
 	get_dlg_f          get_dlg;
51 52
 	release_dlg_f      release_dlg;
52 53
 };
... ...
@@ -279,46 +279,68 @@ void print_lists(struct dlg_cell *dlg) {
279 279
 	}
280 280
 }
281 281
 
282
-static str _dlg_var_strval = STR_NULL;
282
+/**
283
+ * return reference to the dlg variable value
284
+ * - unsafe - use only when it is sure that the value is not updated
285
+ */
286
+str* get_dlg_varref(struct dlg_cell *dlg, str *key)
287
+{
288
+    str* var = NULL;
289
+
290
+    if( !dlg || !key || key->len > strlen(key->s))
291
+    {
292
+        LM_ERR("BUG - bad parameters\n");
293
+
294
+        return NULL;
295
+    }
296
+
297
+    dlg_lock(d_table, &(d_table->entries[dlg->h_entry]));
298
+    var = get_dlg_variable_unsafe( dlg, key);
299
+    dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
300
+
301
+    return var;
302
+}
283 303
 
284
-str * get_dlg_variable(struct dlg_cell *dlg, str *key)
304
+/**
305
+ * set *val to a pv buffer where the dlg value is cloned
306
+ * - safe to use immediately, before another dlg var get or other operation
307
+ *   done by the same process exceeds the number of pv buffer slots
308
+ */
309
+int get_dlg_varval(struct dlg_cell *dlg, str *key, str *val)
285 310
 {
286
-	str* var = NULL;
311
+	str *var = NULL;
287 312
 
288
-	if( !dlg || !key || key->len > strlen(key->s))
289
-	{
313
+	if( !dlg || !key || key->len > strlen(key->s)) {
290 314
 		LM_ERR("BUG - bad parameters\n");
291
-
292
-		return NULL;
315
+		return -1;
293 316
 	}
294 317
 
318
+	val->s = NULL;
319
+	val->len = 0;
320
+
295 321
 	dlg_lock(d_table, &(d_table->entries[dlg->h_entry]));
296
-	var = get_dlg_variable_unsafe( dlg, key);
322
+	var = get_dlg_variable_unsafe(dlg, key);
297 323
 	if(var) {
298
-		_dlg_var_strval.len = pv_get_buffer_size();
299
-		if(_dlg_var_strval.len < var->len+1) {
324
+		val->len = pv_get_buffer_size();
325
+		if(val->len < var->len+1) {
300 326
 			LM_ERR("pv buffer too small (%d) - needed %d\n",
301
-					_dlg_var_strval.len, var->len);
302
-			_dlg_var_strval.s = NULL;
303
-			_dlg_var_strval.len = 0;
327
+					val->len, var->len+1);
328
+			val->s = NULL;
329
+			val->len = 0;
304 330
 			var = NULL;
305 331
 		} else {
306
-			_dlg_var_strval.s = pv_get_buffer();
307
-			strncpy(_dlg_var_strval.s, var->s, var->len);
308
-			_dlg_var_strval.len = var->len;
309
-			_dlg_var_strval.s[_dlg_var_strval.len] = '\0';
332
+			val->s = pv_get_buffer();
333
+			memcpy(val->s, var->s, var->len);
334
+			val->len = var->len;
335
+			val->s[val->len] = '\0';
310 336
 		}
311
-	} else {
312
-		_dlg_var_strval.s = NULL;
313
-		_dlg_var_strval.len = 0;
314 337
 	}
315
-
316 338
 	dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));
317 339
 
318 340
 	if(var) {
319
-		return &_dlg_var_strval;
341
+		return 0;
320 342
 	}
321
-	return NULL;
343
+	return -2;
322 344
 }
323 345
 
324 346
 int get_dlg_variable_uintval(struct dlg_cell *dlg, str *key, unsigned int *uval)
... ...
@@ -25,7 +25,7 @@
25 25
  * \ingroup dialog
26 26
  * Module: \ref dialog
27 27
  */
28
-		       
28
+
29 29
 #ifndef _DLG_VAR_H_
30 30
 #define _DLG_VAR_H_
31 31
 
... ...
@@ -59,7 +59,8 @@ typedef struct dlg_var {
59 59
 	struct dlg_var *next;
60 60
 } dlg_var_t;
61 61
 
62
-str* get_dlg_variable(dlg_cell_t *dlg, str *key);
62
+str* get_dlg_varref(dlg_cell_t *dlg, str *key);
63
+int get_dlg_varval(dlg_cell_t *dlg, str *key, str *val);
63 64
 int set_dlg_variable(dlg_cell_t *dlg, str *key, str *val);
64 65
 
65 66
 int get_dlg_variable_uintval(struct dlg_cell *dlg, str *key, unsigned int *uval);