b51d8b2dd5d0f25c68b32f5e199e3616cc29843a
[asterisk/asterisk.git] / apps / app_milliwatt.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Digital Milliwatt Test
5  * 
6  * Copyright (C) 2002, Mark Spencer
7  *
8  * Mark Spencer <markster@linux-support.net>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
14 #include <asterisk/lock.h>
15 #include <asterisk/file.h>
16 #include <asterisk/logger.h>
17 #include <asterisk/channel.h>
18 #include <asterisk/pbx.h>
19 #include <asterisk/module.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <errno.h>
25
26 #include <pthread.h>
27
28 static char *tdesc = "Digital Milliwatt (mu-law) Test Application";
29
30 static char *app = "Milliwatt";
31
32 static char *synopsis = "Generate a Constant 1000Hz tone at 0dbm (mu-law)";
33
34 static char *descrip = 
35 "Milliwatt(): Generate a Constant 1000Hz tone at 0dbm (mu-law)\n";
36
37 STANDARD_LOCAL_USER;
38
39 LOCAL_USER_DECL;
40
41 static char digital_milliwatt[] = {0x1e,0x0b,0x0b,0x1e,0x9e,0x8b,0x8b,0x9e} ;
42
43 static void *milliwatt_alloc(struct ast_channel *chan, void *params)
44 {
45 int     *indexp;
46         indexp = malloc(sizeof(int));
47         if (indexp == NULL) return(NULL);
48         *indexp = 0;
49         return(indexp);
50 }
51
52 static void milliwatt_release(struct ast_channel *chan, void *data)
53 {
54         free(data);
55         return;
56 }
57
58 static int milliwatt_generate(struct ast_channel *chan, void *data, int len)
59 {
60         struct ast_frame wf;
61         unsigned char waste[AST_FRIENDLY_OFFSET];
62         unsigned char buf[640];
63         int i,*indexp = (int *) data;
64
65         if (len > sizeof(buf))
66         {
67                 ast_log(LOG_WARNING,"Only doing %d bytes (%d bytes requested)\n",sizeof(buf),len);
68                 len = sizeof(buf);
69         }
70         waste[0] = 0; /* make compiler happy */
71         wf.frametype = AST_FRAME_VOICE;
72         wf.subclass = AST_FORMAT_ULAW;
73         wf.offset = AST_FRIENDLY_OFFSET;
74         wf.mallocd = 0;
75         wf.data = buf;
76         wf.datalen = len;
77         wf.samples = wf.datalen;
78         wf.src = "app_milliwatt";
79         /* create a buffer containing the digital milliwatt pattern */
80         for(i = 0; i < len; i++)
81         {
82                 buf[i] = digital_milliwatt[(*indexp)++];
83                 *indexp &= 7;
84         }
85         if (ast_write(chan,&wf) < 0)
86         {
87                 ast_log(LOG_WARNING,"Failed to write frame to '%s': %s\n",chan->name,strerror(errno));
88                 return -1;
89         }
90         return 0;
91 }
92
93 static struct ast_generator milliwattgen = 
94 {
95         alloc: milliwatt_alloc,
96         release: milliwatt_release,
97         generate: milliwatt_generate,
98 } ;
99
100 static int milliwatt_exec(struct ast_channel *chan, void *data)
101 {
102
103         struct localuser *u;
104         LOCAL_USER_ADD(u);
105         ast_set_write_format(chan, AST_FORMAT_ULAW);
106         ast_set_read_format(chan, AST_FORMAT_ULAW);
107         if (chan->_state != AST_STATE_UP)
108         {
109                 ast_answer(chan);
110         }
111         if (ast_activate_generator(chan,&milliwattgen,"milliwatt") < 0)
112         {
113                 ast_log(LOG_WARNING,"Failed to activate generator on '%s'\n",chan->name);
114                 return -1;
115         }
116         while(!ast_safe_sleep(chan, 10000));
117         ast_deactivate_generator(chan);
118         LOCAL_USER_REMOVE(u);
119         return -1;
120 }
121
122 int unload_module(void)
123 {
124         STANDARD_HANGUP_LOCALUSERS;
125         return ast_unregister_application(app);
126 }
127
128 int load_module(void)
129 {
130         return ast_register_application(app, milliwatt_exec, synopsis, descrip);
131 }
132
133 char *description(void)
134 {
135         return tdesc;
136 }
137
138 int usecount(void)
139 {
140         int res;
141         STANDARD_USECOUNT(res);
142         return res;
143 }
144
145 char *key()
146 {
147         return ASTERISK_GPL_KEY;
148 }