Browse code

dialog: deactivate print variable function which is only used for debugging

- deactivate print variable function which is only used for debugging
- this function is not good for performance and might also cause race conditions

Henning Westerholt authored on 16/11/2022 15:33:06
Showing 1 changed files
... ...
@@ -144,6 +144,8 @@ stat_var *expired_dlgs = 0;
144 144
 stat_var *failed_dlgs = 0;
145 145
 stat_var *early_dlgs  = 0;
146 146
 
147
+int debug_variables_list = 0;
148
+
147 149
 struct tm_binds d_tmb;
148 150
 struct rr_binds d_rrb;
149 151
 pv_spec_t timeout_avp;
... ...
@@ -363,6 +365,7 @@ static param_export_t mod_params[]={
363 365
 	{ "bye_early_code",        PARAM_INT, &bye_early_code           },
364 366
 	{ "bye_early_reason",      PARAM_STR, &bye_early_reason         },
365 367
 	{ "dlg_ctxiuid_mode",      PARAM_INT, &dlg_ctxiuid_mode         },
368
+	{ "debug_variables",       PARAM_INT, &debug_variables_list     },
366 369
 
367 370
 	{ 0,0,0 }
368 371
 };
Browse code

dialog: dlg_set_var() support empty totag parameter

* support setting vars for non established dialogs

Victor Seva authored on 04/11/2022 10:23:59 • Victor Seva committed on 10/11/2022 10:47:14
Showing 1 changed files
... ...
@@ -1922,7 +1922,7 @@ static int ki_dlg_set_var(sip_msg_t *msg, str *sc, str *sf, str *st, str *key, s
1922 1922
 		LM_ERR("invalid From tag parameter\n");
1923 1923
 		return -1;
1924 1924
 	}
