mar feb 18 19:15:15 CET 2003
authorMatteo Brancaleoni <mbrancaleoni@espia.it>
Tue, 18 Feb 2003 18:15:30 +0000 (18:15 +0000)
committerMatteo Brancaleoni <mbrancaleoni@espia.it>
Tue, 18 Feb 2003 18:15:30 +0000 (18:15 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@618 65c4cc65-6c06-0410-ace0-fbb531ad65f3

CHANGES
apps/app_agi.c
apps/app_authenticate.c
channels/chan_sip.c
channels/chan_zap.c
cli.c
contrib/scripts/safe_asterisk
rtp.c
safe_asterisk
sounds.txt
sounds/auth-thankyou.gsm [new file with mode: 0755]

diff --git a/CHANGES b/CHANGES
index ff89f86..3cad385 100755 (executable)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,5 @@
+ -- Choose best priority from codec from allow/disallow
+ -- Reject SIP calls to self
  -- Allow SIP registration to provide an alternative contact
  -- Make HOLD on SIP make use of asterisk MOH
  -- Add supervised transfer (tested with Pingtel only)
index e7bcced..a616e81 100755 (executable)
@@ -958,6 +958,8 @@ static agi_command *find_command(char *cmds[], int exact)
                           then this is not a match */
                        if (!commands[x].cmda[y] && !exact)
                                break;
+                       /* don't segfault if the next part of a command doesn't exist */
+                       if (!commands[x].cmda[y]) return NULL;
                        if (strcasecmp(commands[x].cmda[y], cmds[y]))
                                match = 0;
                }
index 69d2443..589ef06 100755 (executable)
@@ -23,7 +23,7 @@
 #include <string.h>
 #include <errno.h>
 #include <stdlib.h>
-
+#include <stdio.h>
 #include <pthread.h>
 
 
