diff options
author | 2009-10-22 21:41:30 +0000 | |
---|---|---|
committer | 2009-10-22 21:41:30 +0000 | |
commit | 43d27ea74e8e06559b86a64ceed1f972180e6f19 (patch) | |
tree | 88f0aad892f748f1fad728436e7bb74c3cf5667e | |
parent | use .Ux in midicat.1, as we do for aucat.1 now (diff) | |
download | wireguard-openbsd-43d27ea74e8e06559b86a64ceed1f972180e6f19.tar.xz wireguard-openbsd-43d27ea74e8e06559b86a64ceed1f972180e6f19.zip |
When starting playback, the client tries to write ``bufsz'' frames
instead of ``appbufsz'', which violates the flow control mechanism.
Fix this longstanding bug by enabling negative values in AMSG_MOVE
messages, this way the client is notified when its stream is
attached to the mixer, and can update its max transfer limit.
Since this fix changes the AMSG_MOVE message format, we crank the
protocol version, and thus remove code specific to the old protocol.
-rw-r--r-- | lib/libsndio/aucat.c | 23 | ||||
-rw-r--r-- | usr.bin/aucat/amsg.h | 4 | ||||
-rw-r--r-- | usr.bin/aucat/sock.c | 51 |
3 files changed, 30 insertions, 48 deletions
diff --git a/lib/libsndio/aucat.c b/lib/libsndio/aucat.c index cc1e977b1f1..681411700de 100644 --- a/lib/libsndio/aucat.c +++ b/lib/libsndio/aucat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aucat.c,v 1.29 2009/10/17 10:55:43 ratchov Exp $ */ +/* $OpenBSD: aucat.c,v 1.30 2009/10/22 21:41:30 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -43,6 +43,9 @@ struct aucat_hdl { int maxwrite; /* latency constraint */ int events; /* events the user requested */ unsigned curvol, reqvol; /* current and requested volume */ + unsigned devbufsz; /* server side buffer size (in frames) */ + unsigned attached; /* stream attached to device */ + int delta; /* some of received deltas */ }; static void aucat_close(struct sio_hdl *); @@ -150,8 +153,17 @@ aucat_runmsg(struct aucat_hdl *hdl) hdl->rtodo = hdl->rmsg.u.data.size; break; case AMSG_MOVE: - hdl->maxwrite += hdl->rmsg.u.ts.delta * (int)hdl->wbpf; - sio_onmove_cb(&hdl->sio, hdl->rmsg.u.ts.delta); + if (!hdl->attached) { + DPRINTF("aucat_runmsg: attached\n"); + hdl->maxwrite += hdl->devbufsz * hdl->wbpf; + hdl->attached = 1; + } + hdl->delta += hdl->rmsg.u.ts.delta; + if (hdl->delta >= 0) { + hdl->maxwrite += hdl->delta * hdl->wbpf; + sio_onmove_cb(&hdl->sio, hdl->delta); + hdl->delta = 0; + } hdl->rstate = STATE_MSG; hdl->rtodo = sizeof(struct amsg); break; @@ -303,7 +315,10 @@ aucat_start(struct sio_hdl *sh) return 0; hdl->wbpf = par.bps * par.pchan; hdl->rbpf = par.bps * par.rchan; - hdl->maxwrite = hdl->wbpf * par.bufsz; + hdl->maxwrite = hdl->wbpf * par.appbufsz; + hdl->devbufsz = par.bufsz - par.appbufsz; + hdl->attached = 0; + hdl->delta = 0; AMSG_INIT(&hdl->wmsg); hdl->wmsg.cmd = AMSG_START; diff --git a/usr.bin/aucat/amsg.h b/usr.bin/aucat/amsg.h index 9492f2bb8d1..fa971543c30 100644 --- a/usr.bin/aucat/amsg.h +++ b/usr.bin/aucat/amsg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: amsg.h,v 1.11 2009/10/17 10:55:43 ratchov Exp $ */ +/* $OpenBSD: amsg.h,v 1.12 2009/10/22 21:41:30 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -89,7 +89,7 @@ struct amsg { #define AMSG_MIDIOUT 0x8 /* MIDI thru output */ #define AMSG_MIXER 0x10 /* MIDI mixer */ uint16_t proto; /* protocol type */ -#define AMSG_VERSION 0 +#define AMSG_VERSION 1 uint8_t version; /* protocol version */ uint8_t reserved1[5]; /* for future use */ char opt[12]; /* profile name */ diff --git a/usr.bin/aucat/sock.c b/usr.bin/aucat/sock.c index 5248d8b3528..0611755a477 100644 --- a/usr.bin/aucat/sock.c +++ b/usr.bin/aucat/sock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sock.c,v 1.32 2009/10/21 05:43:41 ratchov Exp $ */ +/* $OpenBSD: sock.c,v 1.33 2009/10/22 21:41:30 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -130,13 +130,6 @@ rsock_opos(struct aproc *p, struct abuf *obuf, int delta) return; f->delta += delta; - /* - * Negative deltas are xrun notifications for internal uses - * only. Don't generate a packet for this, the client will be - * notified later. - */ - if (delta < 0) - return; f->tickpending++; for (;;) { if (!sock_write(f)) @@ -228,14 +221,7 @@ wsock_ipos(struct aproc *p, struct abuf *obuf, int delta) return; f->delta += delta; - /* - * Negative deltas are xrun notifications for internal uses - * only. Don't generate a packet for this, the client will be - * notified later. - */ - if (delta < 0) - return; - f->tickpending++; + f->tickpending++; for (;;) { if (!sock_write(f)) break; @@ -550,21 +536,6 @@ sock_setpar(struct sock *f) struct amsg_par *p = &f->rmsg.u.par; unsigned min, max, rate; - if (AMSG_ISSET(p->legacy_mode)) { - /* - * allow old clients that don't support HELLO to work - * XXX: remove this. - */ - if ((p->legacy_mode & ~(AMSG_PLAY | AMSG_REC)) || - (p->legacy_mode == 0)) { - return 0; - } - f->mode = 0; - if ((p->legacy_mode & AMSG_PLAY) && dev_mix) - f->mode |= AMSG_PLAY; - if ((p->legacy_mode & AMSG_REC) && dev_sub) - f->mode |= AMSG_REC; - } if (AMSG_ISSET(p->bits)) { if (p->bits < BITS_MIN || p->bits > BITS_MAX) { return 0; @@ -674,9 +645,12 @@ sock_hello(struct sock *f) { struct amsg_hello *p = &f->rmsg.u.hello; - /* XXX : set file name to p->who */ - /* XXX : dev_midi can no longer be NULL, right ? */ - + if (p->version != AMSG_VERSION) { + return 0; + } + /* + * XXX : dev_midi can no longer be NULL, right ? + */ if (dev_midi && (p->proto & (AMSG_MIDIIN | AMSG_MIDIOUT))) { if (p->proto & ~(AMSG_MIDIIN | AMSG_MIDIOUT)) { return 0; @@ -729,13 +703,6 @@ sock_execmsg(struct sock *f) { struct amsg *m = &f->rmsg; - /* - * XXX: allow old clients to work without hello on the default socket - */ - if (f->pstate == SOCK_HELLO && m->cmd != AMSG_HELLO && f->opt != NULL) { - f->pstate = SOCK_INIT; - } - switch (m->cmd) { case AMSG_DATA: if (f->pstate != SOCK_RUN && f->pstate != SOCK_START) { @@ -899,7 +866,7 @@ sock_buildmsg(struct sock *f) /* * If pos changed, build a MOVE message. */ - if (f->tickpending && f->delta >= 0) { + if (f->tickpending) { AMSG_INIT(&f->wmsg); f->wmsg.cmd = AMSG_MOVE; f->wmsg.u.ts.delta = f->delta; |