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