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 */
Console_ltrim(PS8 s)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 */
Console_analizeToken(PS8 name)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 */
Console_stricmp(PS8 s1,PS8 s2,U16 len)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 */
Console_strlwr(PS8 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 */
Console_FreeEntry(ConEntry_t * pEntry)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 */
Console_allocRoot(Console_t * pConsole)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 */
Console_displayDir(Console_t * pConsole)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 */
Console_getWord(Console_t * pConsole,PS8 name,U16 len)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
Console_getStrParam(Console_t * pConsole,PS8 buf,ConParm_t * param)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 */
Console_getNParms(ConEntry_t * p_token)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 */
Console_parseParms(Console_t * pConsole,ConEntry_t * p_token,U16 * pnParms)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 */
Console_searchToken(ConEntry_t * p_dir,PS8 name)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 */
Console_dirHelp(Console_t * pConsole)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 */
Console_displayHelp(Console_t * pConsole,ConEntry_t * p_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 */
Console_chooseAlias(ConEntry_t * p_dir,ConEntry_t * p_new_token)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 */
Console_ParseString(Console_t * pConsole,PS8 input_string)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
Console_Create(const PS8 device_name,S32 BypassSupplicant,PS8 pSupplIfFile)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
Console_Destroy(THandle hConsole)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
Console_Stop(THandle hConsole)793 VOID Console_Stop(THandle hConsole)
794 {
795 ((Console_t*)hConsole)->stop_UI_Monitor = TRUE;
796 }
797
798 /* Monitor driver */
Console_Start(THandle hConsole)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
Console_GetDeviceStatus(THandle hConsole)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 ***************************************************************/
Console_AddDirExt(THandle hConsole,THandle hRoot,const PS8 name,const PS8 desc)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 ***************************************************************/
Console_AddToken(THandle hConsole,THandle hDir,const PS8 name,const PS8 help,FuncToken_t p_func,ConParm_t p_parms[])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
consoleRunScript(char * script_file,THandle hConsole)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