61c4fe4bd620f6c6028bb24fecca70df84e0285e
[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         struct ast_module_user *u;
115
116         u = ast_module_user_add(chan);
117
118         if (ast_strlen_zero(data)) {
119                 ast_log(LOG_WARNING, "Syntax: Morsecode(<string>) - no argument found\n");
120                 ast_module_user_remove(u);
121                 return 0;
122         }
123
124         /* Use variable MORESEDITLEN, if set (else 80) */
125         ditlenc = pbx_builtin_getvar_helper(chan, "MORSEDITLEN");
126         if (ast_strlen_zero(ditlenc) || (sscanf(ditlenc, "%d", &ditlen) != 1)) {
127                 ditlen = 80;
128         }
129
130         /* Use variable MORSETONE, if set (else 800) */
131         tonec = pbx_builtin_getvar_helper(chan, "MORSETONE");
132         if (ast_strlen_zero(tonec) || (sscanf(tonec, "%d", &tone) != 1)) {
133                 tone = 800;
134         }
135
136         for (digit = data; *digit; digit++) {
137                 char *dahdit;
138                 if (*digit < 0) {
139                         continue;
140                 }
141                 for (dahdit = morsecode[(int)*digit]; *dahdit; dahdit++) {
142                         if (*dahdit == '-') {
143                                 playtone(chan, tone, 3 * ditlen);
144                         } else if (*dahdit == '.') {
145                                 playtone(chan, tone, 1 * ditlen);
146                         } else {
147                                 /* Account for ditlen of silence immediately following */
148                                 playtone(chan, 0, 2 * ditlen);
149                         }
150
151                         /* Pause slightly between each dit and dah */
152                         playtone(chan, 0, 1 * ditlen);
153                 }
154                 /* Pause between characters */
155                 playtone(chan, 0, 2 * ditlen);
156         }
157
158         ast_module_user_remove(u);
159         return res;
160 }
161
162 static int unload_module(void)
163 {
164         return ast_unregister_application(app_morsecode);
165 }
166
167 static int load_module(void)
168 {
169         return ast_register_application(app_morsecode, morsecode_exec, morsecode_synopsis, morsecode_descrip);
170 }
171
172 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Morse code");