- better voice frame handling

This commit is contained in:
MelwareDE 2006-06-22 18:17:37 +00:00
parent a7643a747a
commit 28b28e7eeb
2 changed files with 50 additions and 48 deletions

View File

@ -1556,42 +1556,33 @@ static int pbx_capi_write(struct ast_channel *c, struct ast_frame *f)
return -1;
}
cc_mutex_lock(&i->lock);
if ((!(i->isdnstate & CAPI_ISDN_STATE_B3_UP)) || (!i->NCCI) ||
((i->isdnstate & (CAPI_ISDN_STATE_B3_CHANGE | CAPI_ISDN_STATE_LI)))) {
cc_mutex_unlock(&i->lock);
return 0;
}
if ((!(i->ntmode)) && (i->state != CAPI_STATE_CONNECTED)) {
cc_mutex_unlock(&i->lock);
return 0;
}
if (f->frametype == AST_FRAME_NULL) {
cc_mutex_unlock(&i->lock);
return 0;
}
if (f->frametype == AST_FRAME_DTMF) {
cc_log(LOG_ERROR, "dtmf frame should be written\n");
cc_mutex_unlock(&i->lock);
return 0;
}
if (f->frametype != AST_FRAME_VOICE) {
cc_log(LOG_ERROR,"not a voice frame\n");
cc_mutex_unlock(&i->lock);
return 0;
}
if (i->FaxState & CAPI_FAX_STATE_ACTIVE) {
cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: write on fax_receive?\n",
i->vname);
cc_mutex_unlock(&i->lock);
return 0;
}
if ((!f->data) || (!f->datalen)) {
cc_log(LOG_DEBUG, "No data for FRAME_VOICE %s\n", c->name);
cc_mutex_unlock(&i->lock);
return 0;
}
if (i->isdnstate & CAPI_ISDN_STATE_RTP) {
@ -1599,24 +1590,19 @@ static int pbx_capi_write(struct ast_channel *c, struct ast_frame *f)
(f->subclass != capi_capability)) {
cc_log(LOG_ERROR, "don't know how to write subclass %s(%d)\n",
ast_getformatname(f->subclass), f->subclass);
cc_mutex_unlock(&i->lock);
return 0;
}
return capi_write_rtp(c, f);
}
if ((!i->smoother) || (ast_smoother_feed(i->smoother, f) != 0)) {
cc_log(LOG_ERROR, "%s: failed to fill smoother\n", i->vname);
cc_mutex_unlock(&i->lock);
return 0;
}
for (fsmooth = ast_smoother_read(i->smoother);
fsmooth != NULL;
fsmooth = ast_smoother_read(i->smoother)) {
if (i->isdnstate & CAPI_ISDN_STATE_RTP) {
ret = capi_write_rtp(c, fsmooth);
continue;
}
DATA_B3_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
DATA_B3_REQ_NCCI(&CMSG) = i->NCCI;
DATA_B3_REQ_DATALENGTH(&CMSG) = fsmooth->datalen;
@ -1671,12 +1657,13 @@ static int pbx_capi_write(struct ast_channel *c, struct ast_frame *f)
}
if (!error) {
cc_mutex_lock(&i->lock);
i->B3q -= fsmooth->datalen;
if (i->B3q < 0)
i->B3q = 0;
cc_mutex_unlock(&i->lock);
}
}
cc_mutex_unlock(&i->lock);
return ret;
}
@ -3267,6 +3254,7 @@ static void capidev_handle_connect_b3_active_indication(_cmsg *CMSG, unsigned in
i->isdnstate |= CAPI_ISDN_STATE_RTP;
} else {
i->isdnstate &= ~CAPI_ISDN_STATE_RTP;
i->B3q = (CAPI_MAX_B3_BLOCK_SIZE * 3);
}
if ((i->isdnstate & CAPI_ISDN_STATE_B3_CHANGE)) {
@ -4887,6 +4875,7 @@ static int pbxcli_capi_show_channels(int fd, int argc, char *argv[])
struct capi_pvt *i;
char iochar;
char i_state[80];
char b3q[16];
if (argc != 3)
return RESULT_SHOWUSAGE;
@ -4908,8 +4897,13 @@ static int pbxcli_capi_show_channels(int fd, int argc, char *argv[])
else
iochar = 'I';
if (capidebug)
snprintf(b3q, sizeof(b3q), " B3q=%d", i->B3q);
else
b3q[0] = '\0';
ast_cli(fd,
"%-16s %s %s %c %s %-10s 0x%02x '%s'->'%s'\n",
"%-16s %s %s %c %s %-10s 0x%02x '%s'->'%s'%s\n",
i->vname,
i->ntmode ? "yes":"no ",
show_state(i->state),
@ -4918,7 +4912,8 @@ static int pbxcli_capi_show_channels(int fd, int argc, char *argv[])
show_isdnstate(i->isdnstate, i_state),
i->cid_ton,
i->cid,
i->dnid
i->dnid,
b3q
);
}

