You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kamailio/modules_k/rtpproxy/test/rtpproxy.patch

423 lines
13 KiB

diff --git a/Makefile.am b/Makefile.am
index b47241b..a737d77 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,7 +4,7 @@ rtpproxy_SOURCES=main.c rtp.h rtp_server.c rtp_server.h \
rtpp_util.c rtpp_util.h rtp.c rtp_resizer.c rtp_resizer.h rtpp_session.c \
rtpp_command.c rtpp_command.h rtpp_log.c rtpp_network.h rtpp_network.c \
rtpp_syslog_async.c rtpp_syslog_async.h rtpp_notify.c rtpp_notify.h
-rtpproxy_LDADD=-lm -lpthread
+rtpproxy_LDADD=-lm -lpthread @LIBS_XMLRPC@
dist_man_MANS=rtpproxy.8
makeann_SOURCES=makeann.c rtp.h g711.h
makeann_LDADD=@LIBS_G729@ @LIBS_GSM@
diff --git a/config.h.in b/config.h.in
index cd0c23a..87491e3 100644
--- a/config.h.in
+++ b/config.h.in
@@ -14,6 +14,9 @@
/* Define if you have libgsm library installed */
#undef ENABLE_GSM
+/* Define if you have xmlrpc library installed */
+#undef ENABLE_XMLRPC
+
/* Define to 1 if you have `alloca', as a function or macro. */
#undef HAVE_ALLOCA
diff --git a/configure.ac b/configure.ac
index 54c1a60..1c88b99 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,6 +53,17 @@ then
AC_DEFINE([ENABLE_G729], 1, [Define if you have libg729 library installed])
)
fi
+
+# XML-RPC-Libs:
+AC_CHECK_HEADERS(xmlrpc_client.h xmlrpc.h, found_xmlrpc=yes)
+if test "$found_xmlrpc" = yes
+then
+ AC_CHECK_LIB(curl, curl_version,
+ LIBS_XMLRPC="-lcurl -lxmlrpc_client -lxmlrpc -lxmlrpc_util -lxmlrpc_xmlparse -lxmlrpc_xmltok"
+ AC_DEFINE([ENABLE_XMLRPC], 1, [Define if you have XML-RPC-Client library installed])
+ )
+fi
+
##if test -z "$G729_SUPPORT"
##then
## echo "*************************************************************************** $ECHO_C" 1>&6
@@ -94,4 +105,5 @@ AC_CONFIG_FILES([Makefile])
AC_SUBST(AM_CFLAGS)
AC_SUBST(LIBS_GSM)
AC_SUBST(LIBS_G729)
+AC_SUBST(LIBS_XMLRPC)
AC_OUTPUT
diff --git a/rtpp_command.c b/rtpp_command.c
index fa342b8..53c4a40 100644
--- a/rtpp_command.c
+++ b/rtpp_command.c
@@ -52,6 +52,7 @@
#include "rtpp_record.h"
#include "rtpp_session.h"
#include "rtpp_util.h"
+#include "rtpp_notify.h"
struct proto_cap proto_caps[] = {
/*
@@ -67,6 +68,9 @@ struct proto_cap proto_caps[] = {
{ "20081102", "Support for setting codecs in the update/lookup command" },
{ "20081224", "Support for session timeout notifications" },
{ "20090810", "Support for automatic bridging" },
+#ifdef ENABLE_XMLRPC
+ { "20100819", "Support for timeout notifications using XML-RPC towards Kamailio" },
+#endif
{ NULL, NULL }
};
@@ -266,7 +270,9 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
int max_argc;
char *socket_name_u, *notify_tag;
struct sockaddr *local_addr;
+ struct rtpp_timeout_handler * my_timeout_h;
char c;
+ int rtp_timeout_type;
requested_nsamples = -1;
ia[0] = ia[1] = NULL;
@@ -309,6 +315,7 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
if (++ap >= &argv[10])
break;
}
+
cookie = NULL;
if (argc < 1 || (cf->umode != 0 && argc < 2)) {
rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
@@ -459,22 +466,52 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
}
call_id = argv[1];
if (op == UPDATE || op == LOOKUP || op == PLAY) {
- max_argc = (op == UPDATE ? 8 : 6);
+ if (op == UPDATE || op == LOOKUP) max_argc = 9;
+ else max_argc = 6;
if (argc < 5 || argc > max_argc) {
- rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
+ rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error (%d/%d)", argc, max_argc);
reply_error(cf, controlfd, &raddr, rlen, cookie, 4);
return 0;
}
from_tag = argv[4];
- to_tag = argv[5];
+ if ((op == UPDATE || op == LOOKUP) && argc > 5)
+ to_tag = argv[5];
if (op == PLAY && argv[0][1] != '\0')
playcount = atoi(argv[0] + 1);
- if (op == UPDATE && argc > 6) {
- socket_name_u = argv[6];
+ if ((op == UPDATE || op == LOOKUP) && argc > 6) {
+ if (argc == 7) {
+ // Only the Timeout-Socket is set:
+ socket_name_u = argv[6];
+ rtp_timeout_type = RTP_TIMEOUT_TYPE_NATIVE;
+ } else {
+ notify_tag = 0;
+ if (argc == 9) {
+ // 9 Parameters: timeout_type socket notify_tag
+ rtp_timeout_type = atoi(argv[6]);
+ socket_name_u = argv[7];
+ notify_tag = argv[8];
+ } else {
+ // 8 Parameters: May be timeout_type socket or socket tag
+ rtp_timeout_type = -1;
+ for (t = argv[6]; *t != '\0'; t++) {
+ // Parameter 6 is not numerical, lets assume it is std. timeout-socket + tag
+ if (!isdigit(*t)) {
+ socket_name_u = argv[6];
+ rtp_timeout_type = RTP_TIMEOUT_TYPE_NATIVE;
+ notify_tag = argv[7];
+ break;
+ }
+ }
+ // Param 6 was numeric? So it must be a timeout_type_indicator
+ if (rtp_timeout_type == -1) {
+ rtp_timeout_type = atoi(argv[6]);
+ socket_name_u = argv[7];
+ }
+ }
+ }
if (strncmp("unix:", socket_name_u, 5) == 0)
socket_name_u += 5;
- if (argc == 8) {
- notify_tag = argv[7];
+ if (notify_tag != 0) {
len = url_unquote((uint8_t *)notify_tag, strlen(notify_tag));
if (len == -1) {
rtpp_log_write(RTPP_LOG_ERR, cf->glog,
@@ -924,9 +961,29 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
}
}
- if (op == UPDATE) {
- if (cf->timeout_handler.socket_name == NULL && socket_name_u != NULL)
- rtpp_log_write(RTPP_LOG_ERR, spa->log, "must permit notification socket with -n");
+ if (op == UPDATE || op == LOOKUP) {
+ if (cf->timeout_handler.socket_name == NULL && socket_name_u != NULL) {
+ if ((rtp_timeout_type > 0) && (rtp_timeout_type <= RTP_TIMEOUT_TYPE_MAX)) {
+ rtpp_log_write(RTPP_LOG_INFO, spa->log, "setting custom timeout handler (%d)", rtp_timeout_type);
+ my_timeout_h = malloc(sizeof(struct rtpp_timeout_handler));
+ if (my_timeout_h == NULL) {
+ rtpp_log_write(RTPP_LOG_ERR, spa->log, "Unable to allocate memory");
+ } else {
+ memset(my_timeout_h, 0, sizeof(struct rtpp_timeout_handler));
+ my_timeout_h->socket_name = (char *)malloc(strlen(socket_name_u) + 1);
+ if(my_timeout_h->socket_name != NULL) {
+ strcpy(my_timeout_h->socket_name, socket_name_u);
+ spa->timeout_data.rtp_timeout_type = rtp_timeout_type;
+ spa->timeout_data.handler = my_timeout_h;
+ spa->timeout_data.notify_tag = 0;
+ } else {
+ rtpp_log_write(RTPP_LOG_ERR, spa->log, "Unable to allocate memory");
+ free(my_timeout_h);
+ }
+ }
+ } else
+ rtpp_log_write(RTPP_LOG_ERR, spa->log, "must permit notification socket with -n");
+ }
if (spa->timeout_data.notify_tag != NULL) {
free(spa->timeout_data.notify_tag);
spa->timeout_data.notify_tag = NULL;
diff --git a/rtpp_notify.c b/rtpp_notify.c
index 26bb9a5..1553cb4 100644
--- a/rtpp_notify.c
+++ b/rtpp_notify.c
@@ -38,11 +38,26 @@
#include "rtpp_log.h"
#include "rtpp_session.h"
+#include "rtpp_notify.h"
+
+#ifdef ENABLE_XMLRPC
+#include <xmlrpc.h>
+#include <xmlrpc_client.h>
+#define XMLRPC_CLIENT_NAME "XML-RPC RTPProxy Client"
+#define XMLRPC_CLIENT_VERSION "0.1"
+#endif
struct rtpp_notify_wi
{
char *notify_buf;
int len;
+ int rtp_timeout_type;
+#ifdef ENABLE_XMLRPC
+ char *call_id;
+ int call_id_len;
+ char *param;
+ int param_len;
+#endif
struct rtpp_timeout_handler *th;
rtpp_log_t glog;
struct rtpp_notify_wi *next;
@@ -170,7 +185,7 @@ rtpp_notify_schedule(struct cfg *cf, struct rtpp_session *sp)
struct rtpp_timeout_handler *th = sp->timeout_data.handler;
int len;
char *notify_buf;
-
+
if (th == NULL) {
/* Not an error, just nothing to do */
return 0;
@@ -202,8 +217,6 @@ rtpp_notify_schedule(struct cfg *cf, struct rtpp_session *sp)
}
wi->notify_buf = notify_buf;
}
- wi->len = len;
-
if (sp->timeout_data.notify_tag == NULL) {
len = snprintf(wi->notify_buf, len, "%d %d\n",
sp->ports[0], sp->ports[1]);
@@ -211,6 +224,55 @@ rtpp_notify_schedule(struct cfg *cf, struct rtpp_session *sp)
len = snprintf(wi->notify_buf, len, "%s\n",
sp->timeout_data.notify_tag);
}
+ wi->len = len;
+
+ // Take RTP-Timeout type
+ wi->rtp_timeout_type = sp->timeout_data.rtp_timeout_type;
+#ifdef ENABLE_XMLRPC
+ if (wi->rtp_timeout_type == RTP_TIMEOUT_TYPE_KAMAILIO_XMLRPC) {
+ // Copy the Socket-Name
+ len = strlen(wi->th->socket_name)+1;
+ if (wi->param == NULL) {
+ wi->param = malloc(len);
+ if (wi->param == NULL) {
+ rtpp_notify_queue_return_free_item(wi);
+ return -1;
+ }
+ } else {
+ notify_buf = realloc(wi->param, len);
+ if (notify_buf == NULL) {
+ rtpp_notify_queue_return_free_item(wi);
+ return -1;
+ }
+ wi->param = notify_buf;
+ }
+ memset(wi->param, '\0', len);
+ len = snprintf(wi->param, len, "%s",
+ wi->th->socket_name);
+ wi->param_len = len;
+
+ // Copy the Call-ID:
+ len = strlen(sp->call_id)+1;
+ if (wi->call_id == NULL) {
+ wi->call_id = malloc(len);
+ if (wi->call_id == NULL) {
+ rtpp_notify_queue_return_free_item(wi);
+ return -1;
+ }
+ } else {
+ notify_buf = realloc(wi->call_id, len);
+ if (notify_buf == NULL) {
+ rtpp_notify_queue_return_free_item(wi);
+ return -1;
+ }
+ wi->call_id = notify_buf;
+ }
+ memset(wi->call_id, '\0', len);
+ len = snprintf(wi->call_id, len, "%s",
+ sp->call_id);
+ wi->call_id_len = len;
+ }
+#endif
wi->glog = cf->glog;
@@ -249,24 +311,70 @@ reconnect_timeout_handler(rtpp_log_t log, struct rtpp_timeout_handler *th)
}
}
+#ifdef ENABLE_XMLRPC
+static int
+do_xmlrpc_timeout_notification(rtpp_log_t log, struct rtpp_notify_wi *wi) {
+ xmlrpc_env env;
+ xmlrpc_value *result;
+
+ /* Start up our XML-RPC client library. */
+ xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, XMLRPC_CLIENT_NAME, XMLRPC_CLIENT_VERSION);
+ xmlrpc_env_init(&env);
+
+ /* Get the dialog-Info: */
+ result = xmlrpc_client_call(&env, wi->param,
+ "dlg_terminate_dlg", "(s)",
+ wi->call_id);
+ if (env.fault_occurred) {
+ rtpp_log_write(RTPP_LOG_ERR, wi->glog, "XML-RPC Fault: %s (%d)\n", env.fault_string, env.fault_code);
+ return -1;
+ }
+
+ /* Dispose of our result value. */
+ xmlrpc_DECREF(result);
+
+ /* Shutdown our XML-RPC client library. */
+ xmlrpc_env_clean(&env);
+ xmlrpc_client_cleanup();
+
+ return 0;
+}
+#endif
+
+
static void
do_timeout_notification(struct rtpp_notify_wi *wi, int retries)
{
int result;
-
- if (wi->th->connected == 0) {
- reconnect_timeout_handler(wi->glog, wi->th);
-
- /* If connect fails, no notification will be sent */
+ if (wi->rtp_timeout_type > 0) {
+ switch (wi->rtp_timeout_type) {
+#ifdef ENABLE_XMLRPC
+ case RTP_TIMEOUT_TYPE_KAMAILIO_XMLRPC:
+ rtpp_log_write(RTPP_LOG_INFO, wi->glog, "Using XML-RPC-Timeout handler (%s)", wi->param);
+ result = do_xmlrpc_timeout_notification(wi->glog, wi);
+ break;
+#endif
+ default:
+ rtpp_log_write(RTPP_LOG_ERR, wi->glog, "Invalid/unsupported timeout handler type (%d)", wi->rtp_timeout_type);
+ break;
+ }
+ } else {
if (wi->th->connected == 0) {
- rtpp_log_write(RTPP_LOG_ERR, wi->glog, "unable to send timeout notification");
- return;
- }
+ reconnect_timeout_handler(wi->glog, wi->th);
+
+ /* If connect fails, no notification will be sent */
+ if (wi->th->connected == 0) {
+ rtpp_log_write(RTPP_LOG_ERR, wi->glog, "unable to send timeout notification");
+ return;
+ }
+ }
+
+ do {
+ result = send(wi->th->fd, wi->notify_buf, wi->len, 0);
+ } while (result == -1 && errno == EINTR);
+#ifdef ENABLE_XMLRPC
}
-
- do {
- result = send(wi->th->fd, wi->notify_buf, wi->len, 0);
- } while (result == -1 && errno == EINTR);
+#endif
if (result < 0) {
wi->th->connected = 0;
diff --git a/rtpp_notify.h b/rtpp_notify.h
index 10077a4..3f411cb 100644
--- a/rtpp_notify.h
+++ b/rtpp_notify.h
@@ -31,6 +31,10 @@
#include "rtpp_defines.h"
#include "rtpp_session.h"
+#define RTP_TIMEOUT_TYPE_NATIVE 0
+#define RTP_TIMEOUT_TYPE_KAMAILIO_XMLRPC 1
+#define RTP_TIMEOUT_TYPE_MAX 1
+
int rtpp_notify_schedule(struct cfg *, struct rtpp_session *);
int rtpp_notify_init(void);
diff --git a/rtpp_session.c b/rtpp_session.c
index 9962cac..b84cdf3 100644
--- a/rtpp_session.c
+++ b/rtpp_session.c
@@ -205,6 +205,14 @@ remove_session(struct cfg *cf, struct rtpp_session *sp)
if (sp->rtcp->codecs[i] != NULL)
free(sp->rtcp->codecs[i]);
}
+#ifdef ENABLE_XMLRPC
+ // In case we use the Kamailio-XML-RPC-Timeout, we have our own timeout-handler
+ if (sp->timeout_data.handler != &cf->timeout_handler) {
+ free(sp->timeout_data.handler->socket_name);
+ free(sp->timeout_data.handler);
+ }
+#endif
+
if (sp->timeout_data.notify_tag != NULL)
free(sp->timeout_data.notify_tag);
hash_table_remove(cf, sp);
diff --git a/rtpp_session.h b/rtpp_session.h
index 07aa794..9022f12 100644
--- a/rtpp_session.h
+++ b/rtpp_session.h
@@ -38,6 +38,7 @@
struct rtpp_timeout_data {
char *notify_tag;
+ int rtp_timeout_type;
struct rtpp_timeout_handler *handler;
};