67e242f7be639c6e1466a7a8ee53c315e6855591
[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 /*** MODULEINFO
28         <support_level>extended</support_level>
29  ***/
30
31 #include "asterisk.h"
32
33 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
34
35 #include "asterisk/file.h"
36 #include "asterisk/channel.h"
37 #include "asterisk/pbx.h"
38 #include "asterisk/module.h"
39 #include "asterisk/indications.h"
40
41 /*** DOCUMENTATION
42         <application name="Morsecode" language="en_US">
43                 <synopsis>
44                         Plays morse code.
45                 </synopsis>
46                 <syntax>
47                         <parameter name="string" required="true">
48                                 <para>String to playback as morse code to channel</para>
49                         </parameter>
50                 </syntax>
51                 <description>
52                         <para>Plays the Morse code equivalent of the passed string.</para>
53
54                         <para>This application uses the following variables:</para>
55                         <variablelist>
56                                 <variable name="MORSEDITLEN">
57                                         <para>Use this value in (ms) for length of dit</para>
58                                 </variable>
59                                 <variable name="MORSETONE">
60                                         <para>The pitch of the tone in (Hz), default is 800</para>
61                                 </variable>
62                         </variablelist>
63                 </description>
64                 <see-also>
65                         <ref type="application">SayAlpha</ref>
66                         <ref type="application">SayPhonetic</ref>
67                 </see-also>
68         </application>
69  ***/   
70 static const char app_morsecode[] = "Morsecode";
71
72 static const char * const morsecode[] = {
73         "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", /*  0-15 */
74         "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", /* 16-31 */
75         " ",      /* 32 - <space> */
76         ".-.-.-", /* 33 - ! */
77         ".-..-.", /* 34 - " */
78         "",       /* 35 - # */
79         "",       /* 36 - $ */
80         "",       /* 37 - % */
81         "",       /* 38 - & */
82         ".----.", /* 39 - ' */
83         "-.--.-", /* 40 - ( */
84         "-.--.-", /* 41 - ) */
85         "",       /* 42 - * */
86         "",       /* 43 - + */
87         "--..--", /* 44 - , */
88         "-....-", /* 45 - - */
89         ".-.-.-", /* 46 - . */
90         "-..-.",  /* 47 - / */
91         "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", /* 48-57 - 0-9 */
92         "---...", /* 58 - : */
93         "-.-.-.", /* 59 - ; */
94         "",       /* 60 - < */
95         "-...-",  /* 61 - = */
96         "",       /* 62 - > */
97         "..--..", /* 63 - ? */
98         ".--.-.", /* 64 - @ */
99         ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
100         "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..",
101         "-.--.-", /* 91 - [ (really '(') */
102         "-..-.",  /* 92 - \ (really '/') */
103         "-.--.-", /* 93 - ] (really ')') */
104         "",       /* 94 - ^ */
105         "..--.-", /* 95 - _ */
106         ".----.", /* 96 - ` */
107         ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
108         "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..",
109         "-.--.-", /* 123 - { (really '(') */
110         "",       /* 124 - | */
111         "-.--.-", /* 125 - } (really ')') */
112         "-..-.",  /* 126 - ~ (really bar) */
113         ". . .",  /* 127 - <del> (error) */
114 };
115
116 static void playtone(struct ast_channel *chan, int tone, int len)
117 {
118         char dtmf[20];
119         snprintf(dtmf, sizeof(dtmf), "%d/%d", tone, len);
120         ast_playtones_start(chan, 0, dtmf, 0);
121         ast_safe_sleep(chan, len);
122         ast_playtones_stop(chan);
123 }
124
125 static int morsecode_exec(struct ast_channel *chan, const char *data)
126 {
127         int res=0, ditlen, tone;
128         const char *digit;
129         const char *ditlenc, *tonec;
130
131         if (ast_strlen_zero(data)) {
132                 ast_log(LOG_WARNING, "Syntax: Morsecode(<string>) - no argument found\n");
133                 return 0;
134         }
135
136         /* Use variable MORESEDITLEN, if set (else 80) */
137         ast_channel_lock(chan);
138         ditlenc = pbx_builtin_getvar_helper(chan, "MORSEDITLEN");
139         if (ast_strlen_zero(ditlenc) || (sscanf(ditlenc, "%30d", &ditlen) != 1)) {
140                 ditlen = 80;
141         }
142         ast_channel_unlock(chan);
143
144         /* Use variable MORSETONE, if set (else 800) */
145         ast_channel_lock(chan);
146         tonec = pbx_builtin_getvar_helper(chan, "MORSETONE");
147         if (ast_strlen_zero(tonec) || (sscanf(tonec, "%30d", &tone) != 1)) {
148                 tone = 800;
149         }
150         ast_channel_unlock(chan);
151
152         for (digit = data; *digit; digit++) {
153                 int digit2 = *digit;
154                 const char *dahdit;
155                 if (digit2 < 0) {
156                         continue;
157                 }
158                 for (dahdit = morsecode[digit2]; *dahdit; dahdit++) {
159                         if (*dahdit == '-') {
160                                 playtone(chan, tone, 3 * ditlen);
161                         } else if (*dahdit == '.') {
162                                 playtone(chan, tone, 1 * ditlen);
163                         } else {
164                                 /* Account for ditlen of silence immediately following */
165                                 playtone(chan, 0, 2 * ditlen);
166                         }
167
168                         /* Pause slightly between each dit and dah */
169                         playtone(chan, 0, 1 * ditlen);
170                 }
171                 /* Pause between characters */
172                 playtone(chan, 0, 2 * ditlen);
173         }
174
175         return res;
176 }
177
178 static int unload_module(void)
179 {
180         return ast_unregister_application(app_morsecode);
181 }
182
183 static int load_module(void)
184 {
185         return ast_register_application_xml(app_morsecode, morsecode_exec);
186 }
187
188 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Morse code");