33 *
44 * Copyright (c) 2006, Tilghman Lesher. All rights reserved.
55 *
6+ * Updated by Naveen Albert <asterisk@phreaknet.org>
7+ *
68 * Tilghman Lesher <app_morsecode__v001@the-tilghman.com>
79 *
810 * This code is released by the author with no restrictions on usage.
2022 * \brief Morsecode application
2123 *
2224 * \author Tilghman Lesher <app_morsecode__v001@the-tilghman.com>
25+ * \author Naveen Albert <asterisk@phreaknet.org>
2326 *
2427 * \ingroup applications
2528 */
5861 <variable name="MORSETONE">
5962 <para>The pitch of the tone in (Hz), default is 800</para>
6063 </variable>
64+ <variable name="MORSESPACETONE">
65+ <para>The pitch of the spaces in (Hz), default is 0</para>
66+ </variable>
67+ <variable name="MORSETYPE">
68+ <para>The code type to use (AMERICAN for standard American Morse
69+ or INTERNATIONAL for international code.
70+ Default is INTERNATIONAL).</para>
71+ </variable>
6172 </variablelist>
6273 </description>
6374 <see-also>
6879 ***/
6980static const char app_morsecode [] = "Morsecode" ;
7081
71- static const char * const morsecode [] = {
82+ static const char * const internationalcode [] = {
7283 "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , /* 0-15 */
7384 "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , /* 16-31 */
7485 " " , /* 32 - <space> */
@@ -95,80 +106,179 @@ static const char * const morsecode[] = {
95106 "" , /* 62 - > */
96107 "..--.." , /* 63 - ? */
97108 ".--.-." , /* 64 - @ */
98- ".-" , "-..." , "-.-." , "-.." , "." , "..-." , "--." , "...." , ".." , ".---" , "-.-" , ".-.." , "--" ,
99- "-." , "---" , ".--." , "--.-" , ".-." , "..." , "-" , "..-" , "...-" , ".--" , "-..-" , "-.--" , "--.." ,
109+ ".-" , "-..." , "-.-." , "-.." , "." , "..-." , "--." , "...." , ".." , ".---" , "-.-" , ".-.." , "--" , /* A-M */
110+ "-." , "---" , ".--." , "--.-" , ".-." , "..." , "-" , "..-" , "...-" , ".--" , "-..-" , "-.--" , "--.." , /* N-Z */
100111 "-.--.-" , /* 91 - [ (really '(') */
101112 "-..-." , /* 92 - \ (really '/') */
102113 "-.--.-" , /* 93 - ] (really ')') */
103114 "" , /* 94 - ^ */
104115 "..--.-" , /* 95 - _ */
105116 ".----." , /* 96 - ` */
106- ".-" , "-..." , "-.-." , "-.." , "." , "..-." , "--." , "...." , ".." , ".---" , "-.-" , ".-.." , "--" ,
107- "-." , "---" , ".--." , "--.-" , ".-." , "..." , "-" , "..-" , "...-" , ".--" , "-..-" , "-.--" , "--.." ,
117+ ".-" , "-..." , "-.-." , "-.." , "." , "..-." , "--." , "...." , ".." , ".---" , "-.-" , ".-.." , "--" , /* a-m */
118+ "-." , "---" , ".--." , "--.-" , ".-." , "..." , "-" , "..-" , "...-" , ".--" , "-..-" , "-.--" , "--.." , /* n-z */
108119 "-.--.-" , /* 123 - { (really '(') */
109120 "" , /* 124 - | */
110121 "-.--.-" , /* 125 - } (really ')') */
111122 "-..-." , /* 126 - ~ (really bar) */
112123 ". . ." , /* 127 - <del> (error) */
113124};
114125
115- static void playtone (struct ast_channel * chan , int tone , int len )
126+ static const char * const americanmorsecode [] = {
127+ "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , /* 0-15 */
128+ "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , "" , /* 16-31 */
129+ " " , /* 32 - <space> */
130+ "---." , /* 33 - ! */
131+ "..-. -." ,/* 34 - " (QN)*/
132+ "" , /* 35 - # */
133+ "... .-.." ,/* 36 - $ (SX) */
134+ "" , /* 37 - % */
135+ ". ..." , /* 38 - & (ES) */
136+ "..-. .-.." ,/* 39 - ' (QX) */
137+ "..... -." , /* 40 - ( (PN) */
138+ "..... .. .." , /* 41 - ) (PY) */
139+ "" , /* 42 - * */
140+ "" , /* 43 - + */
141+ ".-.-" , /* 44 - , */
142+ ".... .-.." ,/* 45 - (HX) */
143+ "..--.." , /* 46 - . */
144+ "..- -" , /* 47 - / (UT) */
145+ ".--." , "..-.." , "...-." , "....-" , "---" , "......" , "--.." , "-...." , "-..-" , "0" , /* 48-57 - 0-9 */
146+ "-.- . ." ,/* 58 - : (KO) */
147+ "... .." , /* 59 - ; */
148+ "" , /* 60 - < */
149+ "-...-" , /* 61 - = (paragraph mark) */
150+ "" , /* 62 - > */
151+ "-..-." , /* 63 - ? */
152+ ".--.-." , /* 64 - @ */
153+ ".-" , "-..." , ".. ." , "-.." , "." , ".-." , "--." , "...." , ".." , ".-.-" , "-.-" , "L" , "--" , /* A-M */
154+ "-." , ". ." , "....." , "..-." , ". .." , "..." , "-" , "..-" , "...-" , ".--" , ".-.." , ".. .." , "... ." , /* N-Z */
155+ "..... -." , /* 91 - [ (really '(') */
156+ "..- -" , /* 92 - \ (really '/') */
157+ "..... .. .." , /* 93 - ] (really ')') */
158+ "" , /* 94 - ^ */
159+ "..--.-" , /* 95 - _ */
160+ ".----." , /* 96 - ` */
161+ ".-" , "-..." , ".. ." , "-.." , "." , ".-." , "--." , "...." , ".." , ".-.-" , "-.-" , "L" , "--" , /* a-m */
162+ "-." , ". ." , "....." , "..-." , ". .." , "..." , "-" , "..-" , "...-" , ".--" , ".-.." , ".. .." , "... ." , /* n-z */
163+ "..... -." , /* 123 - { (really '(') */
164+ "" , /* 124 - | */
165+ "..... .. .." , /* 125 - } (really ')') */
166+ "..- -" , /* 126 - ~ (really bar) */
167+ ". . ." , /* 127 - <del> (error) */
168+ };
169+
170+ static int playtone (struct ast_channel * chan , int tone , int len )
116171{
172+ int res ;
117173 char dtmf [20 ];
118174 snprintf (dtmf , sizeof (dtmf ), "%d/%d" , tone , len );
119175 ast_playtones_start (chan , 0 , dtmf , 0 );
120- ast_safe_sleep (chan , len );
176+ res = ast_safe_sleep (chan , len );
121177 ast_playtones_stop (chan );
178+ return res ;
122179}
123180
124181static int morsecode_exec (struct ast_channel * chan , const char * data )
125182{
126- int res = 0 , ditlen , tone ;
183+ int res = 0 , ditlen , tone , toneoff , digit2 ;
127184 const char * digit ;
128- const char * ditlenc , * tonec ;
185+ const char * ditlenc , * tonec , * toneb , * codetype ;
129186
130187 if (ast_strlen_zero (data )) {
131188 ast_log (LOG_WARNING , "Syntax: Morsecode(<string>) - no argument found\n" );
132189 return 0 ;
133190 }
134191
135- /* Use variable MORESEDITLEN, if set (else 80) */
136192 ast_channel_lock (chan );
193+ /* Use variable MORESEDITLEN, if set (else 80) */
137194 ditlenc = pbx_builtin_getvar_helper (chan , "MORSEDITLEN" );
138195 if (ast_strlen_zero (ditlenc ) || (sscanf (ditlenc , "%30d" , & ditlen ) != 1 )) {
139196 ditlen = 80 ;
140197 }
141- ast_channel_unlock (chan );
142198
143199 /* Use variable MORSETONE, if set (else 800) */
144200 ast_channel_lock (chan );
145201 tonec = pbx_builtin_getvar_helper (chan , "MORSETONE" );
146202 if (ast_strlen_zero (tonec ) || (sscanf (tonec , "%30d" , & tone ) != 1 )) {
147203 tone = 800 ;
148204 }
149- ast_channel_unlock (chan );
150205
151- for (digit = data ; * digit ; digit ++ ) {
152- int digit2 = * digit ;
153- const char * dahdit ;
154- if (digit2 < 0 ) {
155- continue ;
206+ /* Use variable MORSESPACETONE, if set (else 0) */
207+
208+ toneb = pbx_builtin_getvar_helper (chan , "MORSESPACETONE" );
209+ if (ast_strlen_zero (toneb ) || (sscanf (toneb , "%30d" , & toneoff ) != 1 )) {
210+ toneoff = 0 ;
211+ }
212+
213+ /* Use variable MORSETYPE, if set (else INTERNATIONAL) */
214+ codetype = pbx_builtin_getvar_helper (chan , "MORSETYPE" );
215+ if (!codetype || strcmp (codetype , "AMERICAN" )) {
216+ codetype = "INTERNATIONAL" ;
217+ }
218+
219+ if (!strcmp (codetype , "AMERICAN" )) {
220+ ast_channel_unlock (chan );
221+ for (digit = data ; * digit ; digit ++ ) {
222+ const char * dahdit ;
223+ digit2 = * digit ;
224+ if (digit2 < 0 || digit2 > 127 ) {
225+ continue ;
226+ }
227+ for (dahdit = americanmorsecode [digit2 ]; * dahdit ; dahdit ++ ) {
228+ if (* dahdit == '-' ) {
229+ res = playtone (chan , tone , 3 * ditlen );
230+ } else if (* dahdit == '.' ) {
231+ res = playtone (chan , tone , 1 * ditlen );
232+ } else if (* dahdit == 'L' || * dahdit == 'l' ) {
233+ res = playtone (chan , tone , 6 * ditlen ); /* long dash */
234+ } else if (* dahdit == '0' ) {
235+ res = playtone (chan , tone , 9 * ditlen ); /* extra long dash */
236+ } else if (* dahdit == ' ' ) { /* space char (x20) = 6 dot lengths */
237+ /* Intra-char pauses, specific to American Morse */
238+ res = playtone (chan , toneoff , 3 * ditlen );
239+ } else {
240+ /* Account for ditlen of silence immediately following */
241+ res = playtone (chan , toneoff , 2 * ditlen );
242+ }
243+
244+ /* Pause slightly between each dit and dah */
245+ res = playtone (chan , toneoff , 1 * ditlen );
246+ if (res )
247+ break ;
248+ }
249+ /* Pause between characters */
250+ res = playtone (chan , toneoff , 3 * ditlen );
251+ if (res )
252+ break ;
156253 }
157- for (dahdit = morsecode [digit2 ]; * dahdit ; dahdit ++ ) {
158- if (* dahdit == '-' ) {
159- playtone (chan , tone , 3 * ditlen );
160- } else if (* dahdit == '.' ) {
161- playtone (chan , tone , 1 * ditlen );
162- } else {
163- /* Account for ditlen of silence immediately following */
164- playtone (chan , 0 , 2 * ditlen );
254+ } else { /* International */
255+ ast_channel_unlock (chan );
256+ for (digit = data ; * digit ; digit ++ ) {
257+ const char * dahdit ;
258+ digit2 = * digit ;
259+ if (digit2 < 0 || digit2 > 127 ) {
260+ continue ;
165261 }
262+ for (dahdit = internationalcode [digit2 ]; * dahdit ; dahdit ++ ) {
263+ if (* dahdit == '-' ) {
264+ res = playtone (chan , tone , 3 * ditlen );
265+ } else if (* dahdit == '.' ) {
266+ res = playtone (chan , tone , 1 * ditlen );
267+ } else {
268+ /* Account for ditlen of silence immediately following */
269+ res = playtone (chan , toneoff , 2 * ditlen );
270+ }
166271
167- /* Pause slightly between each dit and dah */
168- playtone (chan , 0 , 1 * ditlen );
272+ /* Pause slightly between each dit and dah */
273+ res = playtone (chan , toneoff , 1 * ditlen );
274+ if (res )
275+ break ;
276+ }
277+ /* Pause between characters */
278+ res = playtone (chan , toneoff , 2 * ditlen );
279+ if (res )
280+ break ;
169281 }
170- /* Pause between characters */
171- playtone (chan , 0 , 2 * ditlen );
172282 }
173283
174284 return res ;
0 commit comments