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