Browse code

evrexec: added rpc command evrexec.run to run an event_route

- kamctl rpc evrexec.run evname [evdata]
- first parameter is the event route name (or KEMI function)
- second parameter (optional, string) is an arbitrary data that becomes
available inside the event route via $evr(data)

Daniel-Constantin Mierla authored on 22/02/2019 10:54:13
Showing 1 changed files
... ...
@@ -32,6 +32,8 @@
32 32
 #include "../../core/ut.h"
33 33
 #include "../../core/cfg/cfg_struct.h"
34 34
 #include "../../core/parser/parse_param.h"
35
+#include "../../core/rpc.h"
36
+#include "../../core/rpc_lookup.h"
35 37
 #include "../../core/kemi.h"
36 38
 #include "../../core/fmsg.h"
37 39
 
... ...
@@ -55,12 +57,20 @@ static int child_init(int);
55 57
 int evrexec_param(modparam_t type, void* val);
56 58
 void evrexec_process(evrexec_task_t *it, int idx);
57 59
 
60
+static int pv_get_evr(sip_msg_t *msg, pv_param_t *param, pv_value_t *res);
61
+static int pv_parse_evr_name(pv_spec_p sp, str *in);
58 62
 
59 63
 static param_export_t params[]={
60 64
 	{"exec",  PARAM_STRING|USE_FUNC_PARAM, (void*)evrexec_param},
61 65
 	{0,0,0}
62 66
 };
63 67
 
68
+static pv_export_t mod_pvs[] = {
69
+	{ {"evr", (sizeof("evr")-1)}, PVT_OTHER, pv_get_evr, 0,
70
+		pv_parse_evr_name, 0, 0, 0 },
71
+
72
+	{ {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
73
+};
64 74
 
65 75
 /** module exports */
66 76
 struct module_exports exports= {
... ...
@@ -69,13 +79,14 @@ struct module_exports exports= {
69 79
 	0,					/* exported functions */
70 80
 	params,				/* exported parameters */
71 81
 	0,					/* RPC method exports */
72
-	0,					/* exported pseudo-variables */
82
+	mod_pvs,			/* exported pseudo-variables */
73 83
 	0,					/* response handling function */
74 84
 	mod_init,			/* module initialization function */
75 85
 	child_init,			/* per-child init function */
76 86
 	0					/* module destroy function */
77 87
 };
78 88
 
89
+static rpc_export_t evr_rpc_methods[];
79 90
 
80 91
 /**
81 92
  * init module function
... ...
@@ -83,6 +94,12 @@ struct module_exports exports= {
83 94
 static int mod_init(void)
84 95
 {
85 96
 	evrexec_task_t *it;
97
+
98
+	if(rpc_register_array(evr_rpc_methods)!=0) {
99
+		LM_ERR("failed to register RPC commands\n");
100
+		return -1;
101
+	}
102
+
86 103
 	if(_evrexec_list==NULL)
87 104
 		return 0;
88 105
 
... ...
@@ -253,3 +270,129 @@ int evrexec_param(modparam_t type, void *val)
253 270
 	free_params(params_list);
254 271
 	return 0;
255 272
 }
273
+
274
+static str *pv_evr_data = NULL;
275
+
276
+/**
277
+ *
278
+ */
279
+static int pv_get_evr(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
280
+{
281
+	if(param==NULL || pv_evr_data==NULL) {
282
+		return pv_get_null(msg, param, res);
283
+	}
284
+
285
+	switch(param->pvn.u.isname.name.n) {
286
+		case 0: /* data */
287
+			return pv_get_strval(msg, param, res, pv_evr_data);
288
+		default:
289
+			return pv_get_null(msg, param, res);
290
+	}
291
+}
292
+
293
+/**
294
+ *
295
+ */
296
+static int pv_parse_evr_name(pv_spec_p sp, str *in)
297
+{
298
+	if(sp==NULL || in==NULL || in->len<=0)
299
+		return -1;
300
+
301
+	switch(in->len) {
302
+		case 4:
303
+			if(strncmp(in->s, "data", 4)==0) {
304
+				sp->pvp.pvn.u.isname.name.n = 0;
305
+			} else {
306
+				goto error;
307
+			}
308
+		break;
309
+		default:
310
+			goto error;
311
+	}
312
+	sp->pvp.pvn.type = PV_NAME_INTSTR;
313
+	sp->pvp.pvn.u.isname.type = 0;
314
+
315
+	return 0;
316
+
317
+error:
318
+	LM_ERR("unknown PV evr key: %.*s\n", in->len, in->s);
319
+	return -1;
320
+}
321
+
322
+/**
323
+ *
324
+ */
325
+const char *rpc_evr_run_doc[2] = {
326
+	"Execute event_route block", 0
327
+};
328
+
329
+/**
330
+ *
331
+ */
332
+void rpc_evr_run(rpc_t *rpc, void *c)
333
+{
334
+	str evr_name = STR_NULL;
335
+	str evr_data = STR_NULL;
336
+	int ret = 0;
337
+	int evr_id = -1;
338
+	sr_kemi_eng_t *keng = NULL;
339
+	sip_msg_t *fmsg = NULL;
340
+	int rtbk = 0;
341
+	char evr_buf[2];
342
+
343
+	ret = rpc->scan(c, "s*s", &evr_name.s, &evr_data.s);
344
+	if(ret<1) {
345
+		LM_ERR("failed getting the parameters");
346
+		rpc->fault(c, 500, "Invalid parameters");
347
+		return;
348
+	}
349
+	evr_name.len = strlen(evr_name.s);
350
+	if(ret<2) {
351
+		evr_buf[0] = '\0';
352
+		evr_data.s = evr_buf;
353
+		evr_data.len = 0;
354
+	} else {
355
+		evr_data.len = strlen(evr_data.s);
356
+	}
357
+
358
+	pv_evr_data = &evr_data;
359
+	keng = sr_kemi_eng_get();
360
+	if(keng==NULL) {
361
+		evr_id = route_lookup(&event_rt, evr_name.s);
362
+		if(evr_id == -1) {
363
+			pv_evr_data = NULL;
364
+			LM_ERR("event route not found: %.*s\n", evr_name.len, evr_name.s);
365
+			rpc->fault(c, 500, "Event route not found");
366
+			return;
367
+		}
368
+	} else {
369
+		evr_id = -1;
370
+	}
371
+
372
+	fmsg = faked_msg_next();
373
+	rtbk = get_route_type();
374
+	set_route_type(LOCAL_ROUTE);
375
+
376
+	if(evr_id>=0) {
377
+		if(event_rt.rlist[evr_id]!=NULL) {
378
+			run_top_route(event_rt.rlist[evr_id], fmsg, 0);
379
+		} else {
380
+			LM_WARN("empty event route block [%.*s]\n",
381
+					evr_name.len, evr_name.s);
382
+		}
383
+	} else {
384
+		if(keng->froute(fmsg, EVENT_ROUTE, &evr_name, &evr_data)<0) {
385
+			LM_ERR("error running event route kemi callback\n");
386
+		}
387
+	}
388
+	set_route_type(rtbk);
389
+	pv_evr_data = NULL;
390
+}
391
+
392
+/**
393
+ *
394
+ */
395
+static rpc_export_t evr_rpc_methods[] = {
396
+	{"evrexec.run",  rpc_evr_run, rpc_evr_run_doc, 0},
397
+	{0, 0, 0, 0}
398
+};
256 399
\ No newline at end of file