00001 #include "app.h"
00002
00003 #include <stdarg.h>
00004
00005 #define DEFAULT_MODULEPORT 10500
00006
00007 static int module_mode = FALSE;
00008 static int module_port = DEFAULT_MODULEPORT;
00009 int module_sd = -1;
00010 static FILE *module_fp;
00011 static RecogProcess *cur = NULL;
00012
00013 #define MAXBUFLEN 4096
00014 static char mbuf[MAXBUFLEN];
00015 static char buf[MAXBUFLEN];
00016 static char inbuf[MAXBUFLEN];
00017 #ifdef CHARACTER_CONVERSION
00018 static char outbuf[MAXBUFLEN];
00019 #endif
00020
00030 int
00031 module_send(int sd, char *fmt, ...)
00032 {
00033 va_list ap;
00034 int ret;
00035 char *buf;
00036
00037 va_start(ap,fmt);
00038 ret = vsnprintf(inbuf, MAXBUFLEN, fmt, ap);
00039 va_end(ap);
00040 if (ret > 0) {
00041
00042 #ifdef CHARACTER_CONVERSION
00043 buf = charconv(inbuf, outbuf, MAXBUFLEN);
00044 #else
00045 buf = inbuf;
00046 #endif
00047 if (
00048 #ifdef WINSOCK
00049 send(sd, buf, strlen(buf), 0)
00050 #else
00051 write(sd, buf, strlen(buf))
00052 #endif
00053 < 0) {
00054 perror("Error: module_send:");
00055 }
00056 }
00057 return(ret);
00058 }
00059
00060 static char *
00061 myfgets(char *buf, int maxlen, FILE *fp)
00062 {
00063 char *ret;
00064 int len;
00065
00066 if ((ret = fgets(buf, maxlen, fp)) != NULL) {
00067 len = strlen(buf);
00068 if (buf[len-1] == '\n') {
00069 buf[len-1] = '\0';
00070 if (len >= 2 && buf[len-2] == '\r') {
00071 buf[len-2] = '\0';
00072 }
00073 }
00074 }
00075 return ret;
00076 }
00077
00090 static boolean
00091 read_grammar(FILE *fp, DFA_INFO **ret_dfa, WORD_INFO **ret_winfo, HTK_HMM_INFO *hmminfo, RecogProcess *r)
00092 {
00093 DFA_INFO *dfa = NULL;
00094 WORD_INFO *winfo;
00095 JCONF_LM *lmconf;
00096
00097
00098 if (r->lmvar != LM_DFA_WORD) {
00099 dfa = dfa_info_new();
00100 if (!rddfa_fp(fp, dfa)) {
00101 return FALSE;
00102 }
00103 }
00104 winfo = word_info_new();
00105 if (r->lmvar == LM_DFA_WORD) {
00106 lmconf = r->lm->config;
00107 if (!voca_load_wordlist_fp(fp, winfo, hmminfo, lmconf->wordrecog_head_silence_model_name, lmconf->wordrecog_tail_silence_model_name, (lmconf->wordrecog_silence_context_name[0] == '\0') ? NULL : lmconf->wordrecog_silence_context_name)) {
00108 return FALSE;
00109 }
00110 } else {
00111 if (!voca_load_htkdict_fp(fp, winfo, hmminfo, FALSE)) {
00112 dfa_info_free(dfa);
00113 return FALSE;
00114 }
00115 }
00116 *ret_dfa = dfa;
00117 *ret_winfo = winfo;
00118 return TRUE;
00119 }
00120
00121
00122 static void
00123 send_process_stat(RecogProcess *r)
00124 {
00125 module_send(module_sd, "<SR ID=\"%d\" NAME=\"%s\"", r->config->id, r->config->name);
00126 switch(r->lmtype) {
00127 case LM_PROB: module_send(module_sd, " LMTYPE=\"PROB\""); break;
00128 case LM_DFA: module_send(module_sd, " LMTYPE=\"DFA\""); break;
00129 }
00130 switch(r->lmvar) {
00131 case LM_NGRAM: module_send(module_sd, " LMVAR=\"NGRAM\""); break;
00132 case LM_DFA_GRAMMAR: module_send(module_sd, " LMVAR=\"GRAMMAR\""); break;
00133 case LM_DFA_WORD: module_send(module_sd, " LMVAR=\"WORD\""); break;
00134 case LM_NGRAM_USER: module_send(module_sd, " LMVAR=\"USER\""); break;
00135 }
00136 if (r->live) {
00137 module_send(module_sd, " LIVE=\"ACTIVE\"");
00138 } else {
00139 module_send(module_sd, " LIVE=\"INACTIVE\"");
00140 }
00141 module_send(module_sd, "/>\n.\n");
00142 }
00143
00144 static void
00145 send_current_process(RecogProcess *r)
00146 {
00147 module_send(module_sd, "<RECOGPROCESS INFO=\"CURRENT\">\n");
00148 send_process_stat(r);
00149 module_send(module_sd, "</RECOGPROCESS>\n.\n");
00150 }
00151
00179 static void
00180 msock_exec_command(char *command, Recog *recog)
00181 {
00182 DFA_INFO *new_dfa;
00183 WORD_INFO *new_winfo;
00184 static char *p, *q;
00185 int gid;
00186 int ret;
00187 RecogProcess *r;
00188
00189
00190 printf("[[%s]]\n",command);
00191
00192 if (cur == NULL) {
00193 cur = recog->process_list;
00194 }
00195
00196 if (strmatch(command, "STATUS")) {
00197
00198 if (recog->process_active) {
00199 module_send(module_sd, "<SYSINFO PROCESS=\"ACTIVE\"/>\n.\n");
00200 } else {
00201 module_send(module_sd, "<SYSINFO PROCESS=\"SLEEP\"/>\n.\n");
00202 }
00203 } else if (strmatch(command, "DIE")) {
00204
00205 close_socket(module_sd);
00206 module_sd = -1;
00207 #if defined(_WIN32) && !defined(__CYGWIN32__)
00208
00209
00210 #else
00211
00212
00213 #endif
00214 } else if (strmatch(command, "VERSION")) {
00215
00216 module_send(module_sd, "<ENGINEINFO TYPE=\"%s\" VERSION=\"%s\" CONF=\"%s\"/>\n.\n",
00217 JULIUS_PRODUCTNAME, JULIUS_VERSION, JULIUS_SETUP);
00218 } else if (strmatch(command, "PAUSE")) {
00219
00220 j_request_pause(recog);
00221 } else if (strmatch(command, "TERMINATE")) {
00222 j_request_terminate(recog);
00223 } else if (strmatch(command, "RESUME")) {
00224 j_request_resume(recog);
00225 } else if (strmatch(command, "INPUTONCHANGE")) {
00226
00227 if (
00228 myfgets(buf, MAXBUFLEN, module_fp)
00229 == NULL) {
00230 fprintf(stderr, "Error: msock(INPUTONCHANGE): no argument\n");
00231 return;
00232 }
00233 if (strmatch(buf, "TERMINATE")) {
00234 recog->gram_switch_input_method = SM_TERMINATE;
00235 } else if (strmatch(buf, "PAUSE")) {
00236 recog->gram_switch_input_method = SM_PAUSE;
00237 } else if (strmatch(buf, "WAIT")) {
00238 recog->gram_switch_input_method = SM_WAIT;
00239 } else {
00240 fprintf(stderr, "Error: msock(INPUTONCHANGE): unknown method [%s]\n", buf); exit(-1);
00241 }
00242 } else if (strnmatch(command, "GRAMINFO", strlen("GRAMINFO"))) {
00243 send_gram_info(cur);
00244 } else if (strnmatch(command, "CHANGEGRAM", strlen("CHANGEGRAM"))) {
00245
00246
00247 p = &(command[strlen("CHANGEGRAM")]);
00248 while (*p == ' ' && *p != '\r' && *p != '\n' && *p != '\0') p++;
00249 if (*p != '\r' && *p != '\n' && *p != '\0') {
00250 q = buf;
00251 while (*p != ' ' && *p != '\r' && *p != '\n' && *p != '\0') *q++ = *p++;
00252 *q = '\0';
00253 p = buf;
00254 } else {
00255 p = NULL;
00256 }
00257
00258 if (read_grammar(module_fp, &new_dfa, &new_winfo, cur->am->hmminfo, cur) == FALSE) {
00259 module_send(module_sd, "<GRAMMAR STATUS=\"ERROR\" REASON=\"WRONG DATA\"/>\n.\n");
00260 } else {
00261 if (cur->lmtype == LM_DFA) {
00262
00263 multigram_delete_all(cur->lm);
00264
00265 multigram_add(new_dfa, new_winfo, p, cur->lm);
00266
00267
00268 schedule_grammar_update(recog);
00269
00270 cur->active = 1;
00271
00272 module_send(module_sd, "<GRAMMAR STATUS=\"RECEIVED\"/>\n.\n");
00273 send_gram_info(cur);
00274 } else {
00275 module_send(module_sd, "<GRAMMAR STATUS=\"ERROR\" REASON=\"NOT A GRAMMAR-BASED LM\"/>\n.\n");
00276 }
00277 }
00278 } else if (strnmatch(command, "ADDGRAM", strlen("ADDGRAM"))) {
00279
00280
00281 p = &(command[strlen("ADDGRAM")]);
00282 while (*p == ' ' && *p != '\r' && *p != '\n' && *p != '\0') p++;
00283 if (*p != '\r' && *p != '\n' && *p != '\0') {
00284 q = buf;
00285 while (*p != ' ' && *p != '\r' && *p != '\n' && *p != '\0') *q++ = *p++;
00286 *q = '\0';
00287 p = buf;
00288 } else {
00289 p = NULL;
00290 }
00291
00292 if (read_grammar(module_fp, &new_dfa, &new_winfo, cur->am->hmminfo, cur) == FALSE) {
00293 module_send(module_sd, "<GRAMMAR STATUS=\"ERROR\" REASON=\"WRONG DATA\"/>\n.\n");
00294 } else {
00295 if (cur->lmtype == LM_DFA) {
00296
00297 multigram_add(new_dfa, new_winfo, p, cur->lm);
00298
00299
00300 cur->active = 1;
00301
00302 schedule_grammar_update(recog);
00303
00304 module_send(module_sd, "<GRAMMAR STATUS=\"RECEIVED\"/>\n.\n");
00305 send_gram_info(cur);
00306 } else {
00307 module_send(module_sd, "<GRAMMAR STATUS=\"ERROR\" REASON=\"NOT A GRAMMAR-BASED LM\"/>\n.\n");
00308 }
00309 }
00310 } else if (strmatch(command, "DELGRAM")) {
00311
00312
00313 if (
00314 myfgets(buf, MAXBUFLEN, module_fp)
00315 == NULL) {
00316 fprintf(stderr, "Error: msock(DELGRAM): no argument\n");
00317 return;
00318 }
00319
00320
00321
00322 if (cur->lmtype == LM_DFA) {
00323 for(p=strtok(buf," ");p;p=strtok(NULL," ")) {
00324 q = p;
00325 while(*q != '\0' && *q != '\r' && *q != '\n') {
00326 if (*q < '0' || *q > '9') break;
00327 q++;
00328 }
00329 if (*q == '\0' || *q == '\r' || *q == '\n') {
00330 gid = atoi(p);
00331 } else {
00332 gid = multigram_get_id_by_name(cur->lm, p);
00333 if (gid == -1) continue;
00334 }
00335 if (multigram_delete(gid, cur->lm) == FALSE) {
00336 fprintf(stderr, "Warning: msock(DELGRAM): gram #%d failed to delete, ignored\n", gid);
00337
00338 module_send(module_sd, "<GRAMMAR STATUS=\"ERROR\" REASON=\"Gram #%d not found\"/>\n.\n", gid);
00339 }
00340 }
00341
00342
00343 schedule_grammar_update(recog);
00344 } else {
00345 module_send(module_sd, "<GRAMMAR STATUS=\"ERROR\" REASON=\"NOT A GRAMMAR-BASED LM\"/>\n.\n");
00346 }
00347 } else if (strmatch(command, "ACTIVATEGRAM")) {
00348
00349
00350 if (
00351 myfgets(buf, MAXBUFLEN, module_fp)
00352 == NULL) {
00353 fprintf(stderr, "Error: msock(ACTIVATEGRAM): no argument\n");
00354 return;
00355 }
00356
00357 if (cur->lmtype == LM_DFA) {
00358 for(p=strtok(buf," ");p;p=strtok(NULL," ")) {
00359 q = p;
00360 while(*q != '\0' && *q != '\r' && *q != '\n') {
00361 if (*q < '0' || *q > '9') break;
00362 q++;
00363 }
00364 if (*q == '\0' || *q == '\r' || *q == '\n') {
00365 gid = atoi(p);
00366 } else {
00367 gid = multigram_get_id_by_name(cur->lm, p);
00368 if (gid == -1) continue;
00369 }
00370 ret = multigram_activate(gid, cur->lm);
00371 if (ret == 1) {
00372
00373 module_send(module_sd, "<WARN MESSAGE=\"Gram #%d already active\"/>\n.\n", gid);
00374 } else if (ret == -1) {
00375
00376 module_send(module_sd, "<WARN MESSAGE=\"Gram #%d not found\"/>\n.\n", gid);
00377 }
00378 }
00379
00380 schedule_grammar_update(recog);
00381 } else {
00382 module_send(module_sd, "<GRAMMAR STATUS=\"ERROR\" REASON=\"NOT A GRAMMAR-BASED LM\"/>\n.\n");
00383 }
00384 } else if (strmatch(command, "DEACTIVATEGRAM")) {
00385
00386
00387 if (
00388 myfgets(buf, MAXBUFLEN, module_fp)
00389 == NULL) {
00390 fprintf(stderr, "Error: msock(DEACTIVATEGRAM): no argument\n");
00391 return;
00392 }
00393 if (cur->lmtype == LM_DFA) {
00394
00395 for(p=strtok(buf," ");p;p=strtok(NULL," ")) {
00396 q = p;
00397 while(*q != '\0' && *q != '\r' && *q != '\n') {
00398 if (*q < '0' || *q > '9') break;
00399 q++;
00400 }
00401 if (*q == '\0' || *q == '\r' || *q == '\n') {
00402 gid = atoi(p);
00403 } else {
00404 gid = multigram_get_id_by_name(cur->lm, p);
00405 if (gid == -1) continue;
00406 }
00407 ret = multigram_deactivate(gid, cur->lm);
00408 if (ret == 1) {
00409
00410 module_send(module_sd, "<WARN MESSAGE=\"Gram #%d already inactive\"/>\n.\n", gid);
00411 } else if (ret == -1) {
00412
00413 module_send(module_sd, "<WARN MESSAGE=\"Gram #%d not found\"/>\n.\n", gid);
00414 }
00415 }
00416 schedule_grammar_update(recog);
00417 } else {
00418 module_send(module_sd, "<GRAMMAR STATUS=\"ERROR\" REASON=\"NOT A GRAMMAR-BASED LM\"/>\n.\n");
00419 }
00420 } else if (strmatch(command, "SYNCGRAM")) {
00421
00422 if (cur->lmtype == LM_DFA) {
00423 multigram_update(cur->lm);
00424 for(r=recog->process_list;r;r=r->next) {
00425 if (r->lmtype == LM_DFA && r->lm->global_modified) {
00426 multigram_build(r);
00427 }
00428 }
00429 cur->lm->global_modified = FALSE;
00430 module_send(module_sd, "<GRAMMAR STATUS=\"READY\"/>\n.\n");
00431 } else {
00432 module_send(module_sd, "<GRAMMAR STATUS=\"ERROR\" REASON=\"NOT A GRAMMAR-BASED LM\"/>\n.\n");
00433 }
00434 } else if (strmatch(command, "CURRENTPROCESS")) {
00435 JCONF_SEARCH *sconf;
00436 RecogProcess *r;
00437 if (
00438 myfgets(buf, MAXBUFLEN, module_fp)
00439 == NULL) {
00440
00441 send_current_process(cur);
00442 return;
00443 }
00444 if (buf[0] == '\0') {
00445
00446 send_current_process(cur);
00447 return;
00448 }
00449 sconf = j_get_searchconf_by_name(recog->jconf, buf);
00450 if (sconf == NULL) {
00451 fprintf(stderr, "Error: msock(CURRENTPROCESS): no such process \"%s\"\n", buf);
00452 module_send(module_sd, "<RECOGPROCESS STATUS=\"ERROR\" REASON=\"NO SUCH PROCESS\"/>\n.\n");
00453 return;
00454 }
00455 for(r=recog->process_list;r;r=r->next) {
00456 if (r->config == sconf) {
00457 cur = r;
00458 break;
00459 }
00460 }
00461 if (!r) {
00462 fprintf(stderr, "Error: msock(CURRENTPROCESS): no process assigned to searchconf \"%s\"??\n", buf);
00463 module_send(module_sd, "<RECOGPROCESS STATUS=\"ERROR\" REASON=\"NO SUCH PROCESS\"/>\n.\n");
00464 return;
00465 }
00466 send_current_process(cur);
00467 }
00468
00469 else if (strmatch(command, "SHIFTPROCESS")) {
00470 cur = cur->next;
00471 if (cur == NULL) {
00472 fprintf(stderr, "SHIFTPROCESS: reached end, rotated to first\n");
00473 cur = recog->process_list;
00474 }
00475 send_process_stat(cur);
00476 }
00477
00478 else if (strmatch(command, "ADDPROCESS")) {
00479 Jconf *jconf;
00480 JCONF_LM *lmconf;
00481 JCONF_AM *amconf;
00482 JCONF_SEARCH *sconf;
00483 RecogProcess *r;
00484
00485 if (
00486 myfgets(buf, MAXBUFLEN, module_fp)
00487 == NULL) {
00488 fprintf(stderr, "Error: msock(ADDPROCESS): no argument\n");
00489 module_send(module_sd, "<RECOGPROCESS STATUS=\"ERROR\" REASON=\"NO ARGUMENT\"/>\n.\n");
00490 return;
00491 }
00492
00493 jconf = j_jconf_new();
00494 j_config_load_file(jconf, buf);
00495 lmconf = jconf->lmnow;
00496
00497
00498 sconf = j_jconf_search_new();
00499
00500
00501
00502 if (j_process_add_lm(recog, lmconf, sconf, buf) == FALSE) {
00503 fprintf(stderr, "Error: failed to regist new process \"%s\"\n", buf);
00504 module_send(module_sd, "<RECOGPROCESS STATUS=\"ERROR\" REASON=\"FAILED TO REGISTER\"/>\n.\n");
00505 j_jconf_search_free(sconf);
00506 return;
00507 }
00508 printf("added process: SR%02d %s\n", sconf->id, sconf->name);
00509 module_send(module_sd, "<RECOGPROCESS INFO=\"ADDED\">\n");
00510 for(r=recog->process_list;r;r=r->next) {
00511 if (r->config == sconf) {
00512 send_process_stat(r);
00513 }
00514 }
00515 module_send(module_sd, "</RECOGPROCESS>\n.\n");
00516 }
00517
00518 else if (strmatch(command, "DELPROCESS")) {
00519 JCONF_LM *lmconf;
00520 JCONF_AM *amconf;
00521 JCONF_SEARCH *sconf;
00522 RecogProcess *r;
00523
00524 if (
00525 myfgets(buf, MAXBUFLEN, module_fp)
00526 == NULL) {
00527 fprintf(stderr, "Error: msock(DELPROCESS): no argument\n");
00528 module_send(module_sd, "<RECOGPROCESS STATUS=\"ERROR\" REASON=\"NO ARGUMENT\"/>\n.\n");
00529 return;
00530 }
00531
00532 lmconf = j_get_lmconf_by_name(recog->jconf, buf);
00533 if (lmconf == NULL) {
00534 fprintf(stderr, "Error: msock(DELPROCESS): no lmconf named %s\n", buf);
00535 module_send(module_sd, "<RECOGPROCESS STATUS=\"ERROR\" REASON=\"NO LM PROCESS OF THE NAME\"/>\n.\n");
00536 return;
00537 }
00538 sconf = j_get_searchconf_by_name(recog->jconf, buf);
00539 if (sconf == NULL) {
00540 fprintf(stderr, "Error: msock(DELPROCESS): no searchconf named %s\n", buf);
00541 module_send(module_sd, "<RECOGPROCESS STATUS=\"ERROR\" REASON=\"NO RECOGPROCESS OF THE NAME\"/>\n.\n");
00542 return;
00543 }
00544 printf("remove process: SR%02d %s, LM%02d %s\n", sconf->id, sconf->name, lmconf->id, lmconf->name);
00545 module_send(module_sd, "<RECOGPROCESS INFO=\"DELETE\">\n");
00546 for(r=recog->process_list;r;r=r->next) {
00547 if (r->config == sconf) send_process_stat(r);
00548 }
00549 module_send(module_sd, "</RECOGPROCESS>\n.\n");
00550 j_process_remove(recog, sconf);
00551 j_process_lm_remove(recog, lmconf);
00552
00553 for(r=recog->process_list;r;r=r->next) {
00554 if (r == cur) break;
00555 }
00556 if (!r) {
00557 cur = recog->process_list;
00558 printf("now current moved to SR%02d %s\n", cur->config->id, cur->config->name);
00559 send_current_process(cur);
00560 }
00561
00562 }
00563
00564 else if (strmatch(command, "LISTPROCESS")) {
00565 RecogProcess *r;
00566
00567 module_send(module_sd, "<RECOGPROCESS INFO=\"STATUS\">\n");
00568 for(r=recog->process_list;r;r=r->next) {
00569 send_process_stat(r);
00570 }
00571 module_send(module_sd, "</RECOGPROCESS>\n.\n");
00572 }
00573
00574 else if (strmatch(command, "ACTIVATEPROCESS")) {
00575 if (
00576 myfgets(buf, MAXBUFLEN, module_fp)
00577 == NULL) {
00578 fprintf(stderr, "Error: msock(ACTIVATEPROCESS): no argument\n");
00579 module_send(module_sd, "<RECOGPROCESS STATUS=\"ERROR\" REASON=\"NO ARGUMENT\"/>\n.\n");
00580 return;
00581 }
00582 if (j_process_activate(recog, buf) == FALSE) {
00583 module_send(module_sd, "<RECOGPROCESS STATUS=\"ERROR\" REASON=\"ACTIVATION FAILED\"/>\n.\n");
00584 } else {
00585 module_send(module_sd, "<RECOGPROCESS INFO=\"ACTIVATED\" NAME=\"%s\"/>\n.\n", buf);
00586 }
00587 }
00588 else if (strmatch(command, "DEACTIVATEPROCESS")) {
00589 if (
00590 myfgets(buf, MAXBUFLEN, module_fp)
00591 == NULL) {
00592 fprintf(stderr, "Error: msock(DEACTIVATEPROCESS): no argument\n");
00593 module_send(module_sd, "<RECOGPROCESS STATUS=\"ERROR\" REASON=\"NO ARGUMENT\"/>\n.\n");
00594 return;
00595 }
00596 if (j_process_deactivate(recog, buf) == FALSE) {
00597 module_send(module_sd, "<RECOGPROCESS STATUS=\"ERROR\" REASON=\"DEACTIVATION FAILED\"/>\n.\n");
00598 } else {
00599 module_send(module_sd, "<RECOGPROCESS INFO=\"DEACTIVATED\" NAME=\"%s\"/>\n.\n", buf);
00600 }
00601 module_send(module_sd, ".\n");
00602 }
00603 else if (strmatch(command, "ADDWORD")) {
00604 WORD_INFO *words;
00605 boolean ret;
00606 int id;
00607
00608
00609 if (
00610 myfgets(buf, MAXBUFLEN, module_fp)
00611 == NULL) {
00612 fprintf(stderr, "Error: msock(DEACTIVATEPROCESS): no argument\n");
00613 module_send(module_sd, "<RECOGPROCESS STATUS=\"ERROR\" REASON=\"NO ARGUMENT\"/>\n.\n");
00614 return;
00615 }
00616 id = atoi(buf);
00617
00618
00619 words = word_info_new();
00620 voca_load_start(words, cur->am->hmminfo, FALSE);
00621 while (
00622 myfgets(buf, MAXBUFLEN, module_fp)
00623 != NULL) {
00624 if (cur->lmvar == LM_DFA_WORD) {
00625 ret = voca_load_word_line(buf, words, cur->am->hmminfo,
00626 cur->lm->config->wordrecog_head_silence_model_name,
00627 cur->lm->config->wordrecog_tail_silence_model_name,
00628 (cur->lm->config->wordrecog_silence_context_name[0] == '\0') ? NULL : cur->lm->config->wordrecog_silence_context_name);
00629 } else {
00630 ret = voca_load_line(buf, words, cur->am->hmminfo);
00631 }
00632 if (ret == FALSE) break;
00633 }
00634 ret = voca_load_end(words);
00635 if (ret == FALSE) {
00636 fprintf(stderr, "Error: msock(ADDWORD): error in reading word entries\n");
00637 module_send(module_sd, "<RECOGPROCESS STATUS=\"ERROR\" REASON=\"ERROR IN READING WORD ENTRIES\"/>\n.\n");
00638 word_info_free(words);
00639 return;
00640 }
00641 if (words->num == 0) {
00642 fprintf(stderr, "Error: msock(ADDWORD): no word specified\n");
00643 module_send(module_sd, "<RECOGPROCESS STATUS=\"ERROR\" REASON=\"NO WORD SPECIFIED\"/>\n.\n");
00644 word_info_free(words);
00645 return;
00646 }
00647 printf("%d words read\n", words->num);
00648
00649 if (multigram_add_words_to_grammar_by_id(cur->lm, id, words) == FALSE) {
00650 fprintf(stderr, "Error: msock(ADDWORD): failed to add words to grammar #%d\n", id);
00651 module_send(module_sd, "<RECOGPROCESS STATUS=\"ERROR\" REASON=\"FAILED\"/>\n.\n");
00652 word_info_free(words);
00653 return;
00654 }
00655
00656 schedule_grammar_update(recog);
00657 module_send(module_sd, "%d words added to grammar #%d\n.\n", words->num, id);
00658 module_send(module_sd, "<RECOGPROCESS INFO=\"ADDEDWORD\" GRAMMARID=\"%d\" NUM=\"%d\"/>\n.\n", id, words->num);
00659
00660 word_info_free(words);
00661 }
00662 }
00663
00676 static void
00677 msock_check_and_process_command(Recog *recog, void *dummy)
00678 {
00679 fd_set rfds;
00680 int ret;
00681 struct timeval tv;
00682
00683
00684 FD_ZERO(&rfds);
00685 FD_SET(module_sd, &rfds);
00686 tv.tv_sec = 0;
00687 tv.tv_usec = 0;
00688 ret = select(module_sd+1, &rfds, NULL, NULL, &tv);
00689 if (ret < 0) {
00690 perror("msock_check_and_process_command: cannot poll\n");
00691 }
00692 if (ret > 0) {
00693
00694
00695 while(select(module_sd+1, &rfds, NULL, NULL, &tv) > 0 &&
00696 myfgets(mbuf, MAXBUFLEN, module_fp)
00697 != NULL) {
00698 msock_exec_command(mbuf, recog);
00699 }
00700 }
00701 }
00702
00718 static void
00719 msock_process_command(Recog *recog, void *dummy)
00720 {
00721
00722 while(!recog->process_active) {
00723 if (
00724 myfgets(mbuf, MAXBUFLEN, module_fp)
00725 != NULL) {
00726 msock_exec_command(mbuf, recog);
00727 }
00728 }
00729 }
00730
00731 static void
00732 module_regist_callback(Recog *recog, void *data)
00733 {
00734 callback_add(recog, CALLBACK_POLL, msock_check_and_process_command, data);
00735 callback_add(recog, CALLBACK_PAUSE_FUNCTION, msock_process_command, data);
00736 }
00737
00738
00739 static boolean
00740 opt_module(Jconf *jconf, char *arg[], int argnum)
00741 {
00742 module_mode = TRUE;
00743 if (argnum > 0) {
00744 module_port = atoi(arg[0]);
00745 }
00746 return TRUE;
00747 }
00748
00749 static boolean
00750 opt_outcode(Jconf *jconf, char *arg[], int argnum)
00751 {
00752 decode_output_selection(arg[0]);
00753 return TRUE;
00754 }
00755
00756 void
00757 module_add_option()
00758 {
00759 j_add_option("-module", 1, 0, "run as a server module", opt_module);
00760 j_add_option("-outcode", 1, 1, "select info to output to the module: WLPSCwlps", opt_outcode);
00761 }
00762
00763 boolean
00764 is_module_mode()
00765 {
00766 return module_mode;
00767 }
00768
00769 void
00770 module_setup(Recog *recog, void *data)
00771 {
00772
00773 module_regist_callback(recog, data);
00774 setup_output_msock(recog, data);
00775 }
00776
00777 void
00778 module_server()
00779 {
00780 int listen_sd;
00781 #if defined(_WIN32) && !defined(__CYGWIN32__)
00782 int sd;
00783 #endif
00784
00785
00786 if ((listen_sd = ready_as_server(module_port)) < 0) {
00787 fprintf(stderr, "Error: failed to bind socket\n");
00788 return;
00789 }
00790
00791 printf ("///////////////////////////////\n");
00792 printf ("/// Module mode ready\n");
00793 printf ("/// waiting client at %5d\n", module_port);
00794 printf ("///////////////////////////////\n");
00795 printf ("/// ");
00796
00797
00798 if ((module_sd = accept_from(listen_sd)) < 0) {
00799 fprintf(stderr, "Error: failed to accept connection\n");
00800 return;
00801 }
00802 #if defined(_WIN32) && !defined(__CYGWIN32__)
00803
00804 if ((sd = _open_osfhandle(module_sd, O_RDWR|O_BINARY)) < 0) {
00805 fprintf(stderr, "Error: failed to open_osfhandle\n");
00806 return;
00807 }
00808 if ((module_fp = fdopen(sd, "rb+")) == NULL) {
00809 fprintf(stderr, "Error: failed to fdopen socket\n");
00810 return;
00811 }
00812 #else
00813 if ((module_fp = fdopen(module_sd, "r+")) == NULL) {
00814 fprintf(stderr, "Error; failed to fdopen socket\n");
00815 return;
00816 }
00817 #endif
00818 }
00819
00820 void
00821 module_disconnect()
00822 {
00823
00824 if (module_sd >= 0) {
00825 module_send(module_sd, "<SYSINFO PROCESS=\"ERREXIT\"/>\n.\n");
00826 close_socket(module_sd);
00827 module_sd = -1;
00828 }
00829 }