Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:19

0001 /*
0002  * Copyright (c) 2011 embedded brains GmbH & Co. KG
0003  *
0004  * The license and distribution terms for this file may be
0005  * found in the file LICENSE in this distribution or at
0006  * http://www.rtems.org/license/LICENSE.
0007  */
0008 
0009 #ifdef HAVE_CONFIG_H
0010 #include "config.h"
0011 #endif
0012 
0013 #include <rtems/shell.h>
0014 
0015 #include <termios.h>
0016 #include <unistd.h>
0017 
0018 static rtems_status_code change_serial_settings(int fd, struct termios *term)
0019 {
0020   rtems_status_code sc = RTEMS_UNSATISFIED;
0021   int rv = tcgetattr(fd, term);
0022 
0023   if (rv == 0) {
0024     struct termios new_term = *term;
0025 
0026     new_term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
0027     new_term.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
0028     new_term.c_cflag &= ~(CSIZE | PARENB);
0029     new_term.c_cflag |= CS8;
0030 
0031     new_term.c_cc [VMIN] = 0;
0032     new_term.c_cc [VTIME] = 10;
0033 
0034     rv = tcsetattr(fd, TCSANOW, &new_term);
0035     if (rv == 0) {
0036       sc = RTEMS_SUCCESSFUL;
0037     }
0038   }
0039 
0040   return sc;
0041 }
0042 
0043 static rtems_status_code restore_serial_settings(int fd, struct termios *term)
0044 {
0045   int rv = tcsetattr(fd, TCSANOW, term);
0046 
0047   return rv == 0 ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
0048 }
0049 
0050 rtems_status_code rtems_shell_wait_for_explicit_input(
0051   int fd,
0052   int timeout_in_seconds,
0053   rtems_shell_wait_for_input_notification notification,
0054   void *notification_arg,
0055   int desired_input
0056 )
0057 {
0058   struct termios term;
0059   rtems_status_code sc = change_serial_settings(fd, &term);
0060 
0061   if (sc == RTEMS_SUCCESSFUL) {
0062     bool input_detected = false;
0063     int i = 0;
0064 
0065     for (i = 0; i < timeout_in_seconds && !input_detected; ++i) {
0066       unsigned char c;
0067 
0068       (*notification)(fd, timeout_in_seconds - i, notification_arg);
0069 
0070       input_detected = read(fd, &c, sizeof(c)) > 0
0071         && (desired_input == -1 || desired_input == c);
0072     }
0073 
0074     sc = restore_serial_settings(fd, &term);
0075     if (sc == RTEMS_SUCCESSFUL) {
0076       sc = input_detected ? RTEMS_SUCCESSFUL : RTEMS_TIMEOUT;
0077     }
0078   }
0079 
0080   return sc;
0081 }
0082 
0083 rtems_status_code rtems_shell_wait_for_input(
0084   int fd,
0085   int timeout_in_seconds,
0086   rtems_shell_wait_for_input_notification notification,
0087   void *notification_arg
0088 )
0089 {
0090   return rtems_shell_wait_for_explicit_input(
0091     fd,
0092     timeout_in_seconds,
0093     notification,
0094     notification_arg,
0095     -1
0096   );
0097 }