Browse code

dialog: new rpc commands dlg.list_match and dlg.list_match_ctx

- list dialogs matching the expression given via parameters
- prototype: dlg.list_match mkey mop mval [limit]
- parameters:
* mkey - matching key - can be: ruri, furi, turi or callid
* mop - matching operator - can be: eq (string comparison), re
(regular expression), sw (starts with)
- mval - matching value

Daniel-Constantin Mierla authored on 05/12/2018 16:16:43
Showing 1 changed files
... ...
@@ -2196,6 +2196,12 @@ static const char *rpc_print_dlgs_doc[2] = {
2196 2196
 static const char *rpc_print_dlgs_ctx_doc[2] = {
2197 2197
 	"Print all dialogs with associated context", 0
2198 2198
 };
2199
+static const char *rpc_dlg_list_match_doc[2] = {
2200
+	"Print matching dialogs", 0
2201
+};
2202
+static const char *rpc_dlg_list_match_ctx_doc[2] = {
2203
+	"Print matching dialogs with associated context", 0
2204
+};
2199 2205
 static const char *rpc_print_dlg_doc[2] = {
2200 2206
 	"Print dialog based on callid and optionally fromtag", 0
2201 2207
 };
... ...
@@ -2454,9 +2460,161 @@ static void rpc_dlg_stats_active(rpc_t *rpc, void *c)
2454 2454
 		"all", dlg_starting + dlg_connecting + dlg_answering + dlg_ongoing);
2455 2455
 }
2456 2456
 
