Esempio n. 1
0
static int
set_tty_settings (int tty, TIOTYPE *tiop)
{
  while (SETATTR (tty, tiop) < 0)
    {
      if (errno != EINTR)
	return -1;
      errno = 0;
    }

#if 0

#if defined (TERMIOS_TTY_DRIVER)
#  if defined (__ksr1__)
  if (ksrflow)
    {
      ksrflow = 0;
      tcflow (tty, TCOON);
    }
#  else /* !ksr1 */
  tcflow (tty, TCOON);		/* Simulate a ^Q. */
#  endif /* !ksr1 */
#else
  ioctl (tty, TCXONC, 1);	/* Simulate a ^Q. */
#endif /* !TERMIOS_TTY_DRIVER */

#endif

  return 0;
}
Esempio n. 2
0
int
rl_restart_output (int count, int key)
{
  int fildes = fileno (rl_outstream);
#if defined (TIOCSTART)
#if defined (apollo)
  ioctl (&fildes, TIOCSTART, 0);
#else
  ioctl (fildes, TIOCSTART, 0);
#endif /* apollo */

#else /* !TIOCSTART */
#  if defined (TERMIOS_TTY_DRIVER)
#    if defined (__ksr1__)
  if (ksrflow)
    {
      ksrflow = 0;
      tcflow (fildes, TCOON);
    }
#    else /* !ksr1 */
  tcflow (fildes, TCOON);		/* Simulate a ^Q. */
#    endif /* !ksr1 */
#  else /* !TERMIOS_TTY_DRIVER */
#    if defined (TCXONC)
  ioctl (fildes, TCXONC, TCOON);
#    endif /* TCXONC */
#  endif /* !TERMIOS_TTY_DRIVER */
#endif /* !TIOCSTART */

  return 0;
}
Esempio n. 3
0
File: bti.c Progetto: pferor/bti
static void read_password(char *buf, size_t len, char *host)
{
	char pwd[80];
	struct termios old;
	struct termios tp;

	tcgetattr(0, &tp);
	old = tp;

	tp.c_lflag &= (~ECHO);
	tcsetattr(0, TCSANOW, &tp);

	fprintf(stdout, "Enter password for %s: ", host);
	fflush(stdout);
	tcflow(0, TCOOFF);

	/*
	 * I'd like to do something with the return value here, but really,
	 * what can be done?
	 */
	(void)scanf("%79s", pwd);

	tcflow(0, TCOON);
	fprintf(stdout, "\n");

	tcsetattr(0, TCSANOW, &old);

	strncpy(buf, pwd, len);
	buf[len-1] = '\0';
}
Esempio n. 4
0
static void read_password(char *buf, size_t len, char *host)
{
	char pwd[80];
	int retval;
	struct termios old;
	struct termios tp;

	tcgetattr(0, &tp);
	old = tp;

	tp.c_lflag &= (~ECHO);
	tcsetattr(0, TCSANOW, &tp);

	fprintf(stdout, "Enter password for %s: ", host);
	fflush(stdout);
	tcflow(0, TCOOFF);
	retval = scanf("%79s", pwd);
	tcflow(0, TCOON);
	fprintf(stdout, "\n");

	tcsetattr(0, TCSANOW, &old);

	strncpy(buf, pwd, len);
	buf[len-1] = '\0';
}
Esempio n. 5
0
unit
posix_tty_tcflow(cerr er, int fd, int action)
{
	if(tcflow(fd, action) == -1)
		send_errno(er,errno);
	return empty_record;
}
Esempio n. 6
0
int
rl_stop_output (int count, int key)
{
  int fildes = fileno (rl_instream);

#if defined (TIOCSTOP)
# if defined (apollo)
  ioctl (&fildes, TIOCSTOP, 0);
# else
  ioctl (fildes, TIOCSTOP, 0);
# endif /* apollo */
#else /* !TIOCSTOP */
# if defined (TERMIOS_TTY_DRIVER)
#  if defined (__ksr1__)
  ksrflow = 1;
#  endif /* ksr1 */
  tcflow (fildes, TCOOFF);
# else
#   if defined (TCXONC)
  ioctl (fildes, TCXONC, TCOON);
#   endif /* TCXONC */
# endif /* !TERMIOS_TTY_DRIVER */
#endif /* !TIOCSTOP */

  return 0;
}
Esempio n. 7
0
/* The function calling [tcflow]. */
static void worker_tcflow(struct job_tcflow* job)
{
  /* Perform the blocking call. */
  job->result = tcflow(job->fd, job->action);
  /* Save the value of errno. */
  job->errno_copy = errno;
}
Esempio n. 8
0
/*
 * does not change IXON but simulates that IXON has been received:
 */
static NTSTATUS set_XOn(int fd)
{
    if (tcflow(fd, TCOON))
    {
        return FILE_GetNtStatus();
    }
    return STATUS_SUCCESS;
}
Esempio n. 9
0
/***
Suspend transmission or receipt of data.
@function tcflow
@int fd terminal descriptor to act on
@int action one of `TCOOFF`, `TCOON`, `TCIOFF` or `TCION`
@treturn[1] int `0`, if successful
@return[2] nil
@treturn[2] string error message
@treturn[2] int errnum
@see tcflow(3)
*/
static int
Ptcflow(lua_State *L)
{
	int fd = checkint(L, 1);
	int action = checkint(L, 2);
	checknargs(L, 2);
	return pushresult(L, tcflow(fd, action), NULL);
}
Esempio n. 10
0
int main(void)
{
   int  n1, n2, fd;
   if((fd=open("/dev/ttyS0", O_RDWR|O_NOCTTY|O_NONBLOCK))== -1){
      fprintf(stderr, "Open port: Unable to open, %s\n",strerror(errno));
      exit(EXIT_FAILURE);
   }
   write(fd, "Example of line control functions ", 34);
   tcdrain(fd);             /* 等待輸出佇列中的資料全部送出 */
   tcflow(fd, TCOOFF);      /* 懸掛輸出傳輸 */
   n1 = write(fd, "this line will be thrown over\n", 30);
   tcflush(fd, TCOFLUSH);   /* 清除輸出佇列 */ 
   n2 = write(fd, "this line will not be thrown over\n", 34);
   tcflow(fd, TCOON);       /* 還原輸出傳輸 */
   write(fd,"restart the output\n",19);
   exit(EXIT_SUCCESS);
}
Esempio n. 11
0
File: port.c Progetto: mundis/slap
BOOL closetty(INT fd, const struct termios *restore)
	{
	sigset_t mask, oldmask;

	/* must first block SIGINT to avoid possible interrruption between
	 * restoral of termios modes and the final close()...
	 * NOTE: must ensure that we can restore the current signal mask
	 * when finished.
	 */
	sigemptyset(&mask);
	sigemptyset(&oldmask);
	sigaddset(&mask, SIGINT);
	sigprocmask(SIG_BLOCK, &mask, &oldmask);

	/* restore termios modes:
	 */
	tcflow(fd, TCOON);	/* better would be to turn off flow-control! */
	if (tcsetattr(fd, TCSADRAIN, (struct termios *) restore) < 0)
		{
		sigprocmask(SIG_SETMASK, &oldmask, NULL);
		return (NO);
		}

	/* close the port:
	 * NOTE: some UNIX serial UARTs or device-drivers will hard-hang in
	 * close() if the ports transmitter is disabled by flow-control,
	 * EVEN IF THERE ARE NO OUTPUT BYTES QUEUED FOR TRANSMISSION!!!
	 * Thus we must turn off flow-control before calling close()...
	 */
	tcflow(fd, TCOON);
	if (close(fd) < 0)
		{
		sigprocmask(SIG_SETMASK, &oldmask, NULL);
		return (NO);
		}

	/* now is safe to unblock SIGINT:
         */
        sigprocmask(SIG_SETMASK, &oldmask, NULL);

	return (YES);
	}
Esempio n. 12
0
static BOOL _set_xon(WINPR_COMM *pComm)
{
	if (tcflow(pComm->fd, TCION) < 0)
	{
		CommLog_Print(WLOG_WARN, "TCION failure, errno=[%d] %s", errno, strerror(errno));
		SetLastError(ERROR_IO_DEVICE);
		return FALSE;
	}

	return TRUE;
}
Esempio n. 13
0
/******************************************************
*                  re_open_device                     *
*******************************************************/
void re_open_device ()
{
    int j = 0;

    {
        tcflow(serial_filedesc,TCOON);
        close_device();
        usleep(400000);
        open_configure();
    }
}
static PyObject *
termios_tcflow(PyObject *self, PyObject *args)
{
    int fd, action;

    if (!PyArg_ParseTuple(args, "O&i:tcflow",
                          fdconv, &fd, &action))
        return NULL;
    if (tcflow(fd, action) == -1)
        return PyErr_SetFromErrno(TermiosError);

    Py_INCREF(Py_None);
    return Py_None;
}
Esempio n. 15
0
Val   _lib7_P_TTY_tcflow   (Task* task,  Val arg)   {
    //==================
    //
    // Mythrryl type:   (Int, Int) -> Void
    //
    // Suspend transmission or receipt of data.
    //
    // This fn gets bound as   tcflow   in:
    //
    //     src/lib/std/src/posix-1003.1b/posix-tty.pkg

    int status =  tcflow( GET_TUPLE_SLOT_AS_INT(arg, 0),GET_TUPLE_SLOT_AS_INT(arg, 1) );

    CHECK_RETURN_UNIT(task, status)
}
/* this is a fall back, only taking care that input can be 
   read  when getting back into the forground, again */
