console.c revision 981801b95b81e6d1c7a2085967406e86af0f08fc
1/* 2 * console.c 3 * 4 * Copyright 2001-2009 Texas Instruments, Inc. - http://www.ti.com/ 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19/**************************************************************************** 20* 21* MODULE: console.c 22* 23* PURPOSE: 24* 25* DESCRIPTION: 26* ============ 27* 28* 29****************************************************************************/ 30 31/* includes */ 32/************/ 33#include "cu_osapi.h" 34#include "console.h" 35#include "cu_cmd.h" 36 37/* defines */ 38/***********/ 39#define INBUF_LENGTH 2100 40#define MAX_NAME_LEN 64 41#define MAX_HELP_LEN 40 42#define MAX_PARM_LEN 20 43#define ALIAS_LEN 1 44 45#define TOKEN_UP ".." 46#define TOKEN_ROOT "/" 47#define TOKEN_BREAK "#" 48#define TOKEN_HELP "?" 49#define TOKEN_DIRHELP "help" 50 51/* local types */ 52/***************/ 53 54typedef enum 55{ 56 Dir, 57 Token 58} ConEntry_type_t; 59 60/* Token types */ 61typedef enum 62{ 63 EmptyToken, 64 UpToken, 65 RootToken, 66 BreakToken, 67 HelpToken, 68 DirHelpToken, 69 NameToken 70} TokenType_t; 71 72 73/* Monitor token structure */ 74typedef struct ConEntry_t 75{ 76 struct ConEntry_t *next; 77 S8 name[MAX_NAME_LEN+1]; /* Entry name */ 78 S8 help[MAX_HELP_LEN+1]; /* Help string */ 79 PS8 alias; /* Alias - always in upper case*/ 80 ConEntry_type_t sel; /* Entry selector */ 81 82 union 83 { 84 struct 85 { 86 struct ConEntry_t *upper; /* Upper directory */ 87 struct ConEntry_t *first; /* First entry */ 88 } dir; 89 struct t_Token 90 { 91 FuncToken_t f_tokenFunc; /* Token handler */ 92 S32 totalParams; 93 ConParm_t *parm; /* Parameters array with totalParams size */ 94 PS8 *name; /* Parameter name with totalParams size */ 95 } token; 96 } u; 97} ConEntry_t; 98 99/* Module control block */ 100typedef struct Console_t 101{ 102 THandle hCuCmd; 103 104 S32 isDeviceOpen; 105 106 ConEntry_t *p_mon_root; 107 ConEntry_t *p_cur_dir; 108 PS8 p_inbuf; 109 volatile S32 stop_UI_Monitor; 110} Console_t; 111 112/* local variables */ 113/*******************/ 114 115/* local fucntions */ 116/*******************/ 117static VOID Console_allocRoot(Console_t* pConsole); 118 119 120/* Remove leading blanks */ 121static PS8 Console_ltrim(PS8 s) 122{ 123 while( *s == ' ' || *s == '\t' ) s++; 124 return s; 125} 126 127/* 128Make a preliminary analizis of <name> token. 129Returns a token type (Empty, Up, Root, Break, Name) 130*/ 131static TokenType_t Console_analizeToken( PS8 name ) 132{ 133 if (!name[0]) 134 return EmptyToken; 135 136 if (!os_strcmp(name, (PS8)TOKEN_UP ) ) 137 return UpToken; 138 139 if (!os_strcmp(name, (PS8)TOKEN_ROOT ) ) 140 return RootToken; 141 142 if (!os_strcmp(name, (PS8)TOKEN_BREAK ) ) 143 return BreakToken; 144 145 if (!os_strcmp(name, (PS8)TOKEN_HELP ) ) 146 return HelpToken; 147 148 if (!os_strcmp(name, (PS8)TOKEN_DIRHELP ) ) 149 return DirHelpToken; 150 151 return NameToken; 152 153} 154 155/* Compare strings case insensitive */ 156static S32 Console_stricmp( PS8 s1, PS8 s2, U16 len ) 157{ 158 S32 i; 159 160 for( i=0; i<len && s1[i] && s2[i]; i++ ) 161 { 162 if (os_tolower(s1[i]) != os_tolower(s2[i] )) 163 break; 164 } 165 166 return ( (len - i) * (s1[i] - s2[i]) ); 167} 168 169/* Convert string s to lower case. Return pointer to s */ 170static PS8 Console_strlwr( PS8 s ) 171{ 172 PS8 s0=s; 173 174 while( *s ) 175 { 176 *s = (S8)os_tolower(*s ); 177 ++s; 178 } 179 180 return s0; 181} 182 183/* free the entries tree */ 184static VOID Console_FreeEntry(ConEntry_t *pEntry) 185{ 186 ConEntry_t *pEntryTemp,*pEntryTemp1; 187 188 if(pEntry->sel == Dir) 189 { 190 pEntryTemp = pEntry->u.dir.first; 191 192 while (pEntryTemp) 193 { 194 pEntryTemp1 = pEntryTemp->next; 195 Console_FreeEntry(pEntryTemp); 196 pEntryTemp = pEntryTemp1; 197 } 198 } 199 200 /* free the current entry */ 201 os_MemoryFree(pEntry); 202} 203 204 205/* Allocate root directory */ 206static VOID Console_allocRoot(Console_t* pConsole) 207{ 208 /* The very first call. Allocate root structure */ 209 if ((pConsole->p_mon_root=(ConEntry_t *)os_MemoryCAlloc(sizeof( ConEntry_t ), 1) ) == NULL) 210 { 211 os_error_printf(CU_MSG_ERROR, (PS8)( "ERROR - Console_allocRoot(): cant allocate root\n") ); 212 return; 213 } 214 os_strcpy((PS8)pConsole->p_mon_root->name, (PS8)("\\") ); 215 pConsole->p_mon_root->sel = Dir; 216 pConsole->p_cur_dir = pConsole->p_mon_root; 217} 218 219/* Display current directory */ 220static VOID Console_displayDir(Console_t* pConsole) 221{ 222 S8 out_buf[512]; 223 ConEntry_t *p_token; 224 ConEntry_t *p_dir = pConsole->p_cur_dir; 225 226 os_sprintf((PS8)out_buf, (PS8)("%s%s> "), (PS8)(p_dir==pConsole->p_mon_root)? (PS8)("") : (PS8)(".../"), (PS8)p_dir->name ); 227 p_token = p_dir->u.dir.first; 228 while( p_token ) 229 { 230 if( (os_strlen(out_buf) + os_strlen(p_token->name) + 2)>= sizeof(out_buf) ) 231 { 232 os_error_printf(CU_MSG_ERROR, ( (PS8)"ERROR - Console_displayDir(): buffer too small....\n") ); 233 break; 234 } 235 os_strcat(out_buf, p_token->name ); 236 if ( p_token->sel == Dir ) 237 os_strcat((PS8)out_buf, (PS8)("/" ) ); 238 p_token = p_token->next; 239 if (p_token) 240 os_strcat((PS8)out_buf, (PS8)(", ") ); 241 } 242 243 os_error_printf(CU_MSG_INFO2, (PS8)("%s\n"), (PS8)out_buf ); 244} 245 246 247/* 248Cut the first U16 from <p_inbuf>. 249Return the U16 in <name> and updated <p_inbuf> 250*/ 251static TokenType_t Console_getWord(Console_t* pConsole, PS8 name, U16 len ) 252{ 253 U16 i=0; 254 TokenType_t tType; 255 256 pConsole->p_inbuf = Console_ltrim(pConsole->p_inbuf); 257 258 while( *pConsole->p_inbuf && *pConsole->p_inbuf!=' ' && i<len ) 259 name[i++] = *(pConsole->p_inbuf++); 260 261 if (i<len) 262 name[i] = 0; 263 264 tType = Console_analizeToken( name ); 265 266 return tType; 267} 268 269static TokenType_t Console_getStrParam(Console_t* pConsole, PS8 buf, ConParm_t *param ) 270{ 271 TokenType_t tType; 272 U32 i, len = param->hi_val; 273 PS8 end_buf; 274 275 pConsole->p_inbuf = Console_ltrim(pConsole->p_inbuf); 276 277 if( param->flags & CON_PARM_LINE ) 278 { 279 os_strcpy(buf, (PS8)pConsole->p_inbuf ); 280 pConsole->p_inbuf += os_strlen(pConsole->p_inbuf); 281 } 282 else 283 { 284 if( *pConsole->p_inbuf == '\"' ) 285 { 286 end_buf = os_strchr(pConsole->p_inbuf+1, '\"' ); 287 if( !end_buf ) 288 { 289 os_error_printf(CU_MSG_ERROR, (PS8)("ERROR - invalid string param: '%s'\n"), (PS8)pConsole->p_inbuf ); 290 pConsole->p_inbuf += os_strlen(pConsole->p_inbuf); 291 return EmptyToken; 292 } 293 if( (end_buf - pConsole->p_inbuf - 1) > (int)len ) 294 { 295 os_error_printf(CU_MSG_ERROR, (PS8)("ERROR - param is too long: '%s'\n"), (PS8)pConsole->p_inbuf ); 296 pConsole->p_inbuf += os_strlen(pConsole->p_inbuf); 297 return EmptyToken; 298 } 299 *end_buf = 0; 300 os_strcpy( buf, (PS8)(pConsole->p_inbuf+1 ) ); 301 pConsole->p_inbuf = end_buf + 1; 302 } 303 else 304 { 305 for( i=0; *pConsole->p_inbuf && *pConsole->p_inbuf!=' ' && i<len; i++ ) 306 buf[i] = *(pConsole->p_inbuf++); 307 308 buf[i] = 0; 309 if( *pConsole->p_inbuf && *pConsole->p_inbuf != ' ' ) 310 { 311 os_error_printf(CU_MSG_ERROR, (PS8)("ERROR - param is too long: '%s'\n"), (PS8)( pConsole->p_inbuf-os_strlen( buf) ) ); 312 pConsole->p_inbuf += os_strlen(pConsole->p_inbuf); 313 return EmptyToken; 314 } 315 } 316 } 317 318 tType = Console_analizeToken( buf ); 319 320 return tType; 321} 322 323/* Returns number of parameters of the given token 324*/ 325static U16 Console_getNParms( ConEntry_t *p_token ) 326{ 327 U16 i; 328 if ( !p_token->u.token.parm ) 329 return 0; 330 for( i=0; 331 (i<p_token->u.token.totalParams) && 332 p_token->u.token.parm[i].name && 333 p_token->u.token.parm[i].name[0]; 334 i++ ) 335 ; 336 return i; 337} 338 339/* Parse p_inbuf string based on parameter descriptions in <p_token>. 340Fill parameter values in <p_token>. 341Returns the number of parameters filled. 342To Do: add a option of one-by-one user input of missing parameters. 343*/ 344static S32 Console_parseParms(Console_t* pConsole, ConEntry_t *p_token, U16 *pnParms ) 345{ 346 U16 nTotalParms = Console_getNParms( p_token ); 347 U16 nParms=0; 348 PS8 end_buf = NULL; 349 S8 parm[INBUF_LENGTH]; 350 U16 i, print_params = 0; 351 U32 val = 0; 352 S32 sval = 0; 353 354 /* Mark all parameters as don't having an explicit value */ 355 for( i=0; i<nTotalParms; i++ ) 356 p_token->u.token.parm[i].flags |= CON_PARM_NOVAL; 357 358 /* ----------------- */ 359 pConsole->p_inbuf = Console_ltrim(pConsole->p_inbuf); 360 if( pConsole->p_inbuf[0] == '!' && pConsole->p_inbuf[1] == '!' ) 361 { 362 pConsole->p_inbuf += 2; print_params = 1; 363 } 364 /* ----------------- */ 365 366 /* Build a format string */ 367 for( i=0; i<nTotalParms; i++ ) 368 { 369 if (p_token->u.token.parm[i].flags & (CON_PARM_STRING | CON_PARM_LINE) ) 370 { 371 /* For a string parameter value is the string address */ 372 /* and hi_val is the string length */ 373 if (Console_getStrParam(pConsole, parm, &p_token->u.token.parm[i] ) != NameToken) 374 break; 375 if( os_strlen( parm) > p_token->u.token.parm[i].hi_val || 376 (p_token->u.token.parm[i].low_val && p_token->u.token.parm[i].low_val > os_strlen( parm) ) ) 377 { 378 os_error_printf(CU_MSG_ERROR, (PS8)("ERROR - param '%s' must be %ld..%ld chars\n"), (PS8)p_token->u.token.parm[i].name, 379 (PS8)p_token->u.token.parm[i].low_val, (PS8)p_token->u.token.parm[i].hi_val); 380 return FALSE; 381 } 382 os_strcpy((PS8)(char *)p_token->u.token.parm[i].value, (PS8)parm); 383 } 384 else 385 { 386 if (Console_getWord(pConsole, parm, MAX_PARM_LEN ) != NameToken) 387 break; 388 389 if (p_token->u.token.parm[i].flags & CON_PARM_SIGN) 390 { 391 sval = os_strtol( parm, &end_buf, 0 ); 392 } 393 else 394 { 395 val = os_strtoul( parm, &end_buf, 0 ); 396 } 397 if( end_buf <= parm ) 398 break; 399 400 /* Check value */ 401 if (p_token->u.token.parm[i].flags & CON_PARM_RANGE) 402 { 403 if (p_token->u.token.parm[i].flags & CON_PARM_SIGN) 404 { 405 if ((sval < (S32)p_token->u.token.parm[i].low_val) || 406 (sval > (S32)p_token->u.token.parm[i].hi_val) ) 407 { 408 os_error_printf(CU_MSG_ERROR, (PS8)("%s: %d out of range (%d, %d)\n"), 409 (PS8)p_token->u.token.parm[i].name, (int)sval, 410 (int)p_token->u.token.parm[i].low_val, (int)p_token->u.token.parm[i].hi_val ); 411 return FALSE; 412 } 413 414 } 415 else 416 { 417 if ((val < p_token->u.token.parm[i].low_val) || 418 (val > p_token->u.token.parm[i].hi_val) ) 419 { 420 os_error_printf(CU_MSG_ERROR , (PS8)("%s: %ld out of range (%ld, %ld)\n"), 421 (PS8)p_token->u.token.parm[i].name, (PS8)val, 422 (PS8)p_token->u.token.parm[i].low_val, (PS8)p_token->u.token.parm[i].hi_val ); 423 return FALSE; 424 } 425 } 426 } 427 428 if (p_token->u.token.parm[i].flags & CON_PARM_SIGN) 429 p_token->u.token.parm[i].value = sval; 430 else 431 p_token->u.token.parm[i].value = val; 432 } 433 434 p_token->u.token.parm[i].flags &= ~CON_PARM_NOVAL; 435 ++nParms; 436 } 437 438 /* Process default values */ 439 for( ; i<nTotalParms; i++ ) 440 { 441 if ((p_token->u.token.parm[i].flags & CON_PARM_DEFVAL) != 0) 442 { 443 p_token->u.token.parm[i].flags &= ~CON_PARM_NOVAL; 444 ++nParms; 445 } 446 else if (!(p_token->u.token.parm[i].flags & CON_PARM_OPTIONAL) ) 447 { 448 /* Mandatory parameter missing */ 449 return FALSE; 450 } 451 } 452 453 if( print_params ) 454 { 455 os_error_printf((S32)CU_MSG_INFO2, (PS8)("Params: %d\n"), nParms ); 456 for (i=0; i<nParms; i++ ) 457 { 458 os_error_printf(CU_MSG_INFO2, (PS8)("%d: %s - flags:%d"), 459 i+1, (PS8)p_token->u.token.parm[i].name, 460 p_token->u.token.parm[i].flags); 461 462 if (p_token->u.token.parm[i].flags & CON_PARM_SIGN) 463 os_error_printf(CU_MSG_INFO2, (PS8)("min:%d, max:%d, value:%d "),(PS8)p_token->u.token.parm[i].low_val, (PS8)p_token->u.token.parm[i].hi_val, 464 (PS8)p_token->u.token.parm[i].value); 465 else 466 os_error_printf(CU_MSG_INFO2, (PS8)("min:%ld, max:%ld, value:%ld "),(PS8)p_token->u.token.parm[i].low_val, (PS8)p_token->u.token.parm[i].hi_val, 467 (PS8)p_token->u.token.parm[i].value); 468 469 os_error_printf(CU_MSG_INFO2, (PS8)("(%#lx)"),(PS8)p_token->u.token.parm[i].value ); 470 471 if( p_token->u.token.parm[i].flags & (CON_PARM_LINE | CON_PARM_STRING )) 472 { 473 os_error_printf(CU_MSG_INFO2, (PS8)(" - '%s'"), (PS8)(char *) p_token->u.token.parm[i].value ); 474 } 475 os_error_printf(CU_MSG_INFO2, (PS8)("\n") ); 476 } 477 478 } 479 *pnParms = nParms; 480 481 return TRUE; 482} 483 484/* Serach a token by name in the current directory */ 485static ConEntry_t *Console_searchToken( ConEntry_t *p_dir, PS8 name ) 486{ 487 ConEntry_t *p_token; 488 U16 name_len = (U16)os_strlen( name ); 489 490 /* Check alias */ 491 p_token = p_dir->u.dir.first; 492 while( p_token ) 493 { 494 if (p_token->alias && 495 (name_len == ALIAS_LEN) && 496 !Console_stricmp( p_token->alias, name, ALIAS_LEN ) ) 497 return p_token; 498 p_token = p_token->next; 499 } 500 501 /* Check name */ 502 p_token = p_dir->u.dir.first; 503 while( p_token ) 504 { 505 if (!Console_stricmp( p_token->name, name, name_len ) ) 506 break; 507 p_token = p_token->next; 508 } 509 510 return p_token; 511} 512 513 514/* Display help for each entry in the current directory */ 515VOID Console_dirHelp(Console_t* pConsole) 516{ 517 ConEntry_t *p_token; 518 S8 print_str[80]; 519 520 p_token = pConsole->p_cur_dir->u.dir.first; 521 522 while( p_token ) 523 { 524 if (p_token->sel == Dir) 525 os_sprintf( print_str, (PS8)"%s: directory\n", (PS8)p_token->name ); 526 else 527 os_sprintf( print_str, (PS8)("%s(%d parms): %s\n"), 528 (PS8)p_token->name, Console_getNParms(p_token), p_token->help ); 529 os_error_printf(CU_MSG_INFO2, (PS8)print_str ); 530 p_token = p_token->next; 531 } 532 533 os_error_printf(CU_MSG_INFO2, (PS8)("Type ? <name> for command help, \"/\"-root, \"..\"-upper\n") ); 534} 535 536 537/* Display help a token */ 538static VOID Console_displayHelp(Console_t* pConsole, ConEntry_t *p_token ) 539{ 540 S8 bra, ket; 541 U16 nTotalParms = Console_getNParms( p_token ); 542 U16 i; 543 544 545 os_error_printf(CU_MSG_INFO2, (PS8)("%s: %s "), (PS8)p_token->help, (PS8)p_token->name ); 546 for( i=0; i<nTotalParms; i++ ) 547 { 548 if (p_token->u.token.parm[i].flags & CON_PARM_OPTIONAL) 549 { 550 bra = '['; ket=']'; 551 } 552 else 553 { 554 bra = '<'; ket='>'; 555 } 556 os_error_printf(CU_MSG_INFO2, (PS8)("%c%s"), bra, (PS8)p_token->u.token.parm[i].name ); 557 if (p_token->u.token.parm[i].flags & CON_PARM_DEFVAL) 558 { 559 os_error_printf(CU_MSG_INFO2, (PS8)("=%lu"), (PS8)p_token->u.token.parm[i].value); 560 } 561 if (p_token->u.token.parm[i].flags & CON_PARM_RANGE) 562 { 563 os_error_printf(CU_MSG_INFO2, (PS8)(p_token->u.token.parm[i].flags & CON_PARM_SIGN) ? (PS8)(" (%d..%d%s)") : (PS8)(" (%lu..%lu%s)"), 564 (PS8)p_token->u.token.parm[i].low_val, 565 (PS8)p_token->u.token.parm[i].hi_val, 566 (PS8)(p_token->u.token.parm[i].flags & (CON_PARM_STRING | CON_PARM_LINE)) ? (PS8)(" chars") : (PS8)("") ); 567 568 } 569 os_error_printf(CU_MSG_INFO2, (PS8)("%c \n"),ket ); 570 } 571} 572 573/* Choose unique alias for <name> in <p_dir> */ 574/* Currently only single-character aliases are supported */ 575static S32 Console_chooseAlias( ConEntry_t *p_dir, ConEntry_t *p_new_token ) 576{ 577 ConEntry_t *p_token; 578 S32 i; 579 S8 c; 580 PS8 new_alias = NULL; 581 582 /* find alias given from user */ 583 for(i=0; p_new_token->name[i]; i++ ) 584 { 585 if( os_isupper( p_new_token->name[i]) ) 586 { 587 new_alias = &p_new_token->name[i]; 588 break; 589 } 590 } 591 592 Console_strlwr( p_new_token->name ); 593 594 if( new_alias ) 595 { 596 p_token = p_dir->u.dir.first; 597 598 while( p_token ) 599 { 600 if (p_token->alias && (os_tolower(*p_token->alias ) == *new_alias) ) 601 { 602 os_error_printf(CU_MSG_ERROR, (PS8)("Error - duplicated alias '%c' in <%s> and <%s>**\n"), *new_alias, 603 (PS8)p_token->name, (PS8)p_new_token->name ); 604 return 0; 605 } 606 p_token = p_token->next; 607 } 608 *new_alias = (S8)os_toupper(*new_alias); 609 p_new_token->alias = new_alias; 610 return 1; 611 } 612 613 i = 0; 614 while( p_new_token->name[i] ) 615 { 616 c = p_new_token->name[i]; 617 p_token = p_dir->u.dir.first; 618 619 while( p_token ) 620 { 621 if (p_token->alias && 622 (os_tolower(*p_token->alias ) == c) ) 623 break; 624 p_token = p_token->next; 625 } 626 if (p_token) 627 ++i; 628 else 629 { 630 p_new_token->name[i] = (S8)os_toupper( c ); 631 p_new_token->alias = &p_new_token->name[i]; 632 break; 633 } 634 } 635 return 1; 636} 637 638/* Parse the given input string and exit. 639All commands in the input string are executed one by one. 640*/ 641static VOID Console_ParseString(Console_t* pConsole, PS8 input_string ) 642{ 643 ConEntry_t *p_token; 644 S8 name[MAX_NAME_LEN]; 645 TokenType_t tType; 646 U16 nParms; 647 648 if (!pConsole->p_mon_root) 649 return; 650 651 if(!pConsole->isDeviceOpen) 652 { 653 Console_GetDeviceStatus(pConsole); 654 if(!pConsole->isDeviceOpen) 655 { 656 os_error_printf(CU_MSG_ERROR, (PS8)("ERROR - Console_ParseString - Device isn't loaded !!!\n") ); 657 return; 658 } 659 } 660 661 if( input_string[os_strlen( input_string)-1] == '\n' ) 662 { 663 PS8 s = &input_string[os_strlen( input_string)-1]; 664 *s = 0; 665 } 666 pConsole->p_inbuf = input_string; 667 pConsole->stop_UI_Monitor = FALSE; 668 669 /* Interpret empty string as "display directory" */ 670 if ( pConsole->p_inbuf && !*pConsole->p_inbuf ) 671 Console_displayDir(pConsole); 672 673 while(!pConsole->stop_UI_Monitor && pConsole->p_inbuf && *pConsole->p_inbuf) 674 { 675 tType = Console_getWord(pConsole, name, MAX_NAME_LEN ); 676 switch( tType ) 677 { 678 679 case NameToken: 680 p_token = Console_searchToken( pConsole->p_cur_dir, name ); 681 if (p_token == NULL) 682 { 683 os_error_printf(CU_MSG_ERROR, (PS8)("**Error: '%s'**\n"),name); 684 pConsole->p_inbuf = NULL; 685 } 686 else if (p_token->sel == Dir) 687 { 688 pConsole->p_cur_dir = p_token; 689 Console_displayDir(pConsole); 690 } 691 else 692 { /* Function token */ 693 if (!Console_parseParms(pConsole, p_token, &nParms )) 694 { 695 Console_displayHelp(pConsole, p_token ); 696 } 697 else 698 { 699 p_token->u.token.f_tokenFunc(pConsole->hCuCmd, p_token->u.token.parm, nParms ); 700 } 701 } 702 break; 703 704 case UpToken: /* Go to upper directory */ 705 if (pConsole->p_cur_dir->u.dir.upper) 706 pConsole->p_cur_dir = pConsole->p_cur_dir->u.dir.upper; 707 Console_displayDir(pConsole); 708 break; 709 710 case RootToken: /* Go to the root directory */ 711 if (pConsole->p_cur_dir->u.dir.upper) 712 pConsole->p_cur_dir = pConsole->p_mon_root; 713 Console_displayDir(pConsole); 714 break; 715 716 case HelpToken: /* Display help */ 717 if (( Console_getWord(pConsole, name, MAX_NAME_LEN ) == NameToken ) && 718 ((p_token = Console_searchToken( pConsole->p_cur_dir, name )) != NULL ) && 719 (p_token->sel == Token) ) 720 Console_displayHelp(pConsole, p_token); 721 else 722 Console_dirHelp(pConsole); 723 break; 724 725 case DirHelpToken: 726 Console_displayDir(pConsole); 727 os_error_printf(CU_MSG_INFO2, (PS8)("Type ? <name> for command help, \"/\"-root, \"..\"-upper\n") ); 728 break; 729 730 case BreakToken: /* Clear buffer */ 731 pConsole->p_inbuf = NULL; 732 break; 733 734 case EmptyToken: 735 break; 736 737 } 738 } 739} 740 741/* functions */ 742/*************/ 743 744THandle Console_Create(const PS8 device_name, S32 BypassSupplicant, PS8 pSupplIfFile) 745{ 746 Console_t* pConsole = (Console_t*)os_MemoryCAlloc(sizeof(Console_t), sizeof(U8)); 747 if(pConsole == NULL) 748 { 749 os_error_printf(CU_MSG_ERROR, (PS8)("Error - Console_Create - cant allocate control block\n") ); 750 return NULL; 751 } 752 753 pConsole->hCuCmd = CuCmd_Create(device_name, pConsole, BypassSupplicant, pSupplIfFile); 754 if(pConsole->hCuCmd == NULL) 755 { 756 Console_Destroy(pConsole); 757 return NULL; 758 } 759 760 Console_allocRoot(pConsole); 761 762 pConsole->isDeviceOpen = FALSE; 763 764 return pConsole; 765} 766 767VOID Console_Destroy(THandle hConsole) 768{ 769 Console_t* pConsole = (Console_t*)hConsole; 770 771 if(pConsole->hCuCmd) 772 { 773 CuCmd_Destroy(pConsole->hCuCmd); 774 } 775 if (pConsole->p_mon_root) 776 { 777 Console_FreeEntry(pConsole->p_mon_root); 778 } 779 os_MemoryFree(pConsole); 780} 781 782VOID Console_Stop(THandle hConsole) 783{ 784 ((Console_t*)hConsole)->stop_UI_Monitor = TRUE; 785} 786 787/* Monitor driver */ 788VOID Console_Start(THandle hConsole) 789{ 790 Console_t* pConsole = (Console_t*)hConsole; 791 S8 inbuf[INBUF_LENGTH]; 792 S32 res; 793 794 if (!pConsole->p_mon_root) 795 return; 796 797 pConsole->stop_UI_Monitor = FALSE; 798 Console_displayDir(pConsole); 799 800 while(!pConsole->stop_UI_Monitor) 801 { 802 /* get input string */ 803 res = os_getInputString(inbuf, sizeof(inbuf)); 804 if (res == FALSE) 805 { 806 if(pConsole->stop_UI_Monitor) 807 { 808 continue; 809 } 810 else 811 { 812 return; 813 } 814 } 815 816 if(res == OS_GETINPUTSTRING_CONTINUE) 817 continue; 818 819 /* change to NULL terminated strings */ 820 if( inbuf[os_strlen(inbuf)-1] == '\n' ) 821 inbuf[os_strlen(inbuf)-1] = 0; 822 823 /* parse the string */ 824 Console_ParseString(pConsole, inbuf); 825 } 826 827} 828 829VOID Console_GetDeviceStatus(THandle hConsole) 830{ 831 Console_t* pConsole = (Console_t*)hConsole; 832 833 if(OK == CuCmd_GetDeviceStatus(pConsole->hCuCmd)) 834 { 835 pConsole->isDeviceOpen = TRUE; 836 } 837} 838 839 840/*************************************************************** 841 842 Function : consoleAddDirExt 843 844 Description: Add subdirectory 845 846 Parameters: p_root - root directory handle (might be NULL) 847 name - directory name 848 849 Output: the new created directory handle 850 =NULL - failure 851***************************************************************/ 852THandle Console_AddDirExt(THandle hConsole, 853 THandle hRoot, /* Upper directory handle. NULL=root */ 854 const PS8 name, /* New directory name */ 855 const PS8 desc ) /* Optional dir description */ 856{ 857 Console_t* pConsole = (Console_t*)hConsole; 858 ConEntry_t *p_root = (ConEntry_t *)hRoot; 859 ConEntry_t *p_dir; 860 ConEntry_t **p_e; 861 862 if (!p_root) 863 p_root = pConsole->p_mon_root; 864 865 if(!( p_root && (p_root->sel == Dir))) 866 return NULL; 867 868 if ( (p_dir=(ConEntry_t *)os_MemoryAlloc(sizeof( ConEntry_t )) ) == NULL) 869 return NULL; 870 871 os_memset( p_dir, 0, sizeof( ConEntry_t ) ); 872 os_strncpy( p_dir->name, name, MAX_NAME_LEN ); 873 os_strncpy( p_dir->help, desc, MAX_HELP_LEN ); 874 p_dir->sel = Dir; 875 876 Console_chooseAlias( p_root, p_dir ); 877 878 /* Add new directory to the root's list */ 879 p_dir->u.dir.upper = p_root; 880 p_e = &(p_root->u.dir.first); 881 while (*p_e) 882 p_e = &((*p_e)->next); 883 *p_e = p_dir; 884 885 return p_dir; 886} 887 888/*************************************************************** 889 890 Function : consoleAddToken 891 892 Description: Add token 893 894 Parameters: p_dir - directory handle (might be NULL=root) 895 name - token name 896 help - help string 897 p_func - token handler 898 p_parms- array of parameter descriptions. 899 Must be terminated with {0}. 900 Each parm descriptor is a struct 901 { "myname", - name 902 10, - low value 903 20, - high value 904 0 } - default value =-1 no default 905 or address for string parameter 906 907 Output: E_OK - OK 908 !=0 - error 909***************************************************************/ 910consoleErr Console_AddToken( THandle hConsole, 911 THandle hDir, 912 const PS8 name, 913 const PS8 help, 914 FuncToken_t p_func, 915 ConParm_t p_parms[] ) 916{ 917 Console_t* pConsole = (Console_t*)hConsole; 918 ConEntry_t *p_dir = (ConEntry_t *)hDir; 919 ConEntry_t *p_token; 920 ConEntry_t **p_e; 921 U16 i; 922 923 if (!pConsole->p_mon_root) 924 Console_allocRoot(pConsole); 925 926 if (!p_dir) 927 p_dir = pConsole->p_mon_root; 928 929 if(!( p_dir && (p_dir->sel == Dir))) 930 return E_ERROR; 931 932 933 /* Initialize token structure */ 934 if((p_token = (ConEntry_t *)os_MemoryCAlloc(1,sizeof(ConEntry_t))) == NULL) 935 { 936 os_error_printf(CU_MSG_ERROR, (PS8)("** no memory **\n") ); 937 return E_NOMEMORY; 938 } 939 940 941 /* Copy name */ 942 os_strncpy( p_token->name, name, MAX_NAME_LEN ); 943 os_strncpy( p_token->help, help, MAX_HELP_LEN ); 944 p_token->sel = Token; 945 p_token->u.token.f_tokenFunc = p_func; 946 p_token->u.token.totalParams = 0; 947 948 /* Convert name to lower case and choose alias */ 949 Console_chooseAlias( p_dir, p_token ); 950 951 /* Copy parameters */ 952 if ( p_parms ) 953 { 954 ConParm_t *p_tmpParms = p_parms; 955 956 /* find the number of params */ 957 while( p_tmpParms->name && p_tmpParms->name[0] ) 958 { 959 p_token->u.token.totalParams++; 960 p_tmpParms++; 961 } 962 /* allocate the parameters info */ 963 p_token->u.token.parm = (ConParm_t *)os_MemoryAlloc(p_token->u.token.totalParams * sizeof(ConParm_t)); 964 p_token->u.token.name = (PS8*)os_MemoryAlloc(p_token->u.token.totalParams * sizeof(PS8)); 965 if ((p_token->u.token.parm == NULL) || (p_token->u.token.name == NULL)) 966 { 967 os_error_printf(CU_MSG_ERROR, (PS8)("** no memory for params\n") ); 968 os_MemoryFree(p_token); 969 return E_NOMEMORY; 970 } 971 for (i=0; i < p_token->u.token.totalParams; i++) 972 { 973 ConParm_t *p_token_parm = &p_token->u.token.parm[i]; 974 975 /* String parameter must have an address */ 976 if(p_parms->flags & (CON_PARM_STRING | CON_PARM_LINE)) 977 { 978 if ( p_parms->hi_val >= INBUF_LENGTH ) 979 { 980 os_error_printf(CU_MSG_ERROR, (PS8)("** buffer too big: %s/%s\n"), p_dir->name, name); 981 os_MemoryFree(p_token->u.token.parm); 982 os_MemoryFree(p_token->u.token.name); 983 os_MemoryFree(p_token); 984 return E_NOMEMORY; 985 986 } 987 if (p_parms->hi_val == 0 || (p_parms->flags & CON_PARM_RANGE) ) 988 { 989 os_error_printf(CU_MSG_ERROR, (PS8)("** Bad string param definition: %s/%s\n"), p_dir->name, name ); 990 os_MemoryFree(p_token->u.token.parm); 991 os_MemoryFree(p_token->u.token.name); 992 os_MemoryFree(p_token); 993 return E_BADPARM; 994 } 995 p_parms->value = (U32)os_MemoryCAlloc(1,p_parms->hi_val+1); 996 if( !p_parms->value ) 997 { 998 os_error_printf(CU_MSG_ERROR, (PS8)("** No memory: %s/%s (max.size=%ld)\n"), p_dir->name, name, p_parms->hi_val ); 999 os_MemoryFree(p_token->u.token.parm); 1000 os_MemoryFree(p_token->u.token.name); 1001 os_MemoryFree(p_token); 1002 return E_NOMEMORY; 1003 } 1004 } 1005 1006 /* Copy parameter */ 1007 *p_token_parm = *p_parms; 1008 if( p_token_parm->hi_val || p_token_parm->low_val ) 1009 p_token_parm->flags |= CON_PARM_RANGE; 1010 1011 p_token->u.token.name[i] = os_MemoryAlloc(os_strlen(p_parms->name)); 1012 if (p_token->u.token.name[i] == NULL) 1013 { 1014 os_error_printf(CU_MSG_ERROR, (PS8)("** Error allocate param name\n")); 1015 os_MemoryFree(p_token->u.token.parm); 1016 os_MemoryFree(p_token->u.token.name); 1017 os_MemoryFree(p_token); 1018 return E_NOMEMORY; 1019 } 1020 p_token_parm->name = (PS8)p_token->u.token.name[i]; 1021 os_strncpy( p_token->u.token.name[i], p_parms->name, os_strlen(p_parms->name) ); 1022 ++p_parms; 1023 } /*end of for loop*/ 1024 } 1025 1026 /* Add token to the directory */ 1027 p_e = &(p_dir->u.dir.first); 1028 while (*p_e) 1029 p_e = &((*p_e)->next); 1030 *p_e = p_token; 1031 1032 return E_OK; 1033} 1034 1035