00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <pthread.h>
00017 #include <string.h>
00018 #include <sys/time.h>
00019 #include <signal.h>
00020 #include <errno.h>
00021 #include <unistd.h>
00022 #include <dirent.h>
00023 #include <asterisk/channel.h>
00024 #include <asterisk/pbx.h>
00025 #include <asterisk/file.h>
00026 #include <asterisk/app.h>
00027 #include <asterisk/dsp.h>
00028 #include <asterisk/logger.h>
00029 #include <asterisk/options.h>
00030 #include "asterisk.h"
00031 #include "astconf.h"
00032
00033
00034
00035 int ast_app_getdata(struct ast_channel *c, char *prompt, char *s, int maxlen, int timeout)
00036 {
00037 int res,to,fto;
00038
00039 if (prompt) {
00040 res = ast_streamfile(c, prompt, c->language);
00041 if (res < 0)
00042 return res;
00043 }
00044 fto = c->pbx ? c->pbx->rtimeout * 1000 : 6000;
00045 to = c->pbx ? c->pbx->dtimeout * 1000 : 2000;
00046
00047 if (timeout > 0) fto = to = timeout;
00048 if (timeout < 0) fto = to = 1000000000;
00049 res = ast_readstring(c, s, maxlen, to, fto, "#");
00050 return res;
00051 }
00052
00053
00054 int ast_app_getdata_full(struct ast_channel *c, char *prompt, char *s, int maxlen, int timeout, int audiofd, int ctrlfd)
00055 {
00056 int res,to,fto;
00057 if (prompt) {
00058 res = ast_streamfile(c, prompt, c->language);
00059 if (res < 0)
00060 return res;
00061 }
00062 fto = 6000;
00063 to = 2000;
00064 if (timeout > 0) fto = to = timeout;
00065 if (timeout < 0) fto = to = 1000000000;
00066 res = ast_readstring_full(c, s, maxlen, to, fto, "#", audiofd, ctrlfd);
00067 return res;
00068 }
00069
00070 int ast_app_getvoice(struct ast_channel *c, char *dest, char *dstfmt, char *prompt, int silence, int maxsec)
00071 {
00072 int res;
00073 struct ast_filestream *writer;
00074 int rfmt;
00075 int totalms=0, total;
00076
00077 struct ast_frame *f;
00078 struct ast_dsp *sildet;
00079
00080 if (prompt) {
00081 res = ast_streamfile(c, prompt, c->language);
00082 if (res < 0)
00083 return res;
00084 res = ast_waitstream(c,"");
00085 if (res < 0)
00086 return res;
00087 }
00088 rfmt = c->readformat;
00089 res = ast_set_read_format(c, AST_FORMAT_SLINEAR);
00090 if (res < 0) {
00091 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
00092 return -1;
00093 }
00094 sildet = ast_dsp_new();
00095 if (!sildet) {
00096 ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
00097 return -1;
00098 }
00099 writer = ast_writefile(dest, dstfmt, "Voice file", 0, 0, 0666);
00100 if (!writer) {
00101 ast_log(LOG_WARNING, "Unable to open file '%s' in format '%s' for writing\n", dest, dstfmt);
00102 ast_dsp_free(sildet);
00103 return -1;
00104 }
00105 for(;;) {
00106 if ((res = ast_waitfor(c, 2000)) < 0) {
00107 ast_log(LOG_NOTICE, "Waitfor failed while recording file '%s' format '%s'\n", dest, dstfmt);
00108 break;
00109 }
00110 if (res) {
00111 f = ast_read(c);
00112 if (!f) {
00113 ast_log(LOG_NOTICE, "Hungup while recording file '%s' format '%s'\n", dest, dstfmt);
00114 break;
00115 }
00116 if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) {
00117
00118 ast_frfree(f);
00119 break;
00120 } else if (f->frametype == AST_FRAME_VOICE) {
00121 ast_dsp_silence(sildet, f, &total);
00122 if (total > silence) {
00123
00124 ast_frfree(f);
00125 break;
00126 }
00127 totalms += f->samples / 8;
00128 if (totalms > maxsec * 1000) {
00129
00130 ast_log(LOG_NOTICE, "Constraining voice on '%s' to %d seconds\n", c->name, maxsec);
00131 ast_frfree(f);
00132 break;
00133 }
00134 }
00135 ast_frfree(f);
00136 }
00137 }
00138 res = ast_set_read_format(c, rfmt);
00139 if (res)
00140 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", c->name);
00141 ast_dsp_free(sildet);
00142 ast_closestream(writer);
00143 return 0;
00144 }
00145
00146 int ast_app_has_voicemail(const char *mailbox)
00147 {
00148 DIR *dir;
00149 struct dirent *de;
00150 char fn[256];
00151 char tmp[256]="";
00152 char *mb, *cur;
00153 char *context;
00154 int ret;
00155
00156 if (!strlen(mailbox))
00157 return 0;
00158 if (strchr(mailbox, ',')) {
00159 strncpy(tmp, mailbox, sizeof(tmp));
00160 mb = tmp;
00161 ret = 0;
00162 while((cur = strsep(&mb, ","))) {
00163 if (strlen(cur)) {
00164 if (ast_app_has_voicemail(cur))
00165 return 1;
00166 }
00167 }
00168 return 0;
00169 }
00170 strncpy(tmp, mailbox, sizeof(tmp) - 1);
00171 context = strchr(tmp, '@');
00172 if (context) {
00173 *context = '\0';
00174 context++;
00175 } else
00176 context = "default";
00177 snprintf(fn, sizeof(fn), "%s/voicemail/%s/%s/INBOX", (char *)ast_config_AST_SPOOL_DIR, context, tmp);
00178 dir = opendir(fn);
00179 if (!dir)
00180 return 0;
00181 while ((de = readdir(dir))) {
00182 if (!strncasecmp(de->d_name, "msg", 3))
00183 break;
00184 }
00185 closedir(dir);
00186 if (de)
00187 return 1;
00188 return 0;
00189 }
00190
00191 int ast_app_messagecount(const char *mailbox, int *newmsgs, int *oldmsgs)
00192 {
00193 DIR *dir;
00194 struct dirent *de;
00195 char fn[256];
00196 char tmp[256]="";
00197 char *mb, *cur;
00198 char *context;
00199 int ret;
00200 if (newmsgs)
00201 *newmsgs = 0;
00202 if (oldmsgs)
00203 *oldmsgs = 0;
00204
00205 if (!strlen(mailbox))
00206 return 0;
00207 if (strchr(mailbox, ',')) {
00208 int tmpnew, tmpold;
00209 strncpy(tmp, mailbox, sizeof(tmp));
00210 mb = tmp;
00211 ret = 0;
00212 while((cur = strsep(&mb, ", "))) {
00213 if (strlen(cur)) {
00214 if (ast_app_messagecount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
00215 return -1;
00216 else {
00217 if (newmsgs)
00218 *newmsgs += tmpnew;
00219 if (oldmsgs)
00220 *oldmsgs += tmpold;
00221 }
00222 }
00223 }
00224 return 0;
00225 }
00226 strncpy(tmp, mailbox, sizeof(tmp) - 1);
00227 context = strchr(tmp, '@');
00228 if (context) {
00229 *context = '\0';
00230 context++;
00231 } else
00232 context = "default";
00233 if (newmsgs) {
00234 snprintf(fn, sizeof(fn), "%s/voicemail/%s/%s/INBOX", (char *)ast_config_AST_SPOOL_DIR, context, tmp);
00235 dir = opendir(fn);
00236 if (dir) {
00237 while ((de = readdir(dir))) {
00238 if ((strlen(de->d_name) > 3) && !strncasecmp(de->d_name, "msg", 3) &&
00239 !strcasecmp(de->d_name + strlen(de->d_name) - 3, "txt"))
00240 (*newmsgs)++;
00241
00242 }
00243 closedir(dir);
00244 }
00245 }
00246 if (oldmsgs) {
00247 snprintf(fn, sizeof(fn), "%s/voicemail/%s/%s/Old", (char *)ast_config_AST_SPOOL_DIR, context, tmp);
00248 dir = opendir(fn);
00249 if (dir) {
00250 while ((de = readdir(dir))) {
00251 if ((strlen(de->d_name) > 3) && !strncasecmp(de->d_name, "msg", 3) &&
00252 !strcasecmp(de->d_name + strlen(de->d_name) - 3, "txt"))
00253 (*oldmsgs)++;
00254
00255 }
00256 closedir(dir);
00257 }
00258 }
00259 return 0;
00260 }