static char *
retrieve_tty_getpass
  (const char *prompt)
{
  int fd ;
  if ((fd = open ("/dev/tty", O_RDONLY)) < 0) {
    fprintf (stderr, "Cannot open tty (%s)" BLURB, strerror (errno)) ;
    exit (0);
  }
  /* this causes getpass() to retrieve the input properly once 
     it has been brought back in the foreground, again */
  if (tcflow (fd, TCION) < 0) {
    fprintf (stderr, "Cannot access tty (%s)" BLURB, strerror (errno)) ;
    exit (0);
  }
  close (fd);
  return getpass (prompt);
}
Esempio n. 17
0
mraa_result_t
mraa_uart_set_flowcontrol(mraa_uart_context dev, mraa_boolean_t xonxoff, mraa_boolean_t rtscts)
{
    if (!dev) {
        syslog(LOG_ERR, "uart: set_flowcontrol: context is NULL");
        return MRAA_ERROR_INVALID_HANDLE;
    }

    if (IS_FUNC_DEFINED(dev, uart_set_flowcontrol_replace)) {
        return dev->advance_func->uart_set_flowcontrol_replace(dev, xonxoff, rtscts);
    }

    // hardware flow control
    int action = TCIOFF;
    if (xonxoff) {
        action = TCION;
    }
    if (tcflow(dev->fd, action)) {
        return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
    }

    // rtscts
    struct termios termio;

    // get current modes
    if (tcgetattr(dev->fd, &termio)) {
        syslog(LOG_ERR, "uart%i: set_flowcontrol: tcgetattr() failed: %s", dev->index, strerror(errno));
         return MRAA_ERROR_INVALID_RESOURCE;
    }

    if (rtscts) {
        termio.c_cflag |= CRTSCTS;
    } else {
        termio.c_cflag &= ~CRTSCTS;
    }

    if (tcsetattr(dev->fd, TCSAFLUSH, &termio) < 0) {
        syslog(LOG_ERR, "uart%i: set_flowcontrol: tcsetattr() failed: %s", dev->index, strerror(errno));
        return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
    }

    return MRAA_SUCCESS;
}
Esempio n. 18
0
RadioLinux::RadioLinux(const std::string &devfile, int baudrate, Parity p) {
	mBaudRate = baudrate;
	mParity = p;

	mFD = open(devfile.c_str(), O_RDWR | O_ASYNC);
	if (mFD == -1)
		THROW_EXCEPT(RadioException, "Could not open " + devfile);

	struct termios tprops;
	tcgetattr(mFD, &tprops);

	tprops.c_iflag = 0;
	if (mParity != PARITY_NONE)
		tprops.c_iflag |= INPCK;

	tprops.c_oflag = 0;

	tprops.c_cflag = CS8 | CREAD;
	if (mParity != PARITY_NONE) {
		tprops.c_cflag |= PARENB;
		if (mParity == PARITY_ODD)
			tprops.c_cflag |= PARODD;
	}

	tprops.c_lflag = 0;

	// Disable control characaters
	for (int cc = 0; cc < NCCS; ++cc)
		tprops.c_cc[cc] = _POSIX_VDISABLE;

	tprops.c_cc[VMIN]  = 0; // No minimum number of characters for reads
	tprops.c_cc[VTIME] = 0; // No timeout (0 deciseconds)

	speed_t baudspeed = baudToSpeed(mBaudRate);
	cfsetospeed(&tprops, baudspeed);
	cfsetispeed(&tprops, baudspeed);

	tcsetattr(mFD, TCSAFLUSH, &tprops);

	tcflow(mFD, TCOON | TCION);
	tcflush(mFD, TCIOFLUSH);
}
Esempio n. 19
0
bool mdtSerialPortPosix::resumeTransmission()
{
  int err;

  if(flowCtlRtsCtsOn()){
    if(!setRtsOn()){
      return false;
    }
  }
  if(flowCtlXonXoffOn()){
    if(tcflow(pvFd, TCION) < 0){
      err = errno;
      mdtError e(MDT_PORT_IO_ERROR, "tcflow() call failed", mdtError::Error);
      e.setSystemError(err, strerror(err));
      MDT_ERROR_SET_SRC(e, "mdtSerialPortPosix");
      e.commit();
      return false;
    }
  }

  return true;
}
Esempio n. 20
0
File: uart.c Progetto: babuenir/mraa
mraa_result_t
mraa_uart_set_flowcontrol(mraa_uart_context dev, mraa_boolean_t xonxoff, mraa_boolean_t rtscts)
{
    if (!dev) {
        syslog(LOG_ERR, "uart: stop: context is NULL");
        return MRAA_ERROR_INVALID_HANDLE;
    }

    // hardware flow control
    int action = TCIOFF;
    if (xonxoff) {
        action = TCION;
    }
    if (tcflow(dev->fd, action)) {
        return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
    }

    // rtscts
    struct termios termio;

    // get current modes
    if (tcgetattr(dev->fd, &termio)) {
        syslog(LOG_ERR, "uart: tcgetattr() failed");
        return MRAA_ERROR_INVALID_HANDLE;
    }

    if (rtscts) {
        termio.c_cflag |= CRTSCTS;
    } else {
        termio.c_cflag &= ~CRTSCTS;
    }

    if (tcsetattr(dev->fd, TCSAFLUSH, &termio) < 0) {
        syslog(LOG_ERR, "uart: tcsetattr() failed");
        return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
    }

    return MRAA_SUCCESS;
}
Esempio n. 21
0
int uart_init(int baudrate, UARTParity parity) {
	// Establish endianness of the running system
	uint32_t test;
	char *set = (char *)&test;
	set[0] = 0x11;
	set[1] = 0x22;
	set[2] = 0x33;
	set[3] = 0x44;

	if (test == 0x11223344)
		hostendian = 1;  // Big-endian
	else if (test == 0x44332211)
		hostendian = 0;  // Little-endian
	else
		hostendian = -1; // Unsupported

	// Convert to speed_t / validate provided baudrate
	speed_t baud;
	switch (baudrate) {
		case 1200:
			baud = B1200;
			break;
		case 1800:
			baud = B1800;
			break;
		case 2400:
			baud = B2400;
			break;
		case 4800:
			baud = B4800;
			break;
		case 9600:
			baud = B9600;
			break;
		case 19200:
			baud = B19200;
			break;
		case 38400:
			baud = B38400;
			break;
		case 57600:
			baud = B57600;
			break;
		case 115200:
			baud = B115200;
			break;
		case 230400:
			baud = B230400;
			break;

		default:
			generateError("Unsupported baud rate requested");
			return 0;
	}

	uartfd = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NONBLOCK);
	if (uartfd == -1) {
		generateError("Could not open /dev/ttyAMA0");
		return 0;
	}

	struct sigaction sa;
	sa.sa_handler = sigHandlerIO;
	sa.sa_flags = 0;
	sa.sa_restorer = NULL;
	sigaction(SIGIO, &sa, NULL);

	fcntl(uartfd, F_SETOWN, getpid());
	fcntl(uartfd, F_SETFL, O_ASYNC);

	// Set terminal properties for /dev/ttyAMA0
	struct termios tprops;

	tprops.c_iflag = 0;
	if (parity != UART_PARDISABLE)
		tprops.c_iflag = INPCK;

	tprops.c_oflag = 0;

	tprops.c_cflag = CS8 | CREAD;
	if (parity != UART_PARDISABLE) {
		tprops.c_cflag |= PARENB;
		if (parity == UART_PARODD)
			tprops.c_cflag |= PARODD;
	}

	tprops.c_lflag = 0;

	// Disable control characters
	int cc;
	for (cc = 0; cc < NCCS; ++cc)
		tprops.c_cc[cc] = _POSIX_VDISABLE;

	tprops.c_cc[VMIN] = 0;  // No minimum number of characters for reads
	tprops.c_cc[VTIME] = 0; // No timeout (0 deciseconds)

	// Baud rate
	cfsetospeed(&tprops, baud);
	cfsetispeed(&tprops, baud);

	// Set the attributes
	tcsetattr(uartfd, TCSAFLUSH, &tprops);

	tcflow(uartfd, TCOON | TCION); // Restart input and output
	tcflush(uartfd, TCIOFLUSH);    // Flush buffer for clean start

	qb_initialize(&queuebuffer);

	return 1;
}
Esempio n. 22
0
// Serial 1 port setup
void setupSerial1( int baud ) {
/* */
	mraa_uart_context uart1 = mraa_uart_init( 0 );
	char *devPort = mraa_uart_get_dev_path( uart1 ); // "/dev/ttyMFD1"; // mraa_uart_get_dev_path( uart1 );

	printf( "  setupSerial1 at start with dev path: %s\n", devPort );	// sets up uart1, connected to Arduino BB pins 0 & 1

	serialFDOut = -1;                                  // Say that it is not open...
	serialFDIn = -1;
	fPtrOut = NULL;
	fPtrIn = NULL;

	// Try to open File Descriptor
//	char devPort[] = "/dev/ttyMFD1";
	printf( "  Serial port prepare to open %s\n", devPort );

//	int serialFDOut = open( devPort, O_RDWR| O_NONBLOCK | O_NDELAY );
	int serialFDOut = open( devPort, O_RDWR| O_NONBLOCK | O_NOCTTY | O_SYNC );

	// Error check
	if ( serialFDOut < 0 ) {
		printf( "  Error opening %s: %d, %s\n", devPort, errno, strerror( errno ) );
		return;
	}
	printf( "  Serial port %s opened successfully\n", devPort );

    if ( ( fPtrOut = fdopen( serialFDOut, "r+" ) ) == NULL ) {
		printf( "  Error opening file associated with %s: %d, %s\n", devPort, errno, strerror( errno ) );
		close( serialFDOut );
        return;
    }
	printf( "  Serial port access file %s opened successfully\n", devPort );

    // For normal files _pfileIn will simply be _pfileOut likewise for file descriptors
    fPtrIn = fPtrOut;
    serialFDIn = serialFDOut;

    setvbuf( fPtrOut, NULL, _IONBF, BUFSIZ );
    fflush( fPtrOut );

	// Start port config
	struct termios tty;
	memset(&tty, 0, sizeof tty );

	// Error Handling
	if ( tcgetattr ( serialFDOut, &tty ) != 0 ) {
		printf( "  Error from tcgetattr: %d, %s\n", errno, strerror (errno) );
		fclose( fPtrOut );
		close( serialFDOut );
		return;
	}

	speed_t inSpeed  = cfgetispeed( &tty );
	speed_t outSpeed = cfgetispeed( &tty );
	printf( "  Existing port speed, in: %d, out: %d\n", inSpeed, outSpeed );

	// Setting other Port Stuff
	tty.c_cflag     &=  ~PARENB;        // Make 8n1
	tty.c_cflag     &=  ~CSTOPB;
	tty.c_cflag     &=  ~CSIZE;
	tty.c_cflag     &=  ~CRTSCTS;       // no flow control
	tty.c_cflag     |=  CS8 | HUPCL;	// 8 bits, enable lower control lines on close - hang up
	tty.c_cflag     |=  CREAD | CLOCAL; // turn on READ & ignore ctrl lines

	tty.c_lflag     =   0;          	// no signaling chars, no echo, no canonical processing
//	tty.c_lflag     &=  ~(ICANON | ECHO | ECHOE | ISIG);	// make raw

	tty.c_oflag     =   0;              // no remapping, no delays
//	tty.c_oflag     &=  ~OPOST;         // make raw
	tty.c_iflag     =   0;	// turn off s/w flow ctrl
//	tty.c_iflag     &=  ~(IXON | IXOFF | IXANY);	// turn off s/w flow ctrl

	tty.c_cc[VMIN]      =   0;          // read doesn't block
	tty.c_cc[VTIME]     =   5;          // 0.5 seconds read timeout

	// Set Baud Rate
	if ( 0 != baud ) {
		if ( cfsetspeed (&tty, baud ) != 0) {
			printf( "  Error from cfsetspeed: %d, %s\n", errno, strerror (errno) );
			return;
		}
	}

	// Flush Port, then applies attributes
	if ( tcflush( serialFDOut, TCIFLUSH ) != 0) {
		printf( "  Error from tcflush: %d, %s\n", errno, strerror (errno) );
		return;
	}

	if ( tcsetattr ( serialFDOut, TCSAFLUSH, &tty ) != 0) {
		printf( "  Error from tcsetattr: %d, %s\n", errno, strerror (errno) );
		return;
	}

    // enable input & output transmission
    if ( tcflow(serialFDOut, TCOON | TCION) != 0) {
		printf( "  Error from tcflow: %d, %s\n", errno, strerror (errno) );
		return;
	}

    // purge buffer
    {
        char buf[1024];
        int n;
        do {
            usleep( 5000 );                         // 5ms
            n = read( serialFDOut, buf, sizeof( buf ) );
        } while ( n > 0 );
    }
    fcntl( serialFDOut, F_SETFL, 0 );               // disable blocking
/**/
}
Esempio n. 23
0
rtems_task Init(
  rtems_task_argument ignored
)
{
  int sc;
  pid_t pid;
  char *term_name_p;
  char term_name[32];

  puts( "\n\n*** TERMIOS 02 TEST ***" );

  puts( "tcdrain(12) - EBADF" );
  sc = tcdrain(12);
  rtems_test_assert( sc == -1 );
  rtems_test_assert( errno == EBADF );

  puts( "tcdrain(stdin) - OK" );
  sc = tcdrain(0);
  rtems_test_assert( !sc );

  puts( "tcdrain(stdout) - OK" );
  tcdrain(1);
  rtems_test_assert( !sc );

  puts( "tcdrain(stderr) - OK" );
  tcdrain(2);
  rtems_test_assert( !sc );

  puts( "" ); 

  /***** TEST TCFLOW *****/
  puts( "tcflow(stdin, TCOOFF) - ENOTSUP" );
  sc = tcflow( 0, TCOOFF );
  rtems_test_assert( sc == -1 );
  rtems_test_assert( errno = ENOTSUP );

  puts( "tcflow(stdin, TCOON) - ENOTSUP" );
  sc = tcflow( 0, TCOON );
  rtems_test_assert( sc == -1 );
  rtems_test_assert( errno = ENOTSUP );

  puts( "tcflow(stdin, TCIOFF) - ENOTSUP" );
  sc = tcflow( 0, TCIOFF );
  rtems_test_assert( sc == -1 );
  rtems_test_assert( errno = ENOTSUP );

  puts( "tcflow(stdin, TCION) - ENOTSUP" );
  sc = tcflow( 0, TCION );
  rtems_test_assert( sc == -1 );
  rtems_test_assert( errno = ENOTSUP );

  puts( "tcflow(stdin, 22) - EINVAL" );
  sc = tcflow( 0, 22 );
  rtems_test_assert( sc == -1 );
  rtems_test_assert( errno = EINVAL );

  puts( "" ); 

  /***** TEST TCFLUSH *****/
  puts( "tcflush(stdin, TCIFLUSH) - ENOTSUP" );
  sc = tcflush( 0, TCIFLUSH );
  rtems_test_assert( sc == -1 );
  rtems_test_assert( errno = ENOTSUP );

  puts( "tcflush(stdin, TCOFLUSH) - ENOTSUP" );
  sc = tcflush( 0, TCOFLUSH );
  rtems_test_assert( sc == -1 );
  rtems_test_assert( errno = ENOTSUP );

  puts( "tcflush(stdin, TCIOFLUSH) - ENOTSUP" );
  sc = tcflush( 0, TCIOFLUSH );
  rtems_test_assert( sc == -1 );
  rtems_test_assert( errno = ENOTSUP );

  puts( "tcflush(stdin, 22) - EINVAL" );
  sc = tcflush( 0, 22 );
  rtems_test_assert( sc == -1 );
  rtems_test_assert( errno = EINVAL );

  puts( "" );

  /***** TEST TCGETPGRP *****/
  puts( "tcgetpgrp( 1 ) - OK" );
  pid = tcgetpgrp(1);
  rtems_test_assert( pid == getpid() );

  puts( "tcsetpgrp( 1, 3 ) - OK" );
  sc = tcsetpgrp( 1, 3 );
  rtems_test_assert( !sc );

  puts( "" );

  /***** TEST TCSENDBREAK *****/
  puts( "tcsendbreak( 1, 0 ) - OK" );
  sc = tcsendbreak( 1, 0 );
  rtems_test_assert( !sc );

  puts( "" );

  /***** TEST CTERMID *****/
  puts( "ctermid( NULL ) - OK" );
  term_name_p = ctermid( NULL );
  rtems_test_assert( term_name_p );
  printf( "ctermid ==> %s\n", term_name_p );

  puts( "ctermid( term_name ) - OK" );
  term_name_p = ctermid( term_name );
  rtems_test_assert( term_name_p == term_name );
  printf( "ctermid ==> %s\n", term_name_p );

  puts( "*** END OF TERMIOS 02 TEST ***" );
  exit( 0 );
}
Esempio n. 24
0
int xsys_serialSetup(struct xbee_serialInfo *info) {
  struct termios tc;
  speed_t chosenbaud;
	
	if (!info) return XBEE_EMISSINGPARAM;
	
	switch (info->baudrate) {
		case 1200:   chosenbaud = B1200;   break;
		case 2400:   chosenbaud = B2400;   break;
		case 4800:   chosenbaud = B4800;   break;
		case 9600:   chosenbaud = B9600;   break;
		case 19200:  chosenbaud = B19200;  break;
		case 38400:  chosenbaud = B38400;  break;
		case 57600:  chosenbaud = B57600;  break;
		case 115200: chosenbaud = B115200; break;
		default:
			return XBEE_EINVAL;
	}
	
	if ((info->dev.fd = open(info->device, O_RDWR | O_NOCTTY | O_SYNC | O_NONBLOCK)) == -1) return XBEE_EIO;
	
	if ((info->dev.f = fdopen(info->dev.fd, "r+")) == NULL) return XBEE_EIO;
	
	fflush(info->dev.f);
	setvbuf(info->dev.f, NULL, _IONBF, BUFSIZ);
	
	if (tcgetattr(info->dev.fd, &tc)) {
		perror("tcgetattr()");
		return XBEE_ESETUP;
	}
	
  /* input flags */
  tc.c_iflag &= ~ IGNBRK;           /* enable ignoring break */
  tc.c_iflag &= ~(IGNPAR | PARMRK); /* disable parity checks */
  tc.c_iflag &= ~ INPCK;            /* disable parity checking */
  tc.c_iflag &= ~ ISTRIP;           /* disable stripping 8th bit */
  tc.c_iflag &= ~(INLCR | ICRNL);   /* disable translating NL <-> CR */
  tc.c_iflag &= ~ IGNCR;            /* disable ignoring CR */
  tc.c_iflag &= ~(IXON | IXOFF);    /* disable XON/XOFF flow control */
  /* output flags */
  tc.c_oflag &= ~ OPOST;            /* disable output processing */
  tc.c_oflag &= ~(ONLCR | OCRNL);   /* disable translating NL <-> CR */
#ifdef linux
/* not for FreeBSD */
  tc.c_oflag &= ~ OFILL;            /* disable fill characters */
#endif /* linux */
  /* control flags */
  tc.c_cflag |=   CLOCAL;           /* prevent changing ownership */
  tc.c_cflag |=   CREAD;            /* enable reciever */
  tc.c_cflag &= ~ PARENB;           /* disable parity */
  tc.c_cflag &= ~ CSTOPB;           /* disable 2 stop bits */
  tc.c_cflag &= ~ CSIZE;            /* remove size flag... */
  tc.c_cflag |=   CS8;              /* ...enable 8 bit characters */
  tc.c_cflag |=   HUPCL;            /* enable lower control lines on close - hang up */
#ifdef XBEE_NO_RTSCTS
  tc.c_cflag &= ~ CRTSCTS;          /* disable hardware CTS/RTS flow control */
#else
  tc.c_cflag |=   CRTSCTS;          /* enable hardware CTS/RTS flow control */
#endif
  /* local flags */
  tc.c_lflag &= ~ ISIG;             /* disable generating signals */
  tc.c_lflag &= ~ ICANON;           /* disable canonical mode - line by line */
  tc.c_lflag &= ~ ECHO;             /* disable echoing characters */
  tc.c_lflag &= ~ ECHONL;           /* ??? */
  tc.c_lflag &= ~ NOFLSH;           /* disable flushing on SIGINT */
  tc.c_lflag &= ~ IEXTEN;           /* disable input processing */

  /* control characters */
  memset(tc.c_cc,0,sizeof(tc.c_cc));
	
	/* set i/o baud rate */
  if (cfsetspeed(&tc, chosenbaud)) {
		perror("cfsetspeed()");
		return XBEE_ESETUP;
	}
	
  if (tcsetattr(info->dev.fd, TCSAFLUSH, &tc)) {
		perror("tcsetattr()");
		return XBEE_ESETUP;
	}
	
	/* enable input & output transmission */
#ifdef linux
/* for Linux */
  if (tcflow(info->dev.fd, TCOON | TCION)) {
#else
/* for FreeBSD */
  if (tcflow(info->dev.fd, TCOON)) {
#endif
		perror("tcflow()");
		return XBEE_ESETUP;
	}
	
	/* purge buffer */
	{
		char buf[1024];
		int n;
		do {
			usleep(5000); /* 5ms */
			n = read(info->dev.fd, buf, sizeof(buf));
		} while (n > 0);
	}
	fcntl(info->dev.fd, F_SETFL, 0); /* disable blocking */
	
#ifndef linux
/* for FreeBSD */
	usleep(250000); /* it seems that the serial port takes a while to get going... */
#endif
	
	return XBEE_ENONE;
}

int xsys_serialShutdown(struct xbee_serialInfo *info) {
	if (!info) return XBEE_EMISSINGPARAM;
	if (info->dev.f) fclose(info->dev.f);
	info->dev.f = NULL;
	if (info->dev.fd) close(info->dev.fd);
	info->dev.fd = -1;
	return XBEE_ENONE;
}

int xsys_serialRead(struct xbee_serialInfo *info, int len, unsigned char *dest) {
	fd_set fds;
	int ret;
	int pos;
	
	if (!info || !dest) return XBEE_EMISSINGPARAM;
	if (info->dev.fd == -1 || !info->dev.f || len == 0) return XBEE_EINVAL;
	
	for (pos = 0; pos < len; pos += ret) {
		FD_ZERO(&fds);
		FD_SET(info->dev.fd, &fds);
		
		if (select(info->dev.fd + 1, &fds, NULL, NULL, NULL) == -1) {
			if (errno == EINTR) return XBEE_ESELECTINTERRUPTED;
			return XBEE_ESELECT;
		}
		if ((ret = fread(&(dest[pos]), 1, len - pos, info->dev.f)) > 0) continue;
		if (feof(info->dev.f)) {
#ifndef linux
/* for FreeBSD */
			usleep(10000);
			continue;
#else
			return XBEE_EEOF;
#endif /* !linux */
		}
		if (ferror(info->dev.f)) {
			perror("fread()");
			return XBEE_EIO;
		}
	}
	
	return XBEE_ENONE;
}
Esempio n. 25
0
CAMLprim value unix_tcflow(value fd, value action)
{
  if (tcflow(Int_val(fd), action_flag_table[Int_val(action)]) == -1)
    uerror("tcflow", Nothing);
  return Val_unit;
}
Esempio n. 26
0
UINT32 serial_tty_control(SERIAL_TTY* tty, UINT32 IoControlCode, wStream* input, wStream* output, UINT32* abort_io)
{
	int purge_mask;
	UINT32 result;
	UINT32 modemstate;
	BYTE immediate;
	UINT32 ret = STATUS_SUCCESS;
	UINT32 length = 0;
	UINT32 pos;

	DEBUG_SVC("in");

	Stream_Seek(output, sizeof(UINT32));

	switch (IoControlCode)
	{
		case IOCTL_SERIAL_SET_BAUD_RATE:
			Stream_Read_UINT32(input, tty->baud_rate);
			tty_set_termios(tty);
			DEBUG_SVC("SERIAL_SET_BAUD_RATE %d", tty->baud_rate);
			break;

		case IOCTL_SERIAL_GET_BAUD_RATE:
			length = 4;
			Stream_Write_UINT32(output, tty->baud_rate);
			DEBUG_SVC("SERIAL_GET_BAUD_RATE %d", tty->baud_rate);
			break;

		case IOCTL_SERIAL_SET_QUEUE_SIZE:
			Stream_Read_UINT32(input, tty->queue_in_size);
			Stream_Read_UINT32(input, tty->queue_out_size);
			DEBUG_SVC("SERIAL_SET_QUEUE_SIZE in %d out %d", tty->queue_in_size, tty->queue_out_size);
			break;

		case IOCTL_SERIAL_SET_LINE_CONTROL:
			Stream_Read_UINT8(input, tty->stop_bits);
			Stream_Read_UINT8(input, tty->parity);
			Stream_Read_UINT8(input, tty->word_length);
			tty_set_termios(tty);
			DEBUG_SVC("SERIAL_SET_LINE_CONTROL stop %d parity %d word %d",
				tty->stop_bits, tty->parity, tty->word_length);
			break;

		case IOCTL_SERIAL_GET_LINE_CONTROL:
			DEBUG_SVC("SERIAL_GET_LINE_CONTROL");
			length = 3;
			Stream_Write_UINT8(output, tty->stop_bits);
			Stream_Write_UINT8(output, tty->parity);
			Stream_Write_UINT8(output, tty->word_length);
			break;

		case IOCTL_SERIAL_IMMEDIATE_CHAR:
			DEBUG_SVC("SERIAL_IMMEDIATE_CHAR");
			Stream_Read_UINT8(input, immediate);
			tty_write_data(tty, &immediate, 1);
			break;

		case IOCTL_SERIAL_CONFIG_SIZE:
			DEBUG_SVC("SERIAL_CONFIG_SIZE");
			length = 4;
			Stream_Write_UINT32(output, 0);
			break;

		case IOCTL_SERIAL_GET_CHARS:
			DEBUG_SVC("SERIAL_GET_CHARS");
			length = 6;
			Stream_Write(output, tty->chars, 6);
			break;

		case IOCTL_SERIAL_SET_CHARS:
			DEBUG_SVC("SERIAL_SET_CHARS");
			Stream_Read(input, tty->chars, 6);
			tty_set_termios(tty);
			break;

		case IOCTL_SERIAL_GET_HANDFLOW:
			length = 16;
			tty_get_termios(tty);
			Stream_Write_UINT32(output, tty->control);
			Stream_Write_UINT32(output, tty->xonoff);
			Stream_Write_UINT32(output, tty->onlimit);
			Stream_Write_UINT32(output, tty->offlimit);
			DEBUG_SVC("IOCTL_SERIAL_GET_HANDFLOW %X %X %X %X",
				tty->control, tty->xonoff, tty->onlimit, tty->offlimit);
			break;

		case IOCTL_SERIAL_SET_HANDFLOW:
			Stream_Read_UINT32(input, tty->control);
			Stream_Read_UINT32(input, tty->xonoff);
			Stream_Read_UINT32(input, tty->onlimit);
			Stream_Read_UINT32(input, tty->offlimit);
			DEBUG_SVC("IOCTL_SERIAL_SET_HANDFLOW %X %X %X %X",
				tty->control, tty->xonoff, tty->onlimit, tty->offlimit);
			tty_set_termios(tty);
			break;

		case IOCTL_SERIAL_SET_TIMEOUTS:
			Stream_Read_UINT32(input, tty->read_interval_timeout);
			Stream_Read_UINT32(input, tty->read_total_timeout_multiplier);
			Stream_Read_UINT32(input, tty->read_total_timeout_constant);
			Stream_Read_UINT32(input, tty->write_total_timeout_multiplier);
			Stream_Read_UINT32(input, tty->write_total_timeout_constant);

			/* http://www.codeproject.com/KB/system/chaiyasit_t.aspx, see 'ReadIntervalTimeout' section
				http://msdn.microsoft.com/en-us/library/ms885171.aspx */
			if (tty->read_interval_timeout == SERIAL_TIMEOUT_MAX)
			{
				tty->read_interval_timeout = 0;
				tty->read_total_timeout_multiplier = 0;
			}

			DEBUG_SVC("SERIAL_SET_TIMEOUTS read timeout %d %d %d",
				tty->read_interval_timeout,
				tty->read_total_timeout_multiplier,
				tty->read_total_timeout_constant);
			break;

		case IOCTL_SERIAL_GET_TIMEOUTS:
			DEBUG_SVC("SERIAL_GET_TIMEOUTS read timeout %d %d %d",
				tty->read_interval_timeout,
				tty->read_total_timeout_multiplier,
				tty->read_total_timeout_constant);
			length = 20;
			Stream_Write_UINT32(output, tty->read_interval_timeout);
			Stream_Write_UINT32(output, tty->read_total_timeout_multiplier);
			Stream_Write_UINT32(output, tty->read_total_timeout_constant);
			Stream_Write_UINT32(output, tty->write_total_timeout_multiplier);
			Stream_Write_UINT32(output, tty->write_total_timeout_constant);
			break;

		case IOCTL_SERIAL_GET_WAIT_MASK:
			DEBUG_SVC("SERIAL_GET_WAIT_MASK %X", tty->wait_mask);
			length = 4;
			Stream_Write_UINT32(output, tty->wait_mask);
			break;

		case IOCTL_SERIAL_SET_WAIT_MASK:
			Stream_Read_UINT32(input, tty->wait_mask);
			DEBUG_SVC("SERIAL_SET_WAIT_MASK %X", tty->wait_mask);
			break;

		case IOCTL_SERIAL_SET_DTR:
			DEBUG_SVC("SERIAL_SET_DTR");
			ioctl(tty->fd, TIOCMGET, &result);
			result |= TIOCM_DTR;
			ioctl(tty->fd, TIOCMSET, &result);
			tty->dtr = 1;
			break;

		case IOCTL_SERIAL_CLR_DTR:
			DEBUG_SVC("SERIAL_CLR_DTR");
			ioctl(tty->fd, TIOCMGET, &result);
			result &= ~TIOCM_DTR;
			ioctl(tty->fd, TIOCMSET, &result);
			tty->dtr = 0;
			break;

		case IOCTL_SERIAL_SET_RTS:
			DEBUG_SVC("SERIAL_SET_RTS");
			ioctl(tty->fd, TIOCMGET, &result);
			result |= TIOCM_RTS;
			ioctl(tty->fd, TIOCMSET, &result);
			tty->rts = 1;
			break;

		case IOCTL_SERIAL_CLR_RTS:
			DEBUG_SVC("SERIAL_CLR_RTS");
			ioctl(tty->fd, TIOCMGET, &result);
			result &= ~TIOCM_RTS;
			ioctl(tty->fd, TIOCMSET, &result);
			tty->rts = 0;
			break;

		case IOCTL_SERIAL_GET_MODEMSTATUS:
			modemstate = 0;
#ifdef TIOCMGET
			ioctl(tty->fd, TIOCMGET, &result);
			if (result & TIOCM_CTS)
				modemstate |= SERIAL_MS_CTS;
			if (result & TIOCM_DSR)
				modemstate |= SERIAL_MS_DSR;
			if (result & TIOCM_RNG)
				modemstate |= SERIAL_MS_RNG;
			if (result & TIOCM_CAR)
				modemstate |= SERIAL_MS_CAR;
			if (result & TIOCM_DTR)
				modemstate |= SERIAL_MS_DTR;
			if (result & TIOCM_RTS)
				modemstate |= SERIAL_MS_RTS;
#endif
			DEBUG_SVC("SERIAL_GET_MODEMSTATUS %X", modemstate);
			length = 4;
			Stream_Write_UINT32(output, modemstate);
			break;

		case IOCTL_SERIAL_GET_COMMSTATUS:
			length = 18;
			Stream_Write_UINT32(output, 0);	/* Errors */
			Stream_Write_UINT32(output, 0);	/* Hold reasons */

			result = 0;
#ifdef TIOCINQ
			ioctl(tty->fd, TIOCINQ, &result);
#endif
			Stream_Write_UINT32(output, result); /* Amount in in queue */
			if (result)
				DEBUG_SVC("SERIAL_GET_COMMSTATUS in queue %d", result);

			result = 0;
#ifdef TIOCOUTQ
			ioctl(tty->fd, TIOCOUTQ, &result);
#endif
			Stream_Write_UINT32(output, result);	/* Amount in out queue */
			DEBUG_SVC("SERIAL_GET_COMMSTATUS out queue %d", result);

			Stream_Write_UINT8(output, 0); /* EofReceived */
			Stream_Write_UINT8(output, 0); /* WaitForImmediate */
			break;

		case IOCTL_SERIAL_PURGE:
			Stream_Read_UINT32(input, purge_mask);
			DEBUG_SVC("SERIAL_PURGE purge_mask %X", purge_mask);

		/*	See http://msdn.microsoft.com/en-us/library/ms901431.aspx
			PURGE_TXCLEAR 	Clears the output buffer, if the driver has one.
			PURGE_RXCLEAR 	Clears the input buffer, if the driver has one.

			It clearly states to clear the *driver* buffer, not the port buffer
		*/

#ifdef DEBUG_SVC
			if (purge_mask & SERIAL_PURGE_TXCLEAR)
				DEBUG_SVC("Ignoring SERIAL_PURGE_TXCLEAR");
			if (purge_mask & SERIAL_PURGE_RXCLEAR)
				DEBUG_SVC("Ignoring SERIAL_PURGE_RXCLEAR");
#endif

			if (purge_mask & SERIAL_PURGE_TXABORT)
				*abort_io |= SERIAL_ABORT_IO_WRITE;
			if (purge_mask & SERIAL_PURGE_RXABORT)
				*abort_io |= SERIAL_ABORT_IO_READ;
			break;
		case IOCTL_SERIAL_WAIT_ON_MASK:
			DEBUG_SVC("SERIAL_WAIT_ON_MASK %X", tty->wait_mask);
			tty->event_pending = 1;
			length = 4;
			if (serial_tty_get_event(tty, &result))
			{
				DEBUG_SVC("WAIT end  event = %X", result);
				Stream_Write_UINT32(output, result);
				break;
			}
			ret = STATUS_PENDING;
			break;

		case IOCTL_SERIAL_SET_BREAK_ON:
			DEBUG_SVC("SERIAL_SET_BREAK_ON");
			tcsendbreak(tty->fd, 0);
			break;

		case IOCTL_SERIAL_RESET_DEVICE:
			DEBUG_SVC("SERIAL_RESET_DEVICE");
			break;

		case IOCTL_SERIAL_SET_BREAK_OFF:
			DEBUG_SVC("SERIAL_SET_BREAK_OFF");
			break;

		case IOCTL_SERIAL_SET_XOFF:
			DEBUG_SVC("SERIAL_SET_XOFF");
			break;

		case IOCTL_SERIAL_SET_XON:
			DEBUG_SVC("SERIAL_SET_XON");
			tcflow(tty->fd, TCION);
			break;

		default:
			DEBUG_SVC("NOT FOUND IoControlCode SERIAL IOCTL %d", IoControlCode);
			return STATUS_INVALID_PARAMETER;
	}

	/* Write OutputBufferLength */
	pos = Stream_GetPosition(output);
	Stream_SetPosition(output, 16);
	Stream_Write_UINT32(output, length);
	Stream_SetPosition(output, pos);

	return ret;
}
Esempio n. 27
0
static uint32
serial_control(IRP * irp)
{
	int flush_mask, purge_mask;
	uint32 result, modemstate;
	uint8 immediate;
	int size = 0, ret = RD_STATUS_SUCCESS;
	SERIAL_DEVICE_INFO *info = (SERIAL_DEVICE_INFO *) irp->dev->info;
	char *inbuf = irp->inputBuffer;
	char *outbuf = NULL;

	/* the server commands, we obbey */
	switch (irp->ioControlCode)
	{
		case IOCTL_SERIAL_SET_BAUD_RATE:
			info->baud_rate = GET_UINT32(inbuf, 0);
			set_termios(info);
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_BAUD_RATE %d", info->baud_rate));
			break;
		case IOCTL_SERIAL_GET_BAUD_RATE:
			size = 4;
			outbuf = malloc(size);
			SET_UINT32(outbuf, 0, info->baud_rate);
			LLOGLN(10, ("serial_ioctl -> SERIAL_GET_BAUD_RATE %d", info->baud_rate));
			break;
		case IOCTL_SERIAL_SET_QUEUE_SIZE:
			info->queue_in_size = GET_UINT32(inbuf, 0);
			info->queue_out_size = GET_UINT32(inbuf, 4);
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_QUEUE_SIZE in %d out %d", info->queue_in_size, info->queue_out_size));
			break;
		case IOCTL_SERIAL_SET_LINE_CONTROL:
			info->stop_bits = GET_UINT8(inbuf, 0);
			info->parity = GET_UINT8(inbuf, 1);
			info->word_length = GET_UINT8(inbuf, 2);
			set_termios(info);
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_LINE_CONTROL stop %d parity %d word %d",
					info->stop_bits, info->parity, info->word_length));
			break;
		case IOCTL_SERIAL_GET_LINE_CONTROL:
			LLOGLN(10, ("serial_ioctl -> SERIAL_GET_LINE_CONTROL"));
			size = 3;
			outbuf = malloc(size);
			SET_UINT8(outbuf, 0, info->stop_bits);
			SET_UINT8(outbuf, 1, info->parity);
			SET_UINT8(outbuf, 2, info->word_length);
			break;
		case IOCTL_SERIAL_IMMEDIATE_CHAR:
			LLOGLN(10, ("serial_ioctl -> SERIAL_IMMEDIATE_CHAR"));
			immediate = GET_UINT8(inbuf, 0);
			serial_write_data(irp, &immediate, 1);
			break;
		case IOCTL_SERIAL_CONFIG_SIZE:
			LLOGLN(10, ("serial_ioctl -> SERIAL_CONFIG_SIZE"));
			size = 4;
			outbuf = malloc(size);
			SET_UINT32(outbuf, 0, 0);
			break;
		case IOCTL_SERIAL_GET_CHARS:
			LLOGLN(10, ("serial_ioctl -> SERIAL_GET_CHARS"));
			size = 6;
			outbuf = malloc(size);
			memcpy(outbuf, info->chars, size);
			break;
		case IOCTL_SERIAL_SET_CHARS:
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_CHARS"));
			memcpy(info->chars, inbuf, 6);
			set_termios(info);
			break;
		case IOCTL_SERIAL_GET_HANDFLOW:
			LLOGLN(10, ("serial_ioctl -> IOCTL_SERIAL_GET_HANDFLOW"));
			size = 16;
			outbuf = malloc(size);
			get_termios(info);
			SET_UINT32(outbuf, 0, info->control);
			SET_UINT32(outbuf, 4, info->xonoff);
			SET_UINT32(outbuf, 8, info->onlimit);
			SET_UINT32(outbuf, 12, info->offlimit);
			break;
		case IOCTL_SERIAL_SET_HANDFLOW:
			info->control = GET_UINT32(inbuf, 0);
			info->xonoff = GET_UINT32(inbuf, 4);
			info->onlimit = GET_UINT32(inbuf, 8);
			info->offlimit = GET_UINT32(inbuf, 12);
			LLOGLN(10, ("serial_ioctl -> IOCTL_SERIAL_SET_HANDFLOW %x %x %x %x",
				      info->control, info->xonoff, info->onlimit, info->onlimit));
			set_termios(info);
			break;
		case IOCTL_SERIAL_SET_TIMEOUTS:
			info->read_interval_timeout = GET_UINT32(inbuf, 0);
			info->read_total_timeout_multiplier = GET_UINT32(inbuf, 4);
			info->read_total_timeout_constant = GET_UINT32(inbuf, 8);
			info->write_total_timeout_multiplier = GET_UINT32(inbuf, 12);
			info->write_total_timeout_constant = GET_UINT32(inbuf, 16);

			/* http://www.codeproject.com/KB/system/chaiyasit_t.aspx, see 'ReadIntervalTimeout' section
				http://msdn.microsoft.com/en-us/library/ms885171.aspx */
			if (info->read_interval_timeout == SERIAL_TIMEOUT_MAX)
			{
				info->read_interval_timeout = 0;
				info->read_total_timeout_multiplier = 0;
			}

			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_TIMEOUTS read timeout %d %d %d",
				      info->read_interval_timeout,
				      info->read_total_timeout_multiplier,
				      info->read_total_timeout_constant));
			break;
		case IOCTL_SERIAL_GET_TIMEOUTS:
			LLOGLN(10, ("serial_ioctl -> SERIAL_GET_TIMEOUTS read timeout %d %d %d",
				      info->read_interval_timeout,
				      info->read_total_timeout_multiplier,
				      info->read_total_timeout_constant));
			size = 20;
			outbuf = malloc(size);
			SET_UINT32(outbuf, 0, info->read_interval_timeout);
			SET_UINT32(outbuf, 4, info->read_total_timeout_multiplier);
			SET_UINT32(outbuf, 8, info->read_total_timeout_constant);
			SET_UINT32(outbuf, 12, info->write_total_timeout_multiplier);
			SET_UINT32(outbuf, 16, info->write_total_timeout_constant);
			break;
		case IOCTL_SERIAL_GET_WAIT_MASK:
			LLOGLN(10, ("serial_ioctl -> SERIAL_GET_WAIT_MASK %X", info->wait_mask));
			size = 4;
			outbuf = malloc(size);
			SET_UINT32(outbuf, 0, info->wait_mask);
			break;
		case IOCTL_SERIAL_SET_WAIT_MASK:
			info->wait_mask = GET_UINT32(inbuf, 0);
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_WAIT_MASK %X", info->wait_mask));
			break;
		case IOCTL_SERIAL_SET_DTR:
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_DTR"));
			ioctl(info->file, TIOCMGET, &result);
			result |= TIOCM_DTR;
			ioctl(info->file, TIOCMSET, &result);
			info->dtr = 1;
			break;
		case IOCTL_SERIAL_CLR_DTR:
			LLOGLN(10, ("serial_ioctl -> SERIAL_CLR_DTR"));
			ioctl(info->file, TIOCMGET, &result);
			result &= ~TIOCM_DTR;
			ioctl(info->file, TIOCMSET, &result);
			info->dtr = 0;
			break;
		case IOCTL_SERIAL_SET_RTS:
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_RTS"));
			ioctl(info->file, TIOCMGET, &result);
			result |= TIOCM_RTS;
			ioctl(info->file, TIOCMSET, &result);
			info->rts = 1;
			break;
		case IOCTL_SERIAL_CLR_RTS:
			LLOGLN(10, ("serial_ioctl -> SERIAL_CLR_RTS"));
			ioctl(info->file, TIOCMGET, &result);
			result &= ~TIOCM_RTS;
			ioctl(info->file, TIOCMSET, &result);
			info->rts = 0;
			break;
		case IOCTL_SERIAL_GET_MODEMSTATUS:
			modemstate = 0;