@@ -86,7 +86,6 @@ static int auth_exec(struct ast_channel *chan, void *data)
                res = 0;
                if (password[0] == '/') {
                        /* Compare against a file */
-                       char tmp[80];
                        FILE *f;
                        f = fopen(password, "r");
                        if (f) {
@@ -114,6 +113,9 @@ static int auth_exec(struct ast_channel *chan, void *data)
        if ((retries < 3) && !res) {
                if (strchr(opts, 'a')) 
                        ast_cdr_setaccount(chan, passwd);
+               res = ast_streamfile(chan, "auth-thankyou", chan->language);
+               if (!res)
+                       res = ast_waitstream(chan, "");
        } else {
                if (!res)
                        res = ast_streamfile(chan, "vm-goodbye", chan->language);
index 0f8869d..f579f73 100755 (executable)
@@ -112,6 +112,11 @@ static struct io_context *io;
 #define SIP_MAX_HEADERS                64
 #define SIP_MAX_LINES          64
 
+static struct sip_codec_pref {
+       int codec;
+       struct sip_codec_pref *next;
+} *prefs;
+
 struct sip_request {
   char *rlPart1; /* SIP Method Name or "SIP/2.0" protocol version */
   char *rlPart2; /* The Request URI or Response Status */
@@ -411,6 +416,67 @@ static int auto_congest(void *nothing)
        return 0;
 }
 
+static void sip_prefs_free(void)
+{
+       struct sip_codec_pref *cur, *next;
+       cur = prefs;
+       while(cur) {
+               next = cur->next;
+               free(cur);
+               cur = next;
+       }
+       prefs = NULL;
+}
+
+static void sip_pref_remove(int format)
+{
+       struct sip_codec_pref *cur, *prev;
+       cur = prefs;
+       while(cur) {
+               if (cur->codec == format) {
+                       if (prev)
+                               prev->next = cur->next;
+                       else
+                               prefs = cur->next;
+                       free(cur);
+                       return;
+               }
+               prev = cur;
+               cur = cur->next;
+       }
+}
+
+static int sip_pref_append(int format)
+{
+       struct sip_codec_pref *cur, *tmp;
+       sip_pref_remove(format);
+       tmp = (struct sip_codec_pref *)malloc(sizeof(struct sip_codec_pref));
+       if (!tmp)
+               return -1;
+       memset(tmp, 0, sizeof(struct sip_codec_pref));
+       tmp->codec = format;
+       if (prefs) {
+               cur = prefs;
+               while(cur->next)
+                       cur = cur->next;
+               cur->next = tmp;
+       } else
+               prefs = tmp;
+       return 0;
+}
+
+static int sip_codec_choose(int formats)
+{
+       struct sip_codec_pref *cur;
+       cur = prefs;
+       while(cur) {
+               if (formats & cur->codec)
+                       return cur->codec;
+               cur = cur->next;
+       }
+       return ast_best_codec(formats);
+}
+
 static int sip_call(struct ast_channel *ast, char *dest, int timeout)
 {
        int res;
@@ -813,9 +879,12 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, char *title)
        int fmt;
        tmp = ast_channel_alloc(1);
        if (tmp) {
-               tmp->nativeformats = i->capability;
-               if (!tmp->nativeformats)
-                       tmp->nativeformats = capability;
+               /* Select our native format based on codec preference until we receive
+                  something from another device to the contrary. */
+               if (i->capability)
+                       tmp->nativeformats = sip_codec_choose(i->capability);
+               else 
+                       tmp->nativeformats = sip_codec_choose(capability);
                fmt = ast_best_codec(tmp->nativeformats);
                if (title)
                        snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%04x", title, rand() & 0xffff);
@@ -1255,9 +1324,9 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
                return -1;
        }
        if (p->owner) {
-               if (p->owner->nativeformats & p->capability) {
+               if (!(p->owner->nativeformats & p->capability)) {
                        ast_log(LOG_DEBUG, "Oooh, we need to change our formats since our peer supports only %d and not %d\n", p->capability, p->owner->nativeformats);
-                       p->owner->nativeformats = p->capability;
+                       p->owner->nativeformats = sip_codec_choose(p->capability);
                        ast_set_read_format(p->owner, p->owner->readformat);
                        ast_set_write_format(p->owner, p->owner->writeformat);
                }
@@ -3064,6 +3133,14 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
                else 
                        transmit_response_with_allow(p, "200 OK", req);
        } else if (!strcasecmp(cmd, "INVITE")) {
+               if (p->outgoing && p->owner && (p->owner->_state != AST_STATE_UP)) {
+                       /* This is a call to ourself.  Send ourselves an error code and stop
+                          processing immediately, as SIP really has no good mechanism for
+                          being able to call yourself */
+                       transmit_response(p, "482 Loop Detected", req);
+                       /* We do NOT destroy p here, so that our response will be accepted */
+                       return 0;
+               }
                /* Process the SDP portion */
                if (!ignore) {
                        /* Use this as the basis */
@@ -3726,6 +3803,9 @@ static int reload_config()
                ast_log(LOG_NOTICE, "Unable to load config %s, SIP disabled\n", config);
                return 0;
        }
+       
+       sip_prefs_free();
+       
        memset(&bindaddr, 0, sizeof(bindaddr));
        /* Initialize some reasonable defaults */
        strncpy(context, "default", sizeof(context) - 1);
@@ -3755,14 +3835,18 @@ static int reload_config()
                        format = ast_getformatbyname(v->value);
                        if (format < 1) 
                                ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
-                       else
+                       else {
                                capability |= format;
+                               sip_pref_append(format);
+                       }
                } else if (!strcasecmp(v->name, "disallow")) {
                        format = ast_getformatbyname(v->value);
                        if (format < 1) 
                                ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value);
-                       else
+                       else {
                                capability &= ~format;
+                               sip_pref_remove(format);
+                       }
                } else if (!strcasecmp(v->name, "register")) {
                        sip_register(v->value, v->lineno);
                } else if (!strcasecmp(v->name, "tos")) {
index 9e8c9c0..59e036d 100755 (executable)
@@ -5385,9 +5385,9 @@ static void *pri_dchannel(void *vpri)
                                                /* Re-use *69 field for PRI */
                                                snprintf(pri->pvt[chan]->lastcallerid, sizeof(pri->pvt[chan]->lastcallerid), "\"%s\" <%s>", e->facname.callingname, e->facname.callingnum);
                                                pri->pvt[chan]->subs[SUB_REAL].needcallerid =1;
+                                               zt_enable_ec(pri->pvt[chan]);
                                        }
                                }
-                               zt_enable_ec(pri->pvt[chan]);
                                break;                          
                        case PRI_EVENT_ANSWER:
                                chan = e->answer.channel;
diff --git a/cli.c b/cli.c
index d7ebcc7..ef1810d 100755 (executable)
--- a/cli.c
+++ b/cli.c
@@ -801,7 +801,7 @@ static char *__ast_cli_generator(char *text, char *word, int state, int lock)
                                matchnum++;
                                if (matchnum > state) {
                                        /* Now, what we're supposed to return is the next word... */
-                                       if (strlen(word)) {
+                                       if (strlen(word) && x>0) {
                                                res = e->cmda[x-1];
                                        } else {
                                                res = e->cmda[x];
index ad4ba12..9180e83 100755 (executable)
@@ -1,17 +1,30 @@
 #!/bin/sh
 TTY=9                  # TTY (if you want one) for Asterisk to run on
 CONSOLE=yes            # Whether or not you want a console
-NOTIFY=                        # Who to notify about crashes
+#NOTIFY=ben@alkaloid.net       # Who to notify about crashes
+DUMPDROP=/tmp
 #
 # Don't fork when running "safely"
 #
 ASTARGS=""
 if [ "$TTY" != "" ]; then
+       if [ -c /dev/tty${TTY} ]; then
+               TTY=tty${TTY}
+       elif [ -c /dev/vc/${TTY} ]; then
+               TTY=vc/${TTY}
+       else
+               echo "Cannot find your TTY (${TTY})" >&2
+               exit 1
+       fi
        ASTARGS="${ASTARGS} -vvv"
        if [ "$CONSOLE" != "no" ]; then
                ASTARGS="${ASTARGS} -c"
        fi
 fi
+if [ ! -w ${DUMPDROP} ]; then  
+       echo "Cannot write to ${DUMPDROP}" >&2
+       exit 1
+fi
 
 #
 # Let Asterisk dump core
@@ -27,13 +40,15 @@ run_asterisk()
        while :; do 
 
                if [ "$TTY" != "" ]; then
-                       stty sane < /dev/tty${TTY}
-                       asterisk ${ASTARGS} >& /dev/tty${TTY} < /dev/tty${TTY}
+                       cd /tmp
+                       stty sane < /dev/${TTY}
+                       asterisk ${ASTARGS} >& /dev/${TTY} < /dev/${TTY}
                else
+                       cd /tmp
                        asterisk ${ASTARGS}
                fi
                EXITSTATUS=$?
-               #echo "Asterisk ended with exit status $EXITSTATUS"
+               echo "Asterisk ended with exit status $EXITSTATUS"
                if [ "$EXITSTATUS" = "0" ]; then
                        # Properly shutdown....
                        echo "Asterisk shutdown normally."
@@ -45,8 +60,14 @@ run_asterisk()
                                echo "Asterisk exited on signal $EXITSIGNAL.  Might want to take a peek." | \
                                mail -s "Asterisk Died" $NOTIFY
                        fi
+                        if [ -f /tmp/core ]; then
+                               mv /tmp/core ${DUMPDROP}/core.`hostname`-`date -Iseconds` &
+                       fi
                else
                        echo "Asterisk died with code $EXITSTATUS.  Aborting."
+                        if [ -f /tmp/core ]; then
+                               mv /tmp/core ${DUMPDROP}/core.`hostname`-`date -Iseconds` &
+                       fi
                        exit 0
                fi
                echo "Automatically restarting Asterisk."
diff --git a/rtp.c b/rtp.c
index ca5d7a1..a93823c 100755 (executable)
--- a/rtp.c
+++ b/rtp.c
@@ -116,7 +116,7 @@ void ast_rtp_set_callback(struct ast_rtp *rtp, ast_rtp_callback callback)
 
 static struct ast_frame *send_dtmf(struct ast_rtp *rtp)
 {
-       printf("Sending dtmf: %d (%c)\n", rtp->resp, rtp->resp);
+       ast_log(LOG_DEBUG, "Sending dtmf: %d (%c)\n", rtp->resp, rtp->resp);
        rtp->f.frametype = AST_FRAME_DTMF;
        rtp->f.subclass = rtp->resp;
        rtp->f.datalen = 0;
@@ -325,7 +325,7 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
 
        /* Send any pending DTMF */
        if (rtp->resp && !rtp->dtmfcount) {
-               printf("Sending pending DTMF\n");
+               ast_log(LOG_DEBUG, "Sending pending DTMF\n");
                return send_dtmf(rtp);
        }
        rtp->f.mallocd = 0;
@@ -581,7 +581,7 @@ static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec
                pred = rtp->lastts + f->datalen * 8;
                break;
        case AST_FORMAT_GSM:
-               pred = rtp->lastts + f->datalen * 20 / 33;
+               pred = rtp->lastts + (f->datalen * 160 / 33);
                break;
        case AST_FORMAT_G723_1:
                pred = rtp->lastts + g723_samples(f->data, f->datalen);
@@ -596,7 +596,7 @@ static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec
        /* If it's close to ou prediction, go for it */
        if (abs(rtp->lastts - pred) < 640)
                rtp->lastts = pred;
-#if 0
+#if 1
        else
                printf("Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);
 #endif                 
index ad4ba12..9180e83 100755 (executable)
@@ -1,17 +1,30 @@
 #!/bin/sh
 TTY=9                  # TTY (if you want one) for Asterisk to run on
 CONSOLE=yes            # Whether or not you want a console
-NOTIFY=                        # Who to notify about crashes
+#NOTIFY=ben@alkaloid.net       # Who to notify about crashes
+DUMPDROP=/tmp
 #
 # Don't fork when running "safely"
 #
 ASTARGS=""
 if [ "$TTY" != "" ]; then
+       if [ -c /dev/tty${TTY} ]; then
+               TTY=tty${TTY}
+       elif [ -c /dev/vc/${TTY} ]; then
+               TTY=vc/${TTY}
+       else
+               echo "Cannot find your TTY (${TTY})" >&2
+               exit 1
+       fi
        ASTARGS="${ASTARGS} -vvv"
        if [ "$CONSOLE" != "no" ]; then
                ASTARGS="${ASTARGS} -c"
        fi
 fi
+if [ ! -w ${DUMPDROP} ]; then  
+       echo "Cannot write to ${DUMPDROP}" >&2
+       exit 1
+fi
 
 #
 # Let Asterisk dump core
@@ -27,13 +40,15 @@ run_asterisk()
        while :; do 
 
                if [ "$TTY" != "" ]; then
-                       stty sane < /dev/tty${TTY}
-                       asterisk ${ASTARGS} >& /dev/tty${TTY} < /dev/tty${TTY}
+                       cd /tmp
+                       stty sane < /dev/${TTY}
+                       asterisk ${ASTARGS} >& /dev/${TTY} < /dev/${TTY}
                else
+                       cd /tmp
                        asterisk ${ASTARGS}
                fi
                EXITSTATUS=$?
-               #echo "Asterisk ended with exit status $EXITSTATUS"
+               echo "Asterisk ended with exit status $EXITSTATUS"
                if [ "$EXITSTATUS" = "0" ]; then
                        # Properly shutdown....
                        echo "Asterisk shutdown normally."
@@ -45,8 +60,14 @@ run_asterisk()
                                echo "Asterisk exited on signal $EXITSIGNAL.  Might want to take a peek." | \
                                mail -s "Asterisk Died" $NOTIFY
                        fi
+                        if [ -f /tmp/core ]; then
+                               mv /tmp/core ${DUMPDROP}/core.`hostname`-`date -Iseconds` &
+                       fi
                else
                        echo "Asterisk died with code $EXITSTATUS.  Aborting."
+                        if [ -f /tmp/core ]; then
+                               mv /tmp/core ${DUMPDROP}/core.`hostname`-`date -Iseconds` &
+                       fi
                        exit 0
                fi
                echo "Automatically restarting Asterisk."
index 33f57be..bddb29d 100755 (executable)
@@ -16,6 +16,8 @@
 
 %auth-incorrect.gsm%Login incorrect.  Please enter your password followed by the pound key.
 
+%auth-thankyou.gsm%Thank you.
+
 %beep.gsm%(this is a simple beep tone)
 
 %conf-getconfno.gsm%Please enter your conference number followed by the pound key.
diff --git a/sounds/auth-thankyou.gsm b/sounds/auth-thankyou.gsm
new file mode 100755 (executable)
index 0000000..45e7104
Binary files /dev/null and b/sounds/auth-thankyou.gsm differ