- Timestamp:
- Nov 23, 2012 10:30:55 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/cli/pjlib-util/src/pjlib-util/cli_console.c
r3231 r4299 28 28 #include <pjlib-util/errno.h> 29 29 30 #if defined(PJ_LINUX) && PJ_LINUX != 0 || \ 31 defined(PJ_DARWINOS) && PJ_DARWINOS != 0 32 #include <termios.h> 33 34 static struct termios old, new; 35 36 /* Initialize new terminal i/o settings */ 37 void initTermios(int echo) 38 { 39 tcgetattr(0, &old); 40 new = old; 41 new.c_lflag &= ~ICANON; 42 new.c_lflag &= echo ? ECHO : ~ECHO; 43 tcsetattr(0, TCSANOW, &new); 44 } 45 46 /* Restore old terminal i/o settings */ 47 void resetTermios(void) 48 { 49 tcsetattr(0, TCSANOW, &old); 50 } 51 52 /* Read 1 character - echo defines echo mode */ 53 char getch_(int echo) 54 { 55 char ch; 56 initTermios(echo); 57 ch = getchar(); 58 resetTermios(); 59 return ch; 60 } 61 62 /* Read 1 character without echo */ 63 char getch(void) 64 { 65 return getch_(0); 66 } 67 68 #endif 69 70 /** 71 * This specify the state of input character parsing. 72 */ 73 typedef enum cmd_parse_state 74 { 75 ST_NORMAL, 76 ST_SCANMODE, 77 ST_ESC, 78 ST_ARROWMODE 79 } cmd_parse_state; 80 81 /** 82 * This structure contains the command line shown to the user. 83 */ 84 typedef struct console_recv_buf { 85 /** 86 * Buffer containing the characters, NULL terminated. 87 */ 88 unsigned char rbuf[PJ_CLI_MAX_CMDBUF]; 89 90 /** 91 * Current length of the command line. 92 */ 93 unsigned len; 94 95 /** 96 * Current cursor position. 97 */ 98 unsigned cur_pos; 99 } console_recv_buf; 100 101 typedef struct cmd_history 102 { 103 PJ_DECL_LIST_MEMBER(struct cmd_history); 104 pj_str_t command; 105 } cmd_history; 106 30 107 struct cli_console_fe 31 108 { … … 35 112 pj_thread_t *input_thread; 36 113 pj_bool_t thread_quit; 37 pj_sem_t *thread_sem; 114 pj_sem_t *thread_sem; 115 pj_cli_console_cfg cfg; 38 116 39 117 struct async_input_t 40 { 41 char *buf; 42 unsigned maxlen; 43 pj_sem_t *sem; 118 { 119 console_recv_buf recv_buf; 120 pj_sem_t *sem; 44 121 } input; 122 123 cmd_history *history; 124 cmd_history *active_history; 45 125 }; 126 127 static unsigned recv_buf_right_len(console_recv_buf *recv_buf) 128 { 129 return (recv_buf->len - recv_buf->cur_pos); 130 } 131 132 static pj_bool_t recv_buf_insert(console_recv_buf *recv_buf, 133 unsigned char *data) 134 { 135 if (recv_buf->len+1 >= PJ_CLI_MAX_CMDBUF) { 136 return PJ_FALSE; 137 } else { 138 if (*data == '\t' || *data == '?' || *data == '\r') { 139 /* Always insert to the end of line */ 140 recv_buf->rbuf[recv_buf->len] = *data; 141 } else { 142 /* Insert based on the current cursor pos */ 143 unsigned cur_pos = recv_buf->cur_pos; 144 unsigned rlen = recv_buf_right_len(recv_buf); 145 if (rlen > 0) { 146 /* Shift right characters */ 147 pj_memmove(&recv_buf->rbuf[cur_pos+1], 148 &recv_buf->rbuf[cur_pos], 149 rlen+1); 150 } 151 recv_buf->rbuf[cur_pos] = *data; 152 } 153 ++recv_buf->cur_pos; 154 ++recv_buf->len; 155 recv_buf->rbuf[recv_buf->len] = 0; 156 } 157 return PJ_TRUE; 158 } 159 160 static pj_bool_t recv_buf_backspace(console_recv_buf *recv_buf) 161 { 162 if ((recv_buf->cur_pos == 0) || (recv_buf->len == 0)) { 163 return PJ_FALSE; 164 } else { 165 unsigned rlen = recv_buf_right_len(recv_buf); 166 if (rlen) { 167 unsigned cur_pos = recv_buf->cur_pos; 168 pj_memmove(&recv_buf->rbuf[cur_pos-1], &recv_buf->rbuf[cur_pos], 169 rlen); 170 } 171 --recv_buf->cur_pos; 172 --recv_buf->len; 173 recv_buf->rbuf[recv_buf->len] = 0; 174 } 175 return PJ_TRUE; 176 } 46 177 47 178 static void cli_console_write_log(pj_cli_front_end *fe, int level, … … 87 218 pj_assert(param); 88 219 89 param->log_level = PJ_CLI_CONSOLE_LOG_LEVEL; 220 param->log_level = PJ_CLI_CONSOLE_LOG_LEVEL; 90 221 } 91 222 … … 109 240 sess = PJ_POOL_ZALLOC_T(pool, pj_cli_sess); 110 241 fe = PJ_POOL_ZALLOC_T(pool, struct cli_console_fe); 242 fe->history = PJ_POOL_ZALLOC_T(pool, struct cmd_history); 243 pj_list_init(fe->history); 244 fe->active_history = fe->history; 111 245 112 246 if (!param) { … … 129 263 pj_cli_register_front_end(cli, &fe->base); 130 264 265 if (fe->cfg.prompt_str.slen == 0) { 266 pj_str_t prompt_sign = pj_str(">>> "); 267 char *prompt_data = pj_pool_alloc(fe->pool, 5); 268 fe->cfg.prompt_str.ptr = prompt_data; 269 270 pj_strcpy(&fe->cfg.prompt_str, &prompt_sign); 271 prompt_data[4] = 0; 272 } 273 131 274 *p_sess = sess; 132 275 if (p_fe) … … 136 279 } 137 280 138 static int readline_thread(void * p) 139 { 281 static void send_prompt_str(pj_cli_sess *sess) 282 { 283 pj_str_t send_data; 284 char data_str[128]; 285 struct cli_console_fe *fe = (struct cli_console_fe *)sess->fe; 286 287 send_data.ptr = &data_str[0]; 288 send_data.slen = 0; 289 290 pj_strcat(&send_data, &fe->cfg.prompt_str); 291 send_data.ptr[send_data.slen] = 0; 292 293 printf("%s", send_data.ptr); 294 } 295 296 static void send_err_arg(pj_cli_sess *sess, 297 const pj_cli_exec_info *info, 298 const pj_str_t *msg, 299 pj_bool_t with_return, 300 pj_bool_t with_last_cmd) 301 { 302 pj_str_t send_data; 303 char data_str[256]; 304 unsigned len; 305 unsigned i; 306 struct cli_console_fe *fe = (struct cli_console_fe *)sess->fe; 307 console_recv_buf *recv_buf = &fe->input.recv_buf; 308 309 send_data.ptr = &data_str[0]; 310 send_data.slen = 0; 311 312 if (with_return) 313 pj_strcat2(&send_data, "\r\n"); 314 315 len = fe->cfg.prompt_str.slen + info->err_pos; 316 317 for (i=0;i<len;++i) { 318 pj_strcat2(&send_data, " "); 319 } 320 pj_strcat2(&send_data, "^"); 321 pj_strcat2(&send_data, "\r\n"); 322 pj_strcat(&send_data, msg); 323 pj_strcat(&send_data, &fe->cfg.prompt_str); 324 if (with_last_cmd) 325 pj_strcat2(&send_data, (char *)&recv_buf->rbuf[0]); 326 327 send_data.ptr[send_data.slen] = 0; 328 printf("%s", send_data.ptr); 329 } 330 331 static void send_return_key(pj_cli_sess *sess) 332 { 333 PJ_UNUSED_ARG(sess); 334 printf("\r\n"); 335 } 336 337 static void send_inv_arg(pj_cli_sess *sess, 338 const pj_cli_exec_info *info, 339 pj_bool_t with_return, 340 pj_bool_t with_last_cmd) 341 { 342 static const pj_str_t ERR_MSG = {"%Error : Invalid Arguments\r\n", 28}; 343 send_err_arg(sess, info, &ERR_MSG, with_return, with_last_cmd); 344 } 345 346 static void send_too_many_arg(pj_cli_sess *sess, 347 const pj_cli_exec_info *info, 348 pj_bool_t with_return, 349 pj_bool_t with_last_cmd) 350 { 351 static const pj_str_t ERR_MSG = {"%Error : Too Many Arguments\r\n", 29}; 352 send_err_arg(sess, info, &ERR_MSG, with_return, with_last_cmd); 353 } 354 355 static void send_ambi_arg(pj_cli_sess *sess, 356 const pj_cli_exec_info *info, 357 pj_bool_t with_return, 358 pj_bool_t with_last_cmd) 359 { 360 unsigned i; 361 pj_ssize_t j; 362 unsigned len; 363 pj_str_t send_data; 364 char data[1028]; 365 struct cli_console_fe *fe = (struct cli_console_fe *)sess->fe; 366 console_recv_buf *recv_buf = &fe->input.recv_buf; 367 const pj_cli_hint_info *hint = info->hint; 368 pj_bool_t is_process_sc = PJ_FALSE; 369 pj_bool_t valid_type = PJ_FALSE; 370 pj_ssize_t max_length = 0; 371 const pj_str_t sc_type = pj_str("SC"); 372 send_data.ptr = &data[0]; 373 send_data.slen = 0; 374 375 if (with_return) 376 pj_strcat2(&send_data, "\r\n"); 377 378 len = fe->cfg.prompt_str.slen + info->err_pos; 379 380 for (i=0;i<len;++i) { 381 pj_strcat2(&send_data, " "); 382 } 383 pj_strcat2(&send_data, "^"); 384 385 /* Get the max length of the command name */ 386 for (i=0;i<info->hint_cnt;++i) { 387 if (hint[i].name.slen > max_length) { 388 max_length = hint[i].name.slen; 389 } 390 } 391 392 for (i=0;i<info->hint_cnt;++i) { 393 if ((&hint[i].type) && (hint[i].type.slen > 0)) { 394 valid_type = PJ_TRUE; 395 if (pj_stricmp(&hint[i].type, &sc_type) == 0) { 396 if (is_process_sc) { 397 pj_strcat2(&send_data, ", "); 398 } else { 399 pj_strcat2(&send_data, "\r\n\t Shorcut: "); 400 is_process_sc = PJ_TRUE; 401 } 402 pj_strcat(&send_data, &hint[i].name); 403 } else { 404 is_process_sc = PJ_FALSE; 405 } 406 } else { 407 valid_type = PJ_FALSE; 408 is_process_sc = PJ_FALSE; 409 } 410 411 if (!is_process_sc) { 412 pj_strcat2(&send_data, "\r\n\t"); 413 414 if (valid_type) { 415 pj_strcat2(&send_data, "<"); 416 pj_strcat(&send_data, &hint[i].type); 417 pj_strcat2(&send_data, ">"); 418 } else { 419 pj_strcat(&send_data, &hint[i].name); 420 } 421 422 if ((&hint[i].desc) && (hint[i].desc.slen > 0)) { 423 if (!valid_type) { 424 for (j=0;j<(max_length-hint[i].name.slen);++j) { 425 pj_strcat2(&send_data, " "); 426 } 427 } 428 pj_strcat2(&send_data, "\t"); 429 pj_strcat(&send_data, &hint[i].desc); 430 } 431 } 432 } 433 pj_strcat2(&send_data, "\r\n"); 434 pj_strcat(&send_data, &fe->cfg.prompt_str); 435 if (with_last_cmd) 436 pj_strcat2(&send_data, (char *)&recv_buf->rbuf[0]); 437 438 send_data.ptr[send_data.slen] = 0; 439 printf("%s", send_data.ptr); 440 } 441 442 static void send_comp_arg(pj_cli_exec_info *info) 443 { 444 pj_str_t send_data; 445 char data[128]; 446 447 pj_strcat2(&info->hint[0].name, " "); 448 449 send_data.ptr = &data[0]; 450 send_data.slen = 0; 451 452 pj_strcat(&send_data, &info->hint[0].name); 453 454 send_data.ptr[send_data.slen] = 0; 455 printf("%s", send_data.ptr); 456 } 457 458 static int compare_str(void *value, const pj_list_type *nd) 459 { 460 cmd_history *node = (cmd_history*)nd; 461 return (pj_strcmp((pj_str_t *)value, &node->command)); 462 } 463 464 static pj_status_t insert_history(pj_cli_sess *sess, 465 char *cmd_val) 466 { 467 cmd_history *in_history; 468 pj_str_t cmd; 469 struct cli_console_fe *fe = (struct cli_console_fe *)sess->fe; 470 cmd.ptr = cmd_val; 471 cmd.slen = pj_ansi_strlen(cmd_val)-1; 472 473 if (cmd.slen == 0) 474 return PJ_SUCCESS; 475 476 PJ_ASSERT_RETURN(sess, PJ_EINVAL); 477 478 /* Find matching history */ 479 in_history = pj_list_search(fe->history, (void*)&cmd, compare_str); 480 if (!in_history) { 481 if (pj_list_size(fe->history) < PJ_CLI_MAX_CMD_HISTORY) { 482 char *data_history; 483 in_history = PJ_POOL_ZALLOC_T(fe->pool, cmd_history); 484 pj_list_init(in_history); 485 data_history = (char *)pj_pool_calloc(fe->pool, 486 sizeof(char), PJ_CLI_MAX_CMDBUF); 487 in_history->command.ptr = data_history; 488 in_history->command.slen = 0; 489 } else { 490 /* Get the oldest history */ 491 in_history = fe->history->prev; 492 } 493 } else { 494 pj_list_insert_nodes_after(in_history->prev, in_history->next); 495 } 496 pj_strcpy(&in_history->command, pj_strtrim(&cmd)); 497 pj_list_push_front(fe->history, in_history); 498 fe->active_history = fe->history; 499 500 return PJ_SUCCESS; 501 } 502 503 static pj_str_t* get_prev_history(pj_cli_sess *sess, pj_bool_t is_forward) 504 { 505 pj_str_t *retval; 506 pj_size_t history_size; 507 cmd_history *node; 508 cmd_history *root; 509 struct cli_console_fe *fe = (struct cli_console_fe *)sess->fe; 510 511 PJ_ASSERT_RETURN(sess && fe, NULL); 512 513 node = fe->active_history; 514 root = fe->history; 515 history_size = pj_list_size(fe->history); 516 517 if (history_size == 0) { 518 return NULL; 519 } else { 520 if (is_forward) { 521 node = (node->next==root)?node->next->next:node->next; 522 } else { 523 node = (node->prev==root)?node->prev->prev:node->prev; 524 } 525 retval = &node->command; 526 fe->active_history = node; 527 } 528 return retval; 529 } 530 531 static pj_bool_t handle_alfa_num(console_recv_buf *recv_buf, 532 unsigned char *cdata) 533 { 534 if (recv_buf_right_len(recv_buf) > 0) { 535 char out_str[255]; 536 pj_memset(&out_str[0], 0, 255); 537 out_str[0] = *cdata; 538 pj_memcpy(&out_str[1], &recv_buf->rbuf[recv_buf->cur_pos], 539 recv_buf_right_len(recv_buf)); 540 pj_memset(&out_str[recv_buf_right_len(recv_buf)+1], '\b', 541 recv_buf_right_len(recv_buf)); 542 printf("%s", out_str); 543 } else { 544 printf("%c", *cdata); 545 } 546 return PJ_TRUE; 547 } 548 549 static pj_bool_t handle_backspace(console_recv_buf *recv_buf) 550 { 551 if (recv_buf_backspace(recv_buf)) { 552 if(recv_buf_right_len(recv_buf) > 0) { 553 char out_str[255]; 554 pj_memset(&out_str[0], 0, 255); 555 out_str[0] = '\b'; 556 pj_memcpy(&out_str[1], &recv_buf->rbuf[recv_buf->cur_pos], 557 recv_buf_right_len(recv_buf)); 558 out_str[recv_buf_right_len(recv_buf)+1] = ' '; 559 pj_memset(&out_str[recv_buf_right_len(recv_buf)+2], '\b', 560 recv_buf_right_len(recv_buf)+1); 561 printf("%s", out_str); 562 } else { 563 char out_str[4]; 564 out_str[0] = '\b'; 565 out_str[1] = ' '; 566 out_str[2] = '\b'; 567 out_str[3] = 0; 568 printf("%s", out_str); 569 } 570 return PJ_TRUE; 571 } 572 return PJ_FALSE; 573 } 574 575 static pj_bool_t handle_tab(pj_cli_sess *sess) 576 { 577 pj_status_t status; 578 pj_bool_t retval = PJ_TRUE; 579 unsigned len; 580 581 pj_pool_t *pool; 582 pj_cli_cmd_val *cmd_val; 583 pj_cli_exec_info info; 584 struct cli_console_fe *fe = (struct cli_console_fe *)sess->fe; 585 console_recv_buf *recv_buf = &fe->input.recv_buf; 586 pj_cli_t *cli = sess->fe->cli; 587 588 pool = pj_pool_create(pj_cli_get_param(cli)->pf, "handle_tab", 589 PJ_CLI_CONSOLE_POOL_SIZE, PJ_CLI_CONSOLE_POOL_INC, 590 NULL); 591 592 cmd_val = PJ_POOL_ZALLOC_T(pool, pj_cli_cmd_val); 593 594 status = pj_cli_sess_parse(sess, (char *)recv_buf->rbuf, cmd_val, 595 pool, &info); 596 597 len = pj_ansi_strlen((char *)recv_buf->rbuf); 598 599 switch (status) { 600 case PJ_CLI_EINVARG: 601 send_inv_arg(sess, &info, PJ_TRUE, PJ_TRUE); 602 break; 603 case PJ_CLI_ETOOMANYARGS: 604 send_too_many_arg(sess, &info, PJ_TRUE, PJ_TRUE); 605 break; 606 case PJ_CLI_EMISSINGARG: 607 case PJ_CLI_EAMBIGUOUS: 608 send_ambi_arg(sess, &info, PJ_TRUE, PJ_TRUE); 609 break; 610 case PJ_SUCCESS: 611 if (len > recv_buf->cur_pos) 612 { 613 /* Send the cursor to EOL */ 614 unsigned char *data_sent = &recv_buf->rbuf[recv_buf->cur_pos-1]; 615 printf("%s", data_sent); 616 } 617 if (info.hint_cnt > 0) { 618 /* Compelete command */ 619 send_comp_arg(&info); 620 621 pj_memcpy(&recv_buf->rbuf[len], 622 &info.hint[0].name.ptr[0], info.hint[0].name.slen); 623 624 len += info.hint[0].name.slen; 625 recv_buf->rbuf[len] = 0; 626 } else { 627 retval = PJ_FALSE; 628 } 629 break; 630 } 631 recv_buf->len = len; 632 recv_buf->cur_pos = len; 633 634 pj_pool_release(pool); 635 return retval; 636 } 637 638 static pj_bool_t handle_return(pj_cli_sess *sess) 639 { 640 pj_status_t status; 641 pj_bool_t retval = PJ_TRUE; 642 643 pj_pool_t *pool; 644 pj_cli_exec_info info; 645 pj_cli_t *cli = sess->fe->cli; 646 struct cli_console_fe *fe = (struct cli_console_fe *)sess->fe; 647 console_recv_buf *recv_buf = &fe->input.recv_buf; 648 649 send_return_key(sess); 650 insert_history(sess, (char *)&recv_buf->rbuf[0]); 651 652 pool = pj_pool_create(pj_cli_get_param(cli)->pf, "handle_return", 653 PJ_CLI_CONSOLE_POOL_SIZE, PJ_CLI_CONSOLE_POOL_INC, 654 NULL); 655 656 status = pj_cli_sess_exec(sess, (char *)&recv_buf->rbuf[0], 657 pool, &info); 658 659 switch (status) { 660 case PJ_CLI_EINVARG: 661 send_inv_arg(sess, &info, PJ_FALSE, PJ_FALSE); 662 break; 663 case PJ_CLI_ETOOMANYARGS: 664 send_too_many_arg(sess, &info, PJ_FALSE, PJ_FALSE); 665 break; 666 case PJ_CLI_EAMBIGUOUS: 667 case PJ_CLI_EMISSINGARG: 668 send_ambi_arg(sess, &info, PJ_FALSE, PJ_FALSE); 669 break; 670 case PJ_CLI_EEXIT: 671 retval = PJ_FALSE; 672 break; 673 case PJ_SUCCESS: 674 send_prompt_str(sess); 675 break; 676 } 677 if (retval) { 678 recv_buf->rbuf[0] = 0; 679 recv_buf->len = 0; 680 recv_buf->cur_pos = 0; 681 } 682 683 pj_pool_release(pool); 684 return retval; 685 } 686 687 static pj_bool_t handle_up_down(pj_cli_sess *sess, pj_bool_t is_up) 688 { 689 pj_str_t *history; 690 struct cli_console_fe *fe = (struct cli_console_fe *)sess->fe; 691 console_recv_buf *recv_buf = &fe->input.recv_buf; 692 693 PJ_ASSERT_RETURN(sess && fe, PJ_FALSE); 694 695 history = get_prev_history(sess, is_up); 696 if (history) { 697 pj_str_t send_data; 698 char str[PJ_CLI_MAX_CMDBUF]; 699 send_data.ptr = &str[0]; 700 send_data.slen = 0; 701 702 if (recv_buf->cur_pos > 0) { 703 pj_memset(send_data.ptr, 0x08, recv_buf->cur_pos); 704 send_data.slen = recv_buf->cur_pos; 705 } 706 707 if (recv_buf->len > (unsigned)history->slen) { 708 unsigned buf_len = recv_buf->len; 709 pj_memset(&send_data.ptr[send_data.slen], 0x20, buf_len); 710 send_data.slen += buf_len; 711 pj_memset(&send_data.ptr[send_data.slen], 0x08, buf_len); 712 send_data.slen += buf_len; 713 } 714 /* Send data */ 715 pj_strcat(&send_data, history); 716 send_data.ptr[send_data.slen] = 0; 717 printf("%s", send_data.ptr); 718 pj_ansi_strncpy((char*)&recv_buf->rbuf, history->ptr, history->slen); 719 recv_buf->rbuf[history->slen] = 0; 720 recv_buf->len = history->slen; 721 recv_buf->cur_pos = recv_buf->len; 722 return PJ_TRUE; 723 } 724 return PJ_FALSE; 725 } 726 727 static pj_bool_t handle_left_key(console_recv_buf *recv_buf) 728 { 729 const static unsigned char BACK_SPACE = 0x08; 730 if (recv_buf->cur_pos) { 731 printf("%c", BACK_SPACE); 732 --recv_buf->cur_pos; 733 return PJ_TRUE; 734 } 735 return PJ_FALSE; 736 } 737 738 static pj_bool_t handle_right_key(console_recv_buf *recv_buf) 739 { 740 if (recv_buf_right_len(recv_buf)) { 741 unsigned char *data = &recv_buf->rbuf[recv_buf->cur_pos++]; 742 printf("%c", *data); 743 return PJ_TRUE; 744 } 745 return PJ_FALSE; 746 } 747 748 static int readchar_thread(void * p) 749 { 140 750 struct cli_console_fe * fe = (struct cli_console_fe *)p; 141 int i; 751 cmd_parse_state parse_state = ST_NORMAL; 752 753 printf("%s", fe->cfg.prompt_str.ptr); 142 754 143 755 while (!fe->thread_quit) { 144 fgets(fe->input.buf, fe->input.maxlen, stdin); 145 for (i = pj_ansi_strlen(fe->input.buf) - 1; i >= 0; i--) { 146 if (fe->input.buf[i] == '\n' || fe->input.buf[i] == '\r') 147 fe->input.buf[i] = 0; 148 else 149 break; 150 } 151 pj_sem_post(fe->input.sem); 152 /* Sleep until the next call of pj_cli_console_readline() */ 756 unsigned char cdata; 757 console_recv_buf *recv_buf = &fe->input.recv_buf; 758 pj_bool_t is_valid = PJ_TRUE; 759 760 cdata = (unsigned char)getch(); 761 762 switch (parse_state) { 763 case ST_NORMAL: 764 if (cdata == '\b') { 765 is_valid = handle_backspace(recv_buf); 766 } else if (cdata == 224) { 767 parse_state = ST_SCANMODE; 768 } else if (cdata == 27) { 769 parse_state = ST_ESC; 770 } else { 771 if (cdata == '\n') 772 cdata = '\r'; 773 if (recv_buf_insert(recv_buf, &cdata)) { 774 if (cdata == '\r') { 775 is_valid = handle_return(fe->sess); 776 } else if ((cdata == '\t') || (cdata == '?')) { 777 is_valid = handle_tab(fe->sess); 778 } else if (cdata > 31 && cdata < 127) { 779 is_valid = handle_alfa_num(recv_buf, &cdata); 780 } 781 } else { 782 is_valid = PJ_FALSE; 783 } 784 } 785 break; 786 case ST_SCANMODE: 787 switch (cdata) { 788 case 72: 789 //UP 790 case 80: 791 //DOwN 792 is_valid = handle_up_down(fe->sess, (cdata==72)); 793 break; 794 case 75: 795 is_valid = handle_left_key(recv_buf); 796 //LEFT 797 break; 798 case 77: 799 is_valid = handle_right_key(recv_buf); 800 //RIGHT 801 break; 802 }; 803 parse_state = ST_NORMAL; 804 break; 805 case ST_ESC: 806 parse_state = (cdata == 91)?ST_ARROWMODE:ST_NORMAL; 807 break; 808 case ST_ARROWMODE: 809 switch (cdata) { 810 case 65: 811 //UP 812 case 66: 813 //DOwN 814 is_valid = handle_up_down(fe->sess, (cdata==65)); 815 break; 816 case 68: 817 is_valid = handle_left_key(recv_buf); 818 //LEFT 819 break; 820 case 67: 821 is_valid = handle_right_key(recv_buf); 822 //RIGHT 823 break; 824 }; 825 parse_state = ST_NORMAL; 826 break; 827 }; 828 829 pj_sem_post(fe->input.sem); 153 830 pj_sem_wait(fe->thread_sem); 154 831 } … … 158 835 } 159 836 160 PJ_DEF(pj_status_t) pj_cli_console_readline(pj_cli_sess *sess, 161 char *buf, 162 unsigned maxlen) 837 PJ_DEF(pj_status_t) pj_cli_console_process(pj_cli_sess *sess) 163 838 { 164 839 struct cli_console_fe *fe = (struct cli_console_fe *)sess->fe; 165 840 166 PJ_ASSERT_RETURN(sess && buf, PJ_EINVAL); 167 168 fe->input.buf = buf; 169 fe->input.maxlen = maxlen; 841 PJ_ASSERT_RETURN(sess, PJ_EINVAL); 170 842 171 843 if (!fe->input_thread) { 172 844 pj_status_t status; 173 845 174 status = pj_thread_create(fe->pool, NULL, &read line_thread, fe,846 status = pj_thread_create(fe->pool, NULL, &readchar_thread, fe, 175 847 0, 0, &fe->input_thread); 176 848 if (status != PJ_SUCCESS) 177 849 return status; 178 850 } else { 179 /* Wake up read linethread */851 /* Wake up readchar thread */ 180 852 pj_sem_post(fe->thread_sem); 181 853 }
Note: See TracChangeset
for help on using the changeset viewer.