56270733b8b0eca2a42c6289989c5934745102fb
[asterisk/asterisk.git] / pbx / pbx_wilcalu.c
1 /** @file pbx_wilcalu.c 
2  *
3  * Asterisk -- A telephony toolkit for Linux.
4  *
5  * Trivial application to playback a sound file
6  * 
7  * Copyright (C) 1999, Mark Spencer
8  *
9  * Mark Spencer <markster@linux-support.net>
10  *
11  * This program is free software, distributed under the terms of
12  * the GNU General Public License
13
14  *  Autodialer for Asterisk 
15  *  Redirect dialstring thru fifo "/var/run/autodial.ctl"
16  *  Format of string is :
17  *  "tech/tele,filename&" ie. "tor1/23,file&"
18  */
19  
20 #include <asterisk/lock.h>
21 #include <asterisk/file.h>
22 #include <asterisk/logger.h>
23 #include <asterisk/channel.h>
24 #include <asterisk/pbx.h>
25 #include <asterisk/module.h>
26 #include <asterisk/translate.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <pthread.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <errno.h>
34 #include "../astconf.h"
35
36
37 // Globals
38 const   char dialfile[255];
39 static  char *tdesc = "Wil Cal U (Auto Dialer)";
40 static  pthread_t autodialer_thread;
41 static  char buf[257];
42 static  char lastbuf[257];//contains last partial buffer
43 static  char sendbuf[257];
44 extern  int errno;
45 STANDARD_LOCAL_USER;
46 LOCAL_USER_DECL;
47
48 //prototype
49 static void *dialstring(void *string);
50
51 // types
52 struct alarm_data {
53 time_t alarm_time;
54 int    snooze_len;
55 void   *dialstr;
56 };
57
58 static void *autodial(void *ignore)
59 {
60         pthread_t dialstring_thread;
61         char * sendbufptr=sendbuf;
62         int fd=open(dialfile,O_RDONLY);
63         printf("Entered Wil-Calu fd=%d\n",fd);
64         if(fd<0) {
65                 printf("Autodial: Unable to open file\n");
66                 pthread_exit(NULL);
67         }
68         memset(buf,0,257);
69         memset(lastbuf,0,257);
70         memset(sendbuf,0,257);
71         while(1){
72                 ssize_t bytes;
73                 void *pass;
74
75                 memset(buf,0,257);
76                 bytes=read(fd,buf,256);
77                 buf[(int)bytes]=0;
78
79                 if(bytes){
80                         int x;
81                         printf("WilCalu : Read Buf %s\n",buf);
82                         sendbufptr=sendbuf;
83                         for(x=0;lastbuf[x]!=0 && x<257;x++);
84                         if(x) {
85                                 memcpy(sendbuf,lastbuf,x);
86                                 sendbufptr+=x;
87                                 memset(lastbuf,0,257);
88                         }
89                         /* Process bytes read */
90                         for(x=0;x<bytes;x++){
91                                 /* if & then string is complete */
92                                 if(buf[x]=='&'){
93                                         if(NULL!=(pass=(void *)strdup(sendbuf))){
94                                                 pthread_create(&dialstring_thread,NULL,dialstring,pass);
95                                                 sendbufptr=sendbuf;
96                                                 memset(sendbuf,0,257);
97                                         }
98                                         else {
99                                                 perror("Autodial:Strdup failed");
100                                                 close(fd);
101                                                 pthread_exit(NULL);
102                                         }
103                                 } else {
104                                         if(buf[x]=='\n')
105                                                 continue;
106                                         *sendbufptr=buf[x];
107                                         sendbufptr++;
108                                         *sendbufptr=0;
109                                 }
110                         }
111                         if(sendbufptr!=sendbuf)
112                                 memcpy(lastbuf,sendbuf,sendbufptr-sendbuf+1);
113                 }
114         }
115         close(fd);
116         pthread_exit(NULL);
117         return NULL;
118 }
119
120 static void *snooze_alarm(void *pass){
121         
122         pthread_t dialstring_thread;
123         struct alarm_data *data=(struct alarm_data *)pass;
124         sleep(data->snooze_len);
125         pthread_create(&dialstring_thread,NULL,dialstring,data->dialstr);
126         // dialstring will free data->dialstr
127         free(pass);
128         pthread_exit(NULL);
129         return NULL;
130 }
131 static void  set_snooze_alarm(char *dialstr,int snooze_len){
132         pthread_t snooze_alarm_thread;
133         struct alarm_data *pass;
134         printf("Answered: Snooze Requested\n");
135         if(NULL==(pass=malloc(sizeof(struct alarm_data)))){
136                 perror("snooze_alarm: data");
137                 pthread_exit(NULL);
138         }
139         if(NULL==(pass->dialstr=(void *)strdup(dialstr))){
140                 free(pass);
141                 perror("snooze_alarm: dialstr");
142                 pthread_exit(NULL);
143         }
144         pass->snooze_len=snooze_len;
145         pthread_create(&snooze_alarm_thread,NULL,snooze_alarm,pass);
146 }
147                         
148 static void *dialstring(void *string){
149         struct ast_channel *channel;
150         char *bufptr,*destptr;
151         // ms affects number of rings
152         int  ms=10000;
153         int  cnt=0,first;
154         char tech[256];
155         char tele[256];
156         char filename[256];
157         int  answered=0;
158         for(first=0,bufptr=(char *)string,destptr=tech;*bufptr&&cnt<256;cnt++){
159                 if(*bufptr=='/' && !first){
160                         *destptr=0;
161                         destptr=tele;
162                         first=1;
163                 }
164                 else if(*bufptr==','){
165                         *destptr=0;
166                         destptr=filename;
167                 } else {
168                         *destptr=*bufptr;
169                         destptr++;
170                 }
171                 bufptr++;
172         } 
173         *destptr=0;
174         printf("Printing string arg: ");
175         printf((char *)string);
176         printf(" Eos\n");
177         if(strlen(tech)+strlen(tele)+strlen(filename)>256){
178                 printf("Autodial:Error string too long\n");
179                 free(string);
180                 pthread_exit(NULL);
181         }
182         printf("Autodial Tech %s(%d) Tele %s(%d) Filename %s(%d)\n",tech,strlen(tech),tele,strlen(tele),filename,strlen(filename));
183
184         channel=ast_request(tech,AST_FORMAT_SLINEAR,tele);
185         if(channel!=NULL){
186                 ast_call(channel,tele,10000);
187         }
188         else {
189                 printf("Autodial:Sorry unable to obtain channel\n");
190                 free(string);
191                 pthread_exit(NULL);
192         }
193         if(channel->_state==AST_STATE_UP)
194                 printf("Autodial:Line is Up\n");
195         while(ms>0){
196                 struct ast_frame *f;
197                 ms=ast_waitfor(channel,ms);
198                 f=ast_read(channel);
199                 if(!f){
200                         printf("Autodial:Hung Up\n");
201                         break;
202                 }
203                 if(f->frametype==AST_FRAME_CONTROL){
204                         if(f->subclass==AST_CONTROL_ANSWER){
205                                 printf("Autodial:Phone Answered\n");
206                                 if(channel->_state==AST_STATE_UP){
207                                         char res;
208                                         ast_streamfile(channel,filename,0);
209                                         // Press Five for snooze
210                                         res=ast_waitstream(channel, "37");
211                                         if(res=='3'){
212                                                 answered=1;
213                                                 set_snooze_alarm((char *)string,60);
214                                                 ast_streamfile(channel,"demo-thanks",0);
215                                                 ast_waitstream(channel, "");
216                                         }
217                                         else if(res=='7'){
218                                                 answered=1;
219                                                 ast_streamfile(channel,"demo-thanks",0);
220                                                 ast_waitstream(channel, "");
221                                         }
222                                         ast_stopstream(channel);
223                                         ms=0;
224                                 }
225                         }
226                         else if(f->subclass==AST_CONTROL_RINGING)
227                                 printf("Autodial:Phone Ringing end\n");
228                 }
229                 ast_frfree(f);
230         }
231         if(!answered)
232                 set_snooze_alarm((char *)string,5);
233         free(string);
234         ast_hangup(channel);
235         printf("Autodial:Hung up channel\n");
236         pthread_exit(NULL);
237         return NULL;
238 }
239 int unload_module(void)
240 {
241         STANDARD_HANGUP_LOCALUSERS;
242         unlink(dialfile);
243         return 0;
244 }
245
246 int load_module(void)
247 {
248         int val;
249         snprintf((char *)dialfile,sizeof(dialfile)-1,"%s/%s",(char *)ast_config_AST_RUN_DIR,"autodial.ctl");
250         if((val=mkfifo(dialfile, 0700))){
251                 if(errno!=EEXIST){
252                         printf("Error:%d Creating Autodial FIFO\n",errno);
253                         return 0;
254                 }
255         }
256         pthread_create(&autodialer_thread,NULL,autodial,NULL);
257         return 0;
258 }
259
260 char *description(void)
261 {
262         return tdesc;
263 }
264
265 int usecount(void)
266 {
267         int res;
268         STANDARD_USECOUNT(res);
269         return res;
270 }
271
272 char *key()
273 {
274         return ASTERISK_GPL_KEY;
275 }