|
|
|
|
@ -12,7 +12,7 @@
|
|
|
|
|
+include ../../Makefile.modules
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/modules/tcap/tcap_mod.c
|
|
|
|
|
@@ -0,0 +1,37 @@
|
|
|
|
|
@@ -0,0 +1,127 @@
|
|
|
|
|
+#include <stdio.h>
|
|
|
|
|
+#include <stdlib.h>
|
|
|
|
|
+#include <unistd.h>
|
|
|
|
|
@ -21,35 +21,125 @@
|
|
|
|
|
+#include "../../sr_module.h"
|
|
|
|
|
+#include "../../mod_fix.h"
|
|
|
|
|
+#include "../../pvar.h"
|
|
|
|
|
+#include "../../parser/parse_content.h"
|
|
|
|
|
+
|
|
|
|
|
+MODULE_VERSION
|
|
|
|
|
+
|
|
|
|
|
+static int tcap(sip_msg_t *msg, char *su, char *sq);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+static str content_type;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+static int mod_init(void);
|
|
|
|
|
+static int tcap_extract_f(sip_msg_t *msg, char *su, char *sq);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+static cmd_export_t cmds[] = {
|
|
|
|
|
+ {"tcap", (cmd_function)tcap, 2, fixup_spve_spve, 0,
|
|
|
|
|
+ REQUEST_ROUTE | FAILURE_ROUTE},
|
|
|
|
|
+ {"tcap_extract", (cmd_function)tcap_extract_f, 2, fixup_spve_null, 0,
|
|
|
|
|
+ ANY_ROUTE},
|
|
|
|
|
+ {0,}
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+static param_export_t params[] = {
|
|
|
|
|
+ { "content_type", STR_PARAM, &content_type.s },
|
|
|
|
|
+ { 0, }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+struct module_exports exports = {
|
|
|
|
|
+ "tcap",
|
|
|
|
|
+ DEFAULT_DLFLAGS,
|
|
|
|
|
+ cmds,
|
|
|
|
|
+ params,
|
|
|
|
|
+ 0,
|
|
|
|
|
+ 0,
|
|
|
|
|
+ 0,
|
|
|
|
|
+ 0,
|
|
|
|
|
+ 0,
|
|
|
|
|
+ 0,
|
|
|
|
|
+ mod_init,
|
|
|
|
|
+ 0,
|
|
|
|
|
+ 0,
|
|
|
|
|
+ 0
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+static int tcap(sip_msg_t *msg, char *su, char *sq) {
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+static int mod_init(void) {
|
|
|
|
|
+ if (!content_type.s)
|
|
|
|
|
+ content_type.s = "application/tcap";
|
|
|
|
|
+ content_type.len = strlen(content_type.s);
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+static int tcap_extract_f(sip_msg_t *msg, char *su, char *sq) {
|
|
|
|
|
+ str body, spec, s;
|
|
|
|
|
+ static char buf[1024];
|
|
|
|
|
+ struct output_buffer out;
|
|
|
|
|
+ int_str avp_val, avp_name;
|
|
|
|
|
+ static unsigned short avp_type = 0;
|
|
|
|
|
+ pv_spec_t *avp_spec = NULL;
|
|
|
|
|
+
|
|
|
|
|
+ if (fixup_get_svalue(msg, (gparam_p) su, &spec))
|
|
|
|
|
+ goto error;
|
|
|
|
|
+
|
|
|
|
|
+ body.s = get_body(msg);
|
|
|
|
|
+ if (!body.s)
|
|
|
|
|
+ goto error;
|
|
|
|
|
+ body.len = get_content_length(msg);
|
|
|
|
|
+ if (!body.len)
|
|
|
|
|
+ goto error;
|
|
|
|
|
+
|
|
|
|
|
+ if (!msg->content_type)
|
|
|
|
|
+ goto error;
|
|
|
|
|
+ if (msg->content_type->body.len < content_type.len)
|
|
|
|
|
+ goto error;
|
|
|
|
|
+ if (strncasecmp(msg->content_type->body.s, content_type.s, content_type.len))
|
|
|
|
|
+ goto error;
|
|
|
|
|
+
|
|
|
|
|
+ OUTPUT_BUFFER_INIT(&out, buf);
|
|
|
|
|
+ if (tcap_extract(body.s, body.len, spec.s, &out))
|
|
|
|
|
+ goto error;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ s.s = sq; s.len = strlen(s.s);
|
|
|
|
|
+ if (pv_locate_name(&s) != s.len)
|
|
|
|
|
+ {
|
|
|
|
|
+ LM_ERR("invalid parameter\n");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (((avp_spec = pv_cache_get(&s)) == NULL)
|
|
|
|
|
+ || avp_spec->type!=PVT_AVP) {
|
|
|
|
|
+ LM_ERR("malformed or non AVP %s AVP definition\n", sq);
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(pv_get_avp_name(0, &avp_spec->pvp, &avp_name, &avp_type)!=0)
|
|
|
|
|
+ {
|
|
|
|
|
+ LM_ERR("[%s]- invalid AVP definition\n", sq);
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ avp_val.s.s = out.buf;
|
|
|
|
|
+ avp_val.s.len = out.used;
|
|
|
|
|
+ if (add_avp(AVP_VAL_STR | avp_type, avp_name, avp_val) != 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ LM_ERR("Failed to add SDP avp");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return 1;
|
|
|
|
|
+
|
|
|
|
|
+error:
|
|
|
|
|
+ return -1;
|
|
|
|
|
+}
|
|
|
|
|
--- a/Makefile.groups
|
|
|
|
|
+++ b/Makefile.groups
|
|
|
|
|
@@ -13,7 +13,7 @@
|
|
|
|
|
|