• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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