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