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 }