Beispiel #1
0
int canonical(struct termios *saved)
{   //Restaura la configuración original del usuario.
    return( tcsetattr( 0, TCSADRAIN, saved ) );
}
Beispiel #2
0
int openComm(void)
{
#if 1
    struct termios ti;
    char *device = CUST_BT_SERIAL_PORT;

    bt_prompt_trace(MOD_BT, "[UART] openComm");
    bt_android_log("[UART] openComm");
    if (commPort >= 0)  //modified by autumn
    {
        bt_prompt_trace(MOD_BT, "[UART] openComm already opened");
        bt_android_log("[UART][ERR] commPort=%d already opened.", commPort);
        bt_android_log("[BT][UART] + close uart=%d", commPort);
        close(commPort);
        bt_android_log("[BT][UART] - close uart");
    }
    bt_android_log("[BT][UART] + open uart");
    commPort = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK);    // Modified by SH
    bt_android_log("[BT][UART] - open uart");
    if (commPort < 0) {
        bt_prompt_trace(MOD_BT, "[UART]Can't open serial port: %s (%d)\n", strerror(errno), errno);
        bt_android_log("[UART][ERR] Can't open serial port: %s (%d)\n", strerror(errno), errno);
        return -1;
    }

#ifndef __MTK_STP_SUPPORTED__
    //fcntl(commPort, F_SETFL, FASYNC); // Added by SH
    tcflush(commPort, TCIOFLUSH);

    if (tcgetattr(commPort, &ti) < 0) {
        bt_prompt_trace(MOD_BT, "[UART]Can't get port settings: %s (%d)\n", strerror(errno), errno);
        bt_android_log("[UART][ERR] Can't get port settings: %s (%d)\n", strerror(errno), errno);
        bt_android_log("[UART][ERR] Close commPort");
        close(commPort);
        commPort = -1;
        return -1;
    }

    cfmakeraw(&ti);

    ti.c_cflag |= CLOCAL;
    ti.c_cflag &= ~CRTSCTS;
    #if !defined(__ANDROID_EMULATOR__)
    /* Emulator does not support flow control */
    ti.c_iflag &= ~(IXON | IXOFF | IXANY | 0x80000000);
    #endif
	      
    if (tcsetattr(commPort, TCSANOW, &ti) < 0) {
        bt_prompt_trace(MOD_BT, "[UART] Can't change port settings: %s (%d)\n", strerror(errno), errno);
        bt_android_log("[UART][ERR] Can't change port settings: %s (%d)\n", strerror(errno), errno);
        bt_android_log("[UART][ERR] Close commPort");
        close(commPort);
        commPort = -1;
        return -1;
    }
        
    if( set_speed(commPort, &ti, 115200) < 0){
        bt_android_log("[UART][ERR] set_speed failed");
        close(commPort);
        commPort = -1;
        return -1;
    }

    tcflush(commPort, TCIOFLUSH);
#endif /* ifndef __MTK_STP_SUPPORTED__ */
    bt_prompt_trace(MOD_BT, "[UART] Opening UART successfully : %d", commPort);
    bt_android_log("[UART] Opening UART successfully : %d", commPort);
    return 0;
#else
    
    char portName[20];
    
    sprintf(portName, "/dev/ttyS%d", 2/*readUartSetting()*/);

    bt_prompt_trace(MOD_BT, "Opening UART port : %s", portName);
    
    /* Open UART port */
    if (-1 == (commPort = open(portName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) ) 
    {
        bt_prompt_trace(MOD_BT, "[Failed] Opening UART port ");
        return 0;
    } 
    else
    {
        struct termios options;

        //fcntl(commPort, F_SETOWN, getpid());
        fcntl(commPort, F_SETFL, FASYNC);

        /* Get default com port setting */
        if( -1 == tcgetattr(commPort, &options) )
        {
            bt_prompt_trace(MOD_BT, "[Failed] tcgetattr UART port failed");
            close(commPort);
            return 0;
        }

        /* Set baud rate to 115200 */
        cfsetispeed(&options, B115200);
        cfsetospeed(&options, B115200);

        options.c_cflag |= (CLOCAL | CREAD);

        options.c_cflag &= ~PARENB;  /* No parity */
        options.c_cflag &= ~CSTOPB;  /* 1 stop bit */
        options.c_cflag &= ~CSIZE;   /* Mask the character size bits */
        options.c_cflag |= CS8;         /* Select 8 data bits */
        /* Disable RTS & CTS */
        options.c_cflag &= ~CRTSCTS;

        tcflush(commPort, TCIFLUSH);
        /* Set new com port setting */

        if( -1 == tcsetattr(commPort, TCSANOW, &options) )
        {
            bt_prompt_trace(MOD_BT, "[Failed] tcsetattr UART port failed");
            close(commPort);
            return 0;
        }

        return 1;
    }
#endif
} 
Beispiel #3
0
static int daemon_accept(int fd) {
    is_daemon = 1;
    int pid = read_int(fd);
    LOGD("remote pid: %d", pid);
    int atty = read_int(fd);
    LOGD("remote atty: %d", atty);
    daemon_from_uid = read_int(fd);
    LOGD("remote uid: %d", daemon_from_uid);
    daemon_from_pid = read_int(fd);
    LOGD("remote req pid: %d", daemon_from_pid);

    struct ucred credentials;
    int ucred_length = sizeof(struct ucred);
    /* fill in the user data structure */
    if(getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &credentials, &ucred_length)) {
        LOGE("could obtain credentials from unix domain socket");
        exit(-1);
    }
    // if the credentials on the other side of the wire are NOT root,
    // we can't trust anything being sent.
    if (credentials.uid != 0) {
        daemon_from_uid = credentials.uid;
        pid = credentials.pid;
        daemon_from_pid = credentials.pid;
    }

    int mount_storage = read_int(fd);
    int argc = read_int(fd);
    if (argc < 0 || argc > 512) {
        LOGE("unable to allocate args: %d", argc);
        exit(-1);
    }
    LOGD("remote args: %d", argc);
    char** argv = (char**)malloc(sizeof(char*) * (argc + 1));
    argv[argc] = NULL;
    int i;
    for (i = 0; i < argc; i++) {
        argv[i] = read_string(fd);
    }

    char errfile[PATH_MAX];
    char outfile[PATH_MAX];
    char infile[PATH_MAX];
    sprintf(outfile, "%s/%d.stdout", REQUESTOR_DAEMON_PATH, pid);
    sprintf(errfile, "%s/%d.stderr", REQUESTOR_DAEMON_PATH, pid);
    sprintf(infile, "%s/%d.stdin", REQUESTOR_DAEMON_PATH, pid);

    if (mkfifo(outfile, 0660) != 0) {
        PLOGE("mkfifo %s", outfile);
        exit(-1);
    }
    if (mkfifo(errfile, 0660) != 0) {
        PLOGE("mkfifo %s", errfile);
        exit(-1);
    }
    if (mkfifo(infile, 0660) != 0) {
        PLOGE("mkfifo %s", infile);
        exit(-1);
    }

    chown(outfile, daemon_from_uid, 0);
    chown(infile, daemon_from_uid, 0);
    chown(errfile, daemon_from_uid, 0);
    chmod(outfile, 0660);
    chmod(infile, 0660);
    chmod(errfile, 0660);

    // ack
    write_int(fd, 1);

    int ptm = -1;
    char* devname = NULL;
    if (atty) {
        ptm = open("/dev/ptmx", O_RDWR);
        if (ptm <= 0) {
            PLOGE("ptm");
            exit(-1);
        }
        if(grantpt(ptm) || unlockpt(ptm) || ((devname = (char*) ptsname(ptm)) == 0)) {
            PLOGE("ptm setup");
            close(ptm);
            exit(-1);
        }
        LOGD("devname: %s", devname);
    }

    int outfd = open(outfile, O_WRONLY);
    if (outfd <= 0) {
        PLOGE("outfd daemon %s", outfile);
        goto done;
    }
    int errfd = open(errfile, O_WRONLY);
    if (errfd <= 0) {
        PLOGE("errfd daemon %s", errfile);
        goto done;
    }
    int infd = open(infile, O_RDONLY);
    if (infd <= 0) {
        PLOGE("infd daemon %s", infile);
        goto done;
    }

    int code;
    // now fork and run main, watch for the child pid exit, and send that
    // across the control channel as the response.
    int child = fork();
    if (child < 0) {
        code = child;
        goto done;
    }

    // if this is the child, open the fifo streams
    // and dup2 them with stdin/stdout, and run main, which execs
    // the target.
    if (child == 0) {
        close(fd);

        if (devname != NULL) {
            int pts = open(devname, O_RDWR);
            if(pts < 0) {
                PLOGE("pts");
                exit(-1);
            }

            struct termios slave_orig_term_settings; // Saved terminal settings 
            tcgetattr(pts, &slave_orig_term_settings);

            struct termios new_term_settings;
            new_term_settings = slave_orig_term_settings; 
            cfmakeraw(&new_term_settings);
            // WHY DOESN'T THIS WORK, FUUUUU
            new_term_settings.c_lflag &= ~(ECHO);
            tcsetattr(pts, TCSANOW, &new_term_settings);

            setsid();
            ioctl(pts, TIOCSCTTY, 1);

            close(infd);
            close(outfd);
            close(errfd);
            close(ptm);

            errfd = pts;
            infd = pts;
            outfd = pts;
        }

#ifdef SUPERUSER_EMBEDEDED
        if (mount_storage) {
            mount_emulated_storage(multiuser_get_user_id(daemon_from_uid));
        }
#endif

        return run_daemon_child(infd, outfd, errfd, argc, argv);
    }

    if (devname != NULL) {
        // pump ptm across the socket
        pump_async(infd, ptm);
        pump(ptm, outfd);
    }
    else {
        close(infd);
        close(outfd);
        close(errfd);
    }

    // wait for the child to exit, and send the exit code
    // across the wire.
    int status;
    LOGD("waiting for child exit");
    if (waitpid(child, &status, 0) > 0) {
        code = WEXITSTATUS(status);
    }
    else {
        code = -1;
    }

done:
    write(fd, &code, sizeof(int));
    close(fd);
    LOGD("child exited");
    return code;
}
Beispiel #4
0
int close_serial_port(void){
    tcsetattr(ComFd, TCSANOW, &ComTio_Bk);
    return close(ComFd);
}
Beispiel #5
0
NFCSTATUS phDal4Nfc_uart_open_and_configure(pphDal4Nfc_sConfig_t pConfig, void ** pLinkHandle)
{
   int          nComStatus;
   NFCSTATUS    nfcret = NFCSTATUS_SUCCESS;
   int          ret;

   DAL_ASSERT_STR(gComPortContext.nOpened==0, "Trying to open but already done!");

   srand(time(NULL));

   /* open communication port handle */
   gComPortContext.nHandle = open(pConfig->deviceNode, O_RDWR | O_NOCTTY);
   if (gComPortContext.nHandle < 0)
   {
      *pLinkHandle = NULL;
      return PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_INVALID_DEVICE);
   }

   gComPortContext.nOpened = 1;
   *pLinkHandle = (void*)gComPortContext.nHandle;

   /*
    *  Now configure the com port
    */
   ret = tcgetattr(gComPortContext.nHandle, &gComPortContext.nIoConfigBackup); /* save the old io config */
   if (ret == -1)
   {
      /* tcgetattr failed -- it is likely that the provided port is invalid */
      *pLinkHandle = NULL;
      return PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_INVALID_DEVICE);
   }
   ret = fcntl(gComPortContext.nHandle, F_SETFL, 0); /* Makes the read blocking (default).  */
   DAL_ASSERT_STR(ret != -1, "fcntl failed");
   /* Configures the io */
   memset((void *)&gComPortContext.nIoConfig, (int)0, (size_t)sizeof(struct termios));
   /*
    BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed.
    CRTSCTS : output hardware flow control (only used if the cable has
              all necessary lines. See sect. 7 of Serial-HOWTO)
    CS8     : 8n1 (8bit,no parity,1 stopbit)
    CLOCAL  : local connection, no modem contol
    CREAD   : enable receiving characters
   */
   gComPortContext.nIoConfig.c_cflag = DAL_BAUD_RATE | CS8 | CLOCAL | CREAD;  /* Control mode flags */
   gComPortContext.nIoConfig.c_iflag = IGNPAR;                                          /* Input   mode flags : IGNPAR  Ignore parity errors */
   gComPortContext.nIoConfig.c_oflag = 0;                                               /* Output  mode flags */
   gComPortContext.nIoConfig.c_lflag = 0;                                               /* Local   mode flags. Read mode : non canonical, no echo */
   gComPortContext.nIoConfig.c_cc[VTIME] = 0;                                           /* Control characters. No inter-character timer */
   gComPortContext.nIoConfig.c_cc[VMIN]  = 1;                                           /* Control characters. Read is blocking until X characters are read */

   /*
      TCSANOW  Make changes now without waiting for data to complete
      TCSADRAIN   Wait until everything has been transmitted
      TCSAFLUSH   Flush input and output buffers and make the change
   */
   ret = tcsetattr(gComPortContext.nHandle, TCSANOW, &gComPortContext.nIoConfig);
   DAL_ASSERT_STR(ret != -1, "tcsetattr failed");

   /*
      On linux the DTR signal is set by default. That causes a problem for pn544 chip
      because this signal is connected to "reset". So we clear it. (on windows it is cleared by default).
   */
   ret = ioctl(gComPortContext.nHandle, TIOCMGET, &nComStatus);
   DAL_ASSERT_STR(ret != -1, "ioctl TIOCMGET failed");
   nComStatus &= ~TIOCM_DTR;
   ret = ioctl(gComPortContext.nHandle, TIOCMSET, &nComStatus);
   DAL_ASSERT_STR(ret != -1, "ioctl TIOCMSET failed");
   DAL_DEBUG("Com port status=%d\n", nComStatus);
   usleep(10000); /* Mandatory sleep so that the DTR line is ready before continuing */

   return nfcret;
}
Beispiel #6
0
//---------------------------------------------------------------------------
void OpenComms(void)
{
#if ( LIN == 1 )
	speed_t BAUD;
#endif
	const char *device = CommPortString.c_str();
	fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY);
	if (fd == -1) {
		LoggingFile.mLogFile << "failed to open port:" << endl;
		ShowMessage(device);
		CloseComms();
		return;
	}
	
	if (!isatty(fd)) {
		LoggingFile.mLogFile << "not a tty:" << endl;
		ShowMessage(device);
		CloseComms();
		return;
	}
	
	if (tcgetattr(fd, &config) < 0) {
		LoggingFile.mLogFile << "failed to get port info" << endl;
		CloseComms();
		return;
	}
	
	//
	// Input flags - Turn off input processing
	// convert break to null byte, no CR to NL translation,
	// no NL to CR translation, don't mark parity errors or breaks
	// no input parity check, don't strip high bit off,
	// no XON/XOFF software flow control
	//
	config.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | 
						INLCR | PARMRK | INPCK | ISTRIP | IXON);
	//
	// Output flags - Turn off output processing
	// no CR to NL translation, no NL to CR-NL translation,
	// no NL to CR translation, no column 0 CR suppression,
	// no Ctrl-D suppression, no fill characters, no case mapping,
	// no local output processing
	//
	// config.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
	//                     ONOCR | ONOEOT| OFILL | OLCUC | OPOST);
	config.c_oflag = 0;
	
	//
	// No line processing:
	// echo off, echo newline off, canonical mode off, 
	// extended input processing off, signal chars off
	//
	config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
	
	//
	// Turn off character processing
	// clear current char size mask, no parity checking,
	// no output processing, force 8 bit input
	//
	config.c_cflag &= ~(CSIZE | PARENB | CSTOPB);
	config.c_cflag |= CS8;
	
	//
	// One input byte is enough to return from read()
	// Inter-character timer off
	//
	config.c_cc[VMIN]  = 1;
	config.c_cc[VTIME] = 0;
	
	//
	// Communication speed (simple version, using the predefined
	// constants)
	//
