Browse code

app_lua: use kamailio embeded interface to export KSR object

- KSR is an hash table exported to Lua to host functions from Kamailio
core and modules
- now dbg(txt), err(txt) and info(txt) were exported
- in a lua script, can be used like:

KSR.info("message from lua\n");

Daniel-Constantin Mierla authored on 11/04/2016 16:01:44
Showing 3 changed files
... ...
@@ -182,6 +182,7 @@ void lua_sr_openlibs(lua_State *L)
182 182
 {
183 183
 	lua_sr_core_openlibs(L);
184 184
 	lua_sr_exp_openlibs(L);
185
+	lua_sr_kemi_register_core(L);
185 186
 }
186 187
 
187 188
 /**
... ...
@@ -38,6 +38,7 @@
38 38
 #include "../../parser/parse_uri.h"
39 39
 #include "../../lib/kcore/cmpapi.h"
40 40
 #include "../../xavp.h"
41
+#include "../../kemi.h"
41 42
 
42 43
 #include "app_lua_api.h"
43 44
 #include "app_lua_sr.h"
... ...
@@ -1418,3 +1419,265 @@ void lua_sr_core_openlibs(lua_State *L)
1418 1418
 	luaL_openlib(L, "sr.pv",   _sr_pv_Map,   0);
1419 1419
 	luaL_openlib(L, "sr.xavp", _sr_xavp_Map, 0);
1420 1420
 }
1421
+
1422
+
1423
+/**
1424
+ *
1425
+ */
1426
+static int lua_sr_kemi_dbg(sip_msg_t *msg, str *txt)
1427
+{
1428
+	if(txt!=NULL && txt->s!=NULL)
1429
+		LM_DBG("%.*s", txt->len, txt->s);
1430
+	return 0;
1431
+}
1432
+
1433
+/**
1434
+ *
1435
+ */
1436
+static int lua_sr_kemi_err(sip_msg_t *msg, str *txt)
1437
+{
1438
+	if(txt!=NULL && txt->s!=NULL)
1439
+		LM_ERR("%.*s", txt->len, txt->s);
1440
+	return 0;
1441
+}
1442
+
1443
+/**
1444
+ *
1445
+ */
1446
+static int lua_sr_kemi_info(sip_msg_t *msg, str *txt)
1447
+{
1448
+	if(txt!=NULL && txt->s!=NULL)
1449
+		LM_INFO("%.*s", txt->len, txt->s);
1450
+	return 0;
1451
+}
1452
+
1453
+
1454
+/**
1455
+ *
1456
+ */
1457
+static sr_kemi_t _sr_kemi_core[] = {
1458
+	{ str_init(""), str_init("dbg"),
1459
+		SR_KEMIP_NONE, lua_sr_kemi_dbg,
1460
+		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1461
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1462
+	},
1463
+	{ str_init(""), str_init("err"),
1464
+		SR_KEMIP_NONE, lua_sr_kemi_err,
1465
+		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1466
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1467
+	},
1468
+	{ str_init(""), str_init("info"),
1469
+		SR_KEMIP_NONE, lua_sr_kemi_info,
1470
+		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
1471
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
1472
+	},
1473
+
1474
+	{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
1475
+};
1476
+
1477
+/**
1478
+ *
1479
+ */
1480
+int sr_kemi_return(lua_State* L, sr_kemi_t *ket, int rc)
1481
+{
1482
+	if(ket->rtype==SR_KEMIP_INT) {
1483
+		lua_pushinteger(L, rc);
1484
+		return 1;
1485
+	}
1486
+	if(ket->rtype==SR_KEMIP_BOOL && rc!=0) {
1487
+		return app_lua_return_true(L);
1488
+	}
1489
+	return app_lua_return_false(L);
1490
+}
1491
+
1492
+/**
1493
+ *
1494
+ */
1495
+int sr_kemi_exec_func(lua_State* L, str *mname, str *fname)
1496
+{
1497
+	int i;
1498
+	int pdelta;
1499
+	int argc;
1500
+	int ret;
1501
+	sr_kemi_t *ket = NULL;
1502
+	sr_kemi_val_t vps[SR_KEMI_PARAMS_MAX];
1503
+	sr_lua_env_t *env_L;
1504
+
1505
+	env_L = sr_lua_env_get();
1506
+
1507
+	if(mname->len<=0) {
1508
+		pdelta = 1;
1509
+		for(i=0; ; i++) {
1510
+			ket = &_sr_kemi_core[i];
1511
+			if(ket->fname.len==fname->len
1512
+					&& strncasecmp(ket->fname.s, fname->s, fname->len)==0) {
1513
+				break;
1514
+			}
1515
+		}
1516
+	} else {
1517
+		pdelta = 2;
1518
+	}
1519
+	if(ket==NULL) {
1520
+		return app_lua_return_false(L);
1521
+	}
1522
+
1523
+	argc = lua_gettop(L);
1524
+	if(argc==0 && ket->ptypes[0]==SR_KEMIP_NONE) {
1525
+		ret = ((sr_kemi_fm_f)(ket->func))(env_L->msg);
1526
+		return sr_kemi_return(L, ket, ret);
1527
+	}
1528
+	if(argc==0 && ket->ptypes[0]!=SR_KEMIP_NONE) {
1529
+		LM_ERR("invalid number of parameters for: %.*s\n",
1530
+				fname->len, fname->s);
1531
+		return app_lua_return_false(L);
1532
+	}
1533
+
1534
+	if(argc>=SR_KEMI_PARAMS_MAX+pdelta) {
1535
+		LM_ERR("too many parameters for: %.*s\n",
1536
+				fname->len, fname->s);
1537
+		return app_lua_return_false(L);
1538
+	}
1539
+
1540
+	for(i=0; i<SR_KEMI_PARAMS_MAX; i++) {
1541
+		if(ket->ptypes[i]==SR_KEMIP_NONE) {
1542
+			break;
1543
+		} else if(ket->ptypes[i]==SR_KEMIP_STR) {
1544
+			vps[i].s.s = (char*)lua_tostring(L, i+pdelta+1);
1545
+			vps[i].s.len = strlen(vps[i].s.s);
1546
+			LM_DBG("param[%d] for: %.*s is str: %.*s\n", i,
1547
+				fname->len, fname->s, vps[i].s.len, vps[i].s.s);
1548
+		} else if(ket->ptypes[i]==SR_KEMIP_INT) {
1549
+			vps[i].n = lua_tointeger(L, i+pdelta+1);
1550
+			LM_DBG("param[%d] for: %.*s is int: %d\n", i,
1551
+				fname->len, fname->s, vps[i].n);
1552
+		} else {
1553
+			LM_ERR("unknown parameter type %d (%d)\n", ket->ptypes[i], i);
1554
+			return app_lua_return_false(L);
1555
+		}
1556
+	}
1557
+	switch(i) {
1558
+		case 1:
1559
+			if(ket->ptypes[0]==SR_KEMIP_INT) {
1560
+				ret = ((sr_kemi_fmn_f)(ket->func))(env_L->msg, vps[0].n);
1561
+			} else if(ket->ptypes[0]==SR_KEMIP_STR) {
1562
+				ret = ((sr_kemi_fms_f)(ket->func))(env_L->msg, &vps[0].s);
1563
+			} else {
1564
+				LM_ERR("invalid parameters for: %.*s\n",
1565
+						fname->len, fname->s);
1566
+				return app_lua_return_false(L);
1567
+			}
1568
+		break;
1569
+		case 2:
1570
+			if(ket->ptypes[0]==SR_KEMIP_INT) {
1571
+				if(ket->ptypes[1]==SR_KEMIP_INT) {
1572
+					ret = ((sr_kemi_fmnn_f)(ket->func))(env_L->msg, vps[0].n, vps[1].n);
1573
+				} else if(ket->ptypes[1]==SR_KEMIP_STR) {
1574
+					ret = ((sr_kemi_fmns_f)(ket->func))(env_L->msg, vps[0].n, &vps[1].s);
1575
+				} else {
1576
+					LM_ERR("invalid parameters for: %.*s\n",
1577
+							fname->len, fname->s);
1578
+					return app_lua_return_false(L);
1579
+				}
1580
+			} else if(ket->ptypes[0]==SR_KEMIP_STR) {
1581
+				if(ket->ptypes[1]==SR_KEMIP_INT) {
1582
+					ret = ((sr_kemi_fmsn_f)(ket->func))(env_L->msg, &vps[0].s, vps[1].n);
1583
+				} else if(ket->ptypes[1]==SR_KEMIP_STR) {
1584
+					ret = ((sr_kemi_fmss_f)(ket->func))(env_L->msg, &vps[0].s, &vps[1].s);
1585
+				} else {
1586
+					LM_ERR("invalid parameters for: %.*s\n",
1587
+							fname->len, fname->s);
1588
+					return app_lua_return_false(L);
1589
+				}
1590
+			} else {
1591
+				LM_ERR("invalid parameters for: %.*s\n",
1592
+						fname->len, fname->s);
1593
+				return app_lua_return_false(L);
1594
+			}
1595
+		break;
1596
+		case 3:
1597
+			LM_ERR("too many parameters for: %.*s\n",
1598
+					fname->len, fname->s);
1599
+			return app_lua_return_false(L);
1600
+		break;
1601
+		case 4:
1602
+			LM_ERR("too many parameters for: %.*s\n",
1603
+					fname->len, fname->s);
1604
+			return app_lua_return_false(L);
1605
+		break;
1606
+		case 5:
1607
+			LM_ERR("too many parameters for: %.*s\n",
1608
+					fname->len, fname->s);
1609
+			return app_lua_return_false(L);
1610
+		break;
1611
+		case 6:
1612
+			LM_ERR("too many parameters for: %.*s\n",
1613
+					fname->len, fname->s);
1614
+			return app_lua_return_false(L);
1615
+		break;
1616
+		default:
1617
+			LM_ERR("too many parameters for: %.*s\n",
1618
+					fname->len, fname->s);
1619
+			return app_lua_return_false(L);
1620
+	}
1621
+	return app_lua_return_false(L);
1622
+}
1623
+
1624
+/**
1625
+ *
1626
+ */
1627
+int sr_kemi_KSR_C(lua_State* L)
1628
+{
1629
+	str mname = str_init("");
1630
+	str fname;
1631
+
1632
+	fname.s = (char*)lua_tostring(L, 1);
1633
+	if(fname.s==NULL) {
1634
+		LM_ERR("null function name");
1635
+		return app_lua_return_false(L);
1636
+	}
1637
+	fname.len = strlen(fname.s);
1638
+	LM_DBG("function execution of: %s\n", fname.s);
1639
+	return sr_kemi_exec_func(L, &mname, &fname);
1640
+}
1641
+
1642
+/**
1643
+ *
1644
+ */
1645
+int sr_kemi_KSR_MOD_C(lua_State* L)
1646
+{
1647
+	str mname;
1648
+	str fname;
1649
+	mname.s = (char*)lua_tostring(L, 1);
1650
+	fname.s = (char*)lua_tostring(L, 2);
1651
+	if(mname.s==NULL || fname.s==NULL) {
1652
+		LM_ERR("null params: %p %p\n", mname.s, fname.s);
1653
+		return app_lua_return_false(L);
1654
+	}
1655
+	mname.len = strlen(mname.s);
1656
+	fname.len = strlen(fname.s);
1657
+	LM_DBG("module function execution of: %s.%s\n", mname.s, fname.s);
1658
+	return sr_kemi_exec_func(L, &mname, &fname);
1659
+}
1660
+
1661
+
1662
+/**
1663
+ *
1664
+ */
1665
+void lua_sr_kemi_register_core(lua_State *L)
1666
+{
1667
+	int ret;
1668
+
1669
+	lua_register(L, "KSR_C", sr_kemi_KSR_C);
1670
+	lua_register(L, "KSR_MOD_C", sr_kemi_KSR_MOD_C);
1671
+
1672
+	ret = luaL_dostring(L,
1673
+			"KSR = {}\n"
1674
+			"KSR.__index = function (table, key)\n"
1675
+			"  return function (...)\n"
1676
+			"    return KSR_C(key, ...)\n"
1677
+			"  end\n"
1678
+			"end\n"
1679
+			"setmetatable(KSR, KSR)\n"
1680
+		);
1681
+	LM_DBG("pushin lua KSR table definition returned %d\n", ret);
1682
+}
... ...
@@ -25,6 +25,7 @@
25 25
 #include <lua.h>
26 26
 
27 27
 void lua_sr_core_openlibs(lua_State *L);
28
+void lua_sr_kemi_register_core(lua_State *L);
28 29
 
29 30
 #endif
30 31