00001
00017
00018
00019
00020
00021
00022
00023
00024 #include <julius.h>
00025 #include <stdarg.h>
00026
00027 #define MAXBUFLEN 4096
00028 static int listen_sd = -1;
00029 static char mbuf[MAXBUFLEN];
00030
00031
00043 static boolean process_active = TRUE;
00044
00050 static boolean process_want_terminate = FALSE;
00051
00059 static boolean process_want_reload = FALSE;
00060
00061 #ifdef USE_DFA
00062
00063 enum{SM_TERMINATE, SM_PAUSE, SM_WAIT};
00065 static short gram_switch_input_method = SM_PAUSE;
00066 #endif
00067
00088 void
00089 main_module_loop()
00090 {
00091 #if !defined(_WIN32) || defined(__CYGWIN32__)
00092 pid_t cid;
00093 #endif
00094
00095
00096 if ((listen_sd = ready_as_server(module_port)) < 0) {
00097 j_error("Error: failed to bind socket\n");
00098 }
00099
00100 j_printf ("
00101 j_printf ("
00102 j_printf ("
00103 j_printf ("
00104 j_printf ("
00105
00106 #if defined(_WIN32) && !defined(__CYGWIN32__)
00107
00108 /* Win32: no fork, just wait for one connection and proceed */
00109 if ((module_sd = accept_from(listen_sd)) < 0) {
00110 j_error("Error: failed to accept connection\n");
00111 }
00112 /* call main recognition loop here */
00113 main_recognition_loop();
00114
00115 #else
00116
00117 /* server loop */
00118 for(;;) {
00119 /* accept connection from a client */
00120 if ((module_sd = accept_from(listen_sd)) < 0) {
00121 j_error("Error: failed to accept connection\n");
00122 }
00123 /* fork this process */
00124 if ((cid = fork()) != 0) {
00125 /* parent process */
00126 j_printf("
00127 close_socket(module_sd);
00128 continue;
00129 }
00130
00131 close_socket(listen_sd);
00132
00133 main_recognition_loop();
00134 }
00135
00136 #endif
00137 }
00138
00151 boolean
00152 module_disconnect()
00153 {
00154 if (close_socket(module_sd) < 0) return FALSE;
00155 module_sd = -1;
00156 return TRUE;
00157 }
00158
00171 boolean
00172 module_is_connected()
00173 {
00174 if (module_sd < 0) return FALSE;
00175 return TRUE;
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 #ifdef USE_DFA
00218 static boolean
00219 msock_read_grammar(DFA_INFO **ret_dfa, WORD_INFO **ret_winfo)
00220 {
00221 DFA_INFO *dfa;
00222 WORD_INFO *winfo;
00223
00224
00225 dfa = dfa_info_new();
00226 if (!
00227 #ifdef WINSOCK
00228 rddfa_sd(module_sd, dfa)
00229 #else
00230 rddfa_fd(module_sd, dfa)
00231 #endif
00232 ) {
00233 return FALSE;
00234 }
00235 winfo = word_info_new();
00236
00237 if (!
00238 #ifdef WINSOCK
00239 voca_load_htkdict_sd(module_sd, winfo, hmminfo, FALSE)
00240 #else
00241 voca_load_htkdict_fd(module_sd, winfo, hmminfo, FALSE)
00242 #endif
00243 ) {
00244 dfa_info_free(dfa);
00245 return FALSE;
00246 }
00247 *ret_dfa = dfa;
00248 *ret_winfo = winfo;
00249 return TRUE;
00250 }
00251
00268 static void
00269 set_grammar_switch_timing_flag()
00270 {
00271 if (process_active) {
00272
00273
00274 switch(gram_switch_input_method) {
00275 case SM_TERMINATE:
00276 process_want_terminate = TRUE;
00277 process_want_reload = TRUE;
00278 break;
00279 case SM_PAUSE:
00280 process_want_terminate = FALSE;
00281 process_want_reload = TRUE;
00282 break;
00283 case SM_WAIT:
00284 process_want_terminate = FALSE;
00285 process_want_reload = FALSE;
00286 break;
00287 }
00288
00289 } else {
00290
00291
00292
00293
00294 }
00295 }
00296 #endif
00297
00325 void
00326 msock_exec_command(char *command)
00327 {
00328 #ifdef USE_DFA
00329 DFA_INFO *new_dfa;
00330 WORD_INFO *new_winfo;
00331 static char *buf = NULL, *p, *q;
00332 int gid;
00333 char namebuf[MAXGRAMNAMELEN];
00334
00335 if (buf == NULL) buf = mymalloc(MAXBUFLEN);
00336 #endif
00337
00338
00339 j_printf("[[%s]]\n",command);
00340
00341 if (strmatch(command, "STATUS")) {
00342
00343 if (process_active) {
00344 module_send(module_sd, "<SYSINFO PROCESS=\"ACTIVE\"/>\n.\n");
00345 } else {
00346 module_send(module_sd, "<SYSINFO PROCESS=\"SLEEP\"/>\n.\n");
00347 }
00348 } else if (strmatch(command, "DIE")) {
00349 #if defined(_WIN32) && !defined(__CYGWIN32__)
00350
00351
00352 module_disconnect();
00353 #else
00354
00355 module_disconnect();
00356 j_exit();
00357 #endif
00358 } else if (strmatch(command, "VERSION")) {
00359
00360 module_send(module_sd, "<ENGINEINFO TYPE=\"%s\" VERSION=\"%s\" CONF=\"%s\"/>\n.\n",
00361 PRODUCTNAME, VERSION, SETUP);
00362 } else if (strmatch(command, "PAUSE")) {
00363
00364 if (process_active) {
00365 process_want_terminate = FALSE;
00366 process_want_reload = TRUE;
00367 process_active = FALSE;
00368 }
00369 if (speech_input == SP_ADINNET) {
00370
00371
00372 adin_tcpip_send_pause();
00373 }
00374 } else if (strmatch(command, "TERMINATE")) {
00375
00376
00377
00378 if (process_active) {
00379 process_want_terminate = TRUE;
00380 process_want_reload = TRUE;
00381 process_active = FALSE;
00382 }
00383 if (speech_input == SP_ADINNET) {
00384
00385
00386 adin_tcpip_send_terminate();
00387 }
00388 } else if (strmatch(command, "RESUME")) {
00389
00390 if (process_active == FALSE) {
00391 process_want_terminate = FALSE;
00392 process_active = TRUE;
00393 }
00394 if (speech_input == SP_ADINNET) {
00395
00396
00397 adin_tcpip_send_resume();
00398 }
00399 #ifdef USE_DFA
00400 } else if (strmatch(command, "INPUTONCHANGE")) {
00401
00402 if (
00403 #ifdef WINSOCK
00404 getl_sd(buf, MAXBUFLEN, module_sd)
00405 #else
00406 getl_fd(buf, MAXBUFLEN, module_sd)
00407 #endif
00408 == NULL) {
00409 j_error("Error: msock(INPUTONCHANGE): no argument\n");
00410 }
00411 if (strmatch(buf, "TERMINATE")) {
00412 gram_switch_input_method = SM_TERMINATE;
00413 } else if (strmatch(buf, "PAUSE")) {
00414 gram_switch_input_method = SM_PAUSE;
00415 } else if (strmatch(buf, "WAIT")) {
00416 gram_switch_input_method = SM_WAIT;
00417 } else {
00418 j_error("Error: msock(INPUTONCHANGE): unknown method [%s]\n", buf);
00419 }
00420 } else if (strnmatch(command, "CHANGEGRAM", strlen("CHANGEGRAM"))) {
00421
00422
00423 p = &(command[strlen("CHANGEGRAM")]);
00424 while (*p == ' ' && *p != '\r' && *p != '\n' && *p != '\0') p++;
00425 if (*p != '\r' && *p != '\n' && *p != '\0') {
00426 q = buf;
00427 while (*p != ' ' && *p != '\r' && *p != '\n' && *p != '\0') *q++ = *p++;
00428 *q = '\0';
00429 p = buf;
00430 } else {
00431 p = NULL;
00432 }
00433
00434 if (msock_read_grammar(&new_dfa, &new_winfo) == FALSE) {
00435 module_send(module_sd, "<GRAMMAR STATUS=\"ERROR\" REASON=\"WRONG DATA\"/>\n.\n");
00436 } else {
00437
00438 multigram_delete_all();
00439
00440 multigram_add(new_dfa, new_winfo, p);
00441
00442
00443 set_grammar_switch_timing_flag();
00444 module_send(module_sd, "<GRAMMAR STATUS=\"RECEIVED\"/>\n.\n");
00445 }
00446 } else if (strnmatch(command, "ADDGRAM", strlen("ADDGRAM"))) {
00447
00448
00449 p = &(command[strlen("ADDGRAM")]);
00450 while (*p == ' ' && *p != '\r' && *p != '\n' && *p != '\0') p++;
00451 if (*p != '\r' && *p != '\n' && *p != '\0') {
00452 q = buf;
00453 while (*p != ' ' && *p != '\r' && *p != '\n' && *p != '\0') *q++ = *p++;
00454 *q = '\0';
00455 p = buf;
00456 } else {
00457 p = NULL;
00458 }
00459
00460 if (msock_read_grammar(&new_dfa, &new_winfo) == FALSE) {
00461 module_send(module_sd, "<GRAMMAR STATUS=\"ERROR\" REASON=\"WRONG DATA\"/>\n.\n");
00462 } else {
00463
00464 multigram_add(new_dfa, new_winfo, p);
00465
00466
00467 set_grammar_switch_timing_flag();
00468 module_send(module_sd, "<GRAMMAR STATUS=\"RECEIVED\"/>\n.\n");
00469 }
00470 } else if (strmatch(command, "DELGRAM")) {
00471
00472
00473 if (
00474 #ifdef WINSOCK
00475 getl_sd(buf, MAXBUFLEN, module_sd)
00476 #else
00477 getl_fd(buf, MAXBUFLEN, module_sd)
00478 #endif
00479 == NULL) {
00480 j_error("Error: msock(DELGRAM): no argument\n");
00481 }
00482
00483
00484
00485 for(p=strtok(buf," ");p;p=strtok(NULL," ")) {
00486 gid = atoi(p);
00487 if (multigram_delete(gid) == FALSE) {
00488 j_printerr("Warning: msock(DELGRAM): gram #%d failed to delete, ignored\n", gid);
00489 }
00490 }
00491
00492
00493 set_grammar_switch_timing_flag();
00494 } else if (strmatch(command, "ACTIVATEGRAM")) {
00495
00496
00497 if (
00498 #ifdef WINSOCK
00499 getl_sd(buf, MAXBUFLEN, module_sd)
00500 #else
00501 getl_fd(buf, MAXBUFLEN, module_sd)
00502 #endif
00503 == NULL) {
00504 j_error("Error: msock(ACTIVATEGRAM): no argument\n");
00505 }
00506
00507 for(p=strtok(buf," ");p;p=strtok(NULL," ")) {
00508 gid = atoi(p);
00509 multigram_activate(gid);
00510 }
00511
00512 set_grammar_switch_timing_flag();
00513 } else if (strmatch(command, "DEACTIVATEGRAM")) {
00514
00515
00516 if (
00517 #ifdef WINSOCK
00518 getl_sd(buf, MAXBUFLEN, module_sd)
00519 #else
00520 getl_fd(buf, MAXBUFLEN, module_sd)
00521 #endif
00522 == NULL) {
00523 j_error("Error: msock(DEACTIVATEGRAM): no argument\n");
00524 }
00525
00526 for(p=strtok(buf," ");p;p=strtok(NULL," ")) {
00527 gid = atoi(p);
00528 multigram_deactivate(gid);
00529 }
00530
00531 set_grammar_switch_timing_flag();
00532 } else if (strmatch(command, "SYNCGRAM")) {
00533
00534 multigram_exec();
00535 module_send(module_sd, "<GRAMMAR STATUS=\"READY\"/>\n.\n");
00536 #endif
00537 }
00538 }
00539
00540
00562 boolean
00563 module_is_active()
00564 {
00565 return process_active;
00566 }
00567
00591 boolean
00592 module_wants_terminate()
00593 {
00594 return process_want_terminate;
00595 }
00596
00607 void
00608 module_reset_reload()
00609 {
00610 process_want_reload = FALSE;
00611 }
00612
00625 void
00626 msock_process_command()
00627 {
00628 if (
00629 #ifdef WINSOCK
00630 getl_sd(mbuf, MAXBUFLEN, module_sd)
00631 #else
00632 getl_fd(mbuf, MAXBUFLEN, module_sd)
00633 #endif
00634 != NULL) {
00635 msock_exec_command(mbuf);
00636 }
00637 }
00638
00651 void
00652 msock_check_and_process_command()
00653 {
00654 fd_set rfds;
00655 int ret;
00656 struct timeval tv;
00657
00658
00659 FD_ZERO(&rfds);
00660 FD_SET(module_sd, &rfds);
00661 tv.tv_sec = 0;
00662 tv.tv_usec = 0;
00663 ret = select(module_sd+1, &rfds, NULL, NULL, &tv);
00664 if (ret < 0) {
00665 perror("msock_check_and_process_command: cannot poll\n");
00666 }
00667 if (ret > 0) {
00668
00669
00670 while(select(module_sd+1, &rfds, NULL, NULL, &tv) > 0 &&
00671 #ifdef WINSOCK
00672 getl_sd(mbuf, MAXBUFLEN, module_sd)
00673 #else
00674 getl_fd(mbuf, MAXBUFLEN, module_sd)
00675 #endif
00676 != NULL) {
00677 msock_exec_command(mbuf);
00678 }
00679 }
00680 }
00681
00706 int
00707 msock_check_in_adin()
00708 {
00709 if (module_is_connected()) {
00710
00711 msock_check_and_process_command();
00712
00713
00714
00715
00716
00717
00718 if (module_wants_terminate()
00719 && speech_input != SP_ADINNET) {
00720 return(-2);
00721 }
00722 if (process_want_reload) {
00723 return(-1);
00724 }
00725 }
00726 return(0);
00727 }