Version 0.1.4 from FTP
authorMark Spencer <markster@digium.com>
Tue, 25 Jul 2000 20:04:15 +0000 (20:04 +0000)
committerMark Spencer <markster@digium.com>
Tue, 25 Jul 2000 20:04:15 +0000 (20:04 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@215 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_iax.c
codecs/codec_g723_1.c
codecs/codec_gsm.c

index 80e1905..272228e 100755 (executable)
@@ -452,8 +452,9 @@ static int do_deliver(void *data)
                                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);
@@ -899,14 +900,15 @@ static int iax_call(struct ast_channel *c, char *dest, int timeout)
        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, "@");
@@ -920,10 +922,17 @@ static int iax_call(struct ast_channel *c, char *dest, int timeout)
        } 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);
@@ -942,7 +951,7 @@ static int iax_call(struct ast_channel *c, char *dest, int timeout)
                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;
@@ -1321,6 +1330,27 @@ static int apply_ha(struct iax_ha *ha, struct sockaddr_in *sin)
        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 */
@@ -1688,15 +1718,38 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
                                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 */
index b71e28c..72dcd90 100755 (executable)
@@ -173,16 +173,14 @@ static struct ast_frame *g723tolin_frameout(struct ast_translator_pvt *pvt)
        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; 
 }
@@ -200,7 +198,7 @@ static int g723tolin_framein(struct ast_translator_pvt *pvt, struct ast_frame *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
index 1693712..9d43f39 100755 (executable)
@@ -156,7 +156,7 @@ static int lintogsm_framein(struct ast_translator_pvt *tmp, struct ast_frame *f)
        /* 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 {
@@ -187,16 +187,14 @@ static struct ast_frame *lintogsm_frameout(struct ast_translator_pvt *tmp)
        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; 
 }