diff options
author | Alfred E. Heggestad <aeh@db.org> | 2015-12-19 16:17:40 +0100 |
---|---|---|
committer | Alfred E. Heggestad <aeh@db.org> | 2015-12-19 16:17:40 +0100 |
commit | 0e186ba40e7876c39a25e02a16aae6ad651797cf (patch) | |
tree | 0b7a76c12485e284f6749b727e97a7c6b8d641cd | |
parent | 6a8e3d34355826b66457c86424e8c7f3e8a8260a (diff) | |
parent | 6decfc46392a8f68d4eab8f81b2bbe3bdbda2bb6 (diff) |
Merge pull request #95 from sreimers/master
Multi Call Echo Module - Experimental
-rw-r--r-- | modules/echo/echo.c | 157 | ||||
-rw-r--r-- | modules/echo/module.mk | 9 |
2 files changed, 166 insertions, 0 deletions
diff --git a/modules/echo/echo.c b/modules/echo/echo.c new file mode 100644 index 0000000..3fac5ba --- /dev/null +++ b/modules/echo/echo.c @@ -0,0 +1,157 @@ +/** + * @file echo.c Echo module + */ +#include <re.h> +#include <baresip.h> + +/** + * + * Multi Call Echo module + * + * REQUIRES: aubridge + * NOTE: This module is experimental. + * + */ + +struct session { + struct le le; + struct call *call_in; +}; + + +static struct list sessionl; + + +static void destructor(void *arg) +{ + struct session *sess = arg; + + debug("echo: session destroyed (in=%p)\n", + sess->call_in); + + list_unlink(&sess->le); + mem_deref(sess->call_in); +} + + +static void call_event_handler(struct call *call, enum call_event ev, + const char *str, void *arg) +{ + struct session *sess = arg; + + switch (ev) { + + case CALL_EVENT_CLOSED: + debug("echo: CALL_CLOSED: %s\n", str); + mem_deref(sess); + break; + + default: + break; + } +} + + +static void call_dtmf_handler(struct call *call, char key, void *arg) +{ + (void)arg; + + debug("echo: relaying DTMF event: key = '%c'\n", key ? key : '.'); + + call_send_digit(call, key); +} + + +static int new_session(struct call *call) +{ + struct session *sess; + char a[64]; + int err = 0; + + sess = mem_zalloc(sizeof(*sess), destructor); + if (!sess) + return ENOMEM; + + sess->call_in = call; + + re_snprintf(a, sizeof(a), "A-%x", sess); + + audio_set_devicename(call_audio(sess->call_in), a, a); + + call_set_handlers(sess->call_in, call_event_handler, + call_dtmf_handler, sess); + + list_append(&sessionl, &sess->le, sess); + ua_answer(uag_current(), NULL); + + if (err) + mem_deref(sess); + + return err; +} + + +static void ua_event_handler(struct ua *ua, enum ua_event ev, + struct call *call, const char *prm, void *arg) +{ + int err; + (void)prm; + (void)arg; + + switch (ev) { + + case UA_EVENT_CALL_INCOMING: + debug("echo: CALL_INCOMING: peer=%s --> local=%s\n", + call_peeruri(call), + call_localuri(call)); + + err = new_session(call); + if (err) { + ua_hangup(ua, call, 500, "Server Error"); + } + break; + + default: + break; + } +} + + +static int module_init(void) +{ + int err; + + list_init(&sessionl); + + err = uag_event_register(ua_event_handler, 0); + if (err) + return err; + + debug("echo: module loaded\n"); + + return 0; +} + + +static int module_close(void) +{ + debug("echo: module closing..\n"); + + if (!list_isempty(&sessionl)) { + + info("echo: flushing %u sessions\n", list_count(&sessionl)); + list_flush(&sessionl); + } + + uag_event_unregister(ua_event_handler); + + return 0; +} + + +const struct mod_export DECL_EXPORTS(echo) = { + "echo", + "application", + module_init, + module_close +}; diff --git a/modules/echo/module.mk b/modules/echo/module.mk new file mode 100644 index 0000000..0c7ee6f --- /dev/null +++ b/modules/echo/module.mk @@ -0,0 +1,9 @@ +# +# module.mk +# +# + +MOD := echo +$(MOD)_SRCS += echo.c + +include mk/mod.mk |