ratox

FIFO based tox client
Log | Files | Refs | README | LICENSE

commit 1d09a7e9f51e0a3f3034d308521fb1157796e04a
parent e9f47ae7f10d1b05dc56004e442e239fcbecd6a2
Author: z3bra <contactatz3bradotorg>
Date:   Mon Nov 21 13:52:59 +0100

Make sure call is only canceled once

Upon receiving a FINISHED state, the client should consider the call
over, and free its local variable. It should NOT try to send a CANCEL
signal, as it could try to cancel the call twice, resulting in a double
free() that can crash the core.

Diffstat:
ratox.c | 39++++++++++++++++++++++-----------------
1 file changed, 22 insertions(+), 17 deletions(-)
diff --git a/ratox.c b/ratox.c @@ -383,6 +383,7 @@ cbcallstate(ToxAV *av, uint32_t fnum, uint32_t state, void *udata) if ((state & TOXAV_FRIEND_CALL_STATE_ERROR) || (state & TOXAV_FRIEND_CALL_STATE_FINISHED)) { + f->av.state &= ~TRANSMITTING; cancelcall(f, "Finished"); return; } @@ -391,12 +392,23 @@ cbcallstate(ToxAV *av, uint32_t fnum, uint32_t state, void *udata) * As long as we receive a state callback, it means the peer * accepted the call */ - f->av.state |= TRANSMITTING; + if (f->av.state & RINGING) { + f->av.n = 0; + f->av.lastsent.tv_sec = 0; + f->av.lastsent.tv_nsec = 0; + + f->av.frame = malloc(sizeof(int16_t) * framesize); + if (!f->av.frame) + eprintf("malloc:"); + + f->av.state &= ~RINGING; + f->av.state |= TRANSMITTING; + } /* let us start sending audio */ if (state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A) { f->av.state |= OUTGOING; - logmsg(": %s : Audio > Started/Resumed\n", f->name); + logmsg(": %s : Audio > Started\n", f->name); } } @@ -477,6 +489,9 @@ sendfriendcalldata(struct friend *f) ssize_t n; TOXAV_ERR_SEND_FRAME err; + if (!f->av.state) + return; + n = fiforead(f->dirfd, &f->fd[FCALL_IN], ffiles[FCALL_IN], f->av.frame + (f->av.state & INCOMPLETE) * f->av.n, framesize * sizeof(int16_t) - (f->av.state & INCOMPLETE) * f->av.n); @@ -494,10 +509,6 @@ sendfriendcalldata(struct friend *f) return; } - /* discard data if friend doesn't accept audio */ - if (!(f->av.state & OUTGOING)) - return; - clock_gettime(CLOCK_MONOTONIC, &now); diff = timediff(f->av.lastsent, now); if (diff.tv_sec == 0 && diff.tv_nsec < (AUDIOFRAME - 1) * 1E6) { @@ -1672,10 +1683,10 @@ loop(void) } if (f->av.state & TRANSMITTING) { - if ((f->av.state & INCOMING) || (f->av.state & OUTGOING)) - continue; - cancelcall(f, "Hanged up"); - } else { + if (!(f->av.state & INCOMING) && !(f->av.state & OUTGOING)) + cancelcall(f, "Hanged up"); + } + if (f->av.state & RINGING) { if (!(f->av.state & INCOMING)) continue; if (!toxav_answer(toxav, f->num, AUDIOBITRATE, 0, NULL)) { @@ -1759,13 +1770,7 @@ loop(void) fiforeset(f->dirfd, &f->fd[FCALL_IN], ffiles[FCALL_IN]); break; } - f->av.n = 0; - f->av.lastsent.tv_sec = 0; - f->av.lastsent.tv_nsec = 0; - f->av.state |= OUTGOING; - f->av.frame = malloc(sizeof(int16_t) * framesize); - if (!f->av.frame) - eprintf("malloc:"); + f->av.state |= RINGING; logmsg(": %s : Audio : Tx > Inviting\n", f->name); } else { if (f->av.state & OUTGOING)