482c2ee3ae881a46340ccc8f71e9aeb12685724c
[asterisk/asterisk.git] / app.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Channel Management
5  * 
6  * Copyright (C) 1999, Mark Spencer
7  *
8  * Mark Spencer <markster@linux-support.net>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <pthread.h>
17 #include <string.h>
18 #include <sys/time.h>
19 #include <signal.h>
20 #include <errno.h>
21 #include <unistd.h>
22 #include <dirent.h>
23 #include <asterisk/channel.h>
24 #include <asterisk/file.h>
25 #include <asterisk/app.h>
26 #include <asterisk/dsp.h>
27 #include <asterisk/logger.h>
28 #include <asterisk/options.h>
29 #include "asterisk.h"
30 #include "astconf.h"
31
32 /* set timeout to 0 for "standard" timeouts. Set timeout to -1 for 
33    "ludicrous time" (essentially never times out) */
34 int ast_app_getdata(struct ast_channel *c, char *prompt, char *s, int maxlen, int timeout)
35 {
36         int res,to,fto;
37         if (prompt) {
38                 res = ast_streamfile(c, prompt, c->language);
39                 if (res < 0)
40                         return res;
41         }
42         fto = 6000;
43         to = 2000;
44         if (timeout > 0) fto = to = timeout;
45         if (timeout < 0) fto = to = 1000000000;
46         res = ast_readstring(c, s, maxlen, to, fto, "#");
47         return res;
48 }
49
50 int ast_app_getvoice(struct ast_channel *c, char *dest, char *dstfmt, char *prompt, int silence, int maxsec)
51 {
52         int res;
53         struct ast_filestream *writer;
54         int rfmt;
55         int totalms, total;
56         
57         struct ast_frame *f;
58         struct ast_dsp *sildet;
59         /* Play prompt if requested */
60         if (prompt) {
61                 res = ast_streamfile(c, prompt, c->language);
62                 if (res < 0)
63                         return res;
64                 res = ast_waitstream(c,"");
65                 if (res < 0)
66                         return res;
67         }
68         rfmt = c->readformat;
69         res = ast_set_read_format(c, AST_FORMAT_SLINEAR);
70         if (res < 0) {
71                 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
72                 return -1;
73         }
74         sildet = ast_dsp_new();
75         if (!sildet) {
76                 ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
77                 return -1;
78         }
79         writer = ast_writefile(dest, dstfmt, "Voice file", 0, 0, 0666);
80         if (!writer) {
81                 ast_log(LOG_WARNING, "Unable to open file '%s' in format '%s' for writing\n", dest, dstfmt);
82                 ast_dsp_free(sildet);
83                 return -1;
84         }
85         for(;;) {
86                 if ((res = ast_waitfor(c, 2000)) < 0) {
87                         ast_log(LOG_NOTICE, "Waitfor failed while recording file '%s' format '%s'\n", dest, dstfmt);
88                         break;
89                 }
90                 if (res) {
91                         f = ast_read(c);
92                         if (!f) {
93                                 ast_log(LOG_NOTICE, "Hungup while recording file '%s' format '%s'\n", dest, dstfmt);
94                                 break;
95                         }
96                         if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) {
97                                 /* Ended happily with DTMF */
98                                 ast_frfree(f);
99                                 break;
100                         } else if (f->frametype == AST_FRAME_VOICE) {
101                                 ast_dsp_silence(sildet, f, &total); 
102                                 if (total > silence) {
103                                         /* Ended happily with silence */
104                                         ast_frfree(f);
105                                         break;
106                                 }
107                                 totalms += f->samples / 8;
108                                 if (totalms > maxsec * 1000) {
109                                         /* Ended happily with too much stuff */
110                                         ast_log(LOG_NOTICE, "Constraining voice on '%s' to %d seconds\n", c->name, maxsec);
111                                         ast_frfree(f);
112                                         break;
113                                 }
114                         }
115                         ast_frfree(f);
116                 }
117         }
118         res = ast_set_read_format(c, rfmt);
119         if (res)
120                 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", c->name);
121         ast_dsp_free(sildet);
122         ast_closestream(writer);
123         return 0;
124 }
125
126 int ast_app_has_voicemail(char *mailbox)
127 {
128         DIR *dir;
129         struct dirent *de;
130         char fn[256];
131
132         /* If no mailbox, return immediately */
133         if (!strlen(mailbox))
134                 return 0;
135         snprintf(fn, sizeof(fn), "%s/vm/%s/INBOX", (char *)ast_config_AST_SPOOL_DIR, mailbox);
136         dir = opendir(fn);
137         if (!dir)
138                 return 0;
139         while ((de = readdir(dir))) {
140                 if (!strncasecmp(de->d_name, "msg", 3))
141                         break;
142         }
143         closedir(dir);
144         if (de)
145                 return 1;
146         return 0;
147 }