Mon Mar 12 2012 21:25:21

Asterisk developer's documentation


app_test.c File Reference

Applications to test connection and produce report in text file. More...

#include "asterisk.h"
#include <sys/stat.h>
#include "asterisk/paths.h"
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
Include dependency graph for app_test.c:

Go to the source code of this file.

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int load_module (void)
static int measurenoise (struct ast_channel *chan, int ms, char *who)
static int sendnoise (struct ast_channel *chan, int ms)
static int testclient_exec (struct ast_channel *chan, const char *data)
static int testserver_exec (struct ast_channel *chan, const char *data)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Interface Test Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static struct ast_module_infoast_module_info = &__mod_info
static char * testc_app = "TestClient"
static char * tests_app = "TestServer"

Detailed Description

Applications to test connection and produce report in text file.

Author:
Mark Spencer <markster@digium.com>
Russell Bryant <russelb@clemson.edu>

Definition in file app_test.c.


Function Documentation

static void __reg_module ( void  ) [static]

Definition at line 495 of file app_test.c.

static void __unreg_module ( void  ) [static]

Definition at line 495 of file app_test.c.

static int load_module ( void  ) [static]
static int measurenoise ( struct ast_channel chan,
int  ms,
char *  who 
) [static]

Definition at line 84 of file app_test.c.

References ast_debug, AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_set_read_format(), ast_tvdiff_ms(), ast_tvnow(), ast_waitfor(), ast_frame_subclass::codec, ast_frame::data, f, ast_frame::frametype, LOG_NOTICE, ast_frame::ptr, ast_channel::readformat, ast_frame::samples, and ast_frame::subclass.

Referenced by testclient_exec(), and testserver_exec().

{
   int res=0;
   int mssofar;
   int noise=0;
   int samples=0;
   int x;
   short *foo;
   struct timeval start;
   struct ast_frame *f;
   int rformat;
   rformat = chan->readformat;
   if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
      ast_log(LOG_NOTICE, "Unable to set to linear mode!\n");
      return -1;
   }
   start = ast_tvnow();
   for(;;) {
      mssofar = ast_tvdiff_ms(ast_tvnow(), start);
      if (mssofar > ms)
         break;
      res = ast_waitfor(chan, ms - mssofar);
      if (res < 1)
         break;
      f = ast_read(chan);
      if (!f) {
         res = -1;
         break;
      }
      if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.codec == AST_FORMAT_SLINEAR)) {
         foo = (short *)f->data.ptr;
         for (x=0;x<f->samples;x++) {
            noise += abs(foo[x]);
            samples++;
         }
      }
      ast_frfree(f);
   }

   if (rformat) {
      if (ast_set_read_format(chan, rformat)) {
         ast_log(LOG_NOTICE, "Unable to restore original format!\n");
         return -1;
      }
   }
   if (res < 0)
      return res;
   if (!samples) {
      ast_log(LOG_NOTICE, "No samples were received from the other side!\n");
      return -1;
   }
   ast_debug(1, "%s: Noise: %d, samples: %d, avg: %d\n", who, noise, samples, noise / samples);
   return (noise / samples);
}
static int sendnoise ( struct ast_channel chan,
int  ms 
) [static]

Definition at line 139 of file app_test.c.

References ast_tonepair_start(), ast_tonepair_stop(), and ast_waitfordigit().

Referenced by testclient_exec(), and testserver_exec().

{
   int res;
   res = ast_tonepair_start(chan, 1537, 2195, ms, 8192);
   if (!res) {
      res = ast_waitfordigit(chan, ms);
      ast_tonepair_stop(chan);
   }
   return res;
}
static int testclient_exec ( struct ast_channel chan,
const char *  data 
) [static]

Definition at line 150 of file app_test.c.

References ast_channel::_state, ast_answer(), ast_app_getdata(), ast_config_AST_LOG_DIR, ast_debug, ast_dtmf_stream(), ast_log(), ast_mkdir(), ast_safe_sleep(), AST_STATE_UP, ast_strlen_zero(), ast_waitfordigit(), ast_frame::data, f, LOG_NOTICE, LOG_WARNING, measurenoise(), ast_channel::name, and sendnoise().

Referenced by load_module().