#if ( LIN == 1 )
	switch (CommPortSpeed)
	      {
		case 1152000:
                  BAUD = 1152000;
		  break;
		case 1000000:
		  BAUD = 1000000;
		  break;
		case 921600:
                  BAUD = 921600;
		  break;
		case 576000:
		  BAUD = 576000;
		  break;
		case 500000:
		  BAUD = 500000;
		  break;
		case 460800:
		  BAUD = 460800;
                  break;
		case 230400:
		  BAUD = B230400;
		  break;
		case 115200:
		  BAUD = B115200;
                  break;
		case 57600:
		  BAUD = B57600;
                  break;
		 case 38400:
		    BAUD = B38400;
		    break;
		 case 19200:
		    BAUD  = B19200;
		    break;
		 case 9600:
		    BAUD  = B9600;
		    break;
		 case 4800:
		    BAUD  = B4800;
		    break;
		 case 2400:
		    BAUD  = B2400;
		    break;
		 case 1800:
		    BAUD  = B1800;
		    break;
		 case 1200:
		    BAUD  = B1200;
		    break;
		 case 600:
		    BAUD  = B600;
		    break;
		 case 300:
		    BAUD  = B300;
		    break;
		 case 200:
		    BAUD  = B200;
		    break;
		 case 150:
		    BAUD  = B150;
		    break;
		 case 134:
		    BAUD  = B134;
		    break;
		 case 110:
		    BAUD  = B110;
		    break;
		 case 75:
		    BAUD  = B75;
		    break;
		 case 50:
		    BAUD  = B50;
		    break;
		 default:
		    BAUD = B19200;
		    break;

	      }  //end of switch CommPortSpeed
	if (cfsetispeed(&config, BAUD) < 0 || cfsetospeed(&config, BAUD) < 0) {
#else
	if (cfsetispeed(&config, CommPortSpeed) < 0 || cfsetospeed(&config, CommPortSpeed) < 0) {
#endif
		LoggingFile.mLogFile << "failed to set port speed" << endl;
		CloseComms();
		return;
	}
	
	//
	// Finally, apply the configuration
	//
	if (tcsetattr(fd, TCSAFLUSH, &config) < 0) {
		LoggingFile.mLogFile << "failed to configure port" << endl;
		CloseComms();
		return;
	}
	
	LoggingFile.mLogFile << "Opened port " << device << endl;
}
//---------------------------------------------------------------------------


void CloseComms(void)
{
	if (fd != -1) {
		close(fd);
		fd = -1;
		
		LoggingFile.mLogFile << "Closed port" << endl;
	}
}
//---------------------------------------------------------------------------


void SendToComPort(unsigned long ResponseLength, unsigned char *Buffer)
{
	if (fd != -1) {
		int written = write(fd, Buffer, ResponseLength);
		
		if (written != ResponseLength) {
			LoggingFile.mLogFile << "serial write failed (" << ResponseLength << ", " << written << ")" << endl;
		}
	}
}
//---------------------------------------------------------------------------


void ReceiveFromComPort(void)
{
	unsigned long dwBytesTransferred = 0;
	char Byte = 0x00;
	
	if (fd != -1) 
	{
		// Loop for waiting for the data.
		while (read(fd, &Byte, 1) == 1)
		{
			HandleMsgByte(Byte);
		}
	}
}
Beispiel #7
0
static void restore(void)
{
	tcsetattr(STDIN_FILENO, TCSANOW, &term);
}
Beispiel #8
0
 void disable_raw()
 {
     /* Don't even check the return value as it's too late. */
     if (rawmode && tcsetattr(STDIN_FILENO,TCSAFLUSH,&orig_termios) != -1)
         rawmode = 0;
 }
