ts = calc_timestamp(iaxs[fr->callno], 0);
iaxs[fr->callno]->lag = ts - fr->ts;
}
- } else
+ } else {
ast_fr_fdwrite(iaxs[fr->callno]->pipe[1], fr->f);
+ }
}
/* Free the packet */
ast_frfree(fr->f);
char *hname;
char requeststr[256] = "";
char myrdest [5] = "s";
+ char *portno = NULL;
if ((c->state != AST_STATE_DOWN) && (c->state != AST_STATE_RESERVED)) {
ast_log(LOG_WARNING, "Line is already in use (%s)?\n", c->name);
return -1;
}
strncpy(host, dest, sizeof(host));
- strtok(host, ":");
+ strtok(host, "/");
/* If no destination extension specified, use 's' */
- rdest = strtok(NULL, ":");
+ rdest = strtok(NULL, "/");
if (!rdest)
rdest = myrdest;
strtok(rdest, "@");
} else {
hname = host;
}
+ if (strtok(hname, ":")) {
+ strtok(hname, ":");
+ portno = strtok(hname, ":");
+ }
if (create_addr(&sin, hname)) {
ast_log(LOG_WARNING, "No address associated with '%s'\n", hname);
return -1;
}
+ if (portno) {
+ sin.sin_port = htons(atoi(portno));
+ }
/* Now we build our request string */
#define MYSNPRINTF snprintf(requeststr + strlen(requeststr), sizeof(requeststr) - strlen(requeststr),
MYSNPRINTF "exten=%s;", rdest);
requeststr[strlen(requeststr) - 1] = '\0';
/* Transmit the string in a "NEW" request */
if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Calling using options '%s'\n", requeststr);
+ ast_verbose(VERBOSE_PREFIX_3 "Calling using options '%s'\n", requeststr);
send_command((struct chan_iax_pvt *)c->pvt->pvt, AST_FRAME_IAX,
AST_IAX_COMMAND_NEW, 0, requeststr, strlen(requeststr) + 1, -1);
c->state = AST_STATE_RINGING;
return res;
}
+static int iax_getformats(int callno, char *orequest)
+{
+ char *var, *value;
+ char request[256];
+ strncpy(request, orequest, sizeof(request));
+ var = strtok(request, ";");
+ while(var) {
+ value = strchr(var, '=');
+ if (value) {
+ *value='\0';
+ value++;
+ if (!strcmp(var, "formats")) {
+ iaxs[callno]->peerformats = atoi(value);
+ } else
+ ast_log(LOG_WARNING, "Unknown variable '%s' with value '%s'\n", var, value);
+ }
+ var = strtok(NULL, ";");
+ }
+ return 0;
+}
+
static int check_access(int callno, struct sockaddr_in *sin, char *orequest, int requestl)
{
/* Start pessimistic */
iax_destroy(fr.callno);
break;
case AST_IAX_COMMAND_REJECT:
- ((char *)f.data)[f.datalen] = '\0';
+ if (f.data)
+ ((char *)f.data)[f.datalen] = '\0';
ast_log(LOG_WARNING, "Call rejected by %s: %s\n", inet_ntoa(iaxs[fr.callno]->addr.sin_addr), f.data);
iaxs[fr.callno]->error = EPERM;
iax_destroy(fr.callno);
break;
case AST_IAX_COMMAND_ACCEPT:
+ if (f.data) {
+ ((char *)f.data)[f.datalen]='\0';
+ iax_getformats(fr.callno, (char *)f.data);
+ } else {
+ iaxs[fr.callno]->peerformats = iax_capability;
+ }
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s\n", inet_ntoa(iaxs[fr.callno]->addr.sin_addr));
iaxs[fr.callno]->state |= IAX_STATE_STARTED;
+ if (iaxs[fr.callno]->owner) {
+ /* Switch us to use a compatible format */
+ iaxs[fr.callno]->owner->format &= iaxs[fr.callno]->peerformats;
+
+ if (!iaxs[fr.callno]->owner->format)
+ iaxs[fr.callno]->owner->format = iaxs[fr.callno]->peerformats & iax_capability;
+ if (!iaxs[fr.callno]->owner->format) {
+ ast_log(LOG_WARNING, "Unable to negotiate a common format with the peer.");
+ iaxs[fr.callno]->error = EBADE;
+ iax_destroy(fr.callno);
+ } else {
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "Format for call is %d\n", iaxs[fr.callno]->owner->format);
+ }
+
+ }
break;
case AST_IAX_COMMAND_PING:
/* Send back a pong packet with the original timestamp */
tmp->tail = 0;
#if 0
- /* Save a sample frame */
- { static int samplefr = 0;
- if (samplefr == 80) {
- int fd;
- fd = open("g723.example", O_WRONLY | O_CREAT | O_TRUNC, 0644);
- write(fd, tmp->f.data, tmp->f.datalen);
- close(fd);
+ /* Save the frames */
+ {
+ static int fd2 = -1;
+ if (fd2 == -1) {
+ fd2 = open("g723.example", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ }
+ write(fd2, tmp->f.data, tmp->f.datalen);
}
- samplefr++;
- }
#endif
return &tmp->f;
}
#ifdef ANNEX_B
Decod(&tmp->dec, tmpdata, f->data, 0);
for (x=0;x<Frame;x++)
- (tmp->buf + tmp->tail)[x] = (short)tmpdata[x];
+ (tmp->buf + tmp->tail)[x] = (short)(tmpdata[x]);
#else
Decod(&tmp->dec, tmp->buf + tmp->tail, f->data, 0);
#endif
/* XXX We should look at how old the rest of our stream is, and if it
is too old, then we should overwrite it entirely, otherwise we can
get artifacts of earlier talk that do not belong */
- if (tmp->tail + f->datalen < sizeof(tmp->buf) / 2) {
+ if (tmp->tail + f->datalen/2 < sizeof(tmp->buf) / 2) {
memcpy((tmp->buf + tmp->tail), f->data, f->datalen);
tmp->tail += f->datalen/2;
} else {
if (tmp->tail)
memmove(tmp->buf, tmp->buf + 160, tmp->tail * 2);
#if 0
- /* Save a sample frame */
- { static int samplefr = 0;
- if (samplefr == 0) {
- int fd;
- fd = open("gsm.example", O_WRONLY | O_CREAT, 0644);
- write(fd, tmp->f.data, tmp->f.datalen);
- close(fd);
+ /* Save the frames */
+ {
+ static int fd2 = -1;
+ if (fd2 == -1) {
+ fd2 = open("gsm.example", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ }
+ write(fd2, tmp->f.data, tmp->f.datalen);
}
- samplefr++;
- }
#endif
return &tmp->f;
}