{
   int res = 0;
   const char *testid=data;
   char fn[80];
   char serverver[80];
   FILE *f;

   /* Check for test id */
   if (ast_strlen_zero(testid)) {
      ast_log(LOG_WARNING, "TestClient requires an argument - the test id\n");
      return -1;
   }

   if (chan->_state != AST_STATE_UP)
      res = ast_answer(chan);

   /* Wait a few just to be sure things get started */
   res = ast_safe_sleep(chan, 3000);
   /* Transmit client version */
   if (!res)
      res = ast_dtmf_stream(chan, NULL, "8378*1#", 0, 0);
   ast_debug(1, "Transmit client version\n");

   /* Read server version */
   ast_debug(1, "Read server version\n");
   if (!res)
      res = ast_app_getdata(chan, NULL, serverver, sizeof(serverver) - 1, 0);
   if (res > 0)
      res = 0;
   ast_debug(1, "server version: %s\n", serverver);

   if (res > 0)
      res = 0;

   if (!res)
      res = ast_safe_sleep(chan, 1000);
   /* Send test id */
   if (!res)
      res = ast_dtmf_stream(chan, NULL, testid, 0, 0);
   if (!res)
      res = ast_dtmf_stream(chan, NULL, "#", 0, 0);
   ast_debug(1, "send test identifier: %s\n", testid);

   if ((res >=0) && (!ast_strlen_zero(testid))) {
      /* Make the directory to hold the test results in case it's not there */
      snprintf(fn, sizeof(fn), "%s/testresults", ast_config_AST_LOG_DIR);
      ast_mkdir(fn, 0777);
      snprintf(fn, sizeof(fn), "%s/testresults/%s-client.txt", ast_config_AST_LOG_DIR, testid);
      if ((f = fopen(fn, "w+"))) {
         setlinebuf(f);
         fprintf(f, "CLIENTCHAN:    %s\n", chan->name);
         fprintf(f, "CLIENTTEST ID: %s\n", testid);
         fprintf(f, "ANSWER:        PASS\n");
         res = 0;

         if (!res) {
            /* Step 1: Wait for "1" */
            ast_debug(1, "TestClient: 2.  Wait DTMF 1\n");
            res = ast_waitfordigit(chan, 3000);
            fprintf(f, "WAIT DTMF 1:   %s\n", (res != '1') ? "FAIL" : "PASS");
            if (res == '1')
               res = 0;
            else
               res = -1;
         }
         if (!res) {
            res = ast_safe_sleep(chan, 1000);
         }
         if (!res) {
            /* Step 2: Send "2" */
            ast_debug(1, "TestClient: 2.  Send DTMF 2\n");
            res = ast_dtmf_stream(chan, NULL, "2", 0, 0);
            fprintf(f, "SEND DTMF 2:   %s\n", (res < 0) ? "FAIL" : "PASS");
            if (res > 0)
               res = 0;
         }
         if (!res) {
            /* Step 3: Wait one second */
            ast_debug(1, "TestClient: 3.  Wait one second\n");
            res = ast_safe_sleep(chan, 1000);
            fprintf(f, "WAIT 1 SEC:    %s\n", (res < 0) ? "FAIL" : "PASS");
            if (res > 0)
               res = 0;
         }
         if (!res) {
            /* Step 4: Measure noise */
            ast_debug(1, "TestClient: 4.  Measure noise\n");
            res = measurenoise(chan, 5000, "TestClient");
            fprintf(f, "MEASURENOISE:  %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
            if (res > 0)
               res = 0;
         }
         if (!res) {
            /* Step 5: Wait for "4" */
            ast_debug(1, "TestClient: 5.  Wait DTMF 4\n");
            res = ast_waitfordigit(chan, 3000);
            fprintf(f, "WAIT DTMF 4:   %s\n", (res != '4') ? "FAIL" : "PASS");
            if (res == '4')
               res = 0;
            else
               res = -1;
         }
         if (!res) {
            /* Step 6: Transmit tone noise */
            ast_debug(1, "TestClient: 6.  Transmit tone\n");
            res = sendnoise(chan, 6000);
            fprintf(f, "SENDTONE:      %s\n", (res < 0) ? "FAIL" : "PASS");
         }
         if (!res || (res == '5')) {
            /* Step 7: Wait for "5" */
            ast_debug(1, "TestClient: 7.  Wait DTMF 5\n");
            if (!res)
               res = ast_waitfordigit(chan, 3000);
            fprintf(f, "WAIT DTMF 5:   %s\n", (res != '5') ? "FAIL" : "PASS");
            if (res == '5')
               res = 0;
            else
               res = -1;
         }
         if (!res) {
            /* Step 8: Wait one second */
            ast_debug(1, "TestClient: 8.  Wait one second\n");
            res = ast_safe_sleep(chan, 1000);
            fprintf(f, "WAIT 1 SEC:    %s\n", (res < 0) ? "FAIL" : "PASS");
            if (res > 0)
               res = 0;
         }
         if (!res) {
            /* Step 9: Measure noise */
            ast_debug(1, "TestClient: 9.  Measure tone\n");
            res = measurenoise(chan, 4000, "TestClient");
            fprintf(f, "MEASURETONE:   %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
            if (res > 0)
               res = 0;
         }
         if (!res) {
            /* Step 10: Send "7" */
            ast_debug(1, "TestClient: 10.  Send DTMF 7\n");
            res = ast_dtmf_stream(chan, NULL, "7", 0, 0);
            fprintf(f, "SEND DTMF 7:   %s\n", (res < 0) ? "FAIL" : "PASS");
            if (res > 0)
               res =0;
         }
         if (!res) {
            /* Step 11: Wait for "8" */
            ast_debug(1, "TestClient: 11.  Wait DTMF 8\n");
            res = ast_waitfordigit(chan, 3000);
            fprintf(f, "WAIT DTMF 8:   %s\n", (res != '8') ? "FAIL" : "PASS");
            if (res == '8')
               res = 0;
            else
               res = -1;
         }
         if (!res) {
            res = ast_safe_sleep(chan, 1000);
         }
         if (!res) {
            /* Step 12: Hangup! */
            ast_debug(1, "TestClient: 12.  Hangup\n");
         }

         ast_debug(1, "-- TEST COMPLETE--\n");
         fprintf(f, "-- END TEST--\n");
         fclose(f);
         res = -1;
      } else
         res = -1;
   } else {
      ast_log(LOG_NOTICE, "Did not read a test ID on '%s'\n", chan->name);
      res = -1;
   }
   return res;
}
static int testserver_exec ( struct ast_channel chan,
const char *  data 
) [static]

Definition at line 325 of file app_test.c.

References ast_channel::_state, ast_answer(), ast_app_getdata(), ast_config_AST_LOG_DIR, ast_debug, ast_dtmf_stream(), ast_log(), ast_mkdir(), ast_safe_sleep(), AST_STATE_UP, ast_strlen_zero(), ast_waitfordigit(), f, LOG_NOTICE, measurenoise(), ast_channel::name, and sendnoise().

Referenced by load_module().

{
   int res = 0;
   char testid[80]="";
   char fn[80];
   FILE *f;
   if (chan->_state != AST_STATE_UP)
      res = ast_answer(chan);
   /* Read version */
   ast_debug(1, "Read client version\n");
   if (!res)
      res = ast_app_getdata(chan, NULL, testid, sizeof(testid) - 1, 0);
   if (res > 0)
      res = 0;

   ast_debug(1, "client version: %s\n", testid);
   ast_debug(1, "Transmit server version\n");

   res = ast_safe_sleep(chan, 1000);
   if (!res)
      res = ast_dtmf_stream(chan, NULL, "8378*1#", 0, 0);
   if (res > 0)
      res = 0;

   if (!res)
      res = ast_app_getdata(chan, NULL, testid, sizeof(testid) - 1, 0);
   ast_debug(1, "read test identifier: %s\n", testid);
   /* Check for sneakyness */
   if (strchr(testid, '/'))
      res = -1;
   if ((res >=0) && (!ast_strlen_zero(testid))) {
      /* Got a Test ID!  Whoo hoo! */
      /* Make the directory to hold the test results in case it's not there */
      snprintf(fn, sizeof(fn), "%s/testresults", ast_config_AST_LOG_DIR);
      ast_mkdir(fn, 0777);
      snprintf(fn, sizeof(fn), "%s/testresults/%s-server.txt", ast_config_AST_LOG_DIR, testid);
      if ((f = fopen(fn, "w+"))) {
         setlinebuf(f);
         fprintf(f, "SERVERCHAN:    %s\n", chan->name);
         fprintf(f, "SERVERTEST ID: %s\n", testid);
         fprintf(f, "ANSWER:        PASS\n");
         ast_debug(1, "Processing Test ID '%s'\n", testid);
         res = ast_safe_sleep(chan, 1000);
         if (!res) {
            /* Step 1: Send "1" */
            ast_debug(1, "TestServer: 1.  Send DTMF 1\n");
            res = ast_dtmf_stream(chan, NULL, "1", 0,0 );
            fprintf(f, "SEND DTMF 1:   %s\n", (res < 0) ? "FAIL" : "PASS");
            if (res > 0)
               res = 0;
         }
         if (!res) {
            /* Step 2: Wait for "2" */
            ast_debug(1, "TestServer: 2.  Wait DTMF 2\n");
            res = ast_waitfordigit(chan, 3000);
            fprintf(f, "WAIT DTMF 2:   %s\n", (res != '2') ? "FAIL" : "PASS");
            if (res == '2')
               res = 0;
            else
               res = -1;
         }
         if (!res) {
            /* Step 3: Measure noise */
            ast_debug(1, "TestServer: 3.  Measure noise\n");
            res = measurenoise(chan, 6000, "TestServer");
            fprintf(f, "MEASURENOISE:  %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
            if (res > 0)
               res = 0;
         }
         if (!res) {
            /* Step 4: Send "4" */
            ast_debug(1, "TestServer: 4.  Send DTMF 4\n");
            res = ast_dtmf_stream(chan, NULL, "4", 0, 0);
            fprintf(f, "SEND DTMF 4:   %s\n", (res < 0) ? "FAIL" : "PASS");
            if (res > 0)
               res = 0;
         }
         if (!res) {
            /* Step 5: Wait one second */
            ast_debug(1, "TestServer: 5.  Wait one second\n");
            res = ast_safe_sleep(chan, 1000);
            fprintf(f, "WAIT 1 SEC:    %s\n", (res < 0) ? "FAIL" : "PASS");
            if (res > 0)
               res = 0;
         }
         if (!res) {
            /* Step 6: Measure noise */
            ast_debug(1, "TestServer: 6.  Measure tone\n");
            res = measurenoise(chan, 4000, "TestServer");
            fprintf(f, "MEASURETONE:   %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
            if (res > 0)
               res = 0;
         }
         if (!res) {
            /* Step 7: Send "5" */
            ast_debug(1, "TestServer: 7.  Send DTMF 5\n");
            res = ast_dtmf_stream(chan, NULL, "5", 0, 0);
            fprintf(f, "SEND DTMF 5:   %s\n", (res < 0) ? "FAIL" : "PASS");
            if (res > 0)
               res = 0;
         }
         if (!res) {
            /* Step 8: Transmit tone noise */
            ast_debug(1, "TestServer: 8.  Transmit tone\n");
            res = sendnoise(chan, 6000);
            fprintf(f, "SENDTONE:      %s\n", (res < 0) ? "FAIL" : "PASS");
         }

         if (!res || (res == '7')) {
            /* Step 9: Wait for "7" */
            ast_debug(1, "TestServer: 9.  Wait DTMF 7\n");
            if (!res)
               res = ast_waitfordigit(chan, 3000);
            fprintf(f, "WAIT DTMF 7:   %s\n", (res != '7') ? "FAIL" : "PASS");
            if (res == '7')
               res = 0;
            else
               res = -1;
         }
         if (!res) {
            res = ast_safe_sleep(chan, 1000);
         }
         if (!res) {
            /* Step 10: Send "8" */
            ast_debug(1, "TestServer: 10.  Send DTMF 8\n");
            res = ast_dtmf_stream(chan, NULL, "8", 0, 0);
            fprintf(f, "SEND DTMF 8:   %s\n", (res < 0) ? "FAIL" : "PASS");
            if (res > 0)
               res = 0;
         }
         if (!res) {
            /* Step 11: Wait for hangup to arrive! */
            ast_debug(1, "TestServer: 11.  Waiting for hangup\n");
            res = ast_safe_sleep(chan, 10000);
            fprintf(f, "WAIT HANGUP:   %s\n", (res < 0) ? "PASS" : "FAIL");
         }

         ast_log(LOG_NOTICE, "-- TEST COMPLETE--\n");
         fprintf(f, "-- END TEST--\n");
         fclose(f);
         res = -1;
      } else
         res = -1;
   } else {
      ast_log(LOG_NOTICE, "Did not read a test ID on '%s'\n", chan->name);
      res = -1;
   }
   return res;
}
static int unload_module ( void  ) [static]

Definition at line 475 of file app_test.c.

References ast_unregister_application().


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Interface Test Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 495 of file app_test.c.

Definition at line 495 of file app_test.c.

char* testc_app = "TestClient" [static]

Definition at line 82 of file app_test.c.

char* tests_app = "TestServer" [static]

Definition at line 81 of file app_test.c.