Beispiel #9
0
int16 XSERDPort::open(uint16 config)
{
	// Don't open NULL name devices
	if (device_name == NULL)
		return openErr;

	// Init variables
	io_killed = false;
	quitting = false;

	// Open port, according to the syntax of the path
	if (device_name[0] == '|') {
		// Open a process via ptys
		if (!open_pty())
			goto open_error;
	}
	else if (!strcmp(device_name, "midi")) {
		// MIDI:  not yet implemented
		return openErr;
	}
	else {
		// Device special file
		fd = ::open(device_name, O_RDWR);
		if (fd < 0)
			goto open_error;

#if defined(__linux__)
		// Parallel port?
		struct stat st;
		if (fstat(fd, &st) == 0)
			if (S_ISCHR(st.st_mode))
				protocol = ((MAJOR(st.st_rdev) == LP_MAJOR) ? parallel : serial);
#elif defined(__FreeBSD__) || defined(__NetBSD__)
		// Parallel port?
		struct stat st;
		if (fstat(fd, &st) == 0)
			if (S_ISCHR(st.st_mode))
				protocol = (((st.st_rdev >> 16) == 16) ? parallel : serial);
#endif
	}

	// Configure port for raw mode
	if (protocol == serial || protocol == pty) {
		if (tcgetattr(fd, &mode) < 0)
			goto open_error;
		cfmakeraw(&mode);
		mode.c_cflag |= HUPCL;
		mode.c_cc[VMIN] = 1;
		mode.c_cc[VTIME] = 0;
		tcsetattr(fd, TCSAFLUSH, &mode);
	}
	configure(config);

	// Start input/output threads
	input_thread_cancel = false;
	output_thread_cancel = false;
	if (sem_init(&input_signal, 0, 0) < 0)
		goto open_error;
	if (sem_init(&output_signal, 0, 0) < 0)
		goto open_error;
	input_thread_active = (pthread_create(&input_thread, &thread_attr, input_func, this) == 0);
	output_thread_active = (pthread_create(&output_thread, &thread_attr, output_func, this) == 0);
	if (!input_thread_active || !output_thread_active)
		goto open_error;
	return noErr;

open_error:
	if (input_thread_active) {
		input_thread_cancel = true;
#ifdef HAVE_PTHREAD_CANCEL
		pthread_cancel(input_thread);
#endif
		pthread_join(input_thread, NULL);
		sem_destroy(&input_signal);
		input_thread_active = false;
	}
	if (output_thread_active) {
		output_thread_cancel = true;
#ifdef HAVE_PTHREAD_CANCEL
		pthread_cancel(output_thread);
#endif
		pthread_join(output_thread, NULL);
		sem_destroy(&output_signal);
		output_thread_active = false;
	}
	if (fd > 0) {
		::close(fd);
		fd = -1;
	}
	return openErr;
}
void TurtlebotTeleop::keyLoop()
{
  char c;


  // get the console in raw mode                                                              
  tcgetattr(kfd, &cooked);
  memcpy(&raw, &cooked, sizeof(struct termios));
  raw.c_lflag &=~ (ICANON | ECHO);
  // Setting a new line, then end of file                         
  raw.c_cc[VEOL] = 1;
  raw.c_cc[VEOF] = 2;
  tcsetattr(kfd, TCSANOW, &raw);

  puts("Reading from keyboard");
  puts("---------------------------");
  puts("Use arrow keys to move the turtlebot.");


  while (ros::ok())
  {
    // get the next event from the keyboard  
    if(read(kfd, &c, 1) < 0)
    {
      perror("read():");
      exit(-1);
    }


    linear_=angular_=0;
    ROS_DEBUG("value: 0x%02X\n", c);
  
    switch(c)
    {
      case KEYCODE_L:
        ROS_DEBUG("LEFT");
        angular_ = 1.0;
        break;
      case KEYCODE_R:
        ROS_DEBUG("RIGHT");
        angular_ = -1.0;
        break;
      case KEYCODE_U:
        ROS_DEBUG("UP");
        linear_ = 0.5;
        break;
      case KEYCODE_D:
        ROS_DEBUG("DOWN");
        linear_ = -0.5;
        break;
      case KEYCODE_Q:
        ROS_DEBUG("QUIT");
	linear_ = 0.0;
	angular_ = 0.0;
        break;
     }
    boost::mutex::scoped_lock lock(publish_mutex_);
    if (ros::Time::now() > last_publish_ + ros::Duration(1.0)) { 
      first_publish_ = ros::Time::now();
    }
    last_publish_ = ros::Time::now();
    publish(angular_, linear_);
    if(c==KEYCODE_Q)
      quit(SIGINT);
  }

  return;
}
void quit(int sig)
{
  tcsetattr(kfd, TCSANOW, &cooked);
  ros::shutdown();
  exit(0);
}
Beispiel #12
0
/*!
Sets the baud rate of the serial port.  Note that not all rates are applicable on
all platforms.  The following table shows translations of the various baud rate
constants on Windows(including NT/2000) and POSIX platforms.  Speeds marked with an *
are speeds that are usable on both Windows and POSIX.

\note
BAUD76800 may not be supported on all POSIX systems.  SGI/IRIX systems do not support
BAUD1800.

\verbatim

  RATE          Windows Speed   POSIX Speed
  -----------   -------------   -----------
   BAUD50                 110          50
   BAUD75                 110          75
  *BAUD110                110         110
   BAUD134                110         134.5
   BAUD150                110         150
   BAUD200                110         200
  *BAUD300                300         300
  *BAUD600                600         600
  *BAUD1200              1200        1200
   BAUD1800              1200        1800
  *BAUD2400              2400        2400
  *BAUD4800              4800        4800
  *BAUD9600              9600        9600
   BAUD14400            14400        9600
  *BAUD19200            19200       19200
  *BAUD38400            38400       38400
   BAUD56000            56000       38400
  *BAUD57600            57600       57600
   BAUD76800            57600       76800
  *BAUD115200          115200      115200
   BAUD128000          128000      115200
   BAUD256000          256000      115200
\endverbatim
*/
void QextSerialPort::setBaudRate(BaudRateType baudRate)
{
    QMutexLocker lock(mutex);
    if (Settings.BaudRate!=baudRate) {
        switch (baudRate) {
            case BAUD14400:
                Settings.BaudRate=BAUD9600;
                break;

            case BAUD56000:
                Settings.BaudRate=BAUD38400;
                break;

            case BAUD76800:

#ifndef B76800
                Settings.BaudRate=BAUD57600;
#else
                Settings.BaudRate=baudRate;
#endif
                break;

            case BAUD128000:
            case BAUD256000:
                Settings.BaudRate=BAUD115200;
                break;

            default:
                Settings.BaudRate=baudRate;
                break;
        }
    }
    if (isOpen()) {
        switch (baudRate) {

            /*50 baud*/
            case BAUD50:
                TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows does not support 50 baud operation.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B50;
#else
                cfsetispeed(&Posix_CommConfig, B50);
                cfsetospeed(&Posix_CommConfig, B50);
#endif
                break;

            /*75 baud*/
            case BAUD75:
                TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows does not support 75 baud operation.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B75;
#else
                cfsetispeed(&Posix_CommConfig, B75);
                cfsetospeed(&Posix_CommConfig, B75);
#endif
                break;

            /*110 baud*/
            case BAUD110:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B110;
#else
                cfsetispeed(&Posix_CommConfig, B110);
                cfsetospeed(&Posix_CommConfig, B110);
#endif
                break;

            /*134.5 baud*/
            case BAUD134:
                TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows does not support 134.5 baud operation.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B134;
#else
                cfsetispeed(&Posix_CommConfig, B134);
                cfsetospeed(&Posix_CommConfig, B134);
#endif
                break;

            /*150 baud*/
            case BAUD150:
                TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows does not support 150 baud operation.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B150;
#else
                cfsetispeed(&Posix_CommConfig, B150);
                cfsetospeed(&Posix_CommConfig, B150);
#endif
                break;

            /*200 baud*/
            case BAUD200:
                TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows does not support 200 baud operation.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B200;
#else
                cfsetispeed(&Posix_CommConfig, B200);
                cfsetospeed(&Posix_CommConfig, B200);
#endif
                break;

            /*300 baud*/
            case BAUD300:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B300;
#else
                cfsetispeed(&Posix_CommConfig, B300);
                cfsetospeed(&Posix_CommConfig, B300);
#endif
                break;

            /*600 baud*/
            case BAUD600:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B600;
#else
                cfsetispeed(&Posix_CommConfig, B600);
                cfsetospeed(&Posix_CommConfig, B600);
#endif
                break;

            /*1200 baud*/
            case BAUD1200:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B1200;
#else
                cfsetispeed(&Posix_CommConfig, B1200);
                cfsetospeed(&Posix_CommConfig, B1200);
#endif
                break;

            /*1800 baud*/
            case BAUD1800:
                TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows and IRIX do not support 1800 baud operation.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B1800;
#else
                cfsetispeed(&Posix_CommConfig, B1800);
                cfsetospeed(&Posix_CommConfig, B1800);
#endif
                break;

            /*2400 baud*/
            case BAUD2400:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B2400;
#else
                cfsetispeed(&Posix_CommConfig, B2400);
                cfsetospeed(&Posix_CommConfig, B2400);
#endif
                break;

            /*4800 baud*/
            case BAUD4800:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B4800;
#else
                cfsetispeed(&Posix_CommConfig, B4800);
                cfsetospeed(&Posix_CommConfig, B4800);
#endif
                break;

            /*9600 baud*/
            case BAUD9600:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B9600;
#else
                cfsetispeed(&Posix_CommConfig, B9600);
                cfsetospeed(&Posix_CommConfig, B9600);
#endif
                break;

            /*14400 baud*/
            case BAUD14400:
                TTY_WARNING("QextSerialPort: POSIX does not support 14400 baud operation.  Switching to 9600 baud.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B9600;
#else
                cfsetispeed(&Posix_CommConfig, B9600);
                cfsetospeed(&Posix_CommConfig, B9600);
#endif
                break;

            /*19200 baud*/
            case BAUD19200:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B19200;
#else
                cfsetispeed(&Posix_CommConfig, B19200);
                cfsetospeed(&Posix_CommConfig, B19200);
#endif
                break;

            /*38400 baud*/
            case BAUD38400:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B38400;
#else
                cfsetispeed(&Posix_CommConfig, B38400);
                cfsetospeed(&Posix_CommConfig, B38400);
#endif
                break;

            /*56000 baud*/
            case BAUD56000:
                TTY_WARNING("QextSerialPort: POSIX does not support 56000 baud operation.  Switching to 38400 baud.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B38400;
#else
                cfsetispeed(&Posix_CommConfig, B38400);
                cfsetospeed(&Posix_CommConfig, B38400);
#endif
                break;

            /*57600 baud*/
            case BAUD57600:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B57600;
#else
                cfsetispeed(&Posix_CommConfig, B57600);
                cfsetospeed(&Posix_CommConfig, B57600);
#endif
                break;

            /*76800 baud*/
            case BAUD76800:
                TTY_PORTABILITY_WARNING("QextSerialPort Portability Warning: Windows and some POSIX systems do not support 76800 baud operation.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);

#ifdef B76800
                Posix_CommConfig.c_cflag|=B76800;
#else
                TTY_WARNING("QextSerialPort: QextSerialPort was compiled without 76800 baud support.  Switching to 57600 baud.");
                Posix_CommConfig.c_cflag|=B57600;
#endif //B76800
#else  //CBAUD
#ifdef B76800
                cfsetispeed(&Posix_CommConfig, B76800);
                cfsetospeed(&Posix_CommConfig, B76800);
#else
                TTY_WARNING("QextSerialPort: QextSerialPort was compiled without 76800 baud support.  Switching to 57600 baud.");
                cfsetispeed(&Posix_CommConfig, B57600);
                cfsetospeed(&Posix_CommConfig, B57600);
#endif //B76800
#endif //CBAUD
                break;

            /*115200 baud*/
            case BAUD115200:
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B115200;
#else
                cfsetispeed(&Posix_CommConfig, B115200);
                cfsetospeed(&Posix_CommConfig, B115200);
#endif
                break;

            /*128000 baud*/
            case BAUD128000:
                TTY_WARNING("QextSerialPort: POSIX does not support 128000 baud operation.  Switching to 115200 baud.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B115200;
#else
                cfsetispeed(&Posix_CommConfig, B115200);
                cfsetospeed(&Posix_CommConfig, B115200);
#endif
                break;

            /*256000 baud*/
            case BAUD256000:
                TTY_WARNING("QextSerialPort: POSIX does not support 256000 baud operation.  Switching to 115200 baud.");
#ifdef CBAUD
                Posix_CommConfig.c_cflag&=(~CBAUD);
                Posix_CommConfig.c_cflag|=B115200;
#else
                cfsetispeed(&Posix_CommConfig, B115200);
                cfsetospeed(&Posix_CommConfig, B115200);
#endif
                break;
        }
        tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig);
    }
}
Beispiel #13
0
/*!
Sets the parity associated with the serial port.  The possible values of parity are:
\verbatim
    PAR_SPACE       Space Parity
    PAR_MARK        Mark Parity
    PAR_NONE        No Parity
    PAR_EVEN        Even Parity
    PAR_ODD         Odd Parity
\endverbatim

\note
This function is subject to the following limitations:
\par
POSIX systems do not support mark parity.
\par
POSIX systems support space parity only if tricked into doing so, and only with
   fewer than 8 data bits.  Use space parity very carefully with POSIX systems.
*/
void QextSerialPort::setParity(ParityType parity)
{
    QMutexLocker lock(mutex);
    if (Settings.Parity!=parity) {
        if (parity==PAR_MARK || (parity==PAR_SPACE && Settings.DataBits==DATA_8)) {
        }
        else {
            Settings.Parity=parity;
        }
    }
    if (isOpen()) {
        switch (parity) {

            /*space parity*/
            case PAR_SPACE:
                if (Settings.DataBits==DATA_8) {
                    TTY_PORTABILITY_WARNING("QextSerialPort:  Space parity is only supported in POSIX with 7 or fewer data bits");
                }
                else {

                    /*space parity not directly supported - add an extra data bit to simulate it*/
                    Posix_CommConfig.c_cflag&=~(PARENB|CSIZE);
                    switch(Settings.DataBits) {
                        case DATA_5:
                            Settings.DataBits=DATA_6;
                            Posix_CommConfig.c_cflag|=CS6;
                            break;

                        case DATA_6:
                            Settings.DataBits=DATA_7;
                            Posix_CommConfig.c_cflag|=CS7;
                            break;

                        case DATA_7:
                            Settings.DataBits=DATA_8;
                            Posix_CommConfig.c_cflag|=CS8;
                            break;

                        case DATA_8:
                            break;
                    }
                    tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig);
                }
                break;

            /*mark parity - WINDOWS ONLY*/
            case PAR_MARK:
                TTY_WARNING("QextSerialPort: Mark parity is not supported by POSIX.");
                break;

            /*no parity*/
            case PAR_NONE:
                Posix_CommConfig.c_cflag&=(~PARENB);
                tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig);
                break;

            /*even parity*/
            case PAR_EVEN:
                Posix_CommConfig.c_cflag&=(~PARODD);
                Posix_CommConfig.c_cflag|=PARENB;
                tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig);
                break;

            /*odd parity*/
            case PAR_ODD:
                Posix_CommConfig.c_cflag|=(PARENB|PARODD);
                tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig);
                break;
        }
    }
}
Beispiel #14
0
/*!
Sets the number of data bits used by the serial port.  Possible values of dataBits are:
\verbatim
    DATA_5      5 data bits
    DATA_6      6 data bits
    DATA_7      7 data bits
    DATA_8      8 data bits
\endverbatim

\note
This function is subject to the following restrictions:
\par
    5 data bits cannot be used with 2 stop bits.
\par
    8 data bits cannot be used with space parity on POSIX systems.
*/
void QextSerialPort::setDataBits(DataBitsType dataBits)
{
    QMutexLocker lock(mutex);
    if (Settings.DataBits!=dataBits) {
        if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) ||
            (Settings.StopBits==STOP_1_5 && dataBits!=DATA_5) ||
            (Settings.Parity==PAR_SPACE && dataBits==DATA_8)) {
        }
        else {
            Settings.DataBits=dataBits;
        }
    }
    if (isOpen()) {
        switch(dataBits) {

            /*5 data bits*/
            case DATA_5:
                if (Settings.StopBits==STOP_2) {
                    TTY_WARNING("QextSerialPort: 5 Data bits cannot be used with 2 stop bits.");
                }
                else {
                    Settings.DataBits=dataBits;
                    Posix_CommConfig.c_cflag&=(~CSIZE);
                    Posix_CommConfig.c_cflag|=CS5;
                    tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig);
                }
                break;

            /*6 data bits*/
            case DATA_6:
                if (Settings.StopBits==STOP_1_5) {
                    TTY_WARNING("QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits.");
                }
                else {
                    Settings.DataBits=dataBits;
                    Posix_CommConfig.c_cflag&=(~CSIZE);
                    Posix_CommConfig.c_cflag|=CS6;
                    tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig);
                }
                break;

            /*7 data bits*/
            case DATA_7:
                if (Settings.StopBits==STOP_1_5) {
                    TTY_WARNING("QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits.");
                }
                else {
                    Settings.DataBits=dataBits;
                    Posix_CommConfig.c_cflag&=(~CSIZE);
                    Posix_CommConfig.c_cflag|=CS7;
                    tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig);
                }
                break;

            /*8 data bits*/
            case DATA_8:
                if (Settings.StopBits==STOP_1_5) {
                    TTY_WARNING("QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits.");
                }
                else {
                    Settings.DataBits=dataBits;
                    Posix_CommConfig.c_cflag&=(~CSIZE);
                    Posix_CommConfig.c_cflag|=CS8;
                    tcsetattr(fd, TCSAFLUSH, &Posix_CommConfig);
                }
                break;
        }
    }
}
Beispiel #15
0
static void             /* Reset terminal mode on program exit */
ttyReset(void)
{
    if (tcsetattr(STDIN_FILENO, TCSANOW, &ttyOrig) == -1)
        errExit("tcsetattr");
}
Beispiel #16
0
int16 XSERDPort::control(uint32 pb, uint32 dce, uint16 code)
{
	switch (code) {
		case 1:			// KillIO
			io_killed = true;
			if (protocol == serial)
				tcflush(fd, TCIOFLUSH);
			while (read_pending || write_pending)
				usleep(10000);
			io_killed = false;
			return noErr;

		case kSERDConfiguration:
			if (configure(ReadMacInt16(pb + csParam)))
				return noErr;
			else
				return paramErr;

		case kSERDInputBuffer:
			return noErr;	// Not supported under Unix

		case kSERDSerHShake:
			set_handshake(pb + csParam, false);
			return noErr;

		case kSERDSetBreak:
			if (protocol == serial)
				tcsendbreak(fd, 0);
			return noErr;

		case kSERDClearBreak:
			return noErr;

		case kSERDBaudRate: {
			if (protocol != serial)
				return noErr;
			uint16 rate = ReadMacInt16(pb + csParam);
			speed_t baud_rate;
			if (rate <= 50) {
				rate = 50; baud_rate = B50;
			} else if (rate <= 75) {
				rate = 75; baud_rate = B75;
			} else if (rate <= 110) {
				rate = 110; baud_rate = B110;
			} else if (rate <= 134) {
				rate = 134; baud_rate = B134;
			} else if (rate <= 150) {
				rate = 150; baud_rate = B150;
			} else if (rate <= 200) {
				rate = 200; baud_rate = B200;
			} else if (rate <= 300) {
				rate = 300; baud_rate = B300;
			} else if (rate <= 600) {
				rate = 600; baud_rate = B600;
			} else if (rate <= 1200) {
				rate = 1200; baud_rate = B1200;
			} else if (rate <= 1800) {
				rate = 1800; baud_rate = B1800;
			} else if (rate <= 2400) {
				rate = 2400; baud_rate = B2400;
			} else if (rate <= 4800) {
				rate = 4800; baud_rate = B4800;
			} else if (rate <= 9600) {
				rate = 9600; baud_rate = B9600;
			} else if (rate <= 19200) {
				rate = 19200; baud_rate = B19200;
			} else if (rate <= 38400) {
				rate = 38400; baud_rate = B38400;
			} else if (rate <= 57600) {
				rate = 57600; baud_rate = B57600;
			} else {
				// Just for safety in case someone wants a rate between 57600 and 65535
				rate = 57600; baud_rate = B57600;
			}
			WriteMacInt16(pb + csParam, rate);
			cfsetispeed(&mode, baud_rate);
			cfsetospeed(&mode, baud_rate);
			tcsetattr(fd, TCSANOW, &mode);
			return noErr;
		}

		case kSERDHandshake:
		case kSERDHandshakeRS232:
			set_handshake(pb + csParam, true);
			return noErr;

		case kSERDMiscOptions:
			if (protocol != serial)
				return noErr;
			if (ReadMacInt8(pb + csParam) & kOptionPreserveDTR)
				mode.c_cflag &= ~HUPCL;
			else
				mode.c_cflag |= HUPCL;
			tcsetattr(fd, TCSANOW, &mode);
			return noErr;

		case kSERDAssertDTR: {
			if (protocol != serial)
				return noErr;
			unsigned int status = TIOCM_DTR;
			ioctl(fd, TIOCMBIS, &status);
			return noErr;
		}

		case kSERDNegateDTR: {
			if (protocol != serial)
				return noErr;
			unsigned int status = TIOCM_DTR;
			ioctl(fd, TIOCMBIC, &status);
			return noErr;
		}

		case kSERDSetPEChar:
		case kSERDSetPEAltChar:
			return noErr;	// Not supported under Unix

		case kSERDResetChannel:
			if (protocol == serial)
				tcflush(fd, TCIOFLUSH);
			return noErr;

		case kSERDAssertRTS: {
			if (protocol != serial)
				return noErr;
			unsigned int status = TIOCM_RTS;
			ioctl(fd, TIOCMBIS, &status);
			return noErr;
		}

		case kSERDNegateRTS: {
			if (protocol != serial)
				return noErr;
			unsigned int status = TIOCM_RTS;
			ioctl(fd, TIOCMBIC, &status);
			return noErr;
		}

		case kSERD115KBaud:
			if (protocol != serial)
				return noErr;
			cfsetispeed(&mode, B115200);
			cfsetospeed(&mode, B115200);
			tcsetattr(fd, TCSANOW, &mode);
			return noErr;

		case kSERD230KBaud:
		case kSERDSetHighSpeed:
			if (protocol != serial)
				return noErr;
			cfsetispeed(&mode, B230400);
			cfsetospeed(&mode, B230400);
			tcsetattr(fd, TCSANOW, &mode);
			return noErr;

		default:
			printf("WARNING: SerialControl(): unimplemented control code %d\n", code);
			return controlErr;
	}
}
Beispiel #17
0
int
pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
{
#if defined(HAVE_OPENPTY) || defined(BSD4_4)
	/* openpty(3) exists in OSF/1 and some other os'es */
	char *name;
	int i;

	i = openpty(ptyfd, ttyfd, NULL, NULL, NULL);
	if (i < 0) {
		error("openpty: %.100s", strerror(errno));
		return 0;
	}
	name = ttyname(*ttyfd);
	if (!name)
		fatal("openpty returns device for which ttyname fails.");

	strlcpy(namebuf, name, namebuflen);	/* possible truncation */
	return 1;
#else /* HAVE_OPENPTY */
#ifdef HAVE__GETPTY
	/*
	 * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
	 * pty's automagically when needed
	 */
	char *slave;

	slave = _getpty(ptyfd, O_RDWR, 0622, 0);
	if (slave == NULL) {
		error("_getpty: %.100s", strerror(errno));
		return 0;
	}
	strlcpy(namebuf, slave, namebuflen);
	/* Open the slave side. */
	*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
	if (*ttyfd < 0) {
		error("%.200s: %.100s", namebuf, strerror(errno));
		close(*ptyfd);
		return 0;
	}
	return 1;
#else /* HAVE__GETPTY */
#if defined(HAVE_DEV_PTMX)
	/*
	 * This code is used e.g. on Solaris 2.x.  (Note that Solaris 2.3
	 * also has bsd-style ptys, but they simply do not work.)
	 */
	int ptm;
	char *pts;
	mysig_t old_signal;

	ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY);
	if (ptm < 0) {
		error("/dev/ptmx: %.100s", strerror(errno));
		return 0;
	}
	old_signal = mysignal(SIGCHLD, SIG_DFL);
	if (grantpt(ptm) < 0) {
		error("grantpt: %.100s", strerror(errno));
		return 0;
	}
	mysignal(SIGCHLD, old_signal);
	if (unlockpt(ptm) < 0) {
		error("unlockpt: %.100s", strerror(errno));
		return 0;
	}
	pts = ptsname(ptm);
	if (pts == NULL)
		error("Slave pty side name could not be obtained.");
	strlcpy(namebuf, pts, namebuflen);
	*ptyfd = ptm;

	/* Open the slave side. */
	*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
	if (*ttyfd < 0) {
		error("%.100s: %.100s", namebuf, strerror(errno));
		close(*ptyfd);
		return 0;
	}
