summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfred E. Heggestad <aeh@db.org>2014-03-29 22:52:56 +0100
committerAlfred E. Heggestad <aeh@db.org>2014-03-29 22:52:56 +0100
commit7766b0130f88d52e7dce1edb9439b81394b5213b (patch)
treedbbaed6a80fcf0b8f8883b56b281848ff5450694
parent2f701685d7230b39ce2e0f8ad230ee84bc156595 (diff)
parentd26a5481b91afc3a4dfd0d8fc5f615f9a42d1fa2 (diff)
Merge branch 'master' into ausrc_api
-rw-r--r--include/baresip.h1
-rw-r--r--mk/modules.mk1
-rw-r--r--modules/dtmfio/dtmfio.c136
-rw-r--r--modules/dtmfio/module.mk12
-rw-r--r--modules/portaudio/portaudio.c4
-rw-r--r--src/call.c40
-rw-r--r--src/stream.c8
-rw-r--r--src/ua.c12
8 files changed, 198 insertions, 16 deletions
diff --git a/include/baresip.h b/include/baresip.h
index 8bfd75d..6f0deae 100644
--- a/include/baresip.h
+++ b/include/baresip.h
@@ -74,6 +74,7 @@ void call_set_handlers(struct call *call, call_event_h *eh,
call_dtmf_h *dtmfh, void *arg);
uint16_t call_scode(const struct call *call);
uint32_t call_duration(const struct call *call);
+uint32_t call_setup_duration(const struct call *call);
const char *call_peeruri(const struct call *call);
const char *call_peername(const struct call *call);
const char *call_localuri(const struct call *call);
diff --git a/mk/modules.mk b/mk/modules.mk
index c205a6b..242299c 100644
--- a/mk/modules.mk
+++ b/mk/modules.mk
@@ -187,6 +187,7 @@ USE_QTCAPTURE := yes
endif
ifeq ($(OS),linux)
USE_EVDEV := $(shell [ -f $(SYSROOT)/include/linux/input.h ] && echo "yes")
+MODULES += dtmfio
endif
ifeq ($(OS),win32)
USE_WINWAVE := yes
diff --git a/modules/dtmfio/dtmfio.c b/modules/dtmfio/dtmfio.c
new file mode 100644
index 0000000..5d9534c
--- /dev/null
+++ b/modules/dtmfio/dtmfio.c
@@ -0,0 +1,136 @@
+/*************************************************************************/
+/* Copyright (c) 2014, Aaron Herting 'qwertos' <aaron@herting.cc> */
+/* Based upon code licensed under the same license by Creytiv.com */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions */
+/* are met: */
+/* */
+/* 1. Redistributions of source code must retain the above copyright */
+/* notice, this list of conditions and the following disclaimer. */
+/* */
+/* 2. Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* 3. Neither the name of the copyright holder nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
+/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
+/* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS */
+/* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED */
+/* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
+/* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY */
+/* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
+/* POSSIBILITY OF SUCH DAMAGE. */
+/*************************************************************************/
+
+
+/*
+ * # DTMFIO Module
+ *
+ * ## Description
+ *
+ * Writes received dtmf button presses to a FIFO located at /tmp/dtmf.out.
+ *
+ * Also, will write an 'E' when a call is established and an 'F' when the
+ * call is finished.
+ *
+ * ## To Do
+ *
+ * + Proper error handling
+ * + Using a dtmf.in file, be able to send DTMF signals
+ * + Use a filename specified by the user in the config file
+ * + Clean up build output so there aren't errors regarding unused vars
+ */
+
+#include <stdio.h>
+#include <re.h>
+#include <baresip.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+
+static FILE *fd;
+static const char *DTMF_OUT = "/tmp/dtmf.out";
+
+
+static void dtmf_handler(struct call *call, char key, void *arg)
+{
+ (void)call;
+ (void)arg;
+
+ if ( key != 0 ) {
+ fprintf(fd, "%c", key);
+ fflush(fd);
+ }
+}
+
+
+static void ua_event_handler(struct ua *ua,
+ enum ua_event ev,
+ struct call *call,
+ const char *prm,
+ void *arg )
+{
+ (void)ua;
+ (void)prm;
+ (void)arg;
+
+ if ( ev == UA_EVENT_CALL_ESTABLISHED ) {
+ fprintf(fd, "E");
+ fflush(fd);
+ call_set_handlers( call, NULL, dtmf_handler, NULL);
+ }
+
+ if (ev == UA_EVENT_CALL_CLOSED ) {
+ fprintf(fd, "F");
+ fflush(fd);
+ }
+}
+
+
+static int module_init(void)
+{
+ uag_event_register( ua_event_handler, NULL );
+
+ if ( mkfifo( DTMF_OUT, S_IWUSR | S_IRUSR ) ) {
+ error("Creation of the FIFO errored."
+ " This might cause issues.\n");
+ }
+
+ fd = fopen( DTMF_OUT , "w+" );
+
+ if ( fd == 0 ){
+ error("Opening of the FIFO errored."
+ " This might cause issues.\n");
+ }
+
+ return 0;
+}
+
+
+static int module_close(void)
+{
+ fclose(fd);
+
+ unlink(DTMF_OUT);
+
+ return 0;
+}
+
+
+const struct mod_export DECL_EXPORTS(dtmfio) = {
+ "dtmfio",
+ "application",
+ module_init,
+ module_close
+};
diff --git a/modules/dtmfio/module.mk b/modules/dtmfio/module.mk
new file mode 100644
index 0000000..cb1264b
--- /dev/null
+++ b/modules/dtmfio/module.mk
@@ -0,0 +1,12 @@
+#
+# module.mk
+#
+# Copyright (C) 2010 Creytiv.com
+# Modified by Aaron Herting <aaron@herting.cc>
+#
+
+MOD := dtmfio
+$(MOD)_SRCS += dtmfio.c
+$(MOD)_LFLAGS +=
+
+include mk/mod.mk
diff --git a/modules/portaudio/portaudio.c b/modules/portaudio/portaudio.c
index 0e81dff..2da18fc 100644
--- a/modules/portaudio/portaudio.c
+++ b/modules/portaudio/portaudio.c
@@ -49,7 +49,7 @@ static int read_callback(const void *inputBuffer, void *outputBuffer,
PaStreamCallbackFlags statusFlags, void *userData)
{
struct ausrc_st *st = userData;
- unsigned sampc;
+ size_t sampc;
(void)outputBuffer;
(void)timeInfo;
@@ -72,7 +72,7 @@ static int write_callback(const void *inputBuffer, void *outputBuffer,
PaStreamCallbackFlags statusFlags, void *userData)
{
struct auplay_st *st = userData;
- unsigned sampc;
+ size_t sampc;
(void)inputBuffer;
(void)timeInfo;
diff --git a/src/call.c b/src/call.c
index dc3edb5..41c6d16 100644
--- a/src/call.c
+++ b/src/call.c
@@ -62,6 +62,7 @@ struct call {
struct tmr tmr_inv; /**< Timer for incoming calls */
struct tmr tmr_dtmf; /**< Timer for incoming DTMF events */
time_t time_start; /**< Time when call started */
+ time_t time_conn; /**< Time when call initiated */
time_t time_stop; /**< Time when call stopped */
bool got_offer; /**< Got SDP Offer from Peer */
struct mnat_sess *mnats; /**< Media NAT session */
@@ -631,7 +632,10 @@ int call_hangup(struct call *call, uint16_t scode, const char *reason)
break;
default:
- info("call: terminate call with %s\n", call->peer_uri);
+ info("call: terminate call '%s' with %s\n",
+ sip_dialog_callid(sipsess_dialog(call->sess)),
+ call->peer_uri);
+
call->sess = mem_deref(call->sess);
break;
}
@@ -694,7 +698,7 @@ int call_answer(struct call *call, uint16_t scode)
return err;
err = sipsess_answer(call->sess, scode, "Answering", desc,
- "Allow: %s\r\n", uag_allowed_methods());
+ "Allow: %s\r\n", uag_allowed_methods());
mem_deref(desc);
@@ -1115,7 +1119,7 @@ static void sipsess_refer_handler(struct sip *sip, const struct sip_msg *msg,
ua_cuser(call->ua), "message/sipfrag",
auth_handler, call->acc, true,
sipnot_close_handler, call,
- "Allow: %s\r\n", uag_allowed_methods());
+ "Allow: %s\r\n", uag_allowed_methods());
if (err) {
warning("call: refer: sipevent_accept failed: %m\n", err);
return;
@@ -1307,6 +1311,9 @@ static int send_invite(struct call *call)
warning("call: sipsess_connect: %m\n", err);
}
+ /* save call setup timer */
+ call->time_conn = time(NULL);
+
mem_deref(desc);
return err;
@@ -1330,6 +1337,22 @@ uint32_t call_duration(const struct call *call)
/**
+ * Get the current call setup time in seconds
+ *
+ * @param call Call object
+ *
+ * @return Call setup in seconds
+ */
+uint32_t call_setup_duration(const struct call *call)
+{
+ if (!call || !call->time_conn || call->time_conn <= 0 )
+ return 0;
+
+ return (uint32_t)(call->time_start - call->time_conn);
+}
+
+
+/**
* Get the audio object for the current call
*
* @param call Call object
@@ -1553,7 +1576,12 @@ void call_set_handlers(struct call *call, call_event_h *eh,
if (!call)
return;
- call->eh = eh;
- call->dtmfh = dtmfh;
- call->arg = arg;
+ if (eh)
+ call->eh = eh;
+
+ if (dtmfh)
+ call->dtmfh = dtmfh;
+
+ if (arg)
+ call->arg = arg;
}
diff --git a/src/stream.c b/src/stream.c
index 0e5b89c..122cd96 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -76,11 +76,15 @@ static void print_rtp_stats(struct stream *s)
{
info("\n%-9s Transmit: Receive:\n"
"packets: %7u %7u\n"
- "avg. bitrate: %7.1f %7.1f (kbit/s)\n",
+ "avg. bitrate: %7.1f %7.1f (kbit/s)\n"
+ "errors: %7d %7d\n"
+ ,
sdp_media_name(s->sdp),
s->metric_tx.n_packets, s->metric_rx.n_packets,
1.0*metric_avg_bitrate(&s->metric_tx)/1000,
- 1.0*metric_avg_bitrate(&s->metric_rx)/1000);
+ 1.0*metric_avg_bitrate(&s->metric_rx)/1000,
+ s->metric_tx.n_err, s->metric_rx.n_err
+ );
if (s->rtcp_stats.tx.sent || s->rtcp_stats.rx.sent) {
diff --git a/src/ua.c b/src/ua.c
index cb99011..5e05e98 100644
--- a/src/ua.c
+++ b/src/ua.c
@@ -474,18 +474,18 @@ int ua_alloc(struct ua **uap, const char *aor)
ua->af = AF_INET;
#endif
- /* generate a unique contact-user, this is needed to route
- incoming requests when using multiple useragents */
- err = re_sdprintf(&ua->cuser, "%p", ua);
- if (err)
- goto out;
-
/* Decode SIP address */
err = account_alloc(&ua->acc, aor);
if (err)
goto out;
+ /* generate a unique contact-user, this is needed to route
+ incoming requests when using multiple useragents */
+ err = re_sdprintf(&ua->cuser, "%r-%p", &ua->acc->luri.user, ua);
+ if (err)
+ goto out;
+
if (ua->acc->sipnat) {
ua_printf(ua, "Using sipnat: `%s'\n", ua->acc->sipnat);
}