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