Use the same delimited character as the FILTER function in FIELDQTY and CUT.
[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 <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <string.h>
35
36 #include "asterisk/file.h"
37 #include "asterisk/logger.h"
38 #include "asterisk/options.h"
39 #include "asterisk/channel.h"
40 #include "asterisk/pbx.h"
41 #include "asterisk/module.h"
42 #include "asterisk/indications.h"
43
44 static char *app_morsecode = "Morsecode";
45
46 static char *morsecode_synopsis = "Plays morse code";
47
48 static char *morsecode_descrip =
49 "Usage: Morsecode(<string>)\n"
50 "Plays the Morse code equivalent of the passed string.  If the variable\n"
51 "MORSEDITLEN is set, it will use that value for the length (in ms) of the dit\n"
52 "(defaults to 80).  Additionally, if MORSETONE is set, it will use that tone\n"
53 "(in Hz).  The tone default is 800.\n";
54
55
56 static char *morsecode[] = {
57         "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", /*  0-15 */
58         "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", /* 16-31 */
59         " ",      /* 32 - <space> */
60         ".-.-.-", /* 33 - ! */
61         ".-..-.", /* 34 - " */
62         "",       /* 35 - # */
63         "",       /* 36 - $ */
64         "",       /* 37 - % */
65         "",       /* 38 - & */
66         ".----.", /* 39 - ' */
67         "-.--.-", /* 40 - ( */
68         "-.--.-", /* 41 - ) */
69         "",       /* 42 - * */
70         "",       /* 43 - + */
71         "--..--", /* 44 - , */
72         "-....-", /* 45 - - */
73         ".-.-.-", /* 46 - . */
74         "-..-.",  /* 47 - / */
75         "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", /* 48-57 - 0-9 */
76         "---...", /* 58 - : */
77         "-.-.-.", /* 59 - ; */
78         "",       /* 60 - < */
79         "-...-",  /* 61 - = */
80         "",       /* 62 - > */
81         "..--..", /* 63 - ? */
82         ".--.-.", /* 64 - @ */
83         ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
84         "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..",
85         "-.--.-", /* 91 - [ (really '(') */
86         "-..-.",  /* 92 - \ (really '/') */
87         "-.--.-", /* 93 - ] (really ')') */
88         "",       /* 94 - ^ */
89         "..--.-", /* 95 - _ */
90         ".----.", /* 96 - ` */
91         ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--",
92         "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..",
93         "-.--.-", /* 123 - { (really '(') */
94         "",       /* 124 - | */
95         "-.--.-", /* 125 - } (really ')') */
96         "-..-.",  /* 126 - ~ (really bar) */
97         ". . .",  /* 127 - <del> (error) */
98 };
99
100 static void playtone(struct ast_channel *chan, int tone, int len)
101 {
102         char dtmf[20];
103         snprintf(dtmf, sizeof(dtmf), "%d/%d", tone, len);
104         ast_playtones_start(chan, 0, dtmf, 0);
105         ast_safe_sleep(chan, len);
106         ast_playtones_stop(chan);
107 }
108
109 static int morsecode_exec(struct ast_channel *chan, void *data)
110 {
111         int res=0, ditlen, tone;
112         char *digit;
113         const char *ditlenc, *tonec;
114
115         if (ast_strlen_zero(data)) {
116                 ast_log(LOG_WARNING, "Syntax: Morsecode(<string>) - no argument found\n");
117                 return 0;
118         }
119
120         /* Use variable MORESEDITLEN, if set (else 80) */
121         ditlenc = pbx_builtin_getvar_helper(chan, "MORSEDITLEN");
122         if (ast_strlen_zero(ditlenc) || (sscanf(ditlenc, "%d", &ditlen) != 1)) {
123                 ditlen = 80;
124         }
125
126         /* Use variable MORSETONE, if set (else 800) */
127         tonec = pbx_builtin_getvar_helper(chan, "MORSETONE");
128         if (ast_strlen_zero(tonec) || (sscanf(tonec, "%d", &tone) != 1)) {
129                 tone = 800;
130         }
131
132         for (digit = data; *digit; digit++) {
133                 int digit2 = *digit;
134                 char *dahdit;
135                 if (digit2 < 0) {
136                         continue;
137                 }
138                 for (dahdit = morsecode[digit2]; *dahdit; dahdit++) {
139                         if (*dahdit == '-') {
140                                 playtone(chan, tone, 3 * ditlen);
141                         } else if (*dahdit == '.') {
142                                 playtone(chan, tone, 1 * ditlen);
143                         } else {
144                                 /* Account for ditlen of silence immediately following */
145                                 playtone(chan, 0, 2 * ditlen);
146                         }
147
148                         /* Pause slightly between each dit and dah */
149                         playtone(chan, 0, 1 * ditlen);
150                 }
151                 /* Pause between characters */
152                 playtone(chan, 0, 2 * ditlen);
153         }
154
155         return res;
156 }
157
158 static int unload_module(void)
159 {
160         return ast_unregister_application(app_morsecode);
161 }
162
163 static int load_module(void)
164 {
165         return ast_register_application(app_morsecode, morsecode_exec, morsecode_synopsis, morsecode_descrip);
166 }
167
168 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Morse code");