2457
+/*!
2458
+ * \brief Helper function that outputs matching dialogs via the RPC interface
2459
+ *
2460
+ * \param rpc RPC node that should be filled
2461
+ * \param c RPC void pointer
2462
+ * \param with_context if 1 then the dialog context will be also printed
2463
+ */
2464
+static void rpc_dlg_list_match_ex(rpc_t *rpc, void *c, int with_context)
2465
+{
2466
+	dlg_cell_t *dlg = NULL;
2467
+	int i = 0;
2468
+	str mkey = {NULL, 0};
2469
+	str mop = {NULL, 0};
2470
+	str mval = {NULL, 0};
2471
+	str sval = {NULL, 0};
2472
+	int n = 0;
2473
+	int m = 0;
2474
+	int vkey = 0;
2475
+	int vop = 0;
2476
+	int matched = 0;
2477
+	regex_t mre;
2478
+	regmatch_t pmatch;
2479
+
2480
+	i = rpc->scan(c, "SSS", &mkey, &mop, &mval);
2481
+	if (i < 3) {
2482
+		LM_ERR("unable to read required parameters (%d)\n", i);
2483
+		rpc->fault(c, 500, "Invalid parameters");
2484
+		return;
2485
+	}
2486
+	if(mkey.s==NULL || mkey.len<=0 || mop.s==NULL || mop.len<=0
2487
+			|| mval.s==NULL || mval.len<=0) {
2488
+		LM_ERR("invalid parameters (%d)\n", i);
2489
+		rpc->fault(c, 500, "Invalid parameters");
2490
+		return;
2491
+	}
2492
+	if(mkey.len==4 && strncmp(mkey.s, "ruri", mkey.len)==0) {
2493
+		vkey = 0;
2494
+	} else if(mkey.len==4 && strncmp(mkey.s, "furi", mkey.len)==0) {
2495
+		vkey = 1;
2496
+	} else if(mkey.len==4 && strncmp(mkey.s, "turi", mkey.len)==0) {
2497
+		vkey = 2;
2498
+	} else if(mkey.len==5 && strncmp(mkey.s, "callid", mkey.len)==0) {
2499
+		vkey = 3;
2500
+	} else {
2501
+		LM_ERR("invalid key %.*s\n", mkey.len, mkey.s);
2502
+		rpc->fault(c, 500, "Invalid matching key parameter");
2503
+		return;
2504
+	}
2505
+	if(mop.len!=2) {
2506
+		LM_ERR("invalid matching operator %.*s\n", mop.len, mop.s);
2507
+		rpc->fault(c, 500, "Invalid matching operator parameter");
2508
+		return;
2509
+
2510
+	}
2511
+	if(strncmp(mop.s, "eq", 2)==0) {
2512
+		vop = 0;
2513
+	} else if(strncmp(mop.s, "re", 2)==0) {
2514
+		vop = 1;
2515
+		memset(&mre, 0, sizeof(regex_t));
2516
+		if (regcomp(&mre, mval.s, REG_EXTENDED|REG_ICASE|REG_NEWLINE)!=0) {
2517
+			LM_ERR("failed to compile regex: %.*s\n", mval.len, mval.s);
2518
+			rpc->fault(c, 500, "Invalid matching value parameter");
2519
+			return;
2520
+		}
2521
+	} else if(strncmp(mop.s, "sw", 2)==0) {
2522
+		vop = 2;
2523
+	} else {
2524
+		LM_ERR("invalid matching operator %.*s\n", mop.len, mop.s);
2525
+		rpc->fault(c, 500, "Invalid matching operator parameter");
2526
+		return;
2527
+	}
2528
+	if(rpc->scan(c, "*d", &n)<1) {
2529
+		n = 0;
2530
+	}
2531
+
2532
+	for(i=0; i<d_table->size; i++) {
2533
+		dlg_lock(d_table, &(d_table->entries[i]));
2534
+		for(dlg=d_table->entries[i].first; dlg!=NULL; dlg=dlg->next) {
2535
+			matched = 0;
2536
+			switch(vkey) {
2537
+				case 0:
2538
+					sval = dlg->req_uri;
2539
+				break;
2540
+				case 1:
2541
+					sval = dlg->from_uri;
2542
+				break;
2543
+				case 2:
2544
+					sval = dlg->to_uri;
2545
+				break;
2546
+				case 3:
2547
+					sval = dlg->callid;
2548
+				break;
2549
+			}
2550
+			switch(vop) {
2551
+				case 0:
2552
+					/* string comparison */
2553
+					if(mval.len==sval.len
2554
+							&& strncmp(mval.s, sval.s, mval.len)==0) {
2555
+						matched = 1;
2556
+					}
2557
+				break;
2558
+				case 1:
2559
+					/* regexp matching */
2560
+					if(regexec(&mre, sval.s, 1, &pmatch, 0)==0) {
2561
+						matched = 1;
2562
+					}
2563
+				break;
2564
+				case 2:
2565
+					/* starts with */
2566
+					if(mval.len<=sval.len
2567
+							&& strncmp(mval.s, sval.s, mval.len)==0) {
2568
+						matched = 1;
2569
+					}
2570
+				break;
2571
+			}
2572
+			if (matched==1) {
2573
+				m++;
2574
+				internal_rpc_print_dlg(rpc, c, dlg, with_context);
2575
+				if(n>0 && m==n) {
2576
+					break;
2577
+				}
2578
+			}
2579
+		}
2580
+		dlg_unlock(d_table, &(d_table->entries[i]));
2581
+		if(n>0 && m==n) {
2582
+			break;
2583
+		}
2584
+	}
2585
+	if(m==0) {
2586
+		rpc->fault(c, 404, "Not found");
2587
+		return;
2588
+	}
2589
+}
2590
+
2591
+/*!
2592
+ * \brief Print matching dialogs
2593
+ */
2594
+static void rpc_dlg_list_match(rpc_t *rpc, void *c)
2595
+{
2596
+	rpc_dlg_list_match_ex(rpc, c, 0);
2597
+}
2598
+
2599
+/*!
2600
+ * \brief Print matching dialogs wih context
2601
+ */
2602
+static void rpc_dlg_list_match_ctx(rpc_t *rpc, void *c)
2603
+{
2604
+	rpc_dlg_list_match_ex(rpc, c, 1);
2605
+}
2606
+
2457 2607
 static rpc_export_t rpc_methods[] = {
2458 2608
 	{"dlg.list", rpc_print_dlgs, rpc_print_dlgs_doc, RET_ARRAY},
2459 2609
 	{"dlg.list_ctx", rpc_print_dlgs_ctx, rpc_print_dlgs_ctx_doc, RET_ARRAY},
2610
+	{"dlg.list_match", rpc_dlg_list_match, rpc_dlg_list_match_doc, RET_ARRAY},
2611
+	{"dlg.list_match_ctx", rpc_dlg_list_match_ctx, rpc_dlg_list_match_ctx_doc, RET_ARRAY},
2460 2612
 	{"dlg.dlg_list", rpc_print_dlg, rpc_print_dlg_doc, 0},
2461 2613
 	{"dlg.dlg_list_ctx", rpc_print_dlg_ctx, rpc_print_dlg_ctx_doc, 0},
2462 2614
 	{"dlg.end_dlg", rpc_end_dlg_entry_id, rpc_end_dlg_entry_id_doc, 0},