1925
-	if(st==NULL || st->s==NULL || st->len == 0) {
1925
+	if(st==NULL) {
1926 1926
 		LM_ERR("invalid To tag parameter\n");
1927 1927
 		return -1;
1928 1928
 	}
... ...
@@ -1966,11 +1966,7 @@ static int w_dlg_set_var(struct sip_msg *msg, char *ci, char *ft, char *tt, char
1966 1966
 		LM_ERR("unable to get To Tag\n");
1967 1967
 		return -1;
1968 1968
 	}
1969
-	if(st.s==NULL || st.len == 0)
1970
-	{
1971
-		LM_ERR("invalid To tag parameter\n");
1972
-		return -1;
1973
-	}
1969
+
1974 1970
 	if(fixup_get_svalue(msg, (gparam_p)key, &k)!=0)
1975 1971
 	{
1976 1972
 		LM_ERR("unable to get key name\n");
Browse code

dialog: export new itermodule api functions

- get duplicate var value and status

Daniel-Constantin Mierla authored on 26/09/2022 13:30:51
Showing 1 changed files
... ...
@@ -483,6 +483,8 @@ int load_dlg( struct dlg_binds *dlgb )
483 483
 	dlgb->set_dlg_var = set_dlg_variable;
484 484
 	dlgb->get_dlg_varref = get_dlg_varref;
485 485
 	dlgb->get_dlg_varval = get_dlg_varval;
486
+	dlgb->get_dlg_vardup = get_dlg_vardup;
487
+	dlgb->get_dlg_varstatus = get_dlg_varstatus;
486 488
 	dlgb->get_dlg = dlg_get_msg_dialog;
487 489
 	dlgb->release_dlg = dlg_release;
488 490
 	return 1;
Browse code

dialog: updated ki_dlg_var_is_null() to use safer api function

Daniel-Constantin Mierla authored on 26/09/2022 10:51:50
Showing 1 changed files
... ...
@@ -2518,14 +2518,14 @@ static int ki_dlg_var_rm(sip_msg_t *msg, str *name)
2518 2518
 static int ki_dlg_var_is_null(sip_msg_t *msg, str *name)
2519 2519
 {
2520 2520
 	dlg_cell_t *dlg;
2521
-	str *pval;
2521
+	int ret;
2522 2522
 
2523 2523
 	dlg = dlg_get_msg_dialog(msg);
2524 2524
 	if(dlg==NULL) {
2525 2525
 		return 1;
2526 2526
 	}
2527
-	pval = get_dlg_varref(dlg, name);
2528
-	if(pval==NULL || pval->s==NULL) {
2527
+	ret = get_dlg_varstatus(dlg, name);
2528
+	if(ret==1) {
2529 2529
 		return 1;
2530 2530
 	}
2531 2531
 	return -1;
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 1 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
 	}
Browse code

dialog: added modparam dlg_ctxiuid_mode to control when iuid is set

Daniel-Constantin Mierla authored on 26/08/2022 09:24:30
Showing 1 changed files
... ...
@@ -154,6 +154,7 @@ str dlg_xavp_cfg = {0};
154 154
 int dlg_ka_timer = 0;
155 155
 int dlg_ka_interval = 0;
156 156
 int dlg_clean_timer = 90;
157
+int dlg_ctxiuid_mode = 0;
157 158
 
158 159
 str dlg_lreq_callee_headers = {0};
159 160
 
... ...
@@ -361,6 +362,8 @@ static param_export_t mod_params[]={
361 362
 	{ "dlg_filter_mode",       INT_PARAM, &dlg_filter_mode          },
362 363
 	{ "bye_early_code",        PARAM_INT, &bye_early_code           },
363 364
 	{ "bye_early_reason",      PARAM_STR, &bye_early_reason         },
365
+	{ "dlg_ctxiuid_mode",      PARAM_INT, &dlg_ctxiuid_mode         },
366
+
364 367
 	{ 0,0,0 }
365 368
 };
366 369
 
Browse code

dialog: some formatting fixes and updates

Daniel-Constantin Mierla authored on 17/08/2022 09:21:54
Showing 1 changed files
... ...
@@ -265,7 +265,7 @@ static cmd_export_t cmds[]={
265 265
 	{"dlg_set_property", (cmd_function)w_dlg_set_property,1,fixup_spve_null,
266 266
 			0, ANY_ROUTE },
267 267
 	{"dlg_reset_property", (cmd_function)w_dlg_reset_property,1,fixup_spve_null,
268
-            0, ANY_ROUTE },
268
+			0, ANY_ROUTE },
269 269
 	{"dlg_remote_profile", (cmd_function)w_dlg_remote_profile, 5, fixup_dlg_remote_profile,
270 270
 			0, ANY_ROUTE },
271 271
 	{"dlg_set_ruri",       (cmd_function)w_dlg_set_ruri,  0, NULL,
... ...
@@ -573,8 +573,8 @@ static int mod_init(void)
573 573
 	}
574 574
 
575 575
 	if (timeout_spec.s) {
576
-		if ( pv_parse_spec(&timeout_spec, &timeout_avp)==0
577
-				&& (timeout_avp.type!=PVT_AVP)){
576
+		if (pv_parse_spec(&timeout_spec, &timeout_avp)==0
577
+				&& (timeout_avp.type!=PVT_AVP)) {
578 578
 			LM_ERR("malformed or non AVP timeout "
579 579
 				"AVP definition in '%.*s'\n", timeout_spec.len,timeout_spec.s);
580 580
 			return -1;
... ...
@@ -603,9 +603,8 @@ static int mod_init(void)
603 603
 		return -1;
604 604
 	}
605 605
 
606
-	if (seq_match_mode!=SEQ_MATCH_NO_ID &&
607
-	seq_match_mode!=SEQ_MATCH_FALLBACK &&
608
-	seq_match_mode!=SEQ_MATCH_STRICT_ID ) {
606
+	if (seq_match_mode!=SEQ_MATCH_NO_ID && seq_match_mode!=SEQ_MATCH_FALLBACK
607
+			&& seq_match_mode!=SEQ_MATCH_STRICT_ID ) {
609 608
 		LM_ERR("invalid value %d for seq_match_mode param!!\n",seq_match_mode);
610 609
 		return -1;
611 610
 	}
... ...
@@ -699,7 +698,8 @@ static int mod_init(void)
699 698
 
700 699
 	/* init handlers */
701 700
 	init_dlg_handlers( rr_param, dlg_flag,
702
-		timeout_spec.s?&timeout_avp:0, default_timeout, seq_match_mode, dlg_keep_proxy_rr);
701
+			timeout_spec.s?&timeout_avp:0, default_timeout, seq_match_mode,
702
+			dlg_keep_proxy_rr);
703 703
 
704 704
 	/* init timer */
705 705
 	if (init_dlg_timer(dlg_ontimeout)!=0) {
... ...
@@ -736,8 +736,8 @@ static int mod_init(void)
736 736
 	if (dlg_db_mode==DB_MODE_NONE) {
737 737
 		db_url.s = 0; db_url.len = 0;
738 738
 	} else {
739
-		if (dlg_db_mode!=DB_MODE_REALTIME &&
740
-		dlg_db_mode!=DB_MODE_DELAYED && dlg_db_mode!=DB_MODE_SHUTDOWN ) {
739
+		if (dlg_db_mode!=DB_MODE_REALTIME && dlg_db_mode!=DB_MODE_DELAYED
740
+				&& dlg_db_mode!=DB_MODE_SHUTDOWN ) {
741 741
 			LM_ERR("unsupported db_mode %d\n", dlg_db_mode);
742 742
 			return -1;
743 743
 		}
... ...
@@ -745,13 +745,13 @@ static int mod_init(void)
745 745
 			LM_ERR("db_url not configured for db_mode %d\n", dlg_db_mode);
746 746
 			return -1;
747 747
 		}
748
-		if (init_dlg_db(&db_url, dlg_hash_size, db_update_period, db_fetch_rows, db_skip_load)!=0) {
748
+		if (init_dlg_db(&db_url, dlg_hash_size, db_update_period, db_fetch_rows,
749
+					db_skip_load)!=0) {
749 750
 			LM_ERR("failed to initialize the DB support\n");
750 751
 			return -1;
751 752
 		}
752 753
 	}
753 754
 
754
-
755 755
 	/* timer process to send keep alive requests */
756 756
 	if(dlg_ka_timer>0 && dlg_ka_interval>0)
757 757
 		register_sync_timers(1);
... ...
@@ -1260,7 +1260,8 @@ static int fixup_dlg_req_with_headers_and_content(void** param, int param_no)
1260 1260
 	return 0;
1261 1261
 }
1262 1262
 
1263
-static int w_dlg_req_with_headers_and_content(struct sip_msg *msg, char *side, char *method, char* headers, char *content_type, char *content)
1263
+static int w_dlg_req_with_headers_and_content(struct sip_msg *msg, char *side,
1264
+		char *method, char* headers, char *content_type, char *content)
1264 1265
 {
1265 1266
 	dlg_cell_t *dlg = NULL;
1266 1267
 	int n;
... ...
@@ -1294,7 +1295,7 @@ static int w_dlg_req_with_headers_and_content(struct sip_msg *msg, char *side, c
1294 1295
 		{
1295 1296
 			LM_ERR("invalid Headers parameter\n");
1296 1297
 			goto error;
1297
-		}		
1298
+		}
1298 1299
 	}
1299 1300
 	if (content_type && content) {
1300 1301
 		if(fixup_get_svalue(msg, (gparam_p)content_type, &str_content_type)!=0)
... ...
@@ -1306,7 +1307,7 @@ static int w_dlg_req_with_headers_and_content(struct sip_msg *msg, char *side, c
1306 1307
 		{
1307 1308
 			LM_ERR("invalid Headers parameter\n");
1308 1309
 			goto error;
1309
-		}		
1310
+		}
1310 1311
 		if(fixup_get_svalue(msg, (gparam_p)content, &str_content)!=0)
1311 1312
 		{
1312 1313
 			LM_ERR("unable to get Content\n");
... ...
@@ -1316,23 +1317,27 @@ static int w_dlg_req_with_headers_and_content(struct sip_msg *msg, char *side, c
1316 1317
 		{
1317 1318
 			LM_ERR("invalid Content parameter\n");
1318 1319
 			goto error;
1319
-		}		
1320
+		}
1320 1321
 	}
1321
-	
1322
+
1322 1323
 	n = (int)(long)side;
1323 1324
 	if(n==1)
1324 1325
 	{
1325
-		if(dlg_request_within(msg, dlg, DLG_CALLER_LEG, &str_method, &str_headers, &str_content_type, &str_content)!=0)
1326
+		if(dlg_request_within(msg, dlg, DLG_CALLER_LEG, &str_method, &str_headers,
1327
+					&str_content_type, &str_content)!=0)
1326 1328
 			goto error;
1327 1329
 		goto done;
1328 1330
 	} else if(n==2) {
1329
-		if(dlg_request_within(msg, dlg, DLG_CALLEE_LEG, &str_method, &str_headers, &str_content_type, &str_content)!=0)
1331
+		if(dlg_request_within(msg, dlg, DLG_CALLEE_LEG, &str_method, &str_headers,
1332
+					&str_content_type, &str_content)!=0)
1330 1333
 			goto error;
1331 1334
 		goto done;
1332 1335
 	} else {
1333
-		if(dlg_request_within(msg, dlg, DLG_CALLER_LEG, &str_method, &str_headers, &str_content_type, &str_content)!=0)
1336
+		if(dlg_request_within(msg, dlg, DLG_CALLER_LEG, &str_method, &str_headers,
1337
+					&str_content_type, &str_content)!=0)
1334 1338
 			goto error;
1335
-		if(dlg_request_within(msg, dlg, DLG_CALLEE_LEG, &str_method, &str_headers, &str_content_type, &str_content)!=0)
1339
+		if(dlg_request_within(msg, dlg, DLG_CALLEE_LEG, &str_method, &str_headers,
1340
+					&str_content_type, &str_content)!=0)
1336 1341
 			goto error;
1337 1342
 		goto done;
1338 1343
 	}
... ...
@@ -1343,15 +1348,18 @@ done:
1343 1348
 
1344 1349
 error:
1345 1350
 	dlg_release(dlg);
1346
-	return -1;		
1351
+	return -1;
1347 1352
 }
1348 1353
 
1349
-static int w_dlg_req_with_content(struct sip_msg *msg, char *side, char *method, char *content_type, char *content)
1354
+static int w_dlg_req_with_content(struct sip_msg *msg, char *side, char *method,
1355
+		char *content_type, char *content)
1350 1356
 {
1351
-	return w_dlg_req_with_headers_and_content(msg, side, method, NULL, content_type, content);
1357
+	return w_dlg_req_with_headers_and_content(msg, side, method, NULL,
1358
+			content_type, content);
1352 1359
 }
1353 1360
 
1354
-static int w_dlg_req_with_headers(struct sip_msg *msg, char *side, char *method, char *headers)
1361
+static int w_dlg_req_with_headers(struct sip_msg *msg, char *side, char *method,
1362
+		char *headers)
1355 1363
 {
1356 1364
 	return w_dlg_req_with_headers_and_content(msg, side, method, headers, NULL, NULL);
1357 1365
 }
... ...
@@ -1369,7 +1377,7 @@ static int w_dlg_bye(struct sip_msg *msg, char *side, char *s2)
1369 1377
 	dlg = dlg_get_ctx_dialog();
1370 1378
 	if(dlg==NULL)
1371 1379
 		return -1;
1372
-	
1380
+
1373 1381
 	n = (int)(long)side;
1374 1382
 	if(n==1)
1375 1383
 	{
... ...
@@ -1404,7 +1412,7 @@ static int w_dlg_refer(struct sip_msg *msg, char *side, char *to)
1404 1412
 	dlg = dlg_get_ctx_dialog();
1405 1413
 	if(dlg==NULL)
1406 1414
 		return -1;
1407
-	
1415
+
1408 1416
 	n = (int)(long)side;
1409 1417
 
1410 1418
 	if(fixup_get_svalue(msg, (gparam_p)to, &st)!=0)
... ...
@@ -1658,7 +1666,7 @@ static int w_dlg_reset_property(struct sip_msg *msg, char *prop, char *s2)
1658 1666
 }
1659 1667
 
1660 1668
 static int w_dlg_set_timeout_by_profile3(struct sip_msg *msg, char *profile,
1661
-					char *value, char *timeout_str) 
1669
+					char *value, char *timeout_str)
1662 1670
 {
1663 1671
 	pv_elem_t *pve = NULL;
1664 1672
 	str val_s;
... ...
@@ -1666,22 +1674,21 @@ static int w_dlg_set_timeout_by_profile3(struct sip_msg *msg, char *profile,
1666 1674
 	pve = (pv_elem_t *) value;
1667 1675
 
1668 1676
 	if(pve != NULL && ((struct dlg_profile_table *) profile)->has_value) {
1669
-		if(pv_printf_s(msg,pve, &val_s) != 0 || 
1670
-		   !val_s.s || val_s.len == 0) {
1677
+		if(pv_printf_s(msg,pve, &val_s) != 0 || !val_s.s || val_s.len == 0) {
1671 1678
 			LM_WARN("cannot get string for value\n");
1672 1679
 			return -1;
1673 1680
 		}
1674 1681
 	}
1675 1682
 
1676 1683
 	if(dlg_set_timeout_by_profile((struct dlg_profile_table *) profile,
1677
-				   &val_s, atoi(timeout_str)) != 0)
1684
+				&val_s, atoi(timeout_str)) != 0)
1678 1685
 		return -1;
1679 1686
 
1680 1687
 	return 1;
1681 1688
 }
1682 1689
 
1683
-static int w_dlg_set_timeout_by_profile2(struct sip_msg *msg, 
1684
-					 char *profile, char *timeout_str)
1690
+static int w_dlg_set_timeout_by_profile2(struct sip_msg *msg,
1691
+		char *profile, char *timeout_str)
1685 1692
 {
1686 1693
 	return w_dlg_set_timeout_by_profile3(msg, profile, NULL, timeout_str);
1687 1694
 }
... ...
@@ -3086,12 +3093,12 @@ static const char *rpc_end_dlg_entry_id_doc[2] = {
3086 3093
 	"End a given dialog based on [h_entry] [h_id]", 0
3087 3094
 };
3088 3095
 static const char *rpc_dlg_terminate_dlg_doc[2] = {
3089
-        "End a given dialog based on callid", 0
3096
+	"End a given dialog based on callid", 0
3090 3097
 };
3091 3098
 static const char *rpc_dlg_set_state_doc[3] = {
3092
-        "Set state for a dialog based on callid and tags",
3093
-        "It is targeting the need to update from state 4 (confirmed) to 5 (terminated)",
3094
-        0
3099
+	"Set state for a dialog based on callid and tags",
3100
+	"It is targeting the need to update from state 4 (confirmed) to 5 (terminated)",
3101
+	0
3095 3102
 };
3096 3103
 static const char *rpc_profile_get_size_doc[2] = {
3097 3104
 	"Returns the number of dialogs belonging to a profile", 0
... ...
@@ -3157,10 +3164,10 @@ static void rpc_dlg_terminate_dlg(rpc_t *rpc,void *c){
3157 3164
 	LM_DBG("Dialog bye return code %d \n",ret);
3158 3165
 
3159 3166
 	if(ret>=0) {
3160
-        LM_WARN("Dialog is terminated callid: '%.*s' \n",
3161
-        		callid.len, callid.s);
3162
-        dlg_release(dlg);
3163
-    }
3167
+		LM_WARN("Dialog is terminated callid: '%.*s' \n",
3168
+		callid.len, callid.s);
3169
+		dlg_release(dlg);
3170
+	}
3164 3171
 }
3165 3172
 
3166 3173
 static void rpc_dlg_set_state(rpc_t *rpc,void *c){
... ...
@@ -3251,7 +3258,7 @@ static void rpc_dlg_is_alive(rpc_t *rpc, void *c)
3251 3258
 		return;
3252 3259
 	}
3253 3260
 	state = dlg->state;
3254
-    dlg_release(dlg);
3261
+	dlg_release(dlg);
3255 3262
 	if (state != DLG_STATE_CONFIRMED) {
3256 3263
 		LM_DBG("Dialog with Call-ID '%.*s' is in state: %d (confirmed: %d)\n",
3257 3264
 				callid.len, callid.s, state, DLG_STATE_CONFIRMED);
... ...
@@ -3548,7 +3555,7 @@ static void rpc_dlg_list_match_ex(rpc_t *rpc, void *c, int with_context)
3548 3555
 						matched = 1;
3549 3556
 					}
3550 3557
 				break;
3551
-				case 3:		
3558
+				case 3:
3552 3559
 					/* greater than */
3553 3560
 					if (str2int(&mval, &mival) == 0 && ival > mival) {
3554 3561
 						matched = 1;
Browse code

dialog: dont reset dlg_db_mode in POSTCHILDINIT for DB_MODE_SHUTDOWN

Shane Mitchell authored on 17/08/2022 03:17:17 • Daniel-Constantin Mierla committed on 17/08/2022 08:32:41
Showing 1 changed files
... ...
@@ -824,7 +824,7 @@ static int child_init(int rank)
824 824
 
825 825
 	/* in DB_MODE_SHUTDOWN only PROC_MAIN will do a DB dump at the end, so
826 826
 	 * for the rest of the processes will be the same as DB_MODE_NONE */
827
-	if (dlg_db_mode==DB_MODE_SHUTDOWN && rank!=PROC_MAIN)
827
+	if (dlg_db_mode==DB_MODE_SHUTDOWN && rank!=PROC_POSTCHILDINIT)
828 828
 		dlg_db_mode = DB_MODE_NONE;
829 829
 	/* in DB_MODE_REALTIME and DB_MODE_DELAYED the PROC_MAIN have no DB handle */
830 830
 	if ( (dlg_db_mode==DB_MODE_REALTIME || dlg_db_mode==DB_MODE_DELAYED) &&
Browse code

Revert "Revert "dialog: Terminate dialogs in Early stage and add functionality to send messages within a dialog""

This reverts commit 1465a9b6e9fda36617b7b198ae051f0957803550.

Daniel-Constantin Mierla authored on 24/06/2022 06:11:02
Showing 1 changed files
... ...
@@ -123,6 +123,9 @@ str dlg_bridge_controller = str_init("sip:controller@kamailio.org");
123 123
 
124 124
 str dlg_bridge_contact = str_init("sip:controller@kamailio.org:5060");
125 125
 
126
+int bye_early_code = 480;
127
+str bye_early_reason = str_init("Temporarily Unavailable");
128
+
126 129
 str ruri_pvar_param = str_init("$ru");
127 130
 pv_elem_t * ruri_param_model = NULL;
128 131
 str empty_str = STR_NULL;
... ...
@@ -204,6 +207,16 @@ static int w_dlg_remote_profile(sip_msg_t *msg, char *cmd, char *pname,
204 207
 		char *pval, char *puid, char *expires);
205 208
 static int fixup_dlg_remote_profile(void** param, int param_no);
206 209
 
210
+static int w_dlg_req_with_headers_and_content(struct sip_msg *, char *, char *, char* , char *, char *);
211
+static int w_dlg_req_with_content(struct sip_msg *, char *, char *, char *, char *);
212
+static int w_dlg_req_with_headers(struct sip_msg *, char *, char *, char *);
213
+static int w_dlg_req_within(struct sip_msg *, char *, char *);
214
+
215
+static int fixup_dlg_dlg_req_within(void** , int );
216
+static int fixup_dlg_req_with_headers(void** , int );
217
+static int fixup_dlg_req_with_content(void** , int );
218
+static int fixup_dlg_req_with_headers_and_content(void** , int );
219
+
207 220
 static cmd_export_t cmds[]={
208 221
 	{"dlg_manage", (cmd_function)w_dlg_manage,            0,0,
209 222
 			0, REQUEST_ROUTE },
... ...
@@ -265,6 +278,14 @@ static cmd_export_t cmds[]={
265 278
 			fixup_dlg_get_var_free, ANY_ROUTE },
266 279
 	{"dlg_set_var",(cmd_function)w_dlg_set_var, 5, fixup_dlg_set_var,
267 280
 			fixup_dlg_set_var_free, ANY_ROUTE },
281
+	{"dlg_req_within",  (cmd_function)w_dlg_req_within, 2, fixup_dlg_dlg_req_within,
282
+			0, ANY_ROUTE},
283
+	{"dlg_req_within",  (cmd_function)w_dlg_req_with_headers, 3, fixup_dlg_req_with_headers,
284
+			0, ANY_ROUTE},
285
+	{"dlg_req_within",  (cmd_function)w_dlg_req_with_content, 4, fixup_dlg_req_with_content,
286
+			0, ANY_ROUTE},
287
+	{"dlg_req_within",  (cmd_function)w_dlg_req_with_headers_and_content, 5,
288
+			fixup_dlg_req_with_headers_and_content, 0, ANY_ROUTE},
268 289
 
269 290
 	{"load_dlg",  (cmd_function)load_dlg,   0, 0, 0, 0},
270 291
 	{0,0,0,0,0,0}
... ...
@@ -338,6 +359,8 @@ static param_export_t mod_params[]={
338 359
 	{ "h_id_step",             PARAM_INT, &dlg_h_id_step            },
339 360
 	{ "keep_proxy_rr",         INT_PARAM, &dlg_keep_proxy_rr        },
340 361
 	{ "dlg_filter_mode",       INT_PARAM, &dlg_filter_mode          },
362
+	{ "bye_early_code",        PARAM_INT, &bye_early_code           },
363
+	{ "bye_early_reason",      PARAM_STR, &bye_early_reason         },
341 364
 	{ 0,0,0 }
342 365
 };
343 366
 
... ...
@@ -1112,6 +1135,232 @@ static int w_dlg_manage(struct sip_msg *msg, char *s1, char *s2)
1112 1135
 	return dlg_manage(msg);
1113 1136
 }
1114 1137
 
1138
+static int fixup_dlg_dlg_req_within(void** param, int param_no)
1139
+{
1140
+	char *val;
1141
+	int n = 0;
1142
+
1143
+	if (param_no==1) {
1144
+		val = (char*)*param;
1145
+		if (strcasecmp(val,"all")==0) {
1146
+			n = 0;
1147
+		} else if (strcasecmp(val,"caller")==0) {
1148
+			n = 1;
1149
+		} else if (strcasecmp(val,"callee")==0) {
1150
+			n = 2;
1151
+		} else {
1152
+			LM_ERR("invalid param \"%s\"\n", val);
1153
+			return E_CFG;
1154
+		}
1155
+		pkg_free(*param);
1156
+		*param=(void*)(long)n;
1157
+	} else if (param_no==2) {
1158
+		return fixup_spve_null(param, 1);
1159
+	} else {
1160
+		LM_ERR("called with parameter != 1\n");
1161
+		return E_BUG;
1162
+	}
1163
+	return 0;
1164
+}
1165
+
1166
+static int fixup_dlg_req_with_headers(void** param, int param_no)
1167
+{
1168
+	char *val;
1169
+	int n = 0;
1170
+
1171
+	if (param_no==1) {
1172
+		val = (char*)*param;
1173
+		if (strcasecmp(val,"all")==0) {
1174
+			n = 0;
1175
+		} else if (strcasecmp(val,"caller")==0) {
1176
+			n = 1;
1177
+		} else if (strcasecmp(val,"callee")==0) {
1178
+			n = 2;
1179
+		} else {
1180
+			LM_ERR("invalid param \"%s\"\n", val);
1181
+			return E_CFG;
1182
+		}
1183
+		pkg_free(*param);
1184
+		*param=(void*)(long)n;
1185
+	} else if (param_no==2) {
1186
+		return fixup_spve_null(param, 1);
1187
+	} else if (param_no==3) {
1188
+		return fixup_spve_null(param, 1);
1189
+	} else {
1190
+		LM_ERR("called with parameter != 1\n");
1191
+		return E_BUG;
1192
+	}
1193
+	return 0;
1194
+}
1195
+
1196
+
1197
+static int fixup_dlg_req_with_content(void** param, int param_no)
1198
+{
1199
+	char *val;
1200
+	int n = 0;
1201
+
1202
+	if (param_no==1) {
1203
+		val = (char*)*param;
1204
+		if (strcasecmp(val,"all")==0) {
1205
+			n = 0;
1206
+		} else if (strcasecmp(val,"caller")==0) {
1207
+			n = 1;
1208
+		} else if (strcasecmp(val,"callee")==0) {
1209
+			n = 2;
1210
+		} else {
1211
+			LM_ERR("invalid param \"%s\"\n", val);
1212
+			return E_CFG;
1213
+		}
1214
+		pkg_free(*param);
1215
+		*param=(void*)(long)n;
1216
+	} else if (param_no==2) {
1217
+		return fixup_spve_null(param, 1);
1218
+	} else if (param_no==3) {
1219
+		return fixup_spve_null(param, 1);
1220
+	} else if (param_no==4) {
1221
+		return fixup_spve_null(param, 1);
1222
+	} else {
1223
+		LM_ERR("called with parameter != 1\n");
1224
+		return E_BUG;
1225
+	}
1226
+	return 0;
1227
+}
1228
+
1229
+static int fixup_dlg_req_with_headers_and_content(void** param, int param_no)
1230
+{
1231
+	char *val;
1232
+	int n = 0;
1233
+
1234
+	if (param_no==1) {
1235
+		val = (char*)*param;
1236
+		if (strcasecmp(val,"all")==0) {
1237
+			n = 0;
1238
+		} else if (strcasecmp(val,"caller")==0) {
1239
+			n = 1;
1240
+		} else if (strcasecmp(val,"callee")==0) {
1241
+			n = 2;
1242
+		} else {
1243
+			LM_ERR("invalid param \"%s\"\n", val);
1244
+			return E_CFG;
1245
+		}
1246
+		pkg_free(*param);
1247
+		*param=(void*)(long)n;
1248
+	} else if (param_no==2) {
1249
+		return fixup_spve_null(param, 1);
1250
+	} else if (param_no==3) {
1251
+		return fixup_spve_null(param, 1);
1252
+	} else if (param_no==4) {
1253
+		return fixup_spve_null(param, 1);
1254
+	} else if (param_no==5) {
1255
+		return fixup_spve_null(param, 1);
1256
+	} else {
1257
+		LM_ERR("called with parameter != 1\n");
1258
+		return E_BUG;
1259
+	}
1260
+	return 0;
1261
+}
1262
+
1263
+static int w_dlg_req_with_headers_and_content(struct sip_msg *msg, char *side, char *method, char* headers, char *content_type, char *content)
1264
+{
1265
+	dlg_cell_t *dlg = NULL;
1266
+	int n;
1267
+	str str_method = {0,0};
1268
+	str str_headers = {0,0};
1269
+	str str_content_type = {0,0};
1270
+	str str_content = {0,0};
1271
+
1272
+	dlg = dlg_get_ctx_dialog();
1273
+	if(dlg==NULL)
1274
+		return -1;
1275
+
1276
+	if(fixup_get_svalue(msg, (gparam_p)method, &str_method)!=0)
1277
+	{
1278
+		LM_ERR("unable to get Method\n");
1279
+		goto error;
1280
+	}
1281
+	if(str_method.s==NULL || str_method.len == 0)
1282
+	{
1283
+		LM_ERR("invalid Method parameter\n");
1284
+		goto error;
1285
+	}
1286
+
1287
+	if (headers) {
1288
+		if(fixup_get_svalue(msg, (gparam_p)headers, &str_headers)!=0)
1289
+		{
1290
+			LM_ERR("unable to get Method\n");
1291
+			goto error;
1292
+		}
1293
+		if(str_headers.s==NULL || str_headers.len == 0)
1294
+		{
1295
+			LM_ERR("invalid Headers parameter\n");
1296
+			goto error;
1297
+		}		
1298
+	}
1299
+	if (content_type && content) {
1300
+		if(fixup_get_svalue(msg, (gparam_p)content_type, &str_content_type)!=0)
1301
+		{
1302
+			LM_ERR("unable to get Content-Type\n");
1303
+			goto error;
1304
+		}
1305
+		if(str_content_type.s==NULL || str_content_type.len == 0)
1306
+		{
1307
+			LM_ERR("invalid Headers parameter\n");
1308
+			goto error;
1309
+		}		
1310
+		if(fixup_get_svalue(msg, (gparam_p)content, &str_content)!=0)
1311
+		{
1312
+			LM_ERR("unable to get Content\n");
1313
+			goto error;
1314
+		}
1315
+		if(str_content.s==NULL || str_content.len == 0)
1316
+		{
1317
+			LM_ERR("invalid Content parameter\n");
1318
+			goto error;
1319
+		}		
1320
+	}
1321
+	
1322
+	n = (int)(long)side;
1323
+	if(n==1)
1324
+	{
1325
+		if(dlg_request_within(msg, dlg, DLG_CALLER_LEG, &str_method, &str_headers, &str_content_type, &str_content)!=0)
1326
+			goto error;
1327
+		goto done;
1328
+	} else if(n==2) {
1329
+		if(dlg_request_within(msg, dlg, DLG_CALLEE_LEG, &str_method, &str_headers, &str_content_type, &str_content)!=0)
1330
+			goto error;
1331
+		goto done;
1332
+	} else {
1333
+		if(dlg_request_within(msg, dlg, DLG_CALLER_LEG, &str_method, &str_headers, &str_content_type, &str_content)!=0)
1334
+			goto error;
1335
+		if(dlg_request_within(msg, dlg, DLG_CALLEE_LEG, &str_method, &str_headers, &str_content_type, &str_content)!=0)
1336
+			goto error;
1337
+		goto done;
1338
+	}
1339
+
1340
+done:
1341
+	dlg_release(dlg);
1342
+	return 1;
1343
+
1344
+error:
1345
+	dlg_release(dlg);
1346
+	return -1;		
1347
+}
1348
+
1349
+static int w_dlg_req_with_content(struct sip_msg *msg, char *side, char *method, char *content_type, char *content)
1350
+{
1351
+	return w_dlg_req_with_headers_and_content(msg, side, method, NULL, content_type, content);
1352
+}
1353
+
1354
+static int w_dlg_req_with_headers(struct sip_msg *msg, char *side, char *method, char *headers)
1355
+{
1356
+	return w_dlg_req_with_headers_and_content(msg, side, method, headers, NULL, NULL);
1357
+}
1358
+
1359
+static int w_dlg_req_within(struct sip_msg *msg, char *side, char *method)
1360
+{
1361
+	return w_dlg_req_with_headers_and_content(msg, side, method, NULL, NULL, NULL);
1362
+}
1363
+
1115 1364
 static int w_dlg_bye(struct sip_msg *msg, char *side, char *s2)
1116 1365
 {
1117 1366
 	dlg_cell_t *dlg = NULL;
Browse code

dialog: w_dlg_get_var, fix incompatible pointer

> CC (gcc) [M dialog.so] dialog.o
> dialog.c: In function 'w_dlg_get_var': dialog.c:1608:6: warning: assignment to 'str *' {aka 'struct _str *'} from incompatible pointer type 'sr_kemi_xval_t *' {aka 'struct sr_kemi_xval *'} [-Wincompatible-pointer-types]
> 1608 | val = ki_dlg_get_var(msg, &sc, &sf, &st, &k);
> | ^

Victor Seva authored on 27/05/2022 15:18:01
Showing 1 changed files
... ...
@@ -1568,7 +1568,7 @@ static int w_dlg_get_var(struct sip_msg *msg, char *ci, char *ft, char *tt, char
1568 1568
 	str sf = STR_NULL;
1569 1569
 	str st = STR_NULL;
1570 1570
 	str k = STR_NULL;
1571
-	str *val = NULL;
1571
+	sr_kemi_xval_t *val = NULL;
1572 1572
 	pv_value_t dst_val;
1573 1573
 	pv_spec_t* dst_pv = (pv_spec_t *)pv;
1574 1574
 
... ...
@@ -1606,11 +1606,11 @@ static int w_dlg_get_var(struct sip_msg *msg, char *ci, char *ft, char *tt, char
1606 1606
 		goto error;
1607 1607
 	}
1608 1608
 	val = ki_dlg_get_var(msg, &sc, &sf, &st, &k);
1609
-	if(val) {
1609
+	if(val && val->vtype == SR_KEMIP_STR) {
1610 1610
 		memset(&dst_val, 0, sizeof(pv_value_t));
1611 1611
 		dst_val.flags |= PV_VAL_STR;
1612
-		dst_val.rs.s = val->s;
1613
-		dst_val.rs.len = val->len;
1612
+		dst_val.rs.s = val->v.s.s;
1613
+		dst_val.rs.len = val->v.s.len;
1614 1614
 	} else {
1615 1615
 		pv_get_null(msg, NULL, &dst_val);
1616 1616
 	}
Browse code

dialog: dlg_get_var assure return null on error

Victor Seva authored on 27/05/2022 14:58:28
Showing 1 changed files
... ...
@@ -1570,53 +1570,62 @@ static int w_dlg_get_var(struct sip_msg *msg, char *ci, char *ft, char *tt, char
1570 1570
 	str k = STR_NULL;
1571 1571
 	str *val = NULL;
1572 1572
 	pv_value_t dst_val;
1573
-	pv_spec_t* dst_pv;
1573
+	pv_spec_t* dst_pv = (pv_spec_t *)pv;
1574 1574
 
1575 1575
 	if(ci==0 || ft==0 || tt==0)
1576 1576
 	{
1577 1577
 		LM_ERR("invalid parameters\n");
1578
-		return -1;
1578
+		goto error;
1579 1579
 	}
1580 1580
 
1581 1581
 	if(fixup_get_svalue(msg, (gparam_p)ci, &sc)!=0)
1582 1582
 	{
1583 1583
 		LM_ERR("unable to get Call-ID\n");
1584
-		return -1;
1584
+		goto error;
1585 1585
 	}
1586 1586
 
1587 1587
 	if(fixup_get_svalue(msg, (gparam_p)ft, &sf)!=0)
1588 1588
 	{
1589 1589
 		LM_ERR("unable to get From tag\n");
1590
-		return -1;
1590
+		goto error;
1591 1591
 	}
1592 1592
 
1593 1593
 	if(fixup_get_svalue(msg, (gparam_p)tt, &st)!=0)
1594 1594
 	{
1595 1595
 		LM_ERR("unable to get To Tag\n");
1596
-		return -1;
1596
+		goto error;
1597 1597
 	}
1598 1598
 	if(st.s==NULL || st.len == 0)
1599 1599
 	{
1600 1600
 		LM_ERR("invalid To tag parameter\n");
1601
-		return -1;
1601
+		goto error;
1602 1602
 	}
1603 1603
 	if(fixup_get_svalue(msg, (gparam_p)key, &k)!=0)
1604 1604
 	{
1605 1605
 		LM_ERR("unable to get key name\n");
1606
-		return -1;
1606
+		goto error;
1607 1607
 	}
1608
-	dst_pv = (pv_spec_t *)pv;
1609
-	val = ki_dlg_get_var_helper(msg, &sc, &sf, &st, &k);
1608
+	val = ki_dlg_get_var(msg, &sc, &sf, &st, &k);
1610 1609
 	if(val) {
1611 1610
 		memset(&dst_val, 0, sizeof(pv_value_t));
1612 1611
 		dst_val.flags |= PV_VAL_STR;
1613 1612
 		dst_val.rs.s = val->s;
1614 1613
 		dst_val.rs.len = val->len;
1615
-		if(pv_set_spec_value(msg, dst_pv, 0, &dst_val) != 0) return -1;
1616 1614
 	} else {
1617
-		if(pv_get_null(msg, NULL, &dst_val) != 0) return -1;
1615
+		pv_get_null(msg, NULL, &dst_val);
1616
+	}
1617
+	if(pv_set_spec_value(msg, dst_pv, 0, &dst_val) != 0) {
1618
+		LM_ERR("unable to set value to dst_pv\n");
1619
+		if(val) goto error; else return -1;
1618 1620
 	}
1619 1621
 	return 1;
1622
+
1623
+error:
1624
+	pv_get_null(msg, NULL, &dst_val);
1625
+	if(pv_set_spec_value(msg, dst_pv, 0, &dst_val) != 0) {
1626
+		LM_ERR("unable to set null value to dst_pv\n");
1627
+	}
1628
+	return -1;
1620 1629
 }
1621 1630
 
1622 1631
 static int fixup_dlg_get_var(void** param, int param_no)
Browse code

dialog: fix ki_dlg_get_var() introduced previously

Daniel-Constantin Mierla authored on 21/05/2022 06:21:49
Showing 1 changed files
... ...
@@ -1549,14 +1549,14 @@ static sr_kemi_xval_t *ki_dlg_get_var(sip_msg_t *msg, str *sc, str *sf, str *st,
1549 1549
 
1550 1550
 	memset(&_sr_kemi_dialog_xval, 0, sizeof(sr_kemi_xval_t));
1551 1551
 
1552
-	val = ki_dlg_get_var_helper(msg, &sc, &sf, &st, &k);
1552
+	val = ki_dlg_get_var_helper(msg, sc, sf, st, key);
1553 1553
 	if(!val) {
1554 1554
 		sr_kemi_xval_null(&_sr_kemi_dialog_xval, SR_KEMI_XVAL_NULL_NONE);
1555 1555
 		return &_sr_kemi_dialog_xval;
1556 1556
 	}
1557 1557
 
1558 1558
 	_sr_kemi_dialog_xval.vtype = SR_KEMIP_STR;
1559
-	_sr_kemi_dialog_xval.v.s = *pval;
1559
+	_sr_kemi_dialog_xval.v.s = *val;
1560 1560
 
1561 1561
 	return &_sr_kemi_dialog_xval;
1562 1562
 
Browse code

dialog: reworked kemi export for dlg_get_var()

- return SR_KEMIP_XVAL type

Daniel-Constantin Mierla authored on 20/05/2022 14:07:56
Showing 1 changed files
... ...
@@ -1511,7 +1511,7 @@ static int fixup_dlg_bridge(void** param, int param_no)
1511 1511
 	return 0;
1512 1512
 }
1513 1513
 
1514
-static str *ki_dlg_get_var(sip_msg_t *msg, str *sc, str *sf, str *st, str *key)
1514
+static str *ki_dlg_get_var_helper(sip_msg_t *msg, str *sc, str *sf, str *st, str *key)
1515 1515
 {
1516 1516
 	dlg_cell_t *dlg = NULL;
1517 1517
 	unsigned int dir = 0;
... ...
@@ -1538,6 +1538,30 @@ static str *ki_dlg_get_var(sip_msg_t *msg, str *sc, str *sf, str *st, str *key)
1538 1538
 	return val;
1539 1539
 }
1540 1540
 
1541
+/**
1542
+ *
1543
+ */
1544
+static sr_kemi_xval_t _sr_kemi_dialog_xval = {0};
1545
+
1546
+static sr_kemi_xval_t *ki_dlg_get_var(sip_msg_t *msg, str *sc, str *sf, str *st, str *key)
1547
+{
1548
+	str *val = NULL;
1549
+
1550
+	memset(&_sr_kemi_dialog_xval, 0, sizeof(sr_kemi_xval_t));
1551
+
1552
+	val = ki_dlg_get_var_helper(msg, &sc, &sf, &st, &k);
1553
+	if(!val) {
1554
+		sr_kemi_xval_null(&_sr_kemi_dialog_xval, SR_KEMI_XVAL_NULL_NONE);
1555
+		return &_sr_kemi_dialog_xval;
1556
+	}
1557
+
1558
+	_sr_kemi_dialog_xval.vtype = SR_KEMIP_STR;
1559
+	_sr_kemi_dialog_xval.v.s = *pval;
1560
+
1561
+	return &_sr_kemi_dialog_xval;
1562
+
1563
+}
1564
+
1541 1565
 static int w_dlg_get_var(struct sip_msg *msg, char *ci, char *ft, char *tt, char *key, char *pv)
1542 1566
 {
1543 1567
 	str sc = STR_NULL;
... ...
@@ -1582,7 +1606,7 @@ static int w_dlg_get_var(struct sip_msg *msg, char *ci, char *ft, char *tt, char
1582 1606
 		return -1;
1583 1607
 	}
1584 1608
 	dst_pv = (pv_spec_t *)pv;
1585
-	val = ki_dlg_get_var(msg, &sc, &sf, &st, &k);
1609
+	val = ki_dlg_get_var_helper(msg, &sc, &sf, &st, &k);
1586 1610
 	if(val) {
1587 1611
 		memset(&dst_val, 0, sizeof(pv_value_t));
1588 1612
 		dst_val.flags |= PV_VAL_STR;
... ...
@@ -2155,11 +2179,6 @@ static int ki_dlg_var_sets(sip_msg_t *msg, str *name, str *val)
2155 2179
 	return (ret==0)?1:ret;
2156 2180
 }
2157 2181
 
2158
-/**
2159
- *
2160
- */
2161
-static sr_kemi_xval_t _sr_kemi_dialog_xval = {0};
2162
-
2163 2182
 /**
2164 2183
  *
2165 2184
  */
... ...
@@ -2289,7 +2308,7 @@ static sr_kemi_t sr_kemi_dialog_exports[] = {
2289 2308
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
2290 2309
 	},
2291 2310
 	{ str_init("dialog"), str_init("dlg_get_var"),
2292
-		SR_KEMIP_STR, ki_dlg_get_var,
2311
+		SR_KEMIP_XVAL, ki_dlg_get_var,
2293 2312
 		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
2294 2313
 			SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE }
2295 2314
 	},
Browse code

dialog: dlg_set_var(callid, ft, tt, key, value)

Victor Seva authored on 11/05/2022 13:50:14 • Daniel-Constantin Mierla committed on 17/05/2022 10:34:59
Showing 1 changed files
... ...
@@ -197,6 +197,9 @@ static int w_dlg_db_load_extra(sip_msg_t *msg, char *p1, char *p2);
197 197
 static int fixup_dlg_get_var(void** param, int param_no);
198 198
 static int fixup_dlg_get_var_free(void** param, int param_no);
199 199
 static int w_dlg_get_var(struct sip_msg*, char*, char*, char*, char*, char*);
200
+static int fixup_dlg_set_var(void** param, int param_no);
201
+static int fixup_dlg_set_var_free(void** param, int param_no);
202
+static int w_dlg_set_var(struct sip_msg*, char*, char*, char*, char*, char*);
200 203
 static int w_dlg_remote_profile(sip_msg_t *msg, char *cmd, char *pname,
201 204
 		char *pval, char *puid, char *expires);
202 205
 static int fixup_dlg_remote_profile(void** param, int param_no);
... ...
@@ -260,6 +263,8 @@ static cmd_export_t cmds[]={
260 263
 			0, ANY_ROUTE },
261 264
 	{"dlg_get_var",(cmd_function)w_dlg_get_var, 5, fixup_dlg_get_var,
262 265
 			fixup_dlg_get_var_free, ANY_ROUTE },
266
+	{"dlg_set_var",(cmd_function)w_dlg_set_var, 5, fixup_dlg_set_var,
267
+			fixup_dlg_set_var_free, ANY_ROUTE },
263 268
 
264 269
 	{"load_dlg",  (cmd_function)load_dlg,   0, 0, 0, 0},
265 270
 	{0,0,0,0,0,0}
... ...
@@ -1608,6 +1613,96 @@ static int fixup_dlg_get_var_free(void** param, int param_no)
1608 1613
 	return -1;
1609 1614
 }
1610 1615
 
1616
+static int ki_dlg_set_var(sip_msg_t *msg, str *sc, str *sf, str *st, str *key, str *val)
1617
+{
1618
+	dlg_cell_t *dlg = NULL;
1619
+	unsigned int dir = 0;
1620
+	int ret = 1;
1621
+
1622
+	if(sc==NULL || sc->s==NULL || sc->len == 0) {
1623
+		LM_ERR("invalid Call-ID parameter\n");
1624
+		return -1;
1625
+	}
1626
+	if(sf==NULL || sf->s==NULL || sf->len == 0) {
1627
+		LM_ERR("invalid From tag parameter\n");
1628
+		return -1;
1629
+	}
1630
+	if(st==NULL || st->s==NULL || st->len == 0) {
1631
+		LM_ERR("invalid To tag parameter\n");
1632
+		return -1;
1633
+	}
1634
+
1635
+	dlg = get_dlg(sc, sf, st, &dir);
1636
+	if(dlg==NULL)
1637