0947681e9a50f96539fa106fdd270b5533626c22
[asterisk/asterisk.git] / apps / app_morsecode.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (c) 2006, Tilghman Lesher.  All rights reserved.
5  *
6  * Tilghman Lesher <app_morsecode__v001@the-tilghman.com>
7  *
8  * This code is released by the author with no restrictions on usage.
9  *
10  * See http://www.asterisk.org for more information about
11  * the Asterisk project. Please do not directly contact
12  * any of the maintainers of this project for assistance;
13  * the project provides a web site, mailing lists and IRC
14  * channels for your use.
15  *
16  */
17
18 /*! \file
19  *
20  * \brief Morsecode application
21  *
22  * \author Tilghman Lesher <app_morsecode__v001@the-tilghman.com>
23  *
24  * \ingroup applications
25  */
26
27 #include "asterisk.h"
28
29 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
30
31 #include "asterisk/file.h"
32 #include "asterisk/channel.h"
33 #include "asterisk/pbx.h"
34 #include "asterisk/module.h"
35 #include "asterisk/indications.h"
36
37 /*** DOCUMENTATION
38         <application name="Morsecode" language="en_US">
39                 <synopsis>
40                         Plays morse code.
41                 </synopsis>
42                 <syntax>
43                         <parameter name="string" required="true">
44                                 <para>String to playback as morse code to channel</para>
45                         </parameter>
46                 </syntax>
47                 <description>
48                         <para>Plays the Morse code equivalent of the passed string.</para>
49
50                         <para>This application uses the following variables:</para>
51                         <variablelist>
52                                 <variable name="MORSEDITLEN">
53                                         <para>Use this value in (ms) for length of dit</para>
54                                 </variable>
55                                 <variable name="MORSETONE">
56                                         <para>The pitch of the tone in (Hz), default is 800</para>
57                                 </variable>
58                         </variablelist>
59                 </description>
60                 <see-also>
61                         <ref type="application">SayAlpha</ref>
62                         <ref type="application">SayPhonetic</ref>
63                 </see-also>
64         </application>
65  ***/   
66 static const char app_morsecode[] = "Morsecode";
67
68 static const char * const morsecode[] = {
69         "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", /*  0-15 */
70         "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", /* 16-31 */
71         " ",      /* 32 - <space> */
72         ".-.-.-", /* 33 - ! */
73         ".-..-.", /* 34 - " */
74         "",       /* 35 - # */
75         "",       /* 36 - $ */
76         "",       /* 37 - % */
77         "",       /* 38 - & */
78         ".----.", /* 39 - ' */
79         "-.--.-", /* 40 - ( */
80         "-.--.-", /* 41 - ) */
81         "",       /* 42 - * */
82         "",       /* 43 - + */
83         "--..--", /* 44 - , */
84         "-....-", /* 45 - - */
85         ".-.-.-", /* 46 - . */
86         "-..-.",  /* 47 - / */
87         "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", /* 48-57 - 0-9 */
88         "---...", /* 58 - : */
89         "-.-.-.", /* 59 - ; */
90         "",       /* 60 - < */
91         "-...-",  /* 61 - = */
92         "",       /* 62 - > */
93         "..--..", /* 63 - ? */
94         ".--.-.", /* 64 - @ */
95         ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
96         "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..",
97         "-.--.-", /* 91 - [ (really '(') */
98         "-..-.",  /* 92 - \ (really '/') */
99         "-.--.-", /* 93 - ] (really ')') */
100         "",       /* 94 - ^ */
101         "..--.-", /* 95 - _ */
102         ".----.", /* 96 - ` */
103         ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
104         "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..",
105         "-.--.-", /* 123 - { (really '(') */
106         "",       /* 124 - | */
107         "-.--.-", /* 125 - } (really ')') */
108         "-..-.",  /* 126 - ~ (really bar) */
109         ". . .",  /* 127 - <del> (error) */
110 };
111
112 static void playtone(struct ast_channel *chan, int tone, int len)
113 {
114         char dtmf[20];
115         snprintf(dtmf, sizeof(dtmf), "%d/%d", tone, len);
116         ast_playtones_start(chan, 0, dtmf, 0);
117         ast_safe_sleep(chan, len);
118         ast_playtones_stop(chan);
119 }
120
121 static int morsecode_exec(struct ast_channel *chan, const char *data)
122 {
123         int res=0, ditlen, tone;
124         const char *digit;
125         const char *ditlenc, *tonec;
126
127         if (ast_strlen_zero(data)) {
128                 ast_log(LOG_WARNING, "Syntax: Morsecode(<string>) - no argument found\n");
129                 return 0;
130         }
131
132         /* Use variable MORESEDITLEN, if set (else 80) */
133         ast_channel_lock(chan);
134         ditlenc = pbx_builtin_getvar_helper(chan, "MORSEDITLEN");
135         if (ast_strlen_zero(ditlenc) || (sscanf(ditlenc, "%d", &ditlen) != 1)) {
136                 ditlen = 80;
137         }
138         ast_channel_unlock(chan);
139
140         /* Use variable MORSETONE, if set (else 800) */
141         ast_channel_lock(chan);
142         tonec = pbx_builtin_getvar_helper(chan, "MORSETONE");
143         if (ast_strlen_zero(tonec) || (sscanf(tonec, "%d", &tone) != 1)) {
144                 tone = 800;
145         }
146         ast_channel_unlock(chan);
147
148         for (digit = data; *digit; digit++) {
149                 int digit2 = *digit;
150                 const char *dahdit;
151                 if (digit2 < 0) {
152                         continue;
153                 }
154                 for (dahdit = morsecode[digit2]; *dahdit; dahdit++) {
155                         if (*dahdit == '-') {
156                                 playtone(chan, tone, 3 * ditlen);
157                         } else if (*dahdit == '.') {
158                                 playtone(chan, tone, 1 * ditlen);
159                         } else {
160                                 /* Account for ditlen of silence immediately following */
161                                 playtone(chan, 0, 2 * ditlen);
162                         }
163
164                         /* Pause slightly between each dit and dah */
165                         playtone(chan, 0, 1 * ditlen);
166                 }
167                 /* Pause between characters */
168                 playtone(chan, 0, 2 * ditlen);
169         }
170
171         return res;
172 }
173
174 static int unload_module(void)
175 {
176         return ast_unregister_application(app_morsecode);
177 }
178
179 static int load_module(void)
180 {
181         return ast_register_application_xml(app_morsecode, morsecode_exec);
182 }
183
184 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Morse code");