View File

@ -227,23 +227,18 @@ int capi_write_rtp(struct ast_channel *c, struct ast_frame *f)
{
struct capi_pvt *i = CC_CHANNEL_PVT(c);
_cmsg CMSG;
int rtpheaderlen = RTP_HEADER_SIZE;
struct sockaddr_in us;
int len;
int len, uslen;
unsigned char buf[256];
uslen = sizeof(us);
if (!(i->rtp)) {
cc_log(LOG_ERROR, "rtp struct is NULL\n");
return -1;
}
if (f->datalen > CAPI_MAX_B3_BLOCK_SIZE) {
cc_verbose(4, 0, VERBOSE_PREFIX_4 "%s: rtp write data: frame too big (len = %d).\n",
i->vname, f->datalen);
return 0;
}
ast_rtp_get_us(i->rtp, &us);
us.sin_port = 0; /* don't really send */
ast_rtp_set_peer(i->rtp, &us);
if (ast_rtp_write(i->rtp, f) != 0) {
cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: rtp_write error, dropping packet.\n",
@ -251,29 +246,41 @@ int capi_write_rtp(struct ast_channel *c, struct ast_frame *f)
return 0;
}
if (i->B3q >= CAPI_MAX_B3_BLOCKS) {
cc_log(LOG_WARNING, "%s: B3q is full, dropping packet.\n",
i->vname);
return 0;
while(1) {
len = recvfrom(ast_rtp_fd(i->rtp), buf, sizeof(buf),
0, (struct sockaddr *)&us, &uslen);
if (len <= 0)
break;
if (len > (CAPI_MAX_B3_BLOCK_SIZE + RTP_HEADER_SIZE)) {
cc_verbose(4, 0, VERBOSE_PREFIX_4 "%s: rtp write data: frame too big (len = %d).\n",
i->vname, len);
continue;
}
if (i->B3q >= CAPI_MAX_B3_BLOCKS) {
cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: B3q is full, dropping packet.\n",
i->vname);
continue;
}
cc_mutex_lock(&i->lock);
i->B3q++;
cc_mutex_unlock(&i->lock);
i->send_buffer_handle++;
cc_verbose(6, 1, VERBOSE_PREFIX_4 "%s: RTP write for NCCI=%#x len=%d(%d) %s\n",
i->vname, i->NCCI, len, f->datalen, ast_getformatname(f->subclass));
DATA_B3_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
DATA_B3_REQ_NCCI(&CMSG) = i->NCCI;
DATA_B3_REQ_FLAGS(&CMSG) = 0;
DATA_B3_REQ_DATAHANDLE(&CMSG) = i->send_buffer_handle;
DATA_B3_REQ_DATALENGTH(&CMSG) = len;
DATA_B3_REQ_DATA(&CMSG) = (buf);
_capi_put_cmsg(&CMSG);
}
i->B3q++;
i->send_buffer_handle++;
len = f->datalen + rtpheaderlen;
cc_verbose(6, 1, VERBOSE_PREFIX_4 "%s: RTP write for NCCI=%#x len=%d(%d) %s\n",
i->vname, i->NCCI, len, f->datalen, ast_getformatname(f->subclass));
DATA_B3_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
DATA_B3_REQ_NCCI(&CMSG) = i->NCCI;
DATA_B3_REQ_FLAGS(&CMSG) = 0;
DATA_B3_REQ_DATAHANDLE(&CMSG) = i->send_buffer_handle;
DATA_B3_REQ_DATALENGTH(&CMSG) = len;
DATA_B3_REQ_DATA(&CMSG) = (unsigned char *)(f->data - rtpheaderlen);
_capi_put_cmsg(&CMSG);
return 0;
}