autodial update
[asterisk/asterisk.git] / res / res_musiconhold.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Routines implementing music on hold
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 <asterisk/lock.h>
15 #include <asterisk/file.h>
16 #include <asterisk/logger.h>
17 #include <asterisk/channel.h>
18 #include <asterisk/pbx.h>
19 #include <asterisk/options.h>
20 #include <asterisk/module.h>
21 #include <asterisk/translate.h>
22 #include <asterisk/say.h>
23 #include <asterisk/channel_pvt.h>
24 #include <asterisk/musiconhold.h>
25 #include <asterisk/config.h>
26 #include <asterisk/utils.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <signal.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <sys/time.h>
35 #include <sys/signal.h>
36 #include <netinet/in.h>
37 #include <sys/stat.h>
38 #include <dirent.h>
39 #ifdef ZAPATA_MOH
40 #ifdef __linux__
41 #include <linux/zaptel.h>
42 #else
43 #include <zaptel.h>
44 #endif /* __linux__ */
45 #endif
46 #include <unistd.h>
47 #include <sys/ioctl.h>
48
49 static char *app0 = "MusicOnHold";
50 static char *app1 = "WaitMusicOnHold";
51 static char *app2 = "SetMusicOnHold";
52
53 static char *synopsis0 = "Play Music On Hold indefinitely";
54 static char *synopsis1 = "Wait, playing Music On Hold";
55 static char *synopsis2 = "Set default Music On Hold class";
56
57 static char *descrip0 = "MusicOnHold(class): "
58 "Plays hold music specified by class.  If omitted, the default\n"
59 "music source for the channel will be used. Set the default \n"
60 "class with the SetMusicOnHold() application.\n"
61 "Returns -1 on hangup.\n"
62 "Never returns otherwise.\n";
63
64 static char *descrip1 = "WaitMusicOnHold(delay): "
65 "Plays hold music specified number of seconds.  Returns 0 when\n"
66 "done, or -1 on hangup.  If no hold music is available, the delay will\n"
67 "still occur with no sound.\n";
68
69 static char *descrip2 = "SetMusicOnHold(class): "
70 "Sets the default class for music on hold for a given channel.  When\n"
71 "music on hold is activated, this class will be used to select which\n"
72 "music is played.\n";
73
74 struct mohclass {
75         char class[80];
76         char dir[256];
77         char miscargs[256];
78         char customexec[256];
79         int destroyme;
80         int pid;                /* PID of mpg123 */
81         int quiet;
82         pthread_t thread;
83         struct mohdata *members;
84         /* Source of audio */
85         int srcfd;
86         /* FD for timing source */
87         int pseudofd;
88         struct mohclass *next;
89 };
90
91 struct mohdata {
92         int pipe[2];
93         int origwfmt;
94         struct mohclass *parent;
95         struct mohdata *next;
96 };
97
98 static struct mohclass *mohclasses;
99
100 AST_MUTEX_DEFINE_STATIC(moh_lock);
101
102 #define LOCAL_MPG_123 "/usr/local/bin/mpg123"
103 #define MPG_123 "/usr/bin/mpg123"
104 #define MAX_MP3S 256
105
106 static int spawn_mp3(struct mohclass *class)
107 {
108         int fds[2];
109         int files=0;
110         char fns[MAX_MP3S][80];
111         char *argv[MAX_MP3S + 50];
112         char xargs[256];
113         char *argptr;
114         int argc;
115         DIR *dir;
116         struct dirent *de;
117
118         if(class->customexec && strlen(class->customexec)) {
119                 argc = 0;
120                 strncpy(xargs, class->customexec, sizeof(xargs) - 1);
121                 argptr = xargs;
122                 while(argptr && strlen(argptr)) {
123                         argv[argc] = argptr;
124                         argptr = strchr(argptr, ',');
125                         if (argptr) {
126                                 *argptr = '\0';
127                                 argptr++;
128                         }
129                         argc++;
130                 }
131         }
132         else {
133           dir = opendir(class->dir);
134           if (!dir) {
135             ast_log(LOG_WARNING, "%s is not a valid directory\n", class->dir);
136             return -1;
137           }
138           argv[0] = "mpg123";
139           argv[1] = "-q";
140           argv[2] = "-s";
141           argv[3] = "--mono";
142           argv[4] = "-r";
143           argv[5] = "8000";
144           argv[6] = "-b";
145           argv[7] = "2048";
146           argc = 8;
147           if (class->quiet) {
148             argv[argc++] = "-f";
149             argv[argc++] = "8192";
150           }
151
152           /* Look for extra arguments and add them to the list */
153           strncpy(xargs, class->miscargs, sizeof(xargs) - 1);
154           argptr = xargs;
155           while(argptr && strlen(argptr)) {
156             argv[argc++] = argptr;
157             argptr = strchr(argptr, ',');
158             if (argptr) {
159               *argptr = '\0';
160               argptr++;
161             }
162           }
163
164                 
165
166
167           files = 0;
168           while((de = readdir(dir)) && (files < MAX_MP3S)) {
169             if ((strlen(de->d_name) > 3) && !strcasecmp(de->d_name + strlen(de->d_name) - 4, ".mp3")) {
170               strncpy(fns[files], de->d_name, sizeof(fns[files]));
171               argv[argc++] = fns[files];
172               files++;
173             }
174           }
175           argv[argc] = NULL;
176           closedir(dir);
177         }
178
179
180
181           if (pipe(fds)) {      
182             ast_log(LOG_WARNING, "Pipe failed\n");
183             return -1;
184           }
185 #if 0
186         printf("%d files total, %d args total\n", files, argc);
187         {
188                 int x;
189                 for (x=0;argv[x];x++)
190                         printf("arg%d: %s\n", x, argv[x]);
191         }
192 #endif  
193         if (!files &&  class->customexec && ! strlen(class->customexec)) {
194                 ast_log(LOG_WARNING, "Found no files in '%s'\n", class->dir);
195                 close(fds[0]);
196                 close(fds[1]);
197                 return -1;
198         }
199
200
201
202         class->pid = fork();
203
204         if (class->pid < 0) {
205                 close(fds[0]);
206                 close(fds[1]);
207                 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno));
208                 return -1;
209         }
210
211
212
213
214
215         if (!class->pid) {
216                 int x;
217                 close(fds[0]);
218                 /* Stdout goes to pipe */
219
220                 dup2(fds[1], STDOUT_FILENO);
221
222
223
224
225                 
226                   /* Close unused file descriptors */
227                   for (x=3;x<8192;x++)
228                     close(x);
229                   /* Child */
230                 
231
232                   /* try custom */
233                 execv(argv[0], argv);
234                 chdir(class->dir);
235                 /* Default install is /usr/local/bin */
236                 execv(LOCAL_MPG_123, argv);
237                 /* Many places have it in /usr/bin */
238                 execv(MPG_123, argv);
239                 /* Check PATH as a last-ditch effort */
240                 execvp("mpg123", argv);
241                 ast_log(LOG_WARNING, "Exec failed: %s\n", strerror(errno));
242                 close(fds[1]);
243                 exit(1);
244         } else {
245                 /* Parent */
246                 close(fds[1]);
247         }
248         return fds[0];
249 }
250
251 static void *monmp3thread(void *data)
252 {
253 #define MOH_MS_INTERVAL         100
254
255         struct mohclass *class = data;
256         struct mohdata *moh;
257         char buf[8192];
258         short sbuf[8192];
259         int res, res2;
260         struct timeval tv;
261         struct timeval tv_tmp;
262         long error_sec, error_usec;
263         long delay;
264
265         tv_tmp.tv_sec = 0;
266         tv_tmp.tv_usec = 0;
267         tv.tv_sec = 0;
268         tv.tv_usec = 0;
269         error_sec = 0;
270         error_usec = 0;
271         for(;/* ever */;) {
272                 /* Spawn mp3 player if it's not there */
273                 if (class->srcfd < 0) {
274                         if ((class->srcfd = spawn_mp3(class)) < 0) {
275                                 ast_log(LOG_WARNING, "unable to spawn mp3player\n");
276                                 /* Try again later */
277                                 sleep(500);
278                         }
279                 }
280                 if (class->pseudofd > -1) {
281                         /* Pause some amount of time */
282                         res = read(class->pseudofd, buf, sizeof(buf));
283                 } else {
284                         /* Reliable sleep */
285                         if (gettimeofday(&tv_tmp, NULL) < 0) {
286                                 ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
287                                 return NULL;
288                         }
289                         if (((unsigned long)(tv.tv_sec) > 0)&&((unsigned long)(tv.tv_usec) > 0)) {
290                                 if ((unsigned long)(tv_tmp.tv_usec) < (unsigned long)(tv.tv_usec)) {
291                                         tv_tmp.tv_usec += 1000000;
292                                         tv_tmp.tv_sec -= 1;
293                                 }
294                                 error_sec = (unsigned long)(tv_tmp.tv_sec) - (unsigned long)(tv.tv_sec);
295                                 error_usec = (unsigned long)(tv_tmp.tv_usec) - (unsigned long)(tv.tv_usec);
296                         } else {
297                                 error_sec = 0;
298                                 error_usec = 0;
299                         }
300                         if (error_sec * 1000 + error_usec / 1000 < MOH_MS_INTERVAL) {
301                                 tv.tv_sec = tv_tmp.tv_sec + (MOH_MS_INTERVAL/1000 - error_sec);
302                                 tv.tv_usec = tv_tmp.tv_usec + ((MOH_MS_INTERVAL % 1000) * 1000 - error_usec);
303                                 delay = (MOH_MS_INTERVAL/1000 - error_sec) * 1000 +
304                                                         ((MOH_MS_INTERVAL % 1000) * 1000 - error_usec) / 1000;
305                         } else {
306                                 ast_log(LOG_NOTICE, "Request to schedule in the past?!?!\n");
307                                 tv.tv_sec = tv_tmp.tv_sec;
308                                 tv.tv_usec = tv_tmp.tv_usec;
309                                 delay = 0;
310                         }
311                         if (tv.tv_usec > 1000000) {
312                                 tv.tv_sec++;
313                                 tv.tv_usec-= 1000000;
314                         }
315                         if (delay > 0)
316                                 usleep(delay * 1000);
317                         res = 800;              /* 800 samples */
318                 }
319                 if (!class->members)
320                         continue;
321                 /* Read mp3 audio */
322                 if ((res2 = read(class->srcfd, sbuf, res * 2)) != res * 2) {
323                         if (!res2) {
324                                 close(class->srcfd);
325                                 class->srcfd = -1;
326                                 if (class->pid) {
327                                         kill(class->pid, SIGKILL);
328                                         class->pid = 0;
329                                 }
330                         } else
331                                 ast_log(LOG_DEBUG, "Read %d bytes of audio while expecting %d\n", res2, res * 2);
332                         continue;
333                 }
334                 ast_mutex_lock(&moh_lock);
335                 moh = class->members;
336                 while(moh) {
337                         /* Write data */
338                         if ((res = write(moh->pipe[1], sbuf, res2)) != res2) 
339                                 if (option_debug)
340                                         ast_log(LOG_DEBUG, "Only wrote %d of %d bytes to pipe\n", res, res2);
341                         moh = moh->next;
342                 }
343                 ast_mutex_unlock(&moh_lock);
344         }
345         return NULL;
346 }
347
348 static int moh0_exec(struct ast_channel *chan, void *data)
349 {
350         if (ast_moh_start(chan, data)) {
351                 ast_log(LOG_WARNING, "Unable to start music on hold (class '%s') on channel %s\n", (char *)data, chan->name);
352                 return -1;
353         }
354         while(!ast_safe_sleep(chan, 10000));
355         return -1;
356 }
357
358 static int moh1_exec(struct ast_channel *chan, void *data)
359 {
360         int res;
361         if (!data || !atoi(data)) {
362                 ast_log(LOG_WARNING, "WaitMusicOnHold requires an argument (number of seconds to wait)\n");
363                 return -1;
364         }
365         if (ast_moh_start(chan, NULL)) {
366                 ast_log(LOG_WARNING, "Unable to start music on hold (class '%s') on channel %s\n", (char *)data, chan->name);
367                 return -1;
368         }
369         res = ast_safe_sleep(chan, atoi(data) * 1000);
370         ast_moh_stop(chan);
371         return res;
372 }
373
374 static int moh2_exec(struct ast_channel *chan, void *data)
375 {
376         if (!data || ast_strlen_zero(data)) {
377                 ast_log(LOG_WARNING, "SetMusicOnHold requires an argument (class)\n");
378                 return -1;
379         }
380         strncpy(chan->musicclass, data, sizeof(chan->musicclass));
381         return 0;
382 }
383
384 static struct mohclass *get_mohbyname(char *name)
385 {
386         struct mohclass *moh;
387         moh = mohclasses;
388         while(moh) {
389                 if (!strcasecmp(name, moh->class))
390                         return moh;
391                 moh = moh->next;
392         }
393         return NULL;
394 }
395
396 static struct mohdata *mohalloc(struct mohclass *cl)
397 {
398         struct mohdata *moh;
399         long flags;
400         moh = malloc(sizeof(struct mohdata));
401         if (!moh)
402                 return NULL;
403         memset(moh, 0, sizeof(struct mohdata));
404         if (pipe(moh->pipe)) {
405                 ast_log(LOG_WARNING, "Failed to create pipe: %s\n", strerror(errno));
406                 free(moh);
407                 return NULL;
408         }
409         /* Make entirely non-blocking */
410         flags = fcntl(moh->pipe[0], F_GETFL);
411         fcntl(moh->pipe[0], F_SETFL, flags | O_NONBLOCK);
412         flags = fcntl(moh->pipe[1], F_GETFL);
413         fcntl(moh->pipe[1], F_SETFL, flags | O_NONBLOCK);
414         moh->parent = cl;
415         moh->next = cl->members;
416         cl->members = moh;
417         return moh;
418 }
419
420 static void moh_release(struct ast_channel *chan, void *data)
421 {
422         struct mohdata *moh = data, *prev, *cur;
423         int oldwfmt;
424         ast_mutex_lock(&moh_lock);
425         /* Unlink */
426         prev = NULL;
427         cur = moh->parent->members;
428         while(cur) {
429                 if (cur == moh) {
430                         if (prev)
431                                 prev->next = cur->next;
432                         else
433                                 moh->parent->members = cur->next;
434                         break;
435                 }
436                 prev = cur;
437                 cur = cur->next;
438         }
439         ast_mutex_unlock(&moh_lock);
440         close(moh->pipe[0]);
441         close(moh->pipe[1]);
442         oldwfmt = moh->origwfmt;
443         free(moh);
444         if (chan) {
445                 if (oldwfmt && ast_set_write_format(chan, oldwfmt)) 
446                         ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(oldwfmt));
447                 if (option_verbose > 2)
448                         ast_verbose(VERBOSE_PREFIX_3 "Stopped music on hold on %s\n", chan->name);
449         }
450 }
451
452 static void *moh_alloc(struct ast_channel *chan, void *params)
453 {
454         struct mohdata *res;
455         struct mohclass *class;
456         ast_mutex_lock(&moh_lock);
457         class = get_mohbyname(params);
458         if (class)
459                 res = mohalloc(class);
460         else {
461                 if (strcasecmp(params, "default"))
462                         ast_log(LOG_WARNING, "No class: %s\n", (char *)params);
463                 res = NULL;
464         }
465         ast_mutex_unlock(&moh_lock);
466         if (res) {
467                 res->origwfmt = chan->writeformat;
468                 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
469                         ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format\n", chan->name);
470                         moh_release(NULL, res);
471                         res = NULL;
472                 }
473 #if 0
474                 /* Allow writes to interrupt */
475                 chan->writeinterrupt = 1;
476 #endif          
477                 if (option_verbose > 2)
478                         ast_verbose(VERBOSE_PREFIX_3 "Started music on hold, class '%s', on %s\n", (char *)params, chan->name);
479         }
480         return res;
481 }
482
483 static int moh_generate(struct ast_channel *chan, void *data, int len, int samples)
484 {
485         struct ast_frame f;
486         struct mohdata *moh = data;
487         short buf[1280 + AST_FRIENDLY_OFFSET / 2];
488         int res;
489
490         len = samples * 2;
491         if (len > sizeof(buf) - AST_FRIENDLY_OFFSET) {
492                 ast_log(LOG_WARNING, "Only doing %d of %d requested bytes on %s\n", (int)sizeof(buf), (int)len, chan->name);
493                 len = sizeof(buf) - AST_FRIENDLY_OFFSET;
494         }
495         res = read(moh->pipe[0], buf + AST_FRIENDLY_OFFSET/2, len);
496 #if 0
497         if (res != len) {
498                 ast_log(LOG_WARNING, "Read only %d of %d bytes: %s\n", res, len, strerror(errno));
499         }
500 #endif
501         if (res > 0) {
502                 memset(&f, 0, sizeof(f));
503                 f.frametype = AST_FRAME_VOICE;
504                 f.subclass = AST_FORMAT_SLINEAR;
505                 f.mallocd = 0;
506                 f.datalen = res;
507                 f.samples = res / 2;
508                 f.data = buf + AST_FRIENDLY_OFFSET / 2;
509                 f.offset = AST_FRIENDLY_OFFSET;
510                 if (ast_write(chan, &f)< 0) {
511                         ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror(errno));
512                         return -1;
513                 }
514         }
515         return 0;
516 }
517
518 static struct ast_generator mohgen = 
519 {
520         alloc: moh_alloc,
521         release: moh_release,
522         generate: moh_generate,
523 };
524
525 static int moh_register(char *classname, char *mode, char *param, char *miscargs,char *customexec)
526 {
527         struct mohclass *moh;
528         char custmode[7] = "custom";
529         custmode[7]= (char) NULL;
530 #ifdef ZAPATA_MOH
531         int x;
532 #endif
533         ast_mutex_lock(&moh_lock);
534         moh = get_mohbyname(classname);
535         ast_mutex_unlock(&moh_lock);
536         if (moh) {
537                 ast_log(LOG_WARNING, "Music on Hold '%s' already exists\n", classname);
538                 return -1;
539         }
540         moh = malloc(sizeof(struct mohclass));
541         if (!moh)
542                 return -1;
543         memset(moh, 0, sizeof(struct mohclass));
544
545         strncpy(moh->class, classname, sizeof(moh->class) - 1);
546
547         if(customexec && strlen(customexec)) {
548           strncpy(moh->customexec, customexec, sizeof(moh->customexec) - 1);
549           mode=custmode;
550
551         }
552
553         if (miscargs)
554           strncpy(moh->miscargs, miscargs, sizeof(moh->miscargs) - 1);
555
556
557
558
559
560
561
562
563
564         if (!strcasecmp(mode, "mp3") || !strcasecmp(mode, "quietmp3") || !strcasecmp(mode, "httpmp3") || !strcasecmp(mode, "custom")) {
565
566
567           if(! customexec || (customexec && ! strlen(customexec))) {
568                 if (!strcasecmp(mode, "quietmp3"))
569                         moh->quiet = 1;
570                 strncpy(moh->dir, param, sizeof(moh->dir) - 1);
571           }
572                 moh->srcfd = -1;
573 #ifdef ZAPATA_MOH
574                 /* It's an MP3 Moh -- Open /dev/zap/pseudo for timing...  Is
575                    there a better, yet reliable way to do this? */
576                 moh->pseudofd = open("/dev/zap/pseudo", O_RDONLY);
577                 if (moh->pseudofd < 0) {
578                         ast_log(LOG_WARNING, "Unable to open pseudo channel for timing...  Sound may be choppy.\n");
579                 } else {
580                         x = 320;
581                         ioctl(moh->pseudofd, ZT_SET_BLOCKSIZE, &x);
582                 }
583 #else
584                 moh->pseudofd = -1;
585 #endif
586
587
588
589                 if (pthread_create(&moh->thread, NULL, monmp3thread, moh)) {
590                         ast_log(LOG_WARNING, "Unable to create moh...\n");
591                         if (moh->pseudofd > -1)
592                                 close(moh->pseudofd);
593                         free(moh);
594                         return -1;
595                 }
596         } else {
597                 ast_log(LOG_WARNING, "Don't know how to do a mode '%s' music on hold\n", mode);
598                 free(moh);
599                 return -1;
600         }
601         ast_mutex_lock(&moh_lock);
602         moh->next = mohclasses;
603         mohclasses = moh;
604         ast_mutex_unlock(&moh_lock);
605         return 0;
606 }
607
608 int ast_moh_start(struct ast_channel *chan, char *class)
609 {
610         if (!class || ast_strlen_zero(class))
611                 class = chan->musicclass;
612         if (!class || ast_strlen_zero(class))
613                 class = "default";
614         return ast_activate_generator(chan, &mohgen, class);
615 }
616
617 void ast_moh_stop(struct ast_channel *chan)
618 {
619         ast_deactivate_generator(chan);
620 }
621
622 static void load_moh_classes(void)
623 {
624         struct ast_config *cfg;
625         struct ast_variable *var;
626         char *data;
627         char *args;
628         cfg = ast_load("musiconhold.conf");
629         if (cfg) {
630                 var = ast_variable_browse(cfg, "classes");
631                 while(var) {
632                         data = strchr(var->value, ':');
633                         if (data) {
634                                 *data = '\0';
635                                 data++;
636                                 args = strchr(data, ',');
637                                 if (args) {
638                                         *args = '\0';
639                                         args++;
640                                 }
641                                 moh_register(var->name, var->value, data,args,NULL);
642                         }
643                         var = var->next;
644                 }
645
646
647                 var = ast_variable_browse(cfg, "custom_exec");
648                 while(var) {
649
650                   moh_register(var->name,NULL,NULL,NULL,var->value);
651                   var = var->next;
652                 }
653
654
655                 ast_destroy(cfg);
656         }
657 }
658
659 static void ast_moh_destroy(void)
660 {
661         struct mohclass *moh;
662         char buff[8192];
663         int bytes, tbytes=0, stime = 0;
664         if (option_verbose > 1)
665                 ast_verbose(VERBOSE_PREFIX_2 "Destroying any remaining musiconhold processes\n");
666         ast_mutex_lock(&moh_lock);
667         moh = mohclasses;
668         while(moh) {
669                 if (moh->pid) {
670                         ast_log(LOG_DEBUG, "killing %d!\n", moh->pid);
671                         stime = time(NULL);
672                         kill(moh->pid, SIGKILL);
673                         while ((bytes = read(moh->srcfd, buff, 8192)) && time(NULL) < stime + 5) {
674                                 tbytes = tbytes + bytes;
675                         }
676                         ast_log(LOG_DEBUG, "mpg123 pid %d and child died after %d bytes read\n", moh->pid, tbytes);
677                         close(moh->srcfd);
678                         moh->pid = 0;
679                         }
680                 moh = moh->next;
681         }
682         ast_mutex_unlock(&moh_lock);
683 }
684
685 int load_module(void)
686 {
687         int res;
688         load_moh_classes();
689         res = ast_register_application(app0, moh0_exec, synopsis0, descrip0);
690         ast_register_atexit(ast_moh_destroy);
691         if (!res)
692                 res = ast_register_application(app1, moh1_exec, synopsis1, descrip1);
693         if (!res)
694                 res = ast_register_application(app2, moh2_exec, synopsis2, descrip2);
695         return res;
696 }
697
698 int unload_module(void)
699 {
700         return -1;
701 }
702
703 char *description(void)
704 {
705         return "Music On Hold Resource";
706 }
707
708 int usecount(void)
709 {
710         /* Never allow Music On Hold to be unloaded
711            unresolve needed symbols in the dialer */
712 #if 0
713         int res;
714         STANDARD_USECOUNT(res);
715         return res;
716 #else
717         return 1;
718 #endif
719 }
720
721 char *key()
722 {
723         return ASTERISK_GPL_KEY;
724 }