Browse code

Added the changes to the RTP-Proxy as a patch, for easier review.

Carsten Bock authored on 24/08/2010 09:08:34
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,337 @@
1
+diff --git a/Makefile.am b/Makefile.am
2
+index b47241b..a737d77 100644
3
+--- a/Makefile.am
4
+@@ -4,7 +4,7 @@ rtpproxy_SOURCES=main.c rtp.h rtp_server.c rtp_server.h \
5
+   rtpp_util.c rtpp_util.h rtp.c rtp_resizer.c rtp_resizer.h rtpp_session.c \
6
+   rtpp_command.c rtpp_command.h rtpp_log.c rtpp_network.h rtpp_network.c \
7
+   rtpp_syslog_async.c rtpp_syslog_async.h rtpp_notify.c rtpp_notify.h
8
+-rtpproxy_LDADD=-lm -lpthread
9
++rtpproxy_LDADD=-lm -lpthread @LIBS_XMLRPC@
10
+ dist_man_MANS=rtpproxy.8
11
+ makeann_SOURCES=makeann.c rtp.h g711.h
12
+ makeann_LDADD=@LIBS_G729@ @LIBS_GSM@
13
+diff --git a/config.h.in b/config.h.in
14
+index cd0c23a..87491e3 100644
15
+--- a/config.h.in
16
+@@ -14,6 +14,9 @@
17
+ /* Define if you have libgsm library installed */
18
+ #undef ENABLE_GSM
19
+ 
20
++/* Define if you have xmlrpc library installed */
21
++#undef ENABLE_XMLRPC
22
++
23
+ /* Define to 1 if you have `alloca', as a function or macro. */
24
+ #undef HAVE_ALLOCA
25
+ 
26
+diff --git a/configure.ac b/configure.ac
27
+index 54c1a60..1c88b99 100644
28
+--- a/configure.ac
29
+@@ -53,6 +53,17 @@ then
30
+    AC_DEFINE([ENABLE_G729], 1, [Define if you have libg729 library installed])
31
+   )
32
+ fi
33
++
34
++# XML-RPC-Libs:
35
++AC_CHECK_HEADERS(xmlrpc_client.h xmlrpc.h, found_xmlrpc=yes)
36
++if test "$found_xmlrpc" = yes
37
++then
38
++  AC_CHECK_LIB(curl, curl_version,
39
++   LIBS_XMLRPC="-lcurl -lxmlrpc_client -lxmlrpc -lxmlrpc_util -lxmlrpc_xmlparse -lxmlrpc_xmltok"
40
++   AC_DEFINE([ENABLE_XMLRPC], 1, [Define if you have XML-RPC-Client library installed])
41
++  )
42
++fi
43
++
44
+ ##if test -z "$G729_SUPPORT"
45
+ ##then
46
+ ##  echo "*************************************************************************** $ECHO_C" 1>&6
47
+@@ -94,4 +105,5 @@ AC_CONFIG_FILES([Makefile])
48
+ AC_SUBST(AM_CFLAGS)
49
+ AC_SUBST(LIBS_GSM)
50
+ AC_SUBST(LIBS_G729)
51
++AC_SUBST(LIBS_XMLRPC)
52
+ AC_OUTPUT
53
+diff --git a/rtpp_command.c b/rtpp_command.c
54
+index fa342b8..2b3059d 100644
55
+--- a/rtpp_command.c
56
+@@ -67,6 +67,9 @@ struct proto_cap proto_caps[] = {
57
+     { "20081102", "Support for setting codecs in the update/lookup command" },
58
+     { "20081224", "Support for session timeout notifications" },
59
+     { "20090810", "Support for automatic bridging" },
60
++#ifdef ENABLE_XMLRPC
61
++    { "20100819", "Support for timeout notifications using XML-RPC towards Kamailio" },
62
++#endif
63
+     { NULL, NULL }
64
+ };
65
+ 
66
+@@ -266,6 +269,7 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
67
+     int max_argc;
68
+     char *socket_name_u, *notify_tag;
69
+     struct sockaddr *local_addr;
70
++    struct rtpp_timeout_handler * my_timeout_h;
71
+     char c;
72
+ 
73
+     requested_nsamples = -1;
74
+@@ -309,6 +313,7 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
75
+ 	    if (++ap >= &argv[10])
76
+ 		break;
77
+ 	}
78
++	
79
+     cookie = NULL;
80
+     if (argc < 1 || (cf->umode != 0 && argc < 2)) {
81
+ 	rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
82
+@@ -459,9 +464,11 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
83
+     }
84
+     call_id = argv[1];
85
+     if (op == UPDATE || op == LOOKUP || op == PLAY) {
86
+-	max_argc = (op == UPDATE ? 8 : 6);
87
++	if (op == UPDATE) max_argc = 8;
88
++	if (op == LOOKUP) max_argc = 7;
89
++	else max_argc = 6;
90
+ 	if (argc < 5 || argc > max_argc) {
91
+-	    rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error");
92
++	    rtpp_log_write(RTPP_LOG_ERR, cf->glog, "command syntax error (%d/%d)", argc, max_argc);
93
+ 	    reply_error(cf, controlfd, &raddr, rlen, cookie, 4);
94
+ 	    return 0;
95
+ 	}
96
+@@ -469,7 +476,7 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
97
+ 	to_tag = argv[5];
98
+ 	if (op == PLAY && argv[0][1] != '\0')
99
+ 	    playcount = atoi(argv[0] + 1);
100
+-	if (op == UPDATE && argc > 6) {
101
++	if ((op == UPDATE || op == LOOKUP) && argc > 6) {
102
+ 	    socket_name_u = argv[6];
103
+ 	    if (strncmp("unix:", socket_name_u, 5) == 0)
104
+ 		socket_name_u += 5;
105
+@@ -924,9 +931,30 @@ handle_command(struct cfg *cf, int controlfd, double dtime)
106
+ 	}
107
+     }
108
+ 
109
+-    if (op == UPDATE) {
110
+-	if (cf->timeout_handler.socket_name == NULL && socket_name_u != NULL)
111
++    if (op == UPDATE || op == LOOKUP) {
112
++	if (cf->timeout_handler.socket_name == NULL && socket_name_u != NULL) {
113
++#ifdef ENABLE_XMLRPC
114
++	    if (strncmp("http://", socket_name_u, 7) == 0) {
115
++		rtpp_log_write(RTPP_LOG_INFO, spa->log, "setting Kamailio-timeout handler");
116
++		my_timeout_h = malloc(sizeof(struct rtpp_timeout_handler));
117
++		if (my_timeout_h == NULL) {
118
++			rtpp_log_write(RTPP_LOG_ERR, spa->log, "Unable to allocate memory");
119
++		} else {
120
++			memset(my_timeout_h, 0, sizeof(struct rtpp_timeout_handler));
121
++	    		my_timeout_h->socket_name = (char *)malloc(strlen(socket_name_u) + 1);
122
++	    		if(my_timeout_h->socket_name != NULL) {
123
++				strcpy(my_timeout_h->socket_name, socket_name_u);
124
++				spa->timeout_data.handler = my_timeout_h;
125
++				spa->timeout_data.notify_tag = 0;
126
++			} else {
127
++				rtpp_log_write(RTPP_LOG_ERR, spa->log, "Unable to allocate memory");
128
++				free(my_timeout_h);
129
++			}
130
++		}
131
++	    } else
132
+ 	    rtpp_log_write(RTPP_LOG_ERR, spa->log, "must permit notification socket with -n");
133
++#endif
134
++	}
135
+ 	if (spa->timeout_data.notify_tag != NULL) {
136
+ 	    free(spa->timeout_data.notify_tag);
137
+ 	    spa->timeout_data.notify_tag = NULL;
138
+diff --git a/rtpp_notify.c b/rtpp_notify.c
139
+index 26bb9a5..9fe6a6d 100644
140
+--- a/rtpp_notify.c
141
+@@ -39,10 +39,23 @@
142
+ #include "rtpp_log.h"
143
+ #include "rtpp_session.h"
144
+ 
145
++#ifdef ENABLE_XMLRPC
146
++#include <xmlrpc.h>
147
++#include <xmlrpc_client.h>
148
++#define XMLRPC_CLIENT_NAME       "XML-RPC RTPProxy Client"
149
++#define XMLRPC_CLIENT_VERSION    "0.1"
150
++#endif
151
++
152
+ struct rtpp_notify_wi
153
+ {
154
+     char *notify_buf;
155
+     int len;
156
++#ifdef ENABLE_XMLRPC
157
++    char *call_id;
158
++    int call_id_len;
159
++    char *xmlrpc_server;
160
++    int xmlrpc_server_len;
161
++#endif
162
+     struct rtpp_timeout_handler *th;
163
+     rtpp_log_t glog;
164
+     struct rtpp_notify_wi *next;
165
+@@ -170,7 +183,7 @@ rtpp_notify_schedule(struct cfg *cf, struct rtpp_session *sp)
166
+     struct rtpp_timeout_handler *th = sp->timeout_data.handler;
167
+     int len;
168
+     char *notify_buf;
169
+-
170
++    
171
+     if (th == NULL) {
172
+         /* Not an error, just nothing to do */
173
+         return 0;
174
+@@ -202,8 +215,6 @@ rtpp_notify_schedule(struct cfg *cf, struct rtpp_session *sp)
175
+         }
176
+         wi->notify_buf = notify_buf;
177
+     }
178
+-    wi->len = len;
179
+-
180
+     if (sp->timeout_data.notify_tag == NULL) {
181
+         len = snprintf(wi->notify_buf, len, "%d %d\n",
182
+           sp->ports[0], sp->ports[1]);
183
+@@ -211,6 +222,54 @@ rtpp_notify_schedule(struct cfg *cf, struct rtpp_session *sp)
184
+         len = snprintf(wi->notify_buf, len, "%s\n",
185
+           sp->timeout_data.notify_tag);
186
+     }
187
++    wi->len = len;
188
++
189
++
190
++#ifdef ENABLE_XMLRPC
191
++    if (strncmp(wi->th->socket_name, "http://", 7) == 0) {
192
++	    // Copy the Socket-Name
193
++	    len = strlen(wi->th->socket_name)+1;
194
++	    if (wi->xmlrpc_server == NULL) {
195
++		wi->xmlrpc_server = malloc(len);
196
++		if (wi->xmlrpc_server == NULL) {
197
++		    rtpp_notify_queue_return_free_item(wi);
198
++		    return -1;
199
++		}
200
++	    } else {
201
++		notify_buf = realloc(wi->xmlrpc_server, len);
202
++		if (notify_buf == NULL) {
203
++		    rtpp_notify_queue_return_free_item(wi);
204
++		    return -1;
205
++		}
206
++		wi->xmlrpc_server = notify_buf;
207
++	    }
208
++	    memset(wi->xmlrpc_server, '\0', len);
209
++	    len = snprintf(wi->xmlrpc_server, len, "%s",
210
++		  wi->th->socket_name);
211
++	    wi->xmlrpc_server_len = len;
212
++
213
++	    // Copy the Call-ID:
214
++	    len = strlen(sp->call_id)+1;
215
++	    if (wi->call_id == NULL) {
216
++		wi->call_id = malloc(len);
217
++		if (wi->call_id == NULL) {
218
++		    rtpp_notify_queue_return_free_item(wi);
219
++		    return -1;
220
++		}
221
++	    } else {
222
++		notify_buf = realloc(wi->call_id, len);
223
++		if (notify_buf == NULL) {
224
++		    rtpp_notify_queue_return_free_item(wi);
225
++		    return -1;
226
++		}
227
++		wi->call_id = notify_buf;
228
++	    }
229
++	    memset(wi->call_id, '\0', len);
230
++	    len = snprintf(wi->call_id, len, "%s",
231
++		  sp->call_id);
232
++	    wi->call_id_len = len;
233
++    }
234
++#endif
235
+ 
236
+     wi->glog = cf->glog;
237
+ 
238
+@@ -249,24 +308,63 @@ reconnect_timeout_handler(rtpp_log_t log, struct rtpp_timeout_handler *th)
239
+     }
240
+ }
241
+ 
242
++#ifdef ENABLE_XMLRPC
243
++static int
244
++do_xmlrpc_timeout_notification(rtpp_log_t log, struct rtpp_notify_wi *wi) {
245
++    xmlrpc_env env;
246
++    xmlrpc_value *result;
247
++    
248
++    /* Start up our XML-RPC client library. */
249
++    xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, XMLRPC_CLIENT_NAME, XMLRPC_CLIENT_VERSION);
250
++    xmlrpc_env_init(&env);
251
++
252
++    /* Get the dialog-Info: */
253
++    result = xmlrpc_client_call(&env, wi->xmlrpc_server,
254
++                                "dlg_terminate_dlg", "(s)",
255
++                                wi->call_id);
256
++    if (env.fault_occurred) {
257
++        rtpp_log_write(RTPP_LOG_ERR, wi->glog, "XML-RPC Fault: %s (%d)\n", env.fault_string, env.fault_code);
258
++        return -1;
259
++    }
260
++    
261
++    /* Dispose of our result value. */
262
++    xmlrpc_DECREF(result);
263
++
264
++    /* Shutdown our XML-RPC client library. */
265
++    xmlrpc_env_clean(&env);
266
++    xmlrpc_client_cleanup();
267
++
268
++    return 0;
269
++}
270
++#endif
271
++
272
++
273
+ static void
274
+ do_timeout_notification(struct rtpp_notify_wi *wi, int retries)
275
+ {
276
+     int result;
277
+-
278
+-    if (wi->th->connected == 0) {
279
+-        reconnect_timeout_handler(wi->glog, wi->th);
280
+-
281
+-        /* If connect fails, no notification will be sent */
282
++#ifdef ENABLE_XMLRPC
283
++    if (wi->xmlrpc_server_len > 0) {
284
++	rtpp_log_write(RTPP_LOG_INFO, wi->glog, "Using XML-RPC-Timeout handler (%s)", wi->xmlrpc_server);
285
++	result = do_xmlrpc_timeout_notification(wi->glog, wi);
286
++    } else {
287
++#endif
288
+         if (wi->th->connected == 0) {
289
+-            rtpp_log_write(RTPP_LOG_ERR, wi->glog, "unable to send timeout notification");
290
+-            return;
291
+-        }
292
++	    reconnect_timeout_handler(wi->glog, wi->th);
293
++
294
++    	    /* If connect fails, no notification will be sent */
295
++            if (wi->th->connected == 0) {
296
++	        rtpp_log_write(RTPP_LOG_ERR, wi->glog, "unable to send timeout notification");
297
++    	        return;
298
++            }
299
++	}
300
++
301
++        do {
302
++	    result = send(wi->th->fd, wi->notify_buf, wi->len, 0);
303
++        } while (result == -1 && errno == EINTR);
304
++#ifdef ENABLE_XMLRPC
305
+     }
306
+-
307
+-    do {
308
+-        result = send(wi->th->fd, wi->notify_buf, wi->len, 0);
309
+-    } while (result == -1 && errno == EINTR);
310
++#endif
311
+ 
312
+     if (result < 0) {
313
+         wi->th->connected = 0;
314
+diff --git a/rtpp_session.c b/rtpp_session.c
315
+index 9962cac..b84cdf3 100644
316
+--- a/rtpp_session.c
317
+@@ -205,6 +205,14 @@ remove_session(struct cfg *cf, struct rtpp_session *sp)
318
+ 	if (sp->rtcp->codecs[i] != NULL)
319
+ 	    free(sp->rtcp->codecs[i]);
320
+     }
321
++#ifdef ENABLE_XMLRPC
322
++    // In case we use the Kamailio-XML-RPC-Timeout, we have our own timeout-handler
323
++    if (sp->timeout_data.handler != &cf->timeout_handler) {
324
++ 	free(sp->timeout_data.handler->socket_name);
325
++	free(sp->timeout_data.handler);
326
++    }
327
++#endif
328
++	
329
+     if (sp->timeout_data.notify_tag != NULL)
330
+ 	free(sp->timeout_data.notify_tag);
331
+     hash_table_remove(cf, sp);