mirror of https://gerrit.osmocom.org/libosmocore
core/serial: Add utilities to deal with serial ports
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
This commit is contained in:
parent
bf9d25039c
commit
fe28dedd4c
|
@ -99,6 +99,14 @@ AC_ARG_ENABLE(msgfile,
|
|||
[enable_msgfile=$enableval], [enable_msgfile="yes"])
|
||||
AM_CONDITIONAL(ENABLE_MSGFILE, test x"$enable_msgfile" = x"yes")
|
||||
|
||||
AC_ARG_ENABLE(serial,
|
||||
[AS_HELP_STRING(
|
||||
[--disable-serial],
|
||||
[Disable support for the serial helpers],
|
||||
)],
|
||||
[enable_serial=$enableval], [enable_serial="yes"])
|
||||
AM_CONDITIONAL(ENABLE_SERIAL, test x"$enable_serial" = x"yes")
|
||||
|
||||
AC_ARG_ENABLE(utilities,
|
||||
[AS_HELP_STRING(
|
||||
[--disable-utilities],
|
||||
|
@ -119,6 +127,7 @@ then
|
|||
AM_CONDITIONAL(ENABLE_TESTS, false)
|
||||
AM_CONDITIONAL(ENABLE_PLUGIN, false)
|
||||
AM_CONDITIONAL(ENABLE_MSGFILE, false)
|
||||
AM_CONDITIONAL(ENABLE_SERIAL, false)
|
||||
AM_CONDITIONAL(ENABLE_VTY, false)
|
||||
AM_CONDITIONAL(ENABLE_TALLOC, false)
|
||||
AM_CONDITIONAL(ENABLE_UTILITIES, false)
|
||||
|
|
|
@ -17,4 +17,8 @@ if ENABLE_MSGFILE
|
|||
osmocore_HEADERS += msgfile.h
|
||||
endif
|
||||
|
||||
if ENABLE_SERIAL
|
||||
osmocore_HEADERS += serial.h
|
||||
endif
|
||||
|
||||
osmocoredir = $(includedir)/osmocom/core
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* serial.h
|
||||
*
|
||||
* Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/*! \defgroup serial Utility functions to deal with serial ports
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! \file serial.h
|
||||
* \file Osmocom serial port helpers
|
||||
*/
|
||||
|
||||
#ifndef __OSMO_SERIAL_H__
|
||||
#define __OSMO_SERIAL_H__
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
int osmo_serial_init(const char *dev, speed_t baudrate);
|
||||
int osmo_serial_set_baudrate(int fd, speed_t baudrate);
|
||||
int osmo_serial_set_custom_baudrate(int fd, int baudrate);
|
||||
int osmo_serial_clear_custom_baudrate(int fd);
|
||||
|
||||
/*! }@ */
|
||||
|
||||
#endif /* __OSMO_SERIAL_H__ */
|
|
@ -30,3 +30,7 @@ endif
|
|||
if ENABLE_MSGFILE
|
||||
libosmocore_la_SOURCES += msgfile.c
|
||||
endif
|
||||
|
||||
if ENABLE_SERIAL
|
||||
libosmocore_la_SOURCES += serial.c
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* serial.c
|
||||
*
|
||||
* Utility functions to deal with serial ports
|
||||
*
|
||||
* Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/*! \addtogroup serial
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! \file serial.c
|
||||
* \file Osmocom serial port helpers
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <linux/serial.h>
|
||||
|
||||
|
||||
#include <osmocom/core/serial.h>
|
||||
|
||||
|
||||
#if 0
|
||||
# define dbg_perror(x) perror(x)
|
||||
#else
|
||||
# define dbg_perror(x) do { } while (0)
|
||||
#endif
|
||||
|
||||
/*! \brief Open serial device and does base init
|
||||
* \param[in] dev Path to the device node to open
|
||||
* \param[in] baudrate Baudrate constant (speed_t: B9600, B...)
|
||||
* \returns >=0 file descriptor in case of success or negative errno.
|
||||
*/
|
||||
int
|
||||
osmo_serial_init(const char *dev, speed_t baudrate)
|
||||
{
|
||||
int rc, fd=0, v24;
|
||||
struct termios tio;
|
||||
|
||||
/* Open device */
|
||||
fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY);
|
||||
if (fd < 0) {
|
||||
dbg_perror("open");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/* Configure serial interface */
|
||||
rc = tcgetattr(fd, &tio);
|
||||
if (rc < 0) {
|
||||
dbg_perror("tcgetattr()");
|
||||
rc = -errno;
|
||||
goto error;
|
||||
}
|
||||
|
||||
cfsetispeed(&tio, baudrate);
|
||||
cfsetospeed(&tio, baudrate);
|
||||
|
||||
tio.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS);
|
||||
tio.c_cflag |= (CREAD | CLOCAL | CS8);
|
||||
tio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
|
||||
tio.c_iflag |= (INPCK | ISTRIP);
|
||||
tio.c_iflag &= ~(ISTRIP | IXON | IXOFF | IGNBRK | INLCR | ICRNL | IGNCR);
|
||||
tio.c_oflag &= ~(OPOST | ONLCR);
|
||||
|
||||
rc = tcsetattr(fd, TCSANOW, &tio);
|
||||
if (rc < 0) {
|
||||
dbg_perror("tcsetattr()");
|
||||
rc = -errno;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Set ready to read/write */
|
||||
v24 = TIOCM_DTR | TIOCM_RTS;
|
||||
rc = ioctl(fd, TIOCMBIS, &v24);
|
||||
if (rc < 0) {
|
||||
dbg_perror("ioctl(TIOCMBIS)");
|
||||
rc = -errno;
|
||||
goto error;
|
||||
}
|
||||
|
||||
return fd;
|
||||
|
||||
error:
|
||||
if (fd)
|
||||
close(fd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
_osmo_serial_set_baudrate(int fd, speed_t baudrate)
|
||||
{
|
||||
int rc;
|
||||
struct termios tio;
|
||||
|
||||
rc = tcgetattr(fd, &tio);
|
||||
if (rc < 0) {
|
||||
dbg_perror("tcgetattr()");
|
||||
return -errno;
|
||||
}
|
||||
cfsetispeed(&tio, baudrate);
|
||||
cfsetospeed(&tio, baudrate);
|
||||
|
||||
rc = tcsetattr(fd, TCSANOW, &tio);
|
||||
if (rc < 0) {
|
||||
dbg_perror("tcgetattr()");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \brief Change current baudrate
|
||||
* \param[in] fd File descriptor of the open device
|
||||
* \param[in] baudrate Baudrate constant (speed_t: B9600, B...)
|
||||
* \returns 0 for success or negative errno.
|
||||
*/
|
||||
int
|
||||
osmo_serial_set_baudrate(int fd, speed_t baudrate)
|
||||
{
|
||||
osmo_serial_clear_custom_baudrate(fd);
|
||||
return _osmo_serial_set_baudrate(fd, baudrate);
|
||||
}
|
||||
|
||||
/*! \brief Change current baudrate to a custom one using OS specific method
|
||||
* \param[in] fd File descriptor of the open device
|
||||
* \param[in] baudrate Baudrate as integer
|
||||
* \returns 0 for success or negative errno.
|
||||
*
|
||||
* This function might not work on all OS or with all type of serial adapters
|
||||
*/
|
||||
int
|
||||
osmo_serial_set_custom_baudrate(int fd, int baudrate)
|
||||
{
|
||||
int rc;
|
||||
struct serial_struct ser_info;
|
||||
|
||||
rc = ioctl(fd, TIOCGSERIAL, &ser_info);
|
||||
if (rc < 0) {
|
||||
dbg_perror("ioctl(TIOCGSERIAL)");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
ser_info.flags = ASYNC_SPD_CUST | ASYNC_LOW_LATENCY;
|
||||
ser_info.custom_divisor = ser_info.baud_base / baudrate;
|
||||
|
||||
rc = ioctl(fd, TIOCSSERIAL, &ser_info);
|
||||
if (rc < 0) {
|
||||
dbg_perror("ioctl(TIOCSSERIAL)");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return _osmo_serial_set_baudrate(fd, B38400); /* 38400 is a kind of magic ... */
|
||||
}
|
||||
|
||||
/*! \brief Clear any custom baudrate
|
||||
* \param[in] fd File descriptor of the open device
|
||||
* \returns 0 for success or negative errno.
|
||||
*
|
||||
* This function might not work on all OS or with all type of serial adapters
|
||||
*/
|
||||
int
|
||||
osmo_serial_clear_custom_baudrate(int fd)
|
||||
{
|
||||
int rc;
|
||||
struct serial_struct ser_info;
|
||||
|
||||
rc = ioctl(fd, TIOCGSERIAL, &ser_info);
|
||||
if (rc < 0) {
|
||||
dbg_perror("ioctl(TIOCGSERIAL)");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
ser_info.flags = ASYNC_LOW_LATENCY;
|
||||
ser_info.custom_divisor = 0;
|
||||
|
||||
rc = ioctl(fd, TIOCSSERIAL, &ser_info);
|
||||
if (rc < 0) {
|
||||
dbg_perror("ioctl(TIOCSSERIAL)");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! }@ */
|
Loading…
Reference in New Issue