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