#ifndef HAVE_CYGWIN
	/*
	 * Push the appropriate streams modules, as described in Solaris pts(7).
	 * HP-UX pts(7) doesn't have ttcompat module.
	 */
	if (ioctl(*ttyfd, I_PUSH, "ptem") < 0)
		error("ioctl I_PUSH ptem: %.100s", strerror(errno));
	if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0)
		error("ioctl I_PUSH ldterm: %.100s", strerror(errno));
#ifndef __hpux
	if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0)
		error("ioctl I_PUSH ttcompat: %.100s", strerror(errno));
#endif
#endif
	return 1;
#else /* HAVE_DEV_PTMX */
#ifdef HAVE_DEV_PTS_AND_PTC
	/* AIX-style pty code. */
	const char *name;

	*ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY);
	if (*ptyfd < 0) {
		error("Could not open /dev/ptc: %.100s", strerror(errno));
		return 0;
	}
	name = ttyname(*ptyfd);
	if (!name)
		fatal("Open of /dev/ptc returns device for which ttyname fails.");
	strlcpy(namebuf, name, namebuflen);
	*ttyfd = open(name, O_RDWR | O_NOCTTY);
	if (*ttyfd < 0) {
		error("Could not open pty slave side %.100s: %.100s",
		    name, strerror(errno));
		close(*ptyfd);
		return 0;
	}
	return 1;
#else /* HAVE_DEV_PTS_AND_PTC */
#ifdef _UNICOS
	char buf[64];
	int i;
	int highpty;

#ifdef _SC_CRAY_NPTY
	highpty = sysconf(_SC_CRAY_NPTY);
	if (highpty == -1)
		highpty = 128;
#else
	highpty = 128;
#endif

	for (i = 0; i < highpty; i++) {
		snprintf(buf, sizeof(buf), "/dev/pty/%03d", i);
		*ptyfd = open(buf, O_RDWR|O_NOCTTY);
		if (*ptyfd < 0)
			continue;
		snprintf(namebuf, namebuflen, "/dev/ttyp%03d", i);
		/* Open the slave side. */
		*ttyfd = open(namebuf, O_RDWR|O_NOCTTY);
		if (*ttyfd < 0) {
			error("%.100s: %.100s", namebuf, strerror(errno));
			close(*ptyfd);
			return 0;
		}
		return 1;
	}
	return 0;
#else
	/* BSD-style pty code. */
	char buf[64];
	int i;
	const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
	const char *ptyminors = "0123456789abcdef";
	int num_minors = strlen(ptyminors);
	int num_ptys = strlen(ptymajors) * num_minors;
	struct termios tio;

	for (i = 0; i < num_ptys; i++) {
		snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors],
			 ptyminors[i % num_minors]);
		snprintf(namebuf, namebuflen, "/dev/tty%c%c",
		    ptymajors[i / num_minors], ptyminors[i % num_minors]);

		*ptyfd = open(buf, O_RDWR | O_NOCTTY);
		if (*ptyfd < 0) {
			/* Try SCO style naming */
			snprintf(buf, sizeof buf, "/dev/ptyp%d", i);
			snprintf(namebuf, namebuflen, "/dev/ttyp%d", i);
			*ptyfd = open(buf, O_RDWR | O_NOCTTY);
			if (*ptyfd < 0)
				continue;
		}

		/* Open the slave side. */
		*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
		if (*ttyfd < 0) {
			error("%.100s: %.100s", namebuf, strerror(errno));
			close(*ptyfd);
			return 0;
		}
		/* set tty modes to a sane state for broken clients */
		if (tcgetattr(*ptyfd, &tio) < 0)
			log("Getting tty modes for pty failed: %.100s", strerror(errno));
		else {
			tio.c_lflag |= (ECHO | ISIG | ICANON);
			tio.c_oflag |= (OPOST | ONLCR);
			tio.c_iflag |= ICRNL;

			/* Set the new modes for the terminal. */
			if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0)
				log("Setting tty modes for pty failed: %.100s", strerror(errno));
		}

		return 1;
	}
	return 0;