#ifdef TIOCMGET
			ioctl(info->file, TIOCMGET, &result);
			if (result & TIOCM_CTS)
				modemstate |= SERIAL_MS_CTS;
			if (result & TIOCM_DSR)
				modemstate |= SERIAL_MS_DSR;
			if (result & TIOCM_RNG)
				modemstate |= SERIAL_MS_RNG;
			if (result & TIOCM_CAR)
				modemstate |= SERIAL_MS_CAR;
			if (result & TIOCM_DTR)
				modemstate |= SERIAL_MS_DTR;
			if (result & TIOCM_RTS)
				modemstate |= SERIAL_MS_RTS;
#endif
			LLOGLN(10, ("serial_ioctl -> SERIAL_GET_MODEMSTATUS %X", modemstate));
			size = 4;
			outbuf = malloc(size);
			SET_UINT32(outbuf, 0, modemstate);
			break;
		case IOCTL_SERIAL_GET_COMMSTATUS:
			size = 18;
			outbuf = malloc(size);
			SET_UINT32(outbuf, 0, 0);	/* Errors */
			SET_UINT32(outbuf, 4, 0);	/* Hold reasons */

			result = 0;
#ifdef TIOCINQ
			ioctl(info->file, TIOCINQ, &result);
#endif
			SET_UINT32(outbuf, 8, result);	/* Amount in in queue */
			if (result)
				LLOGLN(10, ("serial_ioctl -> SERIAL_GET_COMMSTATUS in queue %d", result));

			result = 0;
#ifdef TIOCOUTQ
			ioctl(info->file, TIOCOUTQ, &result);
#endif
			SET_UINT32(outbuf, 12, result);	/* Amount in out queue */
			LLOGLN(10, ("serial_ioctl -> SERIAL_GET_COMMSTATUS out queue %d", result));

			SET_UINT8(outbuf, 16, 0);	/* EofReceived */
			SET_UINT8(outbuf, 17, 0);	/* WaitForImmediate */
			break;
		case IOCTL_SERIAL_PURGE:
			purge_mask = GET_UINT32(inbuf, 0);
			LLOGLN(10, ("serial_ioctl -> SERIAL_PURGE purge_mask %X", purge_mask));
			flush_mask = 0;
			if (purge_mask & SERIAL_PURGE_TXCLEAR)
				flush_mask |= TCOFLUSH;
			if (purge_mask & SERIAL_PURGE_RXCLEAR)
				flush_mask |= TCIFLUSH;
			if (flush_mask != 0)
				tcflush(info->file, flush_mask);

			if (purge_mask & SERIAL_PURGE_TXABORT)
				irp->abortIO |= RDPDR_ABORT_IO_WRITE;
			if(purge_mask & SERIAL_PURGE_RXABORT)
				irp->abortIO |= RDPDR_ABORT_IO_READ;
			break;
		case IOCTL_SERIAL_WAIT_ON_MASK:
			LLOGLN(10, ("serial_ioctl -> SERIAL_WAIT_ON_MASK %X", info->wait_mask));
			info->event_pending = 1;
			if (serial_get_event(irp, &result))
			{
				size = 4;
				outbuf = malloc(size);
				LLOGLN(10, ("WAIT end  event = %x", result));
				SET_UINT32(outbuf, 0, result);
				break;
			}
			irp->outputBufferLength = 4;
			ret = RD_STATUS_PENDING;
			break;
		case IOCTL_SERIAL_SET_BREAK_ON:
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_BREAK_ON"));
			tcsendbreak(info->file, 0);
			break;
		case IOCTL_SERIAL_RESET_DEVICE:
			LLOGLN(10, ("serial_ioctl -> SERIAL_RESET_DEVICE"));
			break;
		case IOCTL_SERIAL_SET_BREAK_OFF:
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_BREAK_OFF"));
			break;
		case IOCTL_SERIAL_SET_XOFF:
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_XOFF"));
			break;
		case IOCTL_SERIAL_SET_XON:
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_XON"));
			tcflow(info->file, TCION);
			break;
		default:
			LLOGLN(10, ("NOT FOUND IoControlCode SERIAL IOCTL %d", irp->ioControlCode));
			return RD_STATUS_INVALID_PARAMETER;
	}

	irp->outputBuffer = outbuf;
	irp->outputBufferLength = size;

	return ret;
}
Esempio n. 28
0
// thread main!
int uart_unix_main(void* arg)
{
    dthread_t* self = (dthread_t*) arg;
    dthread_t* other = (dthread_t*) self->arg;
    dmessage_t* mp = NULL;
    dthread_poll_event_t ev, *evp;
    size_t nev;
    dterm_t term;
    uart_ctx_t ctx;
    ErlDrvTermData mp_from;
    ErlDrvTermData mp_ref;
    dthread_t*     mp_source;
    int tmo;
    int r;

    DEBUGF("uart_unix: thread started");

    uart_init(&ctx, self, other);

    dterm_init(&term);

again_tmo:
    tmo = next_timeout(&ctx);
again:
    nev = 0;
    evp = NULL;
    if (ctx.fd >= 0) {
	ev.event = (ErlDrvEvent) ((long)ctx.fd);
	ev.events = 0;
	if ((ctx.option.active != UART_PASSIVE) || ctx.recv) {
	    ev.events |= ERL_DRV_READ;
	    if (ctx.option.ptypkt && (ctx.fd != ctx.tty_fd))
		ev.events |= ERL_DRV_EXCEP;
	}
	if (ctx.oq.mesg)
	    ev.events |= ERL_DRV_WRITE;
	if (ev.events) {
	    evp = &ev;
	    nev = 1;
	}
	DEBUGF("ctx.fd=%d, ev.events=%d", ctx.fd, ev.events);
    }

    DEBUGF("uart_unix_main: nev=%d, events=%x, timeout = %d", 
	   nev, ev.events, tmo);
    r = dthread_poll(self, evp, &nev, tmo);

    if (r < 0) {
	DEBUGF("uart_unix_main: dthread_poll failed=%d", r);
	goto again_tmo;
    }
    else {
	DEBUGF("uart_unix_main: nev=%d, r=%d", nev, r);

	if (evp && (nev == 1)) {
	    if (evp->revents & ERL_DRV_WRITE)
		process_output(&ctx, self);
	    if (evp->revents & (ERL_DRV_READ|ERL_DRV_EXCEP)) {
		while((process_input(&ctx, self, 0) == 1) && 
		      (ctx.option.active != UART_PASSIVE))
		    ;
	    }
	}
	tmo = next_timeout(&ctx);
	DEBUGF("uart_unix_main: timeout = %d", tmo);
	if (ctx.recv) {
	    if (tmo == 0) {
		uart_async_error_am(&ctx, ctx.dport, ctx.caller, am_timeout);
		clear_timeout(&ctx);
		ctx.remain = 0;
	    }
	}
	if (r == 0)
	    goto again;

	// r>0 (number of messages)
	DEBUGF("about to receive message r=%d", r);
	if ((mp = dthread_recv(self, NULL)) == NULL) {
	    DEBUGF("uart_unix_main: message was NULL");
	    goto again;
	}
	mp_from = mp->from;
	mp_ref  = mp->ref;
	mp_source = mp->source;

	switch (mp->cmd) {
	case DTHREAD_STOP:
	    DEBUGF("uart_unix_main: STOP");
	    close_device(&ctx);
	    uart_final(&ctx);
	    dmessage_free(mp);
	    DEBUGF("uart_unix_main: EXIT");
	    dthread_exit(0);
	    break;

	case DTHREAD_OUTPUT: // async send!
	    DEBUGF("uart_unix_main: OUTPUT");
	    if (ctx.fd < 0) {
		dmessage_free(mp);
		goto again;
	    }
	    if (enq_output(&ctx, self, mp, 0) < 0) {
		mp = NULL;
		goto error;
	    }
	    goto again;

	case UART_CMD_CONNECT: {
	    ErlDrvTermData owner;
	    if (mp->used != 0) goto badarg;
	    owner = driver_connected(self->port);
	    self->owner   = owner;
	    other->owner  = owner;
	    goto ok;
	}

	case UART_CMD_CLOSE:
	    DEBUGF("uart_unix_main: CLOSE");
	    close_device(&ctx);
	    goto ok;

	case UART_CMD_SEND: // sync send
	    DEBUGF("uart_unix_main: SEND");
	    if (ctx.fd < 0) goto ebadf;
	    if (enq_output(&ctx, self, mp, mp_from) < 0) {
		mp = NULL;
		goto error;
	    }
	    goto again;
	    
	case UART_CMD_SENDCHAR: // sync send
	    DEBUGF("uart_unix_main: SENDCHAR");
	    if (ctx.fd < 0) goto ebadf;
	    if (enq_output(&ctx, self, mp, mp_from) < 0) {
		mp = NULL;
		goto error;
	    }
	    goto again;

	case UART_CMD_RECV: {  // <<Time:32, Length:32>> Time=0xffffffff=inf
	    uint32_t tm;
	    int len;
	    DEBUGF("uart_unix_main: RECV");
	    if (ctx.fd < 0) goto ebadf;
	    if (ctx.recv) goto ealready;
	    if (mp->used != 8) goto badarg;
	    if (ctx.option.active != UART_PASSIVE) goto badarg;
	    tm = get_uint32((uint8_t*) mp->buffer);
	    len = (int) get_uint32((uint8_t*) (mp->buffer+4));
	    if ((len < 0) || (len > UART_MAX_PACKET_SIZE)) goto badarg;
	    ctx.ref = mp_ref;
	    ctx.caller = mp_from;
	    set_timeout(&ctx, tm);
	    ctx.recv = 1;
	    DEBUGF("recv timeout %lu", tm);
	    process_input(&ctx, self, len);
	    dmessage_free(mp);
	    goto again_tmo;
	}

	case UART_CMD_UNRECV: {  // argument is data to push back
	    uart_buf_push(&ctx.ib, mp->buffer, mp->used);
	    DEBUGF("unrecived %d bytes", ctx.ib.ptr - ctx.ib.ptr_start);
	    if (ctx.option.active != UART_PASSIVE) {
		while((process_input(&ctx, self, 0) == 1) && 
		      (ctx.option.active != UART_PASSIVE))
		    ;
	    }
	    goto ok;
	}

	case UART_CMD_SETOPTS: {
	    uart_com_state_t state  = ctx.state;
	    uart_opt_t       option = ctx.option;
	    uint32_t         sflags = ctx.sflags;

	    // parse & update options in state,option and sflag
	    if (uart_parse_opts(mp->buffer, mp->used, 
				&state, &option, &sflags) < 0)
		goto badarg;

	    //  apply the changed values
	    if ((r=apply_opts(&ctx, &state, &option, sflags)) < 0)
		goto error;

	    if (r == 1) {
		while((process_input(&ctx, self, 0) == 1) && 
		      (ctx.option.active != UART_PASSIVE))
		    ;
	    }
	    goto ok;
	}

	case UART_CMD_GETOPTS: {
	    dterm_mark_t m1;
	    dterm_mark_t m2;
	    // {Ref, {ok,List}} || {Ref, {error,Reason}}
	    dterm_tuple_begin(&term, &m1); {
		dterm_uint(&term, mp_ref);
		dterm_tuple_begin(&term, &m2); {
		    dterm_atom(&term, am_ok);
		    if (uart_get_opts(&term, &ctx,(uint8_t*)mp->buffer,mp->used) < 0) {
			dterm_reset(&term);
			goto badarg;
		    }
		}
		dterm_tuple_end(&term, &m2);
	    }
	    dterm_tuple_end(&term, &m1);
	    dthread_port_send_dterm(mp_source, self, mp_from, &term);
	    dterm_reset(&term);
	    dmessage_free(mp);
	    goto again;
	}

	case UART_CMD_GET_MODEM: {
	    dterm_mark_t m1;
	    dterm_mark_t m2;
	    uart_modem_state_t mstate;
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (get_modem_state(ctx.tty_fd, &mstate) < 0) goto error;

	    dterm_tuple_begin(&term, &m1); {
		dterm_uint(&term, mp_ref);
		dterm_tuple_begin(&term, &m2); {
		    dterm_atom(&term, am_ok);
		    modem_state_dterm(&term, mstate);
		}
		dterm_tuple_end(&term, &m2);
	    }
	    dterm_tuple_end(&term, &m1);
	    dthread_port_send_dterm(mp_source, self, mp_from, &term);
	    dterm_reset(&term);
	    dmessage_free(mp);
	    goto again;
	}

	case UART_CMD_SET_MODEM: {
	    uart_modem_state_t mstate;	    
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (mp->used != 4) goto badarg;
	    mstate = (uart_modem_state_t) get_uint32((uint8_t*) mp->buffer);
	    if (set_modem_state(ctx.tty_fd, mstate, 1) < 0) goto error;
	    goto ok;
	}

	case UART_CMD_CLR_MODEM: {
	    uart_modem_state_t mstate;
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (mp->used != 4) goto badarg;
	    mstate = (uart_modem_state_t) get_uint32((uint8_t*) mp->buffer);
	    if (set_modem_state(ctx.tty_fd, mstate, 0) < 0) goto error;
	    goto ok;
	}
		
	case UART_CMD_HANGUP: {
	    struct termios tio;
	    int r;
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (mp->used != 0) goto badarg;
	    if ((r = tcgetattr(ctx.tty_fd, &tio)) < 0) {
		INFOF("tcgetattr: error=%s\n", strerror(errno));
		goto badarg;
	    }
	    cfsetispeed(&tio, B0);
	    cfsetospeed(&tio, B0);
	    if ((r = tcsetattr(ctx.tty_fd, TCSANOW, &tio)) < 0) {
		INFOF("tcsetattr: error=%s\n", strerror(errno));
		goto badarg;		
	    }
	    goto ok;
	}
		
	case UART_CMD_BREAK: {
	    int duration;
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (mp->used != 4) goto badarg;
	    duration = (int) get_uint32((uint8_t*) mp->buffer);
	    if (tcsendbreak(ctx.tty_fd, duration) < 0)
		goto error;
	    goto ok;
	}
	    
	case UART_CMD_FLOW:
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (mp->used != 1) goto badarg;
	    switch(mp->buffer[0]) {
	    case 0: r = tcflow(ctx.tty_fd, TCIOFF); break;
	    case 1: r = tcflow(ctx.tty_fd, TCION); break;
	    case 2: r = tcflow(ctx.tty_fd, TCOOFF); break;
	    case 3: r = tcflow(ctx.tty_fd, TCOON); break;
	    default: goto badarg; break;
	    }
	    if (r < 0)
		goto error;
	    goto ok;

	default:
	    goto badarg;
	}
    }

ok:
    dthread_port_send_ok(mp_source, self,  mp_from, mp_ref);
    if (mp) dmessage_free(mp);
    goto again;

ebadf:
    errno = EBADF;
    goto error;
badarg:
    errno = EINVAL;
    goto error;
ealready:
    errno = EALREADY;
    goto error;

error:
    dthread_port_send_error(mp_source, self, mp_from, mp_ref,
			    uart_errno(&ctx));
    if (mp) dmessage_free(mp);
    goto again;
}
Esempio n. 29
0
void *Commander::XBeeThreadProc(void *pv)
{
    Commander *pcmdr = (Commander*)pv;
    fd_set readfs;                                // file descriptor set to wait on.
    timeval tv;                                   // how long to wait.

    //    printf("Thread start(%s)\n", pcmdr->_pszDevice);

    // Lets do our init of the xbee here.
    // We will do all of the stuff to intialize the serial port plus we will spawn off our thread.
    struct termios tc;

    if ((pcmdr->fdXBee = open(pcmdr->_pszDevice, O_RDWR | O_NOCTTY | O_SYNC /* |  O_NONBLOCK */)) == -1) 
    {
        printf("Open Failed\n");
        return 0;
    }


    if ((pcmdr->pfileXBee = fdopen(pcmdr->fdXBee, "r+")) == NULL)
    {
        return 0;
    }


    setvbuf(pcmdr->pfileXBee, NULL, _IONBF, BUFSIZ);
    fflush(pcmdr->pfileXBee);

    if (tcgetattr(pcmdr->fdXBee, &tc))
    {
        perror("tcgetattr()");
        return 0;
    }


    /* input flags */
    tc.c_iflag &= ~ IGNBRK;                           /* enable ignoring break */
    tc.c_iflag &= ~(IGNPAR | PARMRK);                 /* disable parity checks */
    tc.c_iflag &= ~ INPCK;                            /* disable parity checking */
    tc.c_iflag &= ~ ISTRIP;                           /* disable stripping 8th bit */
    tc.c_iflag &= ~(INLCR | ICRNL);                   /* disable translating NL <-> CR */
    tc.c_iflag &= ~ IGNCR;                            /* disable ignoring CR */
    tc.c_iflag &= ~(IXON | IXOFF);                    /* disable XON/XOFF flow control */
    /* output flags */
    tc.c_oflag &= ~ OPOST;                            /* disable output processing */
    tc.c_oflag &= ~(ONLCR | OCRNL);                   /* disable translating NL <-> CR */
    /* not for FreeBSD */
    tc.c_oflag &= ~ OFILL;                            /* disable fill characters */
    /* control flags */
    tc.c_cflag |=   CLOCAL;                           /* prevent changing ownership */
    tc.c_cflag |=   CREAD;                            /* enable reciever */
    tc.c_cflag &= ~ PARENB;                           /* disable parity */
    tc.c_cflag &= ~ CSTOPB;                           /* disable 2 stop bits */
    tc.c_cflag &= ~ CSIZE;                            /* remove size flag... */
    tc.c_cflag |=   CS8;                              /* ...enable 8 bit characters */
    tc.c_cflag |=   HUPCL;                            /* enable lower control lines on close - hang up */
    #ifdef XBEE_NO_RTSCTS
    tc.c_cflag &= ~ CRTSCTS;                          /* disable hardware CTS/RTS flow control */
    #else
    tc.c_cflag |=   CRTSCTS;                          /* enable hardware CTS/RTS flow control */
    #endif
    /* local flags */
    tc.c_lflag &= ~ ISIG;                             /* disable generating signals */
    tc.c_lflag &= ~ ICANON;                           /* disable canonical mode - line by line */
    tc.c_lflag &= ~ ECHO;                             /* disable echoing characters */
    tc.c_lflag &= ~ ECHONL;                           /* ??? */
    tc.c_lflag &= ~ NOFLSH;                           /* disable flushing on SIGINT */
    tc.c_lflag &= ~ IEXTEN;                           /* disable input processing */

    /* control characters */
    memset(tc.c_cc,0,sizeof(tc.c_cc));

    /* set i/o baud rate */
    if (cfsetspeed(&tc, pcmdr->_baud))
    {
        perror("cfsetspeed()");
        return 0;
    }


    if (tcsetattr(pcmdr->fdXBee, TCSAFLUSH, &tc))
    {
        perror("tcsetattr()");
        return 0;
    }


    /* enable input & output transmission */
    if (tcflow(pcmdr->fdXBee, TCOON | TCION))
    {
        perror("tcflow()");
        return 0;
    }


    fflush(pcmdr->pfileXBee);                             // again discard anything we have not read...

    //    printf("Thread Init\n");

    // May want to add end code... But for now don't have any defined...
    int ch;
    while(!pcmdr->_fCancel)
    {
        // Lets try using select to block our thread until we have some input available...
        FD_ZERO(&readfs);
        FD_SET(pcmdr->fdXBee, &readfs);                   // Make sure we are set to wait for our descriptor
        tv.tv_sec = 0;
        tv.tv_usec = 250000;                          // 1/4 of a second...
                                                      // wait until some input is available...
        select(pcmdr->fdXBee + 1, &readfs, NULL, NULL, &tv);

        while((!pcmdr->_fCancel) && (ch = getc(pcmdr->pfileXBee)) != EOF)
        {
            if(pcmdr->index == -1)                    // looking for new packet
            {
                if(ch == 0xff)
                {
                    pcmdr->index = 0;
                    pcmdr->checksum = 0;
                }
            }
            else if(pcmdr->index == 0)
            {
                pcmdr->bInBuf[pcmdr->index] = (unsigned char) ch;
                if(pcmdr->bInBuf[pcmdr->index] != 0xff)
                {
                    pcmdr->checksum += ch;
                    pcmdr->index++;
                }
            }
            else
            {
                pcmdr->bInBuf[pcmdr->index] = (unsigned char) ch;
                pcmdr->checksum += ch;
                pcmdr->index++;
                if(pcmdr->index == 7)                 // packet complete
                {
                    if(pcmdr->checksum%256 == 255)
                    {
                        // Lets grab our mutex to keep things consistent
                        pthread_mutex_lock(&pcmdr->lock);
                        for (int i=0; i < 6; i++)
                            pcmdr->vals[i] = pcmdr->bInBuf[i];
                        pcmdr->fValidPacket = true;
                        pthread_mutex_unlock(&pcmdr->lock);
                    }
                    pcmdr->index = -1;                // Say we are ready to start looking for start of next message...
                }
            }
        }
        // If we get to here try sleeping for a little time
        usleep(1000);                                 // Note: we could maybe simply block the thread until input available!
    }

    printf("Commander - XBee thread exit\n");
    return 0;
}
Esempio n. 30
0
s48_ref_t sch_tcflow(s48_call_t call, s48_ref_t sch_fd, s48_ref_t sch_action) {
    if (tcflow (s48_extract_long_2(call, sch_fd),
                s48_extract_long_2(call, sch_action)) == -1)
        s48_os_error_2(call, "sch_tcflow", errno, 2, sch_fd, sch_action);
    return s48_unspecific_2(call);
}