move tools used during build into build_tools subdirectory
[asterisk/asterisk.git] / agi / eagi-sphinx-test.c
1 /*
2  * Extended AGI test application
3  *
4  * This code is released into public domain
5  * without any warranty of any kind.
6  *
7  */
8
9 #include <stdio.h>
10 #include <unistd.h>
11 #include <stdlib.h>
12 #include <errno.h>
13 #include <string.h>
14 #include <sys/select.h>
15 #include <fcntl.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
19 #include <netdb.h>
20 #ifdef SOLARIS
21 #include <solaris-compat/compat.h>
22 #endif
23
24 #define AUDIO_FILENO (STDERR_FILENO + 1)
25
26 #define SPHINX_HOST "192.168.1.108"
27 #define SPHINX_PORT 3460
28
29 static int sphinx_sock = -1;
30
31 static int connect_sphinx(void)
32 {
33         struct hostent *hp;
34         struct sockaddr_in sin;
35         int res;
36         hp = gethostbyname(SPHINX_HOST);
37         if (!hp) {
38                 fprintf(stderr, "Unable to resolve '%s'\n", SPHINX_HOST);
39                 return -1;
40         }
41         sphinx_sock = socket(PF_INET, SOCK_STREAM, 0);
42         if (sphinx_sock < 0) {
43                 fprintf(stderr, "Unable to allocate socket: %s\n", strerror(errno));
44                 return -1;
45         }
46         memset(&sin, 0, sizeof(sin));
47         sin.sin_family = AF_INET;
48         sin.sin_port = htons(SPHINX_PORT);
49         memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
50         if (connect(sphinx_sock, (struct sockaddr *)&sin, sizeof(sin))) {
51                 fprintf(stderr, "Unable to connect on socket: %s\n", strerror(errno));
52                 close(sphinx_sock);
53                 sphinx_sock = -1;
54                 return -1;
55         }
56         res = fcntl(sphinx_sock, F_GETFL);
57         if ((res < 0) || (fcntl(sphinx_sock, F_SETFL, res | O_NONBLOCK) < 0)) {
58                 fprintf(stderr, "Unable to set flags on socket: %s\n", strerror(errno));
59                 close(sphinx_sock);
60                 sphinx_sock = -1;
61                 return -1;
62         }
63         return 0;
64 }
65
66 static int read_environment(void)
67 {
68         char buf[256];
69         char *val;
70         /* Read environment */
71         for(;;) {
72                 fgets(buf, sizeof(buf), stdin);
73                 if (feof(stdin))
74                         return -1;
75                 buf[strlen(buf) - 1] = '\0';
76                 /* Check for end of environment */
77                 if (!strlen(buf))
78                         return 0;
79                 val = strchr(buf, ':');
80                 if (!val) {
81                         fprintf(stderr, "Invalid environment: '%s'\n", buf);
82                         return -1;
83                 }
84                 *val = '\0';
85                 val++;
86                 val++;
87                 /* Skip space */
88                 fprintf(stderr, "Environment: '%s' is '%s'\n", buf, val);
89
90                 /* Load into normal environment */
91                 setenv(buf, val, 1);
92                 
93         }
94         /* Never reached */
95         return 0;
96 }
97
98 static char *wait_result(void)
99 {
100         fd_set fds;
101         int res;
102         int max;
103         static char astresp[256];
104         static char sphinxresp[256];
105         char audiobuf[4096];
106         for (;;) {
107                 FD_ZERO(&fds);
108                 FD_SET(STDIN_FILENO, &fds);
109                 FD_SET(AUDIO_FILENO, &fds);
110                 max = AUDIO_FILENO;
111                 if (sphinx_sock > -1) {
112                         FD_SET(sphinx_sock, &fds);
113                         if (sphinx_sock > max)
114                                 max = sphinx_sock;
115                 }
116                 /* Wait for *some* sort of I/O */
117                 res = select(max + 1, &fds, NULL, NULL, NULL);
118                 if (res < 0) {
119                         fprintf(stderr, "Error in select: %s\n", strerror(errno));
120                         return NULL;
121                 }
122                 if (FD_ISSET(STDIN_FILENO, &fds)) {
123                         fgets(astresp, sizeof(astresp), stdin);
124                         if (feof(stdin)) {
125                                 fprintf(stderr, "Got hungup on apparently\n");
126                                 return NULL;
127                         }
128                         astresp[strlen(astresp) - 1] = '\0';
129                         fprintf(stderr, "Ooh, got a response from Asterisk: '%s'\n", astresp);
130                         return astresp;
131                 }
132                 if (FD_ISSET(AUDIO_FILENO, &fds)) {
133                         res = read(AUDIO_FILENO, audiobuf, sizeof(audiobuf));
134                         if (res > 0) {
135                                 if (sphinx_sock > -1) 
136                                         write(sphinx_sock, audiobuf, res);
137                         }
138                 }
139                 if ((sphinx_sock > -1) && FD_ISSET(sphinx_sock, &fds)) {
140                         res = read(sphinx_sock, sphinxresp, sizeof(sphinxresp));
141                         if (res > 0) {
142                                 fprintf(stderr, "Oooh, Sphinx found a token: '%s'\n", sphinxresp);
143                                 return sphinxresp;
144                         } else if (res == 0) {
145                                 fprintf(stderr, "Hrm, lost sphinx, guess we're on our own\n");
146                                 close(sphinx_sock);
147                                 sphinx_sock = -1;
148                         }
149                 }
150         }
151                 
152 }
153
154 static char *run_command(char *command)
155 {
156         fprintf(stdout, "%s\n", command);
157         return wait_result();
158 }
159
160 static int run_script(void)
161 {
162         char *res;
163         res = run_command("STREAM FILE demo-enterkeywords 0123456789*#");
164         if (!res) {
165                 fprintf(stderr, "Failed to execute command\n");
166                 return -1;
167         }
168         fprintf(stderr, "1. Result is '%s'\n", res);
169         res = run_command("STREAM FILE demo-nomatch 0123456789*#");
170         if (!res) {
171                 fprintf(stderr, "Failed to execute command\n");
172                 return -1;
173         }
174         fprintf(stderr, "2. Result is '%s'\n", res);
175         res = run_command("SAY NUMBER 23452345 0123456789*#");
176         if (!res) {
177                 fprintf(stderr, "Failed to execute command\n");
178                 return -1;
179         }
180         fprintf(stderr, "3. Result is '%s'\n", res);
181         res = run_command("GET DATA demo-enterkeywords");
182         if (!res) {
183                 fprintf(stderr, "Failed to execute command\n");
184                 return -1;
185         }
186         fprintf(stderr, "4. Result is '%s'\n", res);
187         res = run_command("STREAM FILE auth-thankyou \"\"");
188         if (!res) {
189                 fprintf(stderr, "Failed to execute command\n");
190                 return -1;
191         }
192         fprintf(stderr, "5. Result is '%s'\n", res);
193         return 0;
194 }
195
196 int main(int argc, char *argv[])
197 {
198         char *tmp;
199         int ver = 0;
200         int subver = 0;
201         /* Setup stdin/stdout for line buffering */
202         setlinebuf(stdin);
203         setlinebuf(stdout);
204         if (read_environment()) {
205                 fprintf(stderr, "Failed to read environment: %s\n", strerror(errno));
206                 exit(1);
207         }
208         connect_sphinx();
209         tmp = getenv("agi_enhanced");
210         if (tmp) {
211                 if (sscanf(tmp, "%d.%d", &ver, &subver) != 2)
212                         ver = 0;
213         }
214         if (ver < 1) {
215                 fprintf(stderr, "No enhanced AGI services available.  Use EAGI, not AGI\n");
216                 exit(1);
217         }
218         if (run_script())
219                 return -1;
220         exit(0);
221 }