#endif /* CRAY */
#endif /* HAVE_DEV_PTS_AND_PTC */
#endif /* HAVE_DEV_PTMX */
#endif /* HAVE__GETPTY */
#endif /* HAVE_OPENPTY */
}
Beispiel #18
0
bool XSERDPort::configure(uint16 config)
{
	D(bug(" configure %04x\n", config));
	if (protocol != serial)
		return true;

	// Set number of stop bits
	switch (config & 0xc000) {
		case stop10:
			mode.c_cflag &= ~CSTOPB;
			break;
		case stop20:
			mode.c_cflag |= CSTOPB;
			break;
		default:
			return false;
	}

	// Set parity mode
	switch (config & 0x3000) {
		case noParity:
			mode.c_iflag &= ~INPCK;
			mode.c_oflag &= ~PARENB;
			break;
		case oddParity:
			mode.c_iflag |= INPCK;
			mode.c_oflag |= PARENB;
			mode.c_oflag |= PARODD;
			break;
		case evenParity:
			mode.c_iflag |= INPCK;
			mode.c_oflag |= PARENB;
			mode.c_oflag &= ~PARODD;
			break;
		default:
			return false;
	}

	// Set number of data bits
	switch (config & 0x0c00) {
		case data5:
			mode.c_cflag = mode.c_cflag & ~CSIZE | CS5;
			break;
		case data6:
			mode.c_cflag = mode.c_cflag & ~CSIZE | CS6;
			break;
		case data7:
			mode.c_cflag = mode.c_cflag & ~CSIZE | CS7;
			break;
		case data8:
			mode.c_cflag = mode.c_cflag & ~CSIZE | CS8;
			break;
	}

	// Set baud rate
	speed_t baud_rate;
	switch (config & 0x03ff) {
		case baud150: baud_rate = B150; break;
		case baud300: baud_rate = B300; break;
		case baud600: baud_rate = B600; break;
		case baud1200: baud_rate = B1200; break;
		case baud1800: baud_rate = B1800; break;
		case baud2400: baud_rate = B2400; break;
		case baud4800: baud_rate = B4800; break;
		case baud9600: baud_rate = B9600; break;
		case baud19200: baud_rate = B19200; break;
		case baud38400: baud_rate = B38400; break;
		case baud57600: baud_rate = B57600; break;
		default:
			return false;
	}
	cfsetispeed(&mode, baud_rate);
	cfsetospeed(&mode, baud_rate);
	tcsetattr(fd, TCSANOW, &mode);
	return true;
}
Beispiel #19
0
int main(int argc, char *argv[])
{
	int o;
	unsigned short old_rows;
	struct slab_info *slab_list = NULL;
	int run_once = 0, retval = EXIT_SUCCESS;

	static const struct option longopts[] = {
		{ "delay",	required_argument, NULL, 'd' },
		{ "sort",	required_argument, NULL, 's' },
		{ "once",	no_argument,	   NULL, 'o' },
		{ "help",	no_argument,	   NULL, 'h' },
		{ "version",	no_argument,	   NULL, 'V' },
		{  NULL, 0, NULL, 0 }
	};

#ifdef HAVE_PROGRAM_INVOCATION_NAME
	program_invocation_name = program_invocation_short_name;
#endif
	setlocale (LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	sort_func = DEF_SORT_FUNC;

	while ((o = getopt_long(argc, argv, "d:s:ohV", longopts, NULL)) != -1) {
		switch (o) {
		case 'd':
			errno = 0;
			delay = strtol_or_err(optarg, _("illegal delay"));
			if (delay < 1)
				xerrx(EXIT_FAILURE,
					_("delay must be positive integer"));
			break;
		case 's':
			sort_func = (int (*)(const struct slab_info*,
				const struct slab_info *)) set_sort_func(optarg[0]);
			break;
		case 'o':
			run_once=1;
			delay = 0;
			break;
		case 'V':
			printf(PROCPS_NG_VERSION);
			return EXIT_SUCCESS;
		case 'h':
			usage(stdout);
		default:
			usage(stderr);
		}
	}

	if (tcgetattr(STDIN_FILENO, &saved_tty) == -1)
		xwarn(_("terminal setting retrieval"));

	old_rows = rows;
	term_size(0);
	if (!run_once) {
		initscr();
		resizeterm(rows, cols);
		signal(SIGWINCH, term_size);
	}
	signal(SIGINT, sigint_handler);

	do {
		struct slab_info *curr;
		struct slab_stat stats;
		struct timeval tv;
		fd_set readfds;
		char c;
		int i;
		memset(&stats, 0, sizeof(struct slab_stat));

		if (get_slabinfo(&slab_list, &stats)) {
			retval = EXIT_FAILURE;
			break;
		}

		if (!run_once && old_rows != rows) {
			resizeterm(rows, cols);
			old_rows = rows;
		}

		move(0, 0);
		print_line(" %-35s: %d / %d (%.1f%%)\n"
		       " %-35s: %d / %d (%.1f%%)\n"
		       " %-35s: %d / %d (%.1f%%)\n"
		       " %-35s: %.2fK / %.2fK (%.1f%%)\n"
		       " %-35s: %.2fK / %.2fK / %.2fK\n\n",
		       /* Translation Hint: Next five strings must not
			* exceed 35 length in characters.  */
		       /* xgettext:no-c-format */
		       _("Active / Total Objects (% used)"),
		       stats.nr_active_objs, stats.nr_objs,
		       100.0 * stats.nr_active_objs / stats.nr_objs,
	               /* xgettext:no-c-format */
		       _("Active / Total Slabs (% used)"),
		       stats.nr_active_slabs, stats.nr_slabs,
		       100.0 * stats.nr_active_slabs / stats.nr_slabs,
	               /* xgettext:no-c-format */
		       _("Active / Total Caches (% used)"),
		       stats.nr_active_caches, stats.nr_caches,
		       100.0 * stats.nr_active_caches / stats.nr_caches,
	               /* xgettext:no-c-format */
		       _("Active / Total Size (% used)"),
		       stats.active_size / 1024.0, stats.total_size / 1024.0,
		       100.0 * stats.active_size / stats.total_size,
		       _("Minimum / Average / Maximum Object"),
		       stats.min_obj_size / 1024.0, stats.avg_obj_size / 1024.0,
		       stats.max_obj_size / 1024.0);

		slab_list = slabsort(slab_list);

		attron(A_REVERSE);
		/* Translation Hint: Please keep alignment of the
		 * following intact. */
		print_line("%-78s\n", _("  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME"));
		attroff(A_REVERSE);

		curr = slab_list;
		for (i = 0; i < rows - 8 && curr->next; i++) {
			print_line("%6u %6u %3u%% %7.2fK %6u %8u %9uK %-23s\n",
				curr->nr_objs, curr->nr_active_objs, curr->use,
				curr->obj_size / 1024.0, curr->nr_slabs,
				curr->objs_per_slab, (unsigned)(curr->cache_size / 1024),
				curr->name);
			curr = curr->next;
		}

		put_slabinfo(slab_list);
		if (!run_once) {
			refresh();
			FD_ZERO(&readfds);
			FD_SET(STDIN_FILENO, &readfds);
			tv.tv_sec = delay;
			tv.tv_usec = 0;
			if (select(STDOUT_FILENO, &readfds, NULL, NULL, &tv) > 0) {
				if (read(STDIN_FILENO, &c, 1) != 1)
					break;
				parse_input(c);
			}
		}
	} while (delay);

	tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_tty);
	free_slabinfo(slab_list);
	if (!run_once)
		endwin();
	return retval;
}
Beispiel #20
0
int
openpty (int *amaster, int *aslave, char *name,
         struct termios const *termp, struct winsize const *winp)
{
  int master;
  char *slave_name;
  int slave;

# if HAVE__GETPTY /* IRIX */

  slave_name = _getpty (&master, O_RDWR, 0622, 0);
  if (slave_name == NULL)
    return -1;

# else /* AIX 5.1, HP-UX 11, Solaris 10, mingw */

#  if HAVE_POSIX_OPENPT /* Solaris 10 */

  master = posix_openpt (O_RDWR | O_NOCTTY);
  if (master < 0)
    return -1;

#  else /* AIX 5.1, HP-UX 11, Solaris 9, mingw */

#   ifdef _AIX /* AIX */

  master = open ("/dev/ptc", O_RDWR | O_NOCTTY);
  if (master < 0)
    return -1;

#   else /* HP-UX 11, Solaris 9, mingw */

  /* HP-UX, Solaris have /dev/ptmx.
     HP-UX also has /dev/ptym/clone, but this should not be needed.
     Linux also has /dev/ptmx, but Linux already has openpty().
     MacOS X also has /dev/ptmx, but MacOS X already has openpty().
     OSF/1 also has /dev/ptmx and /dev/ptmx_bsd, but OSF/1 already has
     openpty().  */
  master = open ("/dev/ptmx", O_RDWR | O_NOCTTY);
  if (master < 0)
    return -1;

#   endif

#  endif

  /* If all this does not work, we could try to open, one by one:
     - On MacOS X: /dev/pty[p-w][0-9a-f]
     - On *BSD:    /dev/pty[p-sP-S][0-9a-v]
     - On AIX:     /dev/ptyp[0-9a-f]
     - On HP-UX:   /dev/pty[p-r][0-9a-f]
     - On OSF/1:   /dev/pty[p-q][0-9a-f]
     - On Solaris: /dev/pty[p-r][0-9a-f]
   */
# endif

  /* This call does not require a dependency to the 'grantpt' module,
     because AIX, HP-UX, IRIX, Solaris all have the grantpt() function.  */
  if (grantpt (master))
    goto fail;

  /* This call does not require a dependency to the 'unlockpt' module,
     because AIX, HP-UX, IRIX, Solaris all have the unlockpt() function.  */
  if (unlockpt (master))
    goto fail;

# if !HAVE__GETPTY /* !IRIX */
  slave_name = ptsname (master);
  if (slave_name == NULL)
    goto fail;
# endif

  slave = open (slave_name, O_RDWR | O_NOCTTY);
  if (slave == -1)
    goto fail;

# if defined __sun || defined __hpux /* Solaris, HP-UX */
  if (ioctl (slave, I_PUSH, "ptem") < 0
      || ioctl (slave, I_PUSH, "ldterm") < 0
#  if defined __sun
      || ioctl (slave, I_PUSH, "ttcompat") < 0
#  endif
     )
    {
      close (slave);
      goto fail;
    }
# endif

  /* XXX Should we ignore errors here?  */
  if (termp)
    tcsetattr (slave, TCSAFLUSH, termp);
  if (winp)
    ioctl (slave, TIOCSWINSZ, winp);

  *amaster = master;
  *aslave = slave;
  if (name != NULL)
    strcpy (name, slave_name);

  return 0;

 fail:
  close (master);
  return -1;
}
Beispiel #21
0
int main(int argc, char **argv)
{
	int vfd, afd, c;
	int filefd;
	const char *videodev = "/dev/dvb/adapter0/video0";
	const char *audiodev = "/dev/dvb/adapter0/audio0";

	if (((tcgetpgrp(STDIN_FILENO) == getpid()) || (getppid() != (pid_t)1))
	    && (tcgetattr(STDIN_FILENO, &term) == 0)) {
		struct termios newterm;
		memcpy(&newterm, &term, sizeof(struct termios));
		newterm.c_iflag = 0;
		newterm.c_lflag &= ~(ICANON | ECHO);
		newterm.c_cc[VMIN] = 0;
		newterm.c_cc[VTIME] = 0;
		atexit(restore);
		tcsetattr(STDIN_FILENO, TCSANOW, &newterm);
	}

	opterr = 0;
	while ((c = getopt(argc, argv, "+daA")) != -1) {
		switch (c) {
		case 'd':
			dolby++;
			break;
		case 'a':
			audio++;
			break;
		case 'A':
			audio++;
			black++;
			break;
		case '?':
			fprintf(stderr, "usage: test_av_play [-d] [-a] [-A] mpeg_A+V_PES_file\n");
			return 1;
		default:
			break;
		}
	}
	argv += optind;
	argc -= optind;

	if (getenv("VIDEO"))
		videodev = getenv("VIDEO");
	if (getenv("AUDIO"))
		audiodev = getenv("AUDIO");

	printf("using video device '%s'\n", videodev);
	printf("using audio device '%s'\n", audiodev);

	putchar('\n');

	printf("Freeze       by pressing `z'\n");
	printf("Stop         by pressing `s'\n");
	printf("Continue     by pressing `c'\n");
	printf("Start        by pressing `p'\n");
	printf("FastForward  by pressing `f'\n");
	printf("Mute         by pressing `m'\n");
	printf("UnMute       by pressing `u'\n");
	printf("MP2/AC3      by pressing `d'\n");
	printf("SlowMotion   by pressing `l'\n");
	printf("Quit         by pressing `q'\n");

	putchar('\n');

	errno = ENOENT;
	if (!argv[0] || (filefd = open(argv[0], O_RDONLY)) < 0) {
		perror("File open:");
		return -1;
	}
	if ((vfd = open(videodev,O_RDWR|O_NONBLOCK)) < 0) {
		perror("VIDEO DEVICE: ");
		return -1;
	}
	if ((afd = open(audiodev,O_RDWR|O_NONBLOCK)) < 0) {
		perror("AUDIO DEVICE: ");
		return -1;
	}

	play_file_av(filefd, vfd, afd);
	close(vfd);
	close(afd);
	close(filefd);
	return 0;
}
Beispiel #22
0
/*	Restore terminal settings
 *	@param Old settings
 */
