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