Major DISA improvements (bug #2284)
authorMark Spencer <markster@digium.com>
Sat, 28 Aug 2004 17:33:43 +0000 (17:33 +0000)
committerMark Spencer <markster@digium.com>
Sat, 28 Aug 2004 17:33:43 +0000 (17:33 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3670 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_disa.c

index 3022c9e..11c9766 100755 (executable)
@@ -17,6 +17,7 @@
 #include <asterisk/file.h>
 #include <asterisk/logger.h>
 #include <asterisk/channel.h>
+#include <asterisk/indications.h>
 #include <asterisk/pbx.h>
 #include <asterisk/module.h>
 #include <asterisk/translate.h>
@@ -27,9 +28,6 @@
 #include <math.h>
 #include <sys/time.h>
 
-/*
-#define        TONE_BLOCK_SIZE 320
-*/
 
 static char *tdesc = "DISA (Direct Inward System Access) Application";
 
@@ -82,27 +80,9 @@ STANDARD_LOCAL_USER;
 
 LOCAL_USER_DECL;
 
-static float loudness=4096.0;
-
 static int firstdigittimeout = 20000; /* 20 seconds first digit timeout */
 static int digittimeout = 10000; /* 10 seconds subsequent digit timeout */
 
-static void make_tone_block(unsigned char *data, float f1, float f2, int len, int *x)
-{
-int    i;
-float  val;
-
-       for(i = 0; i < len; i++)
-       {
-               val = loudness * sin((f1 * 2.0 * M_PI * (*x))/8000.0);
-               val += loudness * sin((f2 * 2.0 * M_PI * (*x)++)/8000.0);
-               data[i] = AST_LIN2MU((int)val);
-        }              
-         /* wrap back around from 8000 */
-       if (*x >= 8000) *x = 0;
-       return;
-}
-
 static int ms_diff(struct timeval *tv1, struct timeval *tv2)
 {
 int    ms;
@@ -117,14 +97,11 @@ static int disa_exec(struct ast_channel *chan, void *data)
        int i,j,k,x;
        struct localuser *u;
        char tmp[256],arg2[256]="",exten[AST_MAX_EXTENSION],acctcode[20]="";
-       struct {
-               unsigned char offset[AST_FRIENDLY_OFFSET];
-               unsigned char buf[640];
-       } tone_block;
        char *ourcontext,*ourcallerid;
-       struct ast_frame *f,wf;
+       struct ast_frame *f;
        struct timeval lastout, now, lastdigittime;
        int res;
+       time_t rstart;
        FILE *fp;
        char *stringp=NULL;
 
@@ -168,12 +145,18 @@ static int disa_exec(struct ast_channel *chan, void *data)
        exten[0] = 0;
        acctcode[0] = 0;
        /* can we access DISA without password? */ 
+
+       ast_log(LOG_DEBUG, "Context: %s\n",ourcontext);
+
        if (!strcasecmp(tmp, "no-password"))
        {;
                k = 1;
                ast_log(LOG_DEBUG, "DISA no-password login success\n");
        }
        gettimeofday(&lastdigittime,NULL);
+
+       ast_tonepair_start(chan, 350, 440, 0, 0);
+
        for(;;)
        {
                gettimeofday(&now,NULL);
@@ -204,25 +187,7 @@ static int disa_exec(struct ast_channel *chan, void *data)
                        return -1;
                }
                if (f->frametype == AST_FRAME_VOICE) {
-                       if (!i || (ast_ignore_pattern(ourcontext, exten) && k)) {
-                               wf.frametype = AST_FRAME_VOICE;
-                               wf.subclass = AST_FORMAT_ULAW;
-                               wf.offset = AST_FRIENDLY_OFFSET;
-                               wf.mallocd = 0;
-                               wf.data = tone_block.buf;
-                               wf.datalen = f->datalen;
-                               wf.delivery.tv_sec = wf.delivery.tv_usec = 0;
-                               make_tone_block(tone_block.buf, 350, 440, f->datalen, &x);
-                               wf.samples = wf.datalen;
-                               ast_frfree(f);
-                           if (ast_write(chan, &wf)) 
-                               {
-                               ast_log(LOG_WARNING, "DISA Failed to write frame on %s\n",chan->name);
-                                       LOCAL_USER_REMOVE(u);
-                                       return -1;
-                               }
-                       } else
-                               ast_frfree(f);
+                       ast_frfree(f);
                        continue;
                }
                  /* if not DTMF, just do it again */
@@ -234,7 +199,9 @@ static int disa_exec(struct ast_channel *chan, void *data)
 
                j = f->subclass;  /* save digit */
                ast_frfree(f);
-               
+               if (i == 0) 
+                       ast_playtones_stop(chan);
+
                gettimeofday(&lastdigittime,NULL);
                  /* got a DTMF tone */
                if (i < AST_MAX_EXTENSION) /* if still valid number of digits */
@@ -287,7 +254,9 @@ static int disa_exec(struct ast_channel *chan, void *data)
 
                                        }
                                         /* password good, set to dial state */
-                                               ast_log(LOG_WARNING,"DISA on chan %s password is good\n",chan->name);
+                                       ast_log(LOG_DEBUG,"DISA on chan %s password is good\n",chan->name);
+                                       ast_tonepair_start(chan, 350, 440, 0, 0);
+
                                        k = 1;
                                        i = 0;  /* re-set buffer pointer */
                                        exten[sizeof(acctcode)] = 0;
@@ -303,13 +272,15 @@ static int disa_exec(struct ast_channel *chan, void *data)
                          /* if this exists */
 
                          /* if can do some more, do it */
-                       if (!ast_matchmore_extension(chan,ourcontext,exten,1, chan->callerid)) 
+                       if (!ast_matchmore_extension(chan,ourcontext,exten,1, chan->callerid)) {
                                break;
+                       }
                }
        }
 
        if (k && ast_exists_extension(chan,ourcontext,exten,1, chan->callerid))
        {
+               ast_playtones_stop(chan);
                /* We're authenticated and have a valid extension */
                if (ourcallerid && *ourcallerid)
                {
@@ -326,44 +297,20 @@ static int disa_exec(struct ast_channel *chan, void *data)
        }
 
 reorder:
-               
-       /* something is invalid, give em reorder forever */
-       x = 0;
-       k = 0;  /* k = 0 means busy tone, k = 1 means silence) */
-       i = 0;  /* Number of samples we've done */
-       for(;;)
+
+       ast_indicate(chan,AST_CONTROL_CONGESTION);
+       /* something is invalid, give em reorder for several seconds */
+       time(&rstart);
+       while(time(NULL) < rstart + 10)
        {
                if (ast_waitfor(chan, -1) < 0)
                        break;
                f = ast_read(chan);
                if (!f)
                        break;
-               if (f->frametype == AST_FRAME_VOICE) {
-                       wf.frametype = AST_FRAME_VOICE;
-                       wf.subclass = AST_FORMAT_ULAW;
-                       wf.offset = AST_FRIENDLY_OFFSET;
-                       wf.mallocd = 0;
-                       wf.data = tone_block.buf;
-                       wf.datalen = f->datalen;
-                       wf.samples = wf.datalen;
-                       if (k) 
-                               memset(tone_block.buf, 0x7f, wf.datalen);
-                       else
-                               make_tone_block(tone_block.buf,480.0, 620.0,wf.datalen, &x);
-                       i += wf.datalen / 8;
-                       if (i > 250) {
-                               i = 0;
-                               k = !k;
-                       }
-                   if (ast_write(chan, &wf)) 
-                       {
-                       ast_log(LOG_WARNING, "DISA Failed to write frame on %s\n",chan->name);
-                               LOCAL_USER_REMOVE(u);
-                               return -1;
-                       }
-               }
                ast_frfree(f);
        }
+       ast_playtones_stop(chan);
        LOCAL_USER_REMOVE(u);
        return -1;
 }