00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "asterisk.h"
00033
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 209841 $")
00035
00036 #include "asterisk/module.h"
00037 #include "asterisk/channel.h"
00038 #include "asterisk/pbx.h"
00039 #include "asterisk/indications.h"
00040
00041 static char *app = "Milliwatt";
00042
00043 static char *synopsis = "Generate a Constant 1004Hz tone at 0dbm (mu-law)";
00044
00045 static char *descrip =
00046 " Milliwatt([options]): Generate a Constant 1004Hz tone at 0dbm.\n"
00047 "Previous versions of this application generated the tone at 1000Hz. If for\n"
00048 "some reason you would prefer that behavior, supply the 'o' option to get the\n"
00049 "old behavior.\n"
00050 "";
00051
00052 static char digital_milliwatt[] = {0x1e,0x0b,0x0b,0x1e,0x9e,0x8b,0x8b,0x9e} ;
00053
00054 static void *milliwatt_alloc(struct ast_channel *chan, void *params)
00055 {
00056 return ast_calloc(1, sizeof(int));
00057 }
00058
00059 static void milliwatt_release(struct ast_channel *chan, void *data)
00060 {
00061 ast_free(data);
00062 return;
00063 }
00064
00065 static int milliwatt_generate(struct ast_channel *chan, void *data, int len, int samples)
00066 {
00067 unsigned char buf[AST_FRIENDLY_OFFSET + 640];
00068 const int maxsamples = ARRAY_LEN(buf);
00069 int i, *indexp = (int *) data;
00070 struct ast_frame wf = {
00071 .frametype = AST_FRAME_VOICE,
00072 .subclass = AST_FORMAT_ULAW,
00073 .offset = AST_FRIENDLY_OFFSET,
00074 .src = __FUNCTION__,
00075 };
00076 wf.data.ptr = buf + AST_FRIENDLY_OFFSET;
00077
00078
00079
00080
00081
00082
00083 if (samples > maxsamples) {
00084 ast_log(LOG_WARNING, "Only doing %d samples (%d requested)\n", maxsamples, samples);
00085 samples = maxsamples;
00086 }
00087
00088 len = samples * sizeof (buf[0]);
00089 wf.datalen = len;
00090 wf.samples = samples;
00091
00092
00093 for (i = 0; i < len; i++) {
00094 buf[AST_FRIENDLY_OFFSET + i] = digital_milliwatt[(*indexp)++];
00095 *indexp &= 7;
00096 }
00097
00098 if (ast_write(chan,&wf) < 0) {
00099 ast_log(LOG_WARNING,"Failed to write frame to '%s': %s\n",chan->name,strerror(errno));
00100 return -1;
00101 }
00102
00103 return 0;
00104 }
00105
00106 static struct ast_generator milliwattgen = {
00107 alloc: milliwatt_alloc,
00108 release: milliwatt_release,
00109 generate: milliwatt_generate,
00110 };
00111
00112 static int old_milliwatt_exec(struct ast_channel *chan)
00113 {
00114 ast_set_write_format(chan, AST_FORMAT_ULAW);
00115 ast_set_read_format(chan, AST_FORMAT_ULAW);
00116
00117 if (chan->_state != AST_STATE_UP) {
00118 ast_answer(chan);
00119 }
00120
00121 if (ast_activate_generator(chan,&milliwattgen,"milliwatt") < 0) {
00122 ast_log(LOG_WARNING,"Failed to activate generator on '%s'\n",chan->name);
00123 return -1;
00124 }
00125
00126 while (!ast_safe_sleep(chan, 10000))
00127 ;
00128
00129 ast_deactivate_generator(chan);
00130
00131 return -1;
00132 }
00133
00134 static int milliwatt_exec(struct ast_channel *chan, void *data)
00135 {
00136 const char *options = data;
00137 int res = -1;
00138
00139 if (!ast_strlen_zero(options) && strchr(options, 'o')) {
00140 return old_milliwatt_exec(chan);
00141 }
00142
00143 res = ast_playtones_start(chan, 23255, "1004/1000", 0);
00144
00145 while (!res) {
00146 res = ast_safe_sleep(chan, 10000);
00147 }
00148
00149 return res;
00150 }
00151
00152 static int unload_module(void)
00153 {
00154 return ast_unregister_application(app);
00155 }
00156
00157 static int load_module(void)
00158 {
00159 return ast_register_application(app, milliwatt_exec, synopsis, descrip);
00160 }
00161
00162 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Digital Milliwatt (mu-law) Test Application");