eagi-sphinx-test.c 5.0 KB

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