diff options
author | Alfred E. Heggestad <aeh@db.org> | 2014-04-11 19:36:31 +0200 |
---|---|---|
committer | Alfred E. Heggestad <aeh@db.org> | 2014-04-11 19:36:31 +0200 |
commit | 2a9edfbd3d03c2925d5d7d23f435cc5730fe3622 (patch) | |
tree | e6dd3317f93bee44af70083e6aa62329853ec2bb | |
parent | 7766b0130f88d52e7dce1edb9439b81394b5213b (diff) | |
parent | 78271821396aad56bd7cbe83a6552a102b551aa6 (diff) |
Merge branch 'master' into ausrc_api
-rw-r--r-- | docs/README | 1 | ||||
-rw-r--r-- | modules/presence/subscriber.c | 2 | ||||
-rw-r--r-- | modules/sndio/module.mk | 11 | ||||
-rw-r--r-- | modules/sndio/sndio.c | 307 | ||||
-rw-r--r-- | src/account.c | 18 | ||||
-rw-r--r-- | src/call.c | 18 | ||||
-rw-r--r-- | src/config.c | 4 | ||||
-rw-r--r-- | src/core.h | 2 | ||||
-rw-r--r-- | src/message.c | 11 | ||||
-rw-r--r-- | src/sdp.c | 8 | ||||
-rw-r--r-- | src/stream.c | 3 | ||||
-rw-r--r-- | src/ua.c | 4 |
12 files changed, 356 insertions, 33 deletions
diff --git a/docs/README b/docs/README index 2468bfd..f1efe03 100644 --- a/docs/README +++ b/docs/README @@ -187,6 +187,7 @@ selfview Video selfview module silk SILK audio codec snapshot Save video-stream as PNG images sndfile Audio dumper using libsndfile +sndio Audio driver for OpenBSD speex Speex audio codec speex_aec Acoustic Echo Cancellation (AEC) using libspeexdsp speex_pp Audio pre-processor using libspeexdsp diff --git a/modules/presence/subscriber.c b/modules/presence/subscriber.c index 22361d5..b04fa7c 100644 --- a/modules/presence/subscriber.c +++ b/modules/presence/subscriber.c @@ -254,7 +254,7 @@ int subscriber_init(void) struct sip_addr *addr = contact_addr(c); struct pl val; - if (0 == sip_param_decode(&addr->params, "presence", &val) && + if (0 == msg_param_decode(&addr->params, "presence", &val) && 0 == pl_strcasecmp(&val, "p2p")) { err |= presence_alloc(le->data); diff --git a/modules/sndio/module.mk b/modules/sndio/module.mk new file mode 100644 index 0000000..79ace67 --- /dev/null +++ b/modules/sndio/module.mk @@ -0,0 +1,11 @@ +# +# module.mk +# +# Copyright (C) 2014 Creytiv.com +# + +MOD := sndio +$(MOD)_SRCS += sndio.c +$(MOD)_LFLAGS += -lsndio + +include mk/mod.mk diff --git a/modules/sndio/sndio.c b/modules/sndio/sndio.c new file mode 100644 index 0000000..ee0fd46 --- /dev/null +++ b/modules/sndio/sndio.c @@ -0,0 +1,307 @@ +/** + * @file sndio.c SndIO sound driver + * + * Copyright (C) 2014 Creytiv.com + */ +#include <stdlib.h> +#include <string.h> +#include <sndio.h> +#include <pthread.h> +#include <re.h> +#include <rem.h> +#include <baresip.h> + + +struct ausrc_st { + struct ausrc *as; + struct sio_hdl *hdl; + pthread_t thread; + size_t nbytes; + void *buf; + int run; + ausrc_read_h *rh; + void *arg; +}; + +struct auplay_st { + struct auplay *ap; + struct sio_hdl *hdl; + pthread_t thread; + size_t nbytes; + void *buf; + int run; + auplay_write_h *wh; + void *arg; +}; + +static struct ausrc *ausrc; +static struct auplay *auplay; + + +static struct sio_par *sndio_initpar(void *arg) +{ + struct sio_par *par; + struct auplay_prm *prm = arg; + + if ((par = malloc(sizeof(struct sio_par))) == NULL) + return NULL; + + sio_initpar(par); + + /* sndio doesn't support a-low and u-low */ + prm->fmt = AUFMT_S16LE; + par->bits = 16; + par->bps = SIO_BPS(par->bits); + par->sig = 1; + par->le = 1; + + par->rchan = prm->ch; + par->pchan = prm->ch; + par->rate = prm->srate; + + return par; +} + + +static void *read_thread(void *arg) +{ + struct ausrc_st *st = arg; + + if (!sio_start(st->hdl)) { + warning("sndio: could not start record\n"); + goto out; + } + + while (st->run) { + sio_read(st->hdl, st->buf, st->nbytes); + st->rh(st->buf, st->nbytes, st->arg); + } + + out: + return NULL; +} + + +static void *write_thread(void *arg) +{ + struct auplay_st *st = arg; + + if (!sio_start(st->hdl)) { + warning("sndio: could not start playback\n"); + goto out; + } + + while (st->run) { + st->wh(st->buf, st->nbytes, st->arg); + sio_write(st->hdl, st->buf, st->nbytes); + } + + out: + return NULL; +} + + +static void ausrc_destructor(void *arg) +{ + struct ausrc_st *st = arg; + + if (st->run) { + st->run = false; + (void)pthread_join(st->thread, NULL); + } + + sio_close(st->hdl); + + mem_deref(st->buf); + mem_deref(st->as); +} + + +static void auplay_destructor(void *arg) +{ + struct auplay_st *st = arg; + + if (st->run) { + st->run = false; + (void)pthread_join(st->thread, NULL); + } + + sio_close(st->hdl); + + mem_deref(st->buf); + mem_deref(st->ap); +} + + +static int src_alloc(struct ausrc_st **stp, struct ausrc *as, + struct media_ctx **ctx, + struct ausrc_prm *prm, const char *device, + ausrc_read_h *rh, ausrc_error_h *errh, void *arg) +{ + struct ausrc_st *st; + struct sio_par *par; + int err; + const char *name; + + (void)ctx; + (void)errh; + + if (!stp || !as || !prm) + return EINVAL; + + name = (str_isset(device)) ? device : SIO_DEVANY; + + if ((st = mem_zalloc(sizeof(*st), ausrc_destructor)) == NULL) + return ENOMEM; + + st->as = mem_ref(as); + st->rh = rh; + st->arg = arg; + st->hdl = sio_open(name, SIO_REC, 0); + + if (!st->hdl) { + warning("sndio: could not open ausrc device '%s'\n", name); + err = EINVAL; + goto out; + } + + par = sndio_initpar(prm); + if (!par) { + err = ENOMEM; + goto out; + } + + if (!sio_setpar(st->hdl, par)) { + free(par); + err = EINVAL; + goto out; + } + + if (!sio_getpar(st->hdl, par)) { + free(par); + err = EINVAL; + goto out; + } + + st->nbytes = 2 * par->appbufsz; + st->buf = mem_alloc(st->nbytes, NULL); + if (!st->buf) { + free(par); + err = ENOMEM; + goto out; + } + + free(par); + + st->run = true; + err = pthread_create(&st->thread, NULL, read_thread, st); + if (err) + st->run = false; + + out: + if (err) + mem_deref(st); + else + *stp = st; + + return err; +} + + +static int play_alloc(struct auplay_st **stp, struct auplay *ap, + struct auplay_prm *prm, const char *device, + auplay_write_h *wh, void *arg) +{ + struct auplay_st *st; + struct sio_par *par; + int err; + const char *name; + + if (!stp || !ap || !prm) + return EINVAL; + + name = (str_isset(device)) ? device : SIO_DEVANY; + + if ((st = mem_zalloc(sizeof(*st), auplay_destructor)) == NULL) + return ENOMEM; + + st->ap = mem_ref(ap); + st->wh = wh; + st->arg = arg; + st->hdl = sio_open(name, SIO_PLAY, 0); + + if (!st->hdl) { + warning("sndio: could not open auplay device '%s'\n", name); + err = EINVAL; + goto out; + } + + par = sndio_initpar(prm); + if (!par) { + err = ENOMEM; + goto out; + } + + if (!sio_setpar(st->hdl, par)) { + free(par); + err = EINVAL; + goto out; + } + + if (!sio_getpar(st->hdl, par)) { + free(par); + err = EINVAL; + goto out; + } + + st->nbytes = 2 * par->appbufsz; + st->buf = mem_alloc(st->nbytes, NULL); + if (!st->buf) { + free(par); + err = ENOMEM; + goto out; + } + + free(par); + + st->run = true; + err = pthread_create(&st->thread, NULL, write_thread, st); + if (err) + st->run = false; + + out: + if (err) + mem_deref(st); + else + *stp = st; + + return err; +} + + +static int sndio_init(void) +{ + int err = 0; + + err |= ausrc_register(&ausrc, "sndio", src_alloc); + err |= auplay_register(&auplay, "sndio", play_alloc); + + return err; +} + + +static int sndio_close(void) +{ + ausrc = mem_deref(ausrc); + auplay = mem_deref(auplay); + + return 0; +} + + +EXPORT_SYM const struct mod_export DECL_EXPORTS(sndio) = { + "sndio", + "sound", + sndio_init, + sndio_close +}; diff --git a/src/account.c b/src/account.c index 95ceeba..b8945b1 100644 --- a/src/account.c +++ b/src/account.c @@ -43,7 +43,7 @@ static int param_dstr(char **dstr, const struct pl *params, const char *name) { struct pl pl; - if (sip_param_decode(params, name, &pl)) + if (msg_param_decode(params, name, &pl)) return 0; return pl_strdup(dstr, &pl); @@ -54,7 +54,7 @@ static int param_u32(uint32_t *v, const struct pl *params, const char *name) { struct pl pl; - if (sip_param_decode(params, name, &pl)) + if (msg_param_decode(params, name, &pl)) return 0; *v = pl_u32(&pl); @@ -74,7 +74,7 @@ static int stunsrv_decode(struct account *acc, const struct sip_addr *aor) memset(&uri, 0, sizeof(uri)); - if (0 == sip_param_decode(&aor->params, "stunserver", &srv)) { + if (0 == msg_param_decode(&aor->params, "stunserver", &srv)) { info("using stunserver: '%r'\n", &srv); @@ -134,7 +134,7 @@ static void answermode_decode(struct account *prm, const struct pl *pl) { struct pl amode; - if (0 == sip_param_decode(pl, "answermode", &amode)) { + if (0 == msg_param_decode(pl, "answermode", &amode)) { if (0 == pl_strcasecmp(&amode, "manual")) { prm->answermode = ANSWERMODE_MANUAL; @@ -180,12 +180,12 @@ static int audio_codecs_decode(struct account *acc, const struct pl *prm) list_init(&acc->aucodecl); - if (0 == sip_param_exists(prm, "audio_codecs", &tmp)) { + if (0 == msg_param_exists(prm, "audio_codecs", &tmp)) { struct pl acs; char cname[64]; unsigned i = 0; - if (sip_param_decode(prm, "audio_codecs", &acs)) + if (msg_param_decode(prm, "audio_codecs", &acs)) return 0; while (0 == csl_parse(&acs, cname, sizeof(cname))) { @@ -236,12 +236,12 @@ static int video_codecs_decode(struct account *acc, const struct pl *prm) list_init(&acc->vidcodecl); - if (0 == sip_param_exists(prm, "video_codecs", &tmp)) { + if (0 == msg_param_exists(prm, "video_codecs", &tmp)) { struct pl vcs; char cname[64]; unsigned i = 0; - if (sip_param_decode(prm, "video_codecs", &vcs)) + if (msg_param_decode(prm, "video_codecs", &vcs)) return 0; while (0 == csl_parse(&vcs, cname, sizeof(cname))) { @@ -298,7 +298,7 @@ static int sip_params_decode(struct account *acc, const struct sip_addr *aor) err |= param_dstr(&acc->sipnat, &aor->params, "sipnat"); - if (0 == sip_param_decode(&aor->params, "auth_user", &auth_user)) + if (0 == msg_param_decode(&aor->params, "auth_user", &auth_user)) err |= pl_strdup(&acc->auth_user, &auth_user); else err |= pl_strdup(&acc->auth_user, &aor->uri.user); @@ -958,7 +958,8 @@ static int sipsess_answer_handler(const struct sip_msg *msg, void *arg) MAGIC_CHECK(call); - (void)sdp_decode_multipart(&msg->ctype, msg->mb); + if (msg_ctype_cmp(&msg->ctyp, "multipart", "mixed")) + (void)sdp_decode_multipart(&msg->ctyp.params, msg->mb); err = sdp_decode(call->sdp, msg->mb, false); if (err) { @@ -1034,7 +1035,7 @@ static void sipsess_info_handler(struct sip *sip, const struct sip_msg *msg, { struct call *call = arg; - if (!pl_strcasecmp(&msg->ctype, "application/dtmf-relay")) { + if (msg_ctype_cmp(&msg->ctyp, "application", "dtmf-relay")) { struct pl body, sig, dur; int err; @@ -1067,8 +1068,8 @@ static void sipsess_info_handler(struct sip *sip, const struct sip_msg *msg, } } #ifdef USE_VIDEO - else if (!pl_strcasecmp(&msg->ctype, - "application/media_control+xml")) { + else if (msg_ctype_cmp(&msg->ctyp, + "application", "media_control+xml")) { call_handle_info_req(call, msg); (void)sip_reply(sip, msg, 200, "OK"); } @@ -1231,8 +1232,8 @@ static void sipsess_progr_handler(const struct sip_msg *msg, void *arg) MAGIC_CHECK(call); - info("call: SIP Progress: %u %r (%r)\n", - msg->scode, &msg->reason, &msg->ctype); + info("call: SIP Progress: %u %r (%r/%r)\n", + msg->scode, &msg->reason, &msg->ctyp.type, &msg->ctyp.subtype); if (msg->scode <= 100) return; @@ -1245,12 +1246,13 @@ static void sipsess_progr_handler(const struct sip_msg *msg, void *arg) * we must also handle changes to/from 180 and 183, * so we reset the media-stream/ringback each time. */ - if (!pl_strcasecmp(&msg->ctype, "application/sdp") + if (msg_ctype_cmp(&msg->ctyp, "application", "sdp") && mbuf_get_left(msg->mb) && !sdp_decode(call->sdp, msg->mb, false)) { media = true; } - else if (!sdp_decode_multipart(&msg->ctype, msg->mb) && + else if (msg_ctype_cmp(&msg->ctyp, "multipart", "mixed") && + !sdp_decode_multipart(&msg->ctyp.params, msg->mb) && !sdp_decode(call->sdp, msg->mb, false)) { media = true; } diff --git a/src/config.c b/src/config.c index dd65c52..4a84b67 100644 --- a/src/config.c +++ b/src/config.c @@ -334,6 +334,8 @@ static const char *default_audio_device(void) return "oss,/dev/dsp"; #elif defined (WIN32) return "winwave,nil"; +#elif defined (ANDROID) + return "opensles"; #else return "alsa,default"; #endif @@ -583,6 +585,8 @@ int config_write_template(const char *file, const struct config *cfg) (void)re_fprintf(f, "module\t\t\t" MOD_PRE "mda" MOD_EXT "\n"); #elif defined (DARWIN) (void)re_fprintf(f, "module\t\t\t" MOD_PRE "coreaudio" MOD_EXT "\n"); +#elif defined (ANDROID) + (void)re_fprintf(f, "module\t\t\t" MOD_PRE "opensles" MOD_EXT "\n"); #else (void)re_fprintf(f, "module\t\t\t" MOD_PRE "oss" MOD_EXT "\n"); (void)re_fprintf(f, "module\t\t\t" MOD_PRE "alsa" MOD_EXT "\n"); @@ -283,7 +283,7 @@ int sip_req_send(struct ua *ua, const char *method, const char *uri, * SDP */ -int sdp_decode_multipart(const struct pl *ctype, struct mbuf *mb); +int sdp_decode_multipart(const struct pl *ctype_prm, struct mbuf *mb); const struct sdp_format *sdp_media_format_cycle(struct sdp_media *m); diff --git a/src/message.c b/src/message.c index b0e33e1..9d3662b 100644 --- a/src/message.c +++ b/src/message.c @@ -15,15 +15,12 @@ static void *recvarg; static void handle_message(struct ua *ua, const struct sip_msg *msg) { - static const char *ctype_text = "text/plain"; - struct pl mtype; + static const char ctype_text[] = "text/plain"; + struct pl ctype_pl = {ctype_text, sizeof(ctype_text)-1}; (void)ua; - if (re_regex(msg->ctype.p, msg->ctype.l, "[^;]+", &mtype)) - mtype = msg->ctype; - - if (0==pl_strcasecmp(&mtype, ctype_text) && recvh) { - recvh(&msg->from.auri, &msg->ctype, msg->mb, recvarg); + if (msg_ctype_cmp(&msg->ctyp, "text", "plain") && recvh) { + recvh(&msg->from.auri, &ctype_pl, msg->mb, recvarg); (void)sip_reply(uag_sip(), msg, 200, "OK"); } else { @@ -145,18 +145,18 @@ static void decode_part(const struct pl *part, struct mbuf *mb) /** * Decode a multipart/mixed message and find the part with application/sdp */ -int sdp_decode_multipart(const struct pl *ctype, struct mbuf *mb) +int sdp_decode_multipart(const struct pl *ctype_prm, struct mbuf *mb) { struct pl bnd, s, e, p; char expr[64]; int err; - if (!ctype || !mb) + if (!ctype_prm || !mb) return EINVAL; /* fetch the boundary tag, excluding quotes */ - err = re_regex(ctype->p, ctype->l, - "multipart/mixed;[ \t]*boundary=[~]+", NULL, &bnd); + err = re_regex(ctype_prm->p, ctype_prm->l, + "boundary=[~]+", &bnd); if (err) return err; diff --git a/src/stream.c b/src/stream.c index 122cd96..f30bf0c 100644 --- a/src/stream.c +++ b/src/stream.c @@ -565,7 +565,8 @@ int stream_debug(struct re_printf *pf, const struct stream *s) s->pt_enc); sdp_media_raddr_rtcp(s->sdp, &rrtcp); - err |= re_hprintf(pf, " remote: %J/%J\n", + err |= re_hprintf(pf, " local: %J, remote: %J/%J\n", + sdp_media_laddr(s->sdp), sdp_media_raddr(s->sdp), &rrtcp); err |= rtp_debug(pf, s->rtp); @@ -1424,14 +1424,14 @@ struct ua *uag_find_param(const char *name, const char *value) if (value) { - if (0 == sip_param_decode(&laddr->params, name, &val) + if (0 == msg_param_decode(&laddr->params, name, &val) && 0 == pl_strcasecmp(&val, value)) { return ua; } } else { - if (0 == sip_param_exists(&laddr->params, name, &val)) + if (0 == msg_param_exists(&laddr->params, name, &val)) return ua; } } |