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