Applications no longer need to call ast_module_user_add and ast_module_user_remove...
[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                 char *dahdit;
134                 if (*digit < 0) {
135                         continue;
136                 }
137                 for (dahdit = morsecode[(int)*digit]; *dahdit; dahdit++) {
138                         if (*dahdit == '-') {
139                                 playtone(chan, tone, 3 * ditlen);
140                         } else if (*dahdit == '.') {
141                                 playtone(chan, tone, 1 * ditlen);
142                         } else {
143                                 /* Account for ditlen of silence immediately following */
144                                 playtone(chan, 0, 2 * ditlen);
145                         }
146
147                         /* Pause slightly between each dit and dah */
148                         playtone(chan, 0, 1 * ditlen);
149                 }
150                 /* Pause between characters */
151                 playtone(chan, 0, 2 * ditlen);
152         }
153
154         return res;
155 }
156
157 static int unload_module(void)
158 {
159         return ast_unregister_application(app_morsecode);
160 }
161
162 static int load_module(void)
163 {
164         return ast_register_application(app_morsecode, morsecode_exec, morsecode_synopsis, morsecode_descrip);
165 }
166
167 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Morse code");