source: umon/main/common/chario.c @ 87db514

Last change on this file since 87db514 was 87db514, checked in by Amar Takhar <amar@…>, on 04/16/15 at 19:26:21

Initial commit of the umon repository.

Prior to this three changes were made:

  • Remove umon_ prefix from parent directories.
  • Collapse main/target/ into main/
  • Remove ports/template/flashtest.scr.ucon script.
  • Property mode set to 100644
File size: 11.6 KB
Line 
1/**************************************************************************
2 *
3 * Copyright (c) 2013 Alcatel-Lucent
4 *
5 * Alcatel Lucent licenses this file to You under the Apache License,
6 * Version 2.0 (the "License"); you may not use this file except in
7 * compliance with the License.  A copy of the License is contained the
8 * file LICENSE at the top level of this repository.
9 * You may also obtain a copy of the License at:
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 **************************************************************************
20 *
21 * chario.c:
22 * This code supports some basic character io functionality.
23 *
24 * Original author:     Ed Sutter (ed.sutter@alcatel-lucent.com)
25 *
26 */
27#include "config.h"
28#include "cpuio.h"
29#include "genlib.h"
30#include "stddefs.h"
31#include "timer.h"
32#include "ether.h"
33#include "fbi.h"
34
35#define CTLC    0x03    /* control-c */
36
37int rawmode, ConsoleBaudRate;
38
39/* extWatchDog():
40 * This function pointer is used by the application to override the
41 * monitor's configured watchdog functionality.  Refer to config.h
42 * in umon_ports/template for more information on the WATCHDOG macro.
43 */
44#ifdef WATCHDOG_ENABLED
45int (*remoteWatchDog)(void);
46#endif
47
48/* remotexxxx() function pointers:
49 * These function pointers provide the application with the ability to
50 * override the monitor's default putchar/getchar/gotachar functions.
51 * See comments above InitRemoteIO() function below for more info.
52 */
53int     (*remoterawon)(void);
54int (*remoterawoff)(void);
55int     (*remoteputchar)(int);
56int (*remotegetchar)(void);
57int (*remotegotachar)(void);
58
59static char console_echo_off;
60
61/* console_echo():
62 * Enable/disable the output of the console...
63 */
64void
65console_echo(int enable)
66{
67        if (enable)
68                console_echo_off = 0;
69        else
70                console_echo_off = 1;
71}
72
73/* putchar():
74 *      Output a character to the stdout RS232 port.
75 *  If console_echo_off is set, then we DON'T send the
76 *  character to the console.
77 */
78int
79putchar(char c)
80{
81        /* If the remoteputchar function pointer is non-zero, then we
82         * assume that the default putchar function has been overridden
83         * by some overlaying application using mon_com(CHARFUNC_PUTCHAR,),
84         * so we use that redefined function instead...
85         */
86        if (remoteputchar) {
87                remoteputchar(c);
88                return((int)c);
89        }
90
91        if (rawmode) {
92                if (!console_echo_off)
93                        target_putchar(c);
94                fbi_putchar(c);
95                return((int)c);
96        }
97
98        /* If redirection is active, the redirect the character to a file
99         * in TFS.  Note that if INCLUDE_REDIRECT is 0, then this function
100         * is NULL (see genlib.h).
101         */
102        RedirectCharacter(c);
103
104        /* Call the target-specific function that puts the character out on
105         * the console port (precede '\n' with '\r').
106         * For each call to target_putchar(), call SendIPMonChar so that if
107         * this output is generated by moncmd, it will be sent back to the
108         * moncmd client.  Note that if INCLUDE_ETHERNET is 0, then the
109         * function SendIPMonChar is NULL (see ether.h).
110         */
111        if (c == '\n') {
112                SendIPMonChar('\r',0);
113                fbi_putchar('\r');
114                if (!console_echo_off)
115                        target_putchar('\r');
116        }
117        SendIPMonChar(c,0);
118        if (!console_echo_off)
119                target_putchar(c);
120        fbi_putchar(c);
121        WATCHDOG_MACRO;
122        return((int)c);
123}
124
125int
126getchar(void)
127{
128        /* If the remotegetchar function pointer is non-zero, then we
129         * assume that the default getchar function has been overridden
130         * by some overlaying application using mon_com(CHARFUNC_GETCHAR,),
131         * so we use that redefined function instead...
132         */
133    if (remotegetchar)
134        return(remotegetchar());
135   
136        while(!gotachar()) {
137                /* While waiting for an incoming character, call pollethernet()
138                 * to process any incoming packets.  Note that if INCLUDE_ETHERNET
139                 * is 0 in config.h, then this function is NULL (see ether.h).
140                 */
141                WATCHDOG_MACRO;
142        pollethernet();
143        }
144
145        return(target_getchar());
146}
147
148int
149gotachar(void)
150{
151        /* If the remotegotachar function pointer is non-zero, then we
152         * assume that the default gotachar function has been overridden
153         * by some overlaying application using mon_com(CHARFUNC_GOTACHAR,),
154         * so we use that redefined function instead...
155         */
156    if (remotegotachar)
157        return(remotegotachar());
158   
159        fbi_cursor();
160        WATCHDOG_MACRO;
161        return(target_gotachar());
162}
163
164/* flush_console_out():
165 * Call this function to wait for the console UART to flush all outgoing
166 * characters.  Note that this function has a timeout in the loop.
167 */
168void
169flush_console_out(void)
170{
171        int timeout = 0;
172
173    if (remoteputchar)
174        return;
175
176        while(timeout++ < 50000) {
177                if (target_console_empty()) {
178                        monDelay(10);
179                        break;
180                }
181        }
182}
183
184/* flush_console_in(void):
185 * While there is input queued up from the console,
186 * flush it to the bit bucket...
187 */
188void
189flush_console_in(void)
190{
191        while(gotachar())
192                getchar();
193}
194
195
196/* rawon() & rawoff():
197 * Used primarily by xmodem.  When xmodem runs, it must be assured that
198 * the interface is in RAW mode.  For the case of the monitor alone, it
199 * will always be in a raw mode.  These functions are primarily for use
200 * when an application has re-loaded the serial driver and may have put
201 * it in a non-raw mode.  The mon_com() calls CHARFUNC_RAWMODEON and
202 * CHARFUNC_RAWMODEOFF establish these pointers.
203 */
204void
205rawon(void)
206{
207    if (remoterawon)
208        remoterawon();
209        rawmode = 1;
210}
211
212void
213rawoff(void)
214{
215    if (remoterawoff)
216        remoterawoff();
217        rawmode = 0;
218}
219
220/* puts() & putstr():
221 * Two string-output functions. 
222 * puts: normal "puts" as is available in standard c libs.
223 * putstr: same as "puts", but no ending newline.
224 */
225
226void
227putstr(char *string)
228{
229        while(*string) {
230                putchar(*string);
231                string++;
232        }
233}
234
235void
236puts(char *string)
237{
238        putstr(string);
239        putchar('\n');
240}
241
242
243/* getfullline():
244 * Basic line retrieval; but with a few options...
245 * This function is accessed through the getline_xx functions
246 * below.
247 * Args...
248 *      buf:     pointer to buffer to be used to place the incoming characters.
249 *  max:         size of the buffer.
250 *  ledit:       if set, then allow the line-editor to be used if ESC is input.
251 *  timeout: if positive, then after 'timeout' number of seconds waiting
252 *                per character, giveup.
253 *           if negative, then after 'timeout' number of seconds waiting
254 *                total, giveup.
255 *           if zero, then wait forever.
256 *  prefill: if set, prefill the buffer with that string and show the user.
257 *  echo:    if set, characters are echoed as they are entered.
258 */
259int
260getfullline(char *buf,int max,int ledit, int timeout,char *prefill, int echo)
261{
262        char    *base;
263        struct  elapsed_tmr tmr;
264        static  unsigned char  crlf;
265        int             tot, idx, cumulativetimeout;
266
267        cumulativetimeout = 0;
268        tot = idx = 0;
269        base = buf;
270        max -= 1;               /* Make sure there is space for the null terminator. */
271
272        if (prefill) {
273                strcpy(base,prefill);
274                tot = strlen(prefill);
275                putstr(prefill);
276                buf += tot;
277                idx = tot;
278        }
279
280        /* If the timeout parameter is negative, then assume that this is
281         * to be run with a cumulative timeout rather than a timeout that
282         * is re-started after each character...
283         */
284        if (timeout < 0) {
285                cumulativetimeout = 1;
286                timeout = abs(timeout);
287        }
288
289        for(;idx<max;idx++) {
290                if (timeout > 0) {
291                        startElapsedTimer(&tmr,timeout);
292                        while(!msecElapsed(&tmr)) {
293                                if (gotachar())
294                                        break;
295                                pollethernet();
296                        }
297                        if (cumulativetimeout)
298                                timeout = msecRemaining(&tmr);
299
300                        if (ELAPSED_TIMEOUT(&tmr)) {
301                                *buf = 0;
302                                return(-1);     /* Return negative to indicate timeout */
303                        }
304                }
305                if (cumulativetimeout && timeout == 0) {
306                        *buf = 0;
307                        return(-1);
308                }
309
310                *buf = (char)getchar();
311
312                if (getenv("CLI_HEXOUT"))
313                        printf("<%02x>",*buf);
314               
315                if (!*buf) {
316                        idx--;
317                        continue;
318                }
319#if INCLUDE_LINEEDIT
320                if ((*buf == 0x1b) && (ledit)) {
321                        (void)line_edit(base);
322                        break;
323                }
324                else
325#endif
326                {
327                        if ((*buf == '\r') || (*buf == '\n')) {
328                                if ((crlf) && (*buf != crlf)) {
329                                        crlf = 0;
330                                        continue;
331                                }
332                                puts("\r");
333                                crlf = *buf;
334                                *buf = 0;
335                                break;
336                        }
337                        if (*buf == '\b' || *buf == 0x7f) {
338                                if (tot) {
339                                        idx -= 2;
340                                        buf--;
341                                        tot--;
342                                        if (echo)
343                                                putstr("\b \b");
344                                }
345                        }
346                        else if (*buf == CTLC) {
347                                puts("^C");
348                                *base = 0;
349                                return(0);
350                        }
351                        else {
352                                if (echo)
353                                        putchar(*buf);
354                                tot++;
355                                buf++;
356                        }
357                        crlf = 0;
358                }
359        }
360        if (idx == max) {
361                printf((char *)"\007\nInput too long (exceeds %d bytes).\n",max);
362                *buf = 0;
363                return(0);
364        }
365#if INCLUDE_LINEEDIT
366        if (ledit)
367                historylog(base);
368#endif
369        return(strlen(base));
370}
371
372int
373getline(char *buf, int max, int ledit)
374{
375        return(getfullline(buf,max,ledit,0,0,1));
376}
377
378int
379getline_t(char *buf, int max, int timeout)
380{
381        return(getfullline(buf,max,0,timeout,0,1));
382}
383
384int
385getline_p(char *buf, int max, int ledit, char *prefill)
386{
387        return(getfullline(buf,max,ledit,0,prefill,1));
388}
389
390/* getpass():
391 */
392#if INCLUDE_USRLVL
393char *
394getpass(char *prompt,char *buf,int max, int timeout)
395{
396        putstr(prompt);
397        if (getfullline(buf,max,0,timeout*1000,0,0) == -1)
398                putchar('\n');
399        return(buf);
400}
401#endif
402
403/* getbytes():
404 *      Similar to gets() except that the caller specifies the number
405 *      of characters and whether or not to block.
406 *  If the copy to the buffer fails, abort and return the current
407 *  count.
408 */
409
410int
411getbytes(char *buf,int cnt,int block)
412{
413        int     i;
414        volatile char *bp;
415        char c;
416
417        bp = (volatile char *)buf;
418
419        for(i=0;i<cnt;i++) {
420                if (!block && !gotachar())
421                        break;
422                c = (char)getchar();
423                *bp = c;
424                if (*bp != c)
425                        break;
426                bp++;
427        }
428        return(i);
429}
430
431/* getbytes_t():
432 *      Similar to getbytes() except that the caller specifies the allowed
433 *  timeout between two consecutive bytes received.
434 *  If the copy to the buffer fails, or timeout occures, abort and return
435 *      the current count.
436 */
437
438int
439getbytes_t(char *buf,int cnt,int timeout)
440{
441        int     i;
442        struct elapsed_tmr tmr;
443        volatile char *bp;
444        char c;
445
446        bp = (volatile char *)buf;
447
448        for(i=0;i<cnt;i++) {
449                if (!gotachar()) {
450                        startElapsedTimer(&tmr,timeout);
451                        while(!gotachar() && !msecElapsed(&tmr));
452                        if (!gotachar())
453                                break;
454                }
455                c = (char)getchar();
456                *bp = c;
457                if (*bp != c)
458                        break;
459                bp++;
460        }
461        return(i);
462}
463
464int
465putbytes(char *buf, int cnt)
466{
467        char *end;
468
469        end = buf + cnt;
470
471        while(buf < end) {
472                putchar(*buf++);
473        }
474        return(cnt);
475}
476
477int
478askuser(char *msg)
479{
480        int     yes, len;
481
482#if INCLUDE_MONCMD
483        /* If command was issued from UDP (i.e. moncmd), then
484         * immediately return 1...
485         */
486        if (IPMonCmdActive)
487                return(1);
488#endif
489
490        putstr(msg);
491        len = strlen(msg);
492        switch((char)getchar()) {
493                case ' ':
494                case 'y':
495                case '\r':
496                case '\n':
497                        yes = 1;
498                        break;
499                default:
500                        yes = 0;
501                        break;
502        }
503        while(len) {
504                putstr("\b \b");
505                len--;
506        }
507        return(yes);
508}
509
510int
511More(void)
512{
513        return(askuser((char *)"more?"));
514}
515
516int
517hitakey(void)
518{
519        return(askuser((char *)"hit any key to continue..."));
520}
521
522/* RemoteIO functions:
523 * The idea of "remote io" is to allow the monitor commands to still
524 * run when the application has taken over the system.  The monitor's
525 * connection to the serial port is a simple polled interface.  When
526 * the application comes up, it is very likely that it will overlay a
527 * new driver onto the serial port.  If this happens, and the user at
528 * the console interface of the application wants to execute a monitor
529 * command, then the monitor's putchar/getchar/gotachar functions must
530 * use functions that are part of the application.  These remote io
531 * function pointers, if set, will point to those functions.
532 */
533
534void
535InitRemoteIO(void)
536{
537        /* Null out the remote put/getchar functions. */
538        remoterawon = 0;
539        remoterawoff = 0;
540        remoteputchar = 0;
541        remotegetchar = 0;
542        remotegotachar = 0;
543}
Note: See TracBrowser for help on using the repository browser.