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