void BarTermRestore (struct termios *termOrig) {
	tcsetattr (fileno (stdin), TCSANOW, termOrig);
}
Beispiel #23
0
int microcom_main(int argc, char **argv)
{
	struct pollfd pfd[2];
#define sfd (pfd[1].fd)
	char *device_lock_file = NULL;
	const char *s;
	const char *opt_s = "9600";
	unsigned speed;
	int len;
	int exitcode = 1;
	struct termios tio0, tiosfd, tio;

	getopt32(argv, "s:", &opt_s);
	argc -= optind;
	argv += optind;
	if (!argv[0])
		bb_show_usage();
	speed = xatou(opt_s);

	// try to create lock file in /var/lock
	s = bb_basename(argv[0]);
	if (!s[0]) {
		errno = ENODEV;
		bb_perror_msg_and_die("can't lock device");
	}
	device_lock_file = xasprintf("/var/lock/LCK..%s", s);
	sfd = open(device_lock_file, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0644);
	if (sfd < 0) {
		if (ENABLE_FEATURE_CLEAN_UP)
			free(device_lock_file);
		device_lock_file = NULL;
		if (errno == EEXIST)
			bb_perror_msg_and_die("can't lock device");
		// We don't abort on other errors: /var/lock can be
		// non-writable or non-existent
	} else {
		// %4d to make mgetty happy. It treats 4-bytes lock files as binary,
		// not text, PID. Making 5+ char file. Brrr...
		s = xasprintf("%4d\n", getpid());
		write(sfd, s, strlen(s));
		if (ENABLE_FEATURE_CLEAN_UP)
			free((char*)s);
		close(sfd);
	}

	// open device
	sfd = open(argv[0], O_RDWR);
	if (sfd < 0) {
		bb_perror_msg("can't open device");
		goto unlock_and_exit;
	}

	// put stdin to "raw mode", handle one character at a time
	tcgetattr(STDIN_FILENO, &tio0);
	tio = tio0;
	tio.c_lflag &= ~(ICANON|ECHO);
	tio.c_iflag &= ~(IXON|ICRNL);
	tio.c_oflag &= ~(ONLCR);
	tio.c_cc[VMIN] = 1;
	tio.c_cc[VTIME] = 0;
	if (tcsetattr(STDIN_FILENO, TCSANOW, &tio)) {
		bb_perror_msg("can't tcsetattr for %s", "stdin");
		goto unlock_and_exit;
	}

	/* same thing for modem (plus: set baud rate) - TODO: make CLI option */
	tcgetattr(sfd, &tiosfd);
	tio = tiosfd;
	tio.c_lflag &= ~(ICANON|ECHO);
	tio.c_iflag &= ~(IXON|ICRNL);
	tio.c_oflag &= ~(ONLCR);
	tio.c_cc[VMIN] = 1;
	tio.c_cc[VTIME] = 0;
	cfsetispeed(&tio, tty_value_to_baud(speed));
	cfsetospeed(&tio, tty_value_to_baud(speed));
	if (tcsetattr(sfd, TCSANOW, &tio)) {
		bb_perror_msg("can't tcsetattr for %s", "device");
		goto unlock_and_exit;
	}

	// disable SIGINT
	signal(SIGINT, SIG_IGN);

	// drain stdin
	tcflush(STDIN_FILENO, TCIFLUSH);
	printf("connected to '%s' (%d bps), exit with ctrl-X...\r\n", argv[0], speed);

	// main loop: check with poll(), then read/write bytes across
	pfd[0].fd = STDIN_FILENO;
	pfd[0].events = POLLIN;
	/*pfd[1].fd = sfd;*/
	pfd[1].events = POLLIN;
	while (1) {
		int i;
		safe_poll(pfd, 2, -1);
		for (i = 0; i < 2; ++i) {
			if (pfd[i].revents & POLLIN) {
				len = read(pfd[i].fd, bb_common_bufsiz1, COMMON_BUFSIZE);
				if (len > 0) {
					if (!i && 24 == bb_common_bufsiz1[0])
						goto done; // ^X exits
					write(pfd[1-i].fd, bb_common_bufsiz1, len);
				}
			}
		}
	}
 done:
	tcsetattr(sfd, TCSANOW, &tiosfd);
	tcsetattr(STDIN_FILENO, TCSANOW, &tio0);
	tcflush(STDIN_FILENO, TCIFLUSH);

	if (ENABLE_FEATURE_CLEAN_UP)
		close(sfd);
	exitcode = 0;

 unlock_and_exit:
	// delete lock file
	if (device_lock_file) {
		unlink(device_lock_file);
		if (ENABLE_FEATURE_CLEAN_UP)
			free(device_lock_file);
	}
	return exitcode;
}
Beispiel #24
0
int rlSerial::openDevice(const char *devicename, int speed, int block, int rtscts, int bits, int stopbits, int parity)
{
#ifdef RLUNIX
  struct termios buf;

  if(fd != -1) return -1;
  fd = open(devicename, O_RDWR | O_NOCTTY | O_NDELAY);
  if(fd < 0) { return -1; }

  //signal(SIGINT, sighandler);

  if(tcgetattr(fd, &save_termios) < 0) { return -1; }
  buf = save_termios;
  buf.c_cflag = speed | CLOCAL | CREAD;
  if(rtscts   == 1)  buf.c_cflag |= CRTSCTS;
  if(bits     == 7)  buf.c_cflag |= CS7;
  else               buf.c_cflag |= CS8;
  if(stopbits == 2)  buf.c_cflag |= CSTOPB;
  if(parity == rlSerial::ODD)  buf.c_cflag |= (PARENB | PARODD);
  if(parity == rlSerial::EVEN) buf.c_cflag |= PARENB;
  buf.c_lflag = IEXTEN; //ICANON;
  buf.c_oflag     = OPOST;
  buf.c_cc[VMIN]  = 1;
  buf.c_cc[VTIME] = 0;
#ifndef PVMAC
  buf.c_line      = 0;
#endif
  buf.c_iflag     = IGNBRK | IGNPAR | IXANY;
  if(tcsetattr(fd, TCSAFLUSH, &buf) < 0) { return -1; }
  //if(tcsetattr(fd, TCSANOW, &buf) < 0) { return -1; }
  ttystate = RAW;
  ttysavefd = fd;
  if(block == 1) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
  tcflush(fd,TCIOFLUSH);
#endif

#ifdef __VMS
  // Please set com parameters at DCL level
  struct dsc$descriptor_s dsc;
  int status;

  dsc.dsc$w_length  = strlen(devicename);
  dsc.dsc$a_pointer = (char *) devicename;
  dsc.dsc$b_class   = DSC$K_CLASS_S;
  dsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  status = SYS$ASSIGN(&dsc,&vms_channel,0,0);
  if(status != SS$_NORMAL) return -1;
#endif

#ifdef RLWIN32
  DWORD ccsize;
  COMMCONFIG cc;
  int baudrate,ret;
  char devname[100];

  if(strlen(devicename) > 80) return -1;
  sprintf(devname,"\\\\.\\%s",devicename);        // Aenderung: allow more than 4 COM ports
  hdl = CreateFile(
                   devname,                       // devicename, // pointer to name of the file
                   GENERIC_READ | GENERIC_WRITE,  // access (read-write) mode
                   0,                             // share mode
                   0,                             // pointer to security attributes
                   OPEN_EXISTING,                 // how to create
                   0,                             // not overlapped I/O
                   0                              // handle to file with attributes to copy
                  );
  if(hdl == INVALID_HANDLE_VALUE)
  {
    printf("CreateFile(%s) failed\n",devicename);
    return -1;
  }

  baudrate = CBR_9600;
  if(speed == B50     ) baudrate = 50;
  if(speed == B75     ) baudrate = 75;
  if(speed == B110    ) baudrate = CBR_110;
  if(speed == B134    ) baudrate = 134;
  if(speed == B150    ) baudrate = 150;
  if(speed == B200    ) baudrate = 200;
  if(speed == B300    ) baudrate = CBR_300;
  if(speed == B600    ) baudrate = CBR_600;
  if(speed == B1200   ) baudrate = CBR_1200;
  if(speed == B1800   ) baudrate = 1800;
  if(speed == B2400   ) baudrate = CBR_2400;
  if(speed == B4800   ) baudrate = CBR_4800;
  if(speed == B9600   ) baudrate = CBR_9600;
  if(speed == B19200  ) baudrate = CBR_19200;
  if(speed == B38400  ) baudrate = CBR_38400;
  if(speed == B57600  ) baudrate = CBR_57600;
  if(speed == B115200 ) baudrate = CBR_115200;
  if(speed == B230400 ) baudrate = 230400;
  if(speed == B460800 ) baudrate = 460800;
  if(speed == B500000 ) baudrate = 500000;
  if(speed == B576000 ) baudrate = 576000;
  if(speed == B921600 ) baudrate = 921600;
  if(speed == B1000000) baudrate = 1000000;
  if(speed == B1152000) baudrate = 1152000;
  if(speed == B1500000) baudrate = 1500000;
  if(speed == B2000000) baudrate = 2000000;
  if(speed == B2500000) baudrate = 2500000;
  if(speed == B3000000) baudrate = 3000000;
  if(speed == B3500000) baudrate = 3500000;
  if(speed == B4000000) baudrate = 4000000;

  ccsize = sizeof(cc);
  GetCommConfig(hdl,&cc,&ccsize);
  //cc.dwSize            = sizeof(cc);  // size of structure
  //cc.wVersion          = 1;           // version of structure
  //cc.wReserved         = 0;           // reserved
  //  DCB   dcb;                      // device-control block
  cc.dcb.DCBlength     = sizeof(DCB); // sizeof(DCB)
  cc.dcb.BaudRate      = baudrate;    // current baud rate
  cc.dcb.fBinary       = 1;           // binary mode, no EOF check
  cc.dcb.fParity       = 1;           // enable parity checking
  cc.dcb.fOutxCtsFlow  = 0;           // CTS output flow control
  if(rtscts == 1) cc.dcb.fOutxCtsFlow = 1;
  cc.dcb.fOutxDsrFlow  = 0;           // DSR output flow control
  cc.dcb.fDtrControl   = DTR_CONTROL_DISABLE;  // DTR flow control type
  cc.dcb.fDsrSensitivity   = 0;       // DSR sensitivity
  cc.dcb.fTXContinueOnXoff = 1;       // XOFF continues Tx
  //cc.dcb.fOutX         = 0;           // XON/XOFF out flow control
  //cc.dcb.fInX          = 0;           // XON/XOFF in flow control
  //cc.dcb.fErrorChar    = 0;           // enable error replacement
  cc.dcb.fNull         = 0;           // enable null stripping
  cc.dcb.fRtsControl   = RTS_CONTROL_DISABLE;
  if(rtscts == 1)  cc.dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;  // RTS flow control
  cc.dcb.fAbortOnError = 0;           // abort reads/writes on error
  //cc.dcb.fDummy2       = 0;           // reserved
  //cc.dcb.wReserved     = 0;           // not currently used
  //cc.dcb.XonLim        = 0;           // transmit XON threshold
  //cc.dcb.XoffLim       = 0;           // transmit XOFF threshold
  cc.dcb.ByteSize      = bits;        // number of bits/byte, 4-8
  cc.dcb.Parity        = 0;           // 0-4=no,odd,even,mark,space
  if(parity == rlSerial::ODD)    cc.dcb.Parity = 1;
  if(parity == rlSerial::EVEN)   cc.dcb.Parity = 2;
  cc.dcb.StopBits      = ONESTOPBIT;  // 0,1,2 = 1, 1.5, 2
  if(stopbits==2) cc.dcb.StopBits = TWOSTOPBITS;
  //cc.dcb.XonChar       = 0;           // Tx and Rx XON character
  //cc.dcb.XoffChar      = 0;           // Tx and Rx XOFF character
  //cc.dcb.ErrorChar     = 0;           // error replacement character
  //cc.dcb.EofChar       = 0;           // end of input character
  //cc.dcb.EvtChar       = 0;           // received event character
  //cc.dcb.wReserved1    = 0;           // reserved; do not use
  cc.dwProviderSubType = PST_RS232;   // type of provider-specific data
  //cc.dwProviderOffset  = 0;           // offset of provider-specific data
  //cc.dwProviderSize    = 0;           // size of provider-specific data
  //cc.wcProviderData[0] = 0;           // provider-specific data

  ret = SetCommConfig(hdl,&cc,sizeof(cc));
  if(ret == 0)
  {
    printf("SetCommConfig ret=%d devicename=%s LastError=%ld\n",ret,devicename,GetLastError());
    return -1;
  }
  if(block) return 0;
#endif

#ifdef RM3
  RmEntryStruct    CatEntry;        /* Struktur der Deiviceinformationen              */
  int              iStatus;         /* Rckgabewert                                    */
  RmIOStatusStruct DrvSts;          /* Struktur der Rckgabewerte fr RmIO - Funktion   */
  RmBytParmStruct  PBlock;          /* Parameterstruktur fr RmIO - Funktion           */
  static UCD_BYT_PORT Ucd_byt_drv;  /* Struktur zum Setzen der UCD - Werte            */
  ushort           uTimeBd;         /* Timing - Wert der �ertragungsgeschwindigkeit   */
  uint             uMode;           /* Portsteuerungsparameter                        */
  unsigned char    cByte;           /* Byte - Parameter                               */
                                    /* Timing = 748800 / Baudrate;                    */
                                    /**************************************************/
  char byt_com[32];
                                    
  /* COM1=0x3F8 COM2=0x2F8 - Port Adresse           */
  if     (strcmp(devicename,"COM1") == 0)
  {
    strcpy(byt_com,"BYT_COM1");
    com = 0x3f8;
  }
  else if(strcmp(devicename,"COM2") == 0)
  {
    strcpy(byt_com,"BYT_COM2");
    com = 0x2f8;
  }
  else 
  {
    printf("Error: devicename=%s unknown\n",devicename);
    return -1;
  }  
  //printf("Open COM port - inside\n");

  /*
  * Device und Unit - Id auslesen
  */
  if( RmGetEntry( RM_WAIT, byt_com, &CatEntry ) != RM_OK ) /* RM_CONTINUE */
  {
    printf( "Error: %s device not found\n", byt_com);
    return -1;
  }

  device = (int) ((ushort) CatEntry.ide);
  unit   = (int) CatEntry.id;

  /*
  * Ger� reservieren
  */
  if( RmIO( BYT_RESERVE, (unsigned)(device), (unsigned)(unit), 0u, 0u, &DrvSts, &PBlock ) < 0 )
  {
    printf( "Error: Unable to reserve %s device\n", byt_com);
    return -1;
  }

  /*
  * Baudrate ausrechnen
  */
  baudrate = 9600;
  if(speed == B50     ) baudrate = 50;
  if(speed == B75     ) baudrate = 75;
  if(speed == B110    ) baudrate = 110;
  if(speed == B134    ) baudrate = 134;
  if(speed == B150    ) baudrate = 150;
  if(speed == B200    ) baudrate = 200;
  if(speed == B300    ) baudrate = 300;
  if(speed == B600    ) baudrate = 600;
  if(speed == B1200   ) baudrate = 1200;
  if(speed == B1800   ) baudrate = 1800;
  if(speed == B2400   ) baudrate = 2400;
  if(speed == B4800   ) baudrate = 4800;
  if(speed == B9600   ) baudrate = 9600;
  if(speed == B19200  ) baudrate = 19200;
  if(speed == B38400  ) baudrate = 38400;
  if(speed == B57600  ) baudrate = 57600;
  if(speed == B115200 ) baudrate = 115200;
  if(speed == B230400 ) baudrate = 230400;
  if(speed == B460800 ) baudrate = 460800;
  if(speed == B500000 ) baudrate = 500000;
  if(speed == B576000 ) baudrate = 576000;
  if(speed == B921600 ) baudrate = 921600;
  if(speed == B1000000) baudrate = 1000000;
  if(speed == B1152000) baudrate = 1152000;
  if(speed == B1500000) baudrate = 1500000;
  if(speed == B2000000) baudrate = 2000000;
  if(speed == B2500000) baudrate = 2500000;
  if(speed == B3000000) baudrate = 3000000;
  if(speed == B3500000) baudrate = 3500000;
  if(speed == B4000000) baudrate = 4000000;
  uTimeBd = 748800 / baudrate;

  /*
  * Portsteuerungsparameter setzen
  */
  uMode = 0x1000 | DATA_8 | STOP_1 | NOPARITY;

  /*
  * UCD des seriellen Ports auslesen
  */
  PBlock.string = 0;
  PBlock.strlen = 0;
  PBlock.buffer = (char *)&Ucd_byt_drv;
  PBlock.timlen = sizeof(UCD_BYT_PORT);
  PBlock.status = 0;

  iStatus = RmIO( BYT_CREATE_NEW, (unsigned)(device), (unsigned)(unit), 0u, 0u, &DrvSts, &PBlock );

  /*
   * Modus �dern
   */
  Ucd_byt_drv.mobyte[5] |= (ushort) (uMode & 0xFFu);

  /*
   * Timeout setzen
   */
  Ucd_byt_drv.header.timout = timeout;

  /*
   * Werte zuweisen
   */
  PBlock.string = (char*) &Ucd_byt_drv;
  PBlock.strlen = sizeof(UCD_BYT_PORT);
  PBlock.buffer = 0;
  PBlock.timlen = 0;
  PBlock.status = 0;

  iStatus = RmIO( BYT_CREATE_NEW, (unsigned)(device), (unsigned)(unit), 0u, 0u, &DrvSts, &PBlock );

  /*
   * Register 0 und 1 zum Schreiben freigeben
   */
  cByte = inbyte( com + 0x03 );
  outbyte( com + 0x03, (unsigned char)(cByte | 0x80) );

  /*
   * Baudrate setzen
   */
  outbyte( com + 0x00, (ushort) LOW  (uTimeBd) );
  outbyte( com + 0x01, (ushort) HIGH (uTimeBd) );

  /*
   * Register 0 und 1 sperren
   */
  outbyte( com + 0x03, cByte );

  if( iStatus ) printf( "BYT_CREATE_NEW (set ucb): Error status = %X\n", iStatus );
#endif
  
  return 0;
}
Beispiel #25
0
static void term_exit(void)
{
    tcsetattr(0, TCSANOW, &oldtty);
}
int OpenSerialPort()
{
    int        fileDescriptor = -1;
    struct termios  options;
    
    // Open the serial port read/write, with no controlling terminal, and don't wait for a connection.
    // The O_NONBLOCK flag also causes subsequent I/O on the device to be non-blocking.
    // See open(2) ("man 2 open") for details.
    
    fileDescriptor = open("/dev/tty.iap", O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fileDescriptor == -1)
    {
        printf("Error opening serial port %s - %s(%d).\n",
               "/dev/tty.iap", strerror(errno), errno);
        goto error;
    }
    
    // Note that open() follows POSIX semantics: multiple open() calls to the same file will succeed
    // unless the TIOCEXCL ioctl is issued. This will prevent additional opens except by root-owned
    // processes.
    // See tty(4) ("man 4 tty") and ioctl(2) ("man 2 ioctl") for details.
    
    if (ioctl(fileDescriptor, TIOCEXCL) == -1)
    {
        printf("Error setting TIOCEXCL on %s - %s(%d).\n",
               "/dev/tty.iap", strerror(errno), errno);
        goto error;
    }
    
    // Now that the device is open, clear the O_NONBLOCK flag so subsequent I/O will block.
    // See fcntl(2) ("man 2 fcntl") for details.
    
    if (fcntl(fileDescriptor, F_SETFL, 0) == -1)
    {
        printf("Error clearing O_NONBLOCK %s - %s(%d).\n",
               "/dev/tty.iap", strerror(errno), errno);
        goto error;
    }
    
    // Get the current options and save them so we can restore the default settings later.
    if (tcgetattr(fileDescriptor, &gOriginalTTYAttrs) == -1)
    {
        printf("Error getting tty attributes %s - %s(%d).\n",
               "/dev/tty.iap", strerror(errno), errno);
        goto error;
    }
    
    // The serial port attributes such as timeouts and baud rate are set by modifying the termios
    // structure and then calling tcsetattr() to cause the changes to take effect. Note that the
    // changes will not become effective without the tcsetattr() call.
    // See tcsetattr(4) ("man 4 tcsetattr") for details.
    
    options = gOriginalTTYAttrs;
    
    // Print the current input and output baud rates.
    // See tcsetattr(4) ("man 4 tcsetattr") for details.
    
    printf("Current input baud rate is %d\n", (int) cfgetispeed(&options));
    printf("Current output baud rate is %d\n", (int) cfgetospeed(&options));
    
    // Set raw input (non-canonical) mode, with reads blocking until either a single character 
    // has been received or a one second timeout expires.
    // See tcsetattr(4) ("man 4 tcsetattr") and termios(4) ("man 4 termios") for details.
    
    cfmakeraw(&options);
    options.c_cc[VMIN] = 1;
    options.c_cc[VTIME] = 10;
    
    // The baud rate, word length, and handshake options can be set as follows:
    
    cfsetspeed(&options, B9600);    // Set 19200 baud    
    options.c_cflag |= (CS8);  // RTS flow control of input
    
    
    printf("Input baud rate changed to %d\n", (int) cfgetispeed(&options));
    printf("Output baud rate changed to %d\n", (int) cfgetospeed(&options));
    
    // Cause the new options to take effect immediately.
    if (tcsetattr(fileDescriptor, TCSANOW, &options) == -1)
    {
        printf("Error setting tty attributes %s - %s(%d).\n",
               "/dev/tty.iap", strerror(errno), errno);
        goto error;
    }    
    // Success
    return fileDescriptor;
    
    // Failure "/dev/tty.iap"
error:
    if (fileDescriptor != -1)
    {
        close(fileDescriptor);
    }
    
    return -1;
}
Beispiel #27
0
static VeiFlockOfBirds *open_serial(char *name, VeDeviceInstance *i) {
  struct termios t;
  VeiFlockOfBirds *b;
  char *c;

  b = calloc(1,sizeof(VeiFlockOfBirds));
  assert(b != NULL);

  if (c = veDeviceInstOption(i,"line"))
    b->line = veDupString(c);
  else {
    veError(MODULE,"serial source not specified in fob input definition");
    return NULL;
  }

  if (c = veDeviceInstOption(i,"raw"))
    b->raw = atoi(c);

  if (c = veDeviceInstOption(i,"speed"))
    b->speed = str_to_bps(c);
  else
    b->speed = str_to_bps(DEFAULT_FOB_SPEED);
  if (b->speed < 0)
    return NULL;

  b->fd = open(b->line, O_RDWR|O_NOCTTY);
  if (b->fd < 0) {
    veError(MODULE, "could not open serial line %s: %s",
	    b->line, strerror(errno));
    return NULL;
  }

  /* setup serial line, terminal mumbo-jumbo */
  if (tcgetattr(b->fd,&t)) {
    veError(MODULE, "could not get serial attributes for %s: %s",
	    b->line, strerror(errno));
    return NULL;
  }
  
  /* this is "non-portable" or "portability-hostile" but I can't figure
     out which of the many flags was mussing up data from the receiver,
     so we'll just trash them all.  This also seems to kill the 
     slow-startup bug */
  t.c_iflag = 0;
  t.c_oflag = 0;
  t.c_cflag = 0;
  t.c_lflag = 0;
  t.c_cflag |= (CLOCAL|CREAD|CS8);
  t.c_cc[VMIN] = 1;
  t.c_cc[VTIME] = 0;

  cfsetispeed(&t,b->speed);
  cfsetospeed(&t,b->speed);

  /* setup flow control */
  if (c = veDeviceInstOption(i, "flow")) {
    if (strcmp(c, "xonxoff") == 0) {
      t.c_iflag |= (IXON|IXOFF);
#if defined(__sgi)
      t.c_cflag &= ~CNEW_RTSCTS;
#elif defined(__sun) || defined(__linux)
      t.c_cflag &= ~CRTSCTS;
#endif
    } else if (strcmp(c, "rtscts") == 0) {
      /* Hmm... RTS/CTS is not standard...great... */
#if defined(__sgi)
      t.c_cflag |= CNEW_RTSCTS;
#elif defined(__sun) || defined(__linux)
      t.c_cflag |= CRTSCTS;
#else
      veError(MODULE, "RTS/CTS not supported on this platform");
      return NULL;
#endif
    }
  } else {
    t.c_iflag &= ~(IXON|IXOFF|IXANY);
#if defined(__sgi)
      t.c_cflag &= ~CNEW_RTSCTS;
#elif defined(__sun) || defined(__linux)
      t.c_cflag &= ~CRTSCTS;
#endif
  }

  if (tcsetattr(b->fd,TCSAFLUSH,&t)) {
    veError(MODULE, "could not set serial attributes for %s: %s",
	    b->line, strerror(errno));
    return NULL;
  }

  /* try to sync things up in case it is already running */
  sync_bird(b->fd);

  /* build NULL frame */
  veFrameIdentity(&b->frame);

  if (c = veDeviceInstOption(i, "loc"))
    parseVector3(name,c,&b->frame.loc);
  if (c = veDeviceInstOption(i, "dir"))
    parseVector3(name,c,&b->frame.dir);
  if (c = veDeviceInstOption(i, "up"))
    parseVector3(name,c,&b->frame.up);

  return b;
}
Beispiel #28
0
MonoBoolean
ves_icall_System_ConsoleDriver_TtySetup (MonoString *keypad, MonoString *teardown, MonoArray **control_chars, int **size)
{
	int dims;

	MONO_ARCH_SAVE_REGS;

	dims = terminal_get_dimensions ();
	if (dims == -1){
		int cols = 0, rows = 0;
				      
		const char *str = g_getenv ("COLUMNS");
		if (str != NULL)
			cols = atoi (str);
		str = g_getenv ("LINES");
		if (str != NULL)
			rows = atoi (str);

		if (cols != 0 && rows != 0)
			cols_and_lines = (cols << 16) | rows;
		else
			cols_and_lines = -1;
	} else {
		cols_and_lines = dims;
	}
	
	*size = &cols_and_lines;

	/* 17 is the number of entries set in set_control_chars() above.
	 * NCCS is the total size, but, by now, we only care about those 17 values*/
	mono_gc_wbarrier_generic_store (control_chars, (MonoObject*) mono_array_new (mono_domain_get (), mono_defaults.byte_class, 17));
	if (tcgetattr (STDIN_FILENO, &initial_attr) == -1)
		return FALSE;

	mono_attr = initial_attr;
	mono_attr.c_lflag &= ~(ICANON);
	mono_attr.c_iflag &= ~(IXON|IXOFF);
	mono_attr.c_cc [VMIN] = 1;
	mono_attr.c_cc [VTIME] = 0;
#ifdef VDSUSP
	/* Disable C-y being used as a suspend character on OSX */
	mono_attr.c_cc [VDSUSP] = 255;
#endif
	if (tcsetattr (STDIN_FILENO, TCSANOW, &mono_attr) == -1)
		return FALSE;

	set_control_chars (*control_chars, mono_attr.c_cc);
	/* If initialized from another appdomain... */
	if (setup_finished)
		return TRUE;

	keypad_xmit_str = keypad != NULL ? mono_string_to_utf8 (keypad) : NULL;
	
	console_set_signal_handlers ();
	setup_finished = TRUE;
	if (!atexit_called) {
		if (teardown != NULL)
			teardown_str = mono_string_to_utf8 (teardown);

		atexit (tty_teardown);
	}

	return TRUE;
}
Beispiel #29
0
int main(int argc, char *argv[])
{
	int len, cmd_finished, stop, i,try;
	int clientSocket, serial_fd, 
	remotePort,
	status = 0;
	struct hostent *hostPtr = NULL;
	struct sockaddr_in serverName = { 0 };
	unsigned char buffer[BUFFER_SIZE];
	unsigned char buffer2[BUFFER_SIZE];
	char *remoteHost = NULL;
	char *serial_device;
	struct termios oldtio,newtio;
	char *s;
	char *hex_filename;
	FILE *hexfile;
	
	
	if (2 != argc)
 	{
		fprintf(stderr, "Usage: %s <serial_device>\n", argv[0]);
		exit(1);
	};
	
	serial_device = argv[1];
	

	/* 
	Open modem device for reading and writing and not as controlling tty
	because we don't want to get killed if linenoise sends CTRL-C.
       */	
	serial_fd = open(serial_device, O_RDWR | O_NOCTTY ); 
	if (serial_fd <0) {perror(serial_device); exit(-1); }
	
	tcgetattr(serial_fd,&oldtio); /* save current port settings */

	bzero(&newtio, sizeof(newtio));
       /* 
	BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed.
	CRTSCTS : output hardware flow control (only used if the cable has
	all necessary lines. See sect. 7 of Serial-HOWTO)
	CS8     : 8n1 (8bit,no parity,1 stopbit)
	CLOCAL  : local connection, no modem contol
	CREAD   : enable receiving characters
	*/
	newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;

	/*
	IGNPAR  : ignore bytes with parity errors
	ICRNL   : map CR to NL (otherwise a CR input on the other computer
	will not terminate input)
	otherwise make device raw (no other input processing)
	*/
	newtio.c_iflag = IGNPAR;

	/*
	Raw output.
	*/	
	newtio.c_oflag = 0;

	/* set input mode (non-canonical, no echo,...) 
	disable all echo functionality, and don't send signals to calling program
	*/
	newtio.c_lflag = 0;
 
	newtio.c_cc[VTIME]    = 50;   /* time out after 5 seconds */
	newtio.c_cc[VMIN]     = 0;   /* non-blocking read */
	
	/* now clean the modem line and activate the settings for the port */
	tcflush(serial_fd, TCIFLUSH);
	tcsetattr(serial_fd,TCSANOW,&newtio);
	
	printf("Sending break\n");
	/* Send a break to reset device into ISP mode */
	tcsendbreak(serial_fd,3);

	tcflush(serial_fd, TCIFLUSH);
	
	usleep(1000000);
	tcflush(serial_fd, TCIFLUSH);
	usleep(1000000);
	
	/* Send an uppercase U to negotiate baud rate */
	buffer[0] = 'U';
	buffer[1] = 0;
	
	
	/* Send U to serial line */
	if (write_all(serial_fd, buffer, 1) == -1) {
		perror("sendall");
		printf("We only sent %d bytes because of the error!\n", len);
	};		
	
	len = read_cmd(serial_fd, buffer);
	buffer[len] = 0;
	printf("Read %d characters:\n\t", len, buffer[0]);
	for (i=0; i<len; i++)
		printf("%02x ", buffer[i]);
	printf("\n");
	
	tcflush(serial_fd, TCIFLUSH);
			
	/* Send U to serial line to check that we are in sync */
	buffer[0] = 'U';
	if (write_all(serial_fd, buffer, 1) == -1) {
		perror("sendall");
		printf("We only sent %d bytes because of the error!\n", len);
	};		
	
	len = read_cmd(serial_fd, buffer);
	printf("Read %d characters:\n\t", len);
	for (i=0; i<len; i++)
		printf("%02x ", buffer[i]);
	printf("\n");
	
	
	buffer[len] = 0;

	if (buffer[0] == 'U')
		printf("Baud rate successfully negotiated\n");
	else {
		printf("buffer[0] = %02x\n", buffer[0] );
		printf("Error: Could not negotiate baud rate!\n");
		exit(20);
	};

	s=":0100000310EC";
	printf("Manuf. ID \t= ");
	if (0 != send_string(serial_fd,s,buffer2) ) {
		exit(20);	;
	};
	printf("%s\n",buffer2);
	if (0 != strncmp(buffer2, "15", 2)) {
		fprintf(stderr, "ERROR: Device not recognized\n");
		exit(20);
	};
	 
	s=":0100000311EB";
	printf("Device ID \t= ");
	if (0 != send_string(serial_fd,s,buffer2)) {
		exit(20);	;
	};
	printf("%s\n",buffer2);
	if (0 != strncmp(buffer2, "DD", 2)) {
		fprintf(stderr, "ERROR: Device not recognized\n");
		exit(20);
	};
	
	s=":0100000312EA";
	printf("Derivative ID \t= ");
	if (0 != send_string(serial_fd,s,buffer2)) {
		exit(20);	;
	};
	printf("%s\n",buffer2);
	if (0 != strncmp(buffer2, "09", 2)) {
		fprintf(stderr, "ERROR: Device not recognized\n");
		exit(20);
	};
		
	/* Read configuration data */
	s=":0100000300FC";
	printf("UCFG1    \t= ");
	if (0 != send_string(serial_fd,s, buffer2)) {
		exit(-20);	;
	};
	printf("%s\n",buffer2);	
	
	s=":0100000302FA";
	printf("Boot Vector \t= ");
	if (0 != send_string(serial_fd,s,buffer2)) {
		exit(-20);	;
	};
	printf("%s\n",buffer2);
		
	s=":0100000303F9";
	printf("Status Byte \t= ");
	if (0 != send_string(serial_fd,s,buffer2)) {
		exit(-20);	;
	};
	printf("%s\n",buffer2);					

	s=":00000001FF";
	printf("Version ID \t= ");
	if (0 != send_string(serial_fd,s, buffer2)) {
		exit(-20);	;
	};
	printf("%s\n",buffer2);
	
	really_write_sector(serial_fd, 0);
	really_write_sector(serial_fd, 1);
	really_write_sector(serial_fd, 2);
	really_write_sector(serial_fd, 3);
	really_write_sector(serial_fd, 4);
	really_write_sector(serial_fd, 5);
	really_write_sector(serial_fd, 6);

	// The configuration bytes are defined and set in bin2c.c !!! 
	
	
	/* Write Configuration Byte UCFG1 */
	sprintf(buffer, ":0200000200%02X", scart_UCFG1);
	checksum(buffer);	
	if (0 != send_string(serial_fd, buffer, buffer2)) {
		return(20);	;
	};
		
	/* Read UCFG1 */
	s=":0100000300FC";
	printf("UCFG1    \t= ");
	if (0 != send_string(serial_fd,s, buffer2)) {
		exit(-20);	;
	};
	printf("%s\n",buffer2);	
	

	/* Write Boot Vector Byte */
	sprintf(buffer, ":0200000202%02X", scart_bootvec);
	checksum(buffer);	
	if (0 != send_string(serial_fd, buffer, buffer2)) {
		return(20);	;
	};
	s=":0100000302FA";
	printf("Boot Vector \t= ");
	if (0 != send_string(serial_fd,s,buffer2)) {
		exit(-20);	;
	};
	printf("%s\n",buffer2);
				
	
	/* Write Boot Status Byte */	
	sprintf(buffer, ":0200000203%02X", scart_bootstat);
	checksum(buffer);	
	if (0 != send_string(serial_fd, buffer, buffer2)) {
		return(20);	;
	};
	s=":0100000303F9";
	printf("Status Byte \t= ");
	if (0 != send_string(serial_fd,s,buffer2)) {
		exit(-20);	;
	};
	printf("%s\n",buffer2);					
	
	/* Reset the device */
	printf("\nResetting device\n");
	s=":00000008F8";
	write_all(serial_fd, s, strlen(s));

	/* This should be the echo of our RESET command */
	read_cmd(serial_fd, buffer);
	printf("%s\n", buffer);

	/* Restore old serial port settings */
	tcsetattr(serial_fd,TCSANOW,&oldtio);

	
	return 0;
}
Beispiel #30
0
//TODO: use more efficient setvar() which takes a pointer to malloced "VAR=VAL"
//string. hush naturally has it, and ash has setvareq().
//Here we can simply store "VAR=" at buffer start and store read data directly
//after "=", then pass buffer to setvar() to consume.
const char* FAST_FUNC
shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val),
	char       **argv,
	const char *ifs,
	int        read_flags,
	const char *opt_n,
	const char *opt_p,
	const char *opt_t,
	const char *opt_u
)
{
	unsigned err;
	unsigned end_ms; /* -t TIMEOUT */
	int fd; /* -u FD */
	int nchars; /* -n NUM */
	char **pp;
	char *buffer;
	struct termios tty, old_tty;
	const char *retval;
	int bufpos; /* need to be able to hold -1 */
	int startword;
	smallint backslash;

	errno = err = 0;

	pp = argv;
	while (*pp) {
		if (!is_well_formed_var_name(*pp, '\0')) {
			/* Mimic bash message */
			bb_error_msg("read: '%s': not a valid identifier", *pp);
			return (const char *)(uintptr_t)1;
		}
		pp++;
	}

	nchars = 0; /* if != 0, -n is in effect */
	if (opt_n) {
		nchars = bb_strtou(opt_n, NULL, 10);
		if (nchars < 0 || errno)
			return "invalid count";
		/* note: "-n 0": off (bash 3.2 does this too) */
	}
	end_ms = 0;
	if (opt_t) {
		end_ms = bb_strtou(opt_t, NULL, 10);
		if (errno || end_ms > UINT_MAX / 2048)
			return "invalid timeout";
		end_ms *= 1000;
#if 0 /* even bash has no -t N.NNN support */
		ts.tv_sec = bb_strtou(opt_t, &p, 10);
		ts.tv_usec = 0;
		/* EINVAL means number is ok, but not terminated by NUL */
		if (*p == '.' && errno == EINVAL) {
			char *p2;
			if (*++p) {
				int scale;
				ts.tv_usec = bb_strtou(p, &p2, 10);
				if (errno)
					return "invalid timeout";
				scale = p2 - p;
				/* normalize to usec */
				if (scale > 6)
					return "invalid timeout";
				while (scale++ < 6)
					ts.tv_usec *= 10;
			}
		} else if (ts.tv_sec < 0 || errno) {
			return "invalid timeout";
		}
		if (!(ts.tv_sec | ts.tv_usec)) { /* both are 0? */
			return "invalid timeout";
		}
#endif /* if 0 */
	}
	fd = STDIN_FILENO;
	if (opt_u) {
		fd = bb_strtou(opt_u, NULL, 10);
		if (fd < 0 || errno)
			return "invalid file descriptor";
	}

	if (opt_p && isatty(fd)) {
		fputs(opt_p, stderr);
		fflush_all();
	}

	if (ifs == NULL)
		ifs = defifs;

	if (nchars || (read_flags & BUILTIN_READ_SILENT)) {
		tcgetattr(fd, &tty);
		old_tty = tty;
		if (nchars) {
			tty.c_lflag &= ~ICANON;
			// Setting it to more than 1 breaks poll():
			// it blocks even if there's data. !??
			//tty.c_cc[VMIN] = nchars < 256 ? nchars : 255;
			/* reads would block only if < 1 char is available */
			tty.c_cc[VMIN] = 1;
			/* no timeout (reads block forever) */
			tty.c_cc[VTIME] = 0;
		}
		if (read_flags & BUILTIN_READ_SILENT) {
			tty.c_lflag &= ~(ECHO | ECHOK | ECHONL);
		}
		/* This forces execution of "restoring" tcgetattr later */
		read_flags |= BUILTIN_READ_SILENT;
		/* if tcgetattr failed, tcsetattr will fail too.
		 * Ignoring, it's harmless. */
		tcsetattr(fd, TCSANOW, &tty);
	}

	retval = (const char *)(uintptr_t)0;
	startword = 1;
	backslash = 0;
	if (end_ms) /* NB: end_ms stays nonzero: */
		end_ms = ((unsigned)monotonic_ms() + end_ms) | 1;
	buffer = NULL;
	bufpos = 0;
	do {
		char c;
		struct pollfd pfd[1];
		int timeout;

		if ((bufpos & 0xff) == 0)
			buffer = xrealloc(buffer, bufpos + 0x101);

		timeout = -1;
		if (end_ms) {
			timeout = end_ms - (unsigned)monotonic_ms();
			if (timeout <= 0) { /* already late? */
				retval = (const char *)(uintptr_t)1;
				goto ret;
			}
		}

		/* We must poll even if timeout is -1:
		 * we want to be interrupted if signal arrives,
		 * regardless of SA_RESTART-ness of that signal!
		 */
		errno = 0;
		pfd[0].fd = fd;
		pfd[0].events = POLLIN;
		if (poll(pfd, 1, timeout) != 1) {
			/* timed out, or EINTR */
			err = errno;
			retval = (const char *)(uintptr_t)1;
			goto ret;
		}
		if (read(fd, &buffer[bufpos], 1) != 1) {
			err = errno;
			retval = (const char *)(uintptr_t)1;
			break;
		}

		c = buffer[bufpos];
		if (c == '\0')
			continue;
		if (backslash) {
			backslash = 0;
			if (c != '\n')
				goto put;
			continue;
		}
		if (!(read_flags & BUILTIN_READ_RAW) && c == '\\') {
			backslash = 1;
			continue;
		}
		if (c == '\n')
			break;

		/* $IFS splitting. NOT done if we run "read"
		 * without variable names (bash compat).
		 * Thus, "read" and "read REPLY" are not the same.
		 */
		if (argv[0]) {
/* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05 */
			const char *is_ifs = strchr(ifs, c);
			if (startword && is_ifs) {
				if (isspace(c))
					continue;
				/* it is a non-space ifs char */
				startword--;
				if (startword == 1) /* first one? */
					continue; /* yes, it is not next word yet */
			}
			startword = 0;
			if (argv[1] != NULL && is_ifs) {
				buffer[bufpos] = '\0';
				bufpos = 0;
				setvar(*argv, buffer);
				argv++;
				/* can we skip one non-space ifs char? (2: yes) */
				startword = isspace(c) ? 2 : 1;
				continue;
			}
		}
 put:
		bufpos++;
	} while (--nchars);

	if (argv[0]) {
		/* Remove trailing space $IFS chars */
		while (--bufpos >= 0 && isspace(buffer[bufpos]) && strchr(ifs, buffer[bufpos]) != NULL)
			continue;
		buffer[bufpos + 1] = '\0';
		/* Use the remainder as a value for the next variable */
		setvar(*argv, buffer);
		/* Set the rest to "" */
		while (*++argv)
			setvar(*argv, "");
	} else {
		/* Note: no $IFS removal */
		buffer[bufpos] = '\0';
		setvar("REPLY", buffer);
	}

 ret:
	free(buffer);
	if (read_flags & BUILTIN_READ_SILENT)
		tcsetattr(fd, TCSANOW, &old_tty);

	errno = err;
	return retval;
}