Index: rtp.c =================================================================== --- rtp.c (revision 8275) +++ rtp.c (working copy) @@ -1105,6 +1105,30 @@ return (unsigned int) ms; } +struct rtp_enddigit_struct { + int s; + int attempt; + struct sockaddr_in them; + unsigned int rtpheader[64]; +}; + +static int rtp_enddigit(void *data) { + struct rtp_enddigit_struct *red = data; + int res; + + res = sendto(red->s, (void *) red->rtpheader, 16, 0, (struct sockaddr *) &red->them, sizeof(red->them)); + res |= sendto(red->s, (void *) red->rtpheader, 16, 0, (struct sockaddr *) &red->them, sizeof(red->them)); + res |= sendto(red->s, (void *) red->rtpheader, 16, 0, (struct sockaddr *) &red->them, sizeof(red->them)); + + /* Cancel sending after 10 retries */ + if (res && (red->attempt++ > 10)) + res = 0; + + if (!res) + free(red); + return res; +} + int ast_rtp_senddigit(struct ast_rtp *rtp, char digit) { unsigned int *rtpheader; @@ -1114,6 +1138,7 @@ int payload; char data[256]; char iabuf[INET_ADDRSTRLEN]; + struct rtp_enddigit_struct *red; if ((digit <= '9') && (digit >= '0')) digit -= '0'; @@ -1143,7 +1168,8 @@ rtpheader[1] = htonl(rtp->lastdigitts); rtpheader[2] = htonl(rtp->ssrc); rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0)); - for (x = 0; x < 6; x++) { + + for (x = 0; x < 3; x++) { if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) { res = sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them)); if (res < 0) @@ -1156,24 +1182,23 @@ ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastdigitts, res - hdrlen); } /* Sequence number of last two end packets does not get incremented */ - if (x < 3) - rtp->seqno++; + rtp->seqno++; /* Clear marker bit and set seqno */ rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno)); - /* For the last three packets, set the duration and the end bit */ - if (x == 2) { -#if 0 - /* No, this is wrong... Do not increment lastdigitts, that's not according - to the RFC, as best we can determine */ - rtp->lastdigitts++; /* or else the SPA3000 will click instead of beeping... */ - rtpheader[1] = htonl(rtp->lastdigitts); -#endif - /* Make duration 800 (100ms) */ - rtpheader[3] |= htonl((800)); - /* Set the End bit */ - rtpheader[3] |= htonl((1 << 23)); - } } + /* Make duration 800 (100ms) */ + rtpheader[3] |= htonl((800)); + /* Set the End bit */ + rtpheader[3] |= htonl((1 << 23)); + + red = calloc(1, sizeof(*red)); + if (red) { + red->s = rtp->s; + memcpy(&red->them, &rtp->them, sizeof(red->them)); + memcpy(red->rtpheader, data, sizeof(data)); + ast_sched_add(rtp->sched, 50, rtp_enddigit, red); + } + /* Increment the digit timestamp by 120ms, to ensure that digits sent sequentially with no intervening non-digit packets do not get sent with the same timestamp, and that sequential digits