Added doxygen style comments. Fixed a bug in open() return value. The class still doesn't work as it should.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2526 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2003-01-21 19:34:45 +00:00
parent f5b024fb5d
commit d376996084
+202 -96
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2002, Jack Burton. * Copyright 2002, Stefano Ceccherini.
* Copyright 2002, Marcus Overhagen. * Copyright 2002, Marcus Overhagen.
* All rights reserved. * All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
@@ -21,20 +21,19 @@
/* The directory where the serial driver publishes its devices */ /* The directory where the serial driver publishes its devices */
#define SERIAL_DIR "/dev/ports" #define SERIAL_DIR "/dev/ports"
/*! \brief Creates and initializes a BSerialPort object.
/* Creates and initializes a BSerialPort object, */
/* query the driver, and builds a list of available */ Query the driver, and builds a list of the available
/* serial ports. */ serial ports.
The BSerialPort object is initialized to these values:
/* The BSerialPort object is initialized to these */ - \c B_19200_BPS
/* values: */ - \c B_DATA_BITS_8
/* 19200 BPS, */ - \c B_STOP_BIT_1
/* 8 Data Bits, */ - \c B_NO_PARITY
/* 1 Stop Bit, */ - \c B_HARDWARE_CONTROL
/* No Parity, */ - \c B_INFINITE_TIMEOUT
/* Hardware Flow Control, */ - Blocking mode
/* Infinite Timeout */ */
/* and Blocking mode. */
BSerialPort::BSerialPort() BSerialPort::BSerialPort()
: ffd(-1), : ffd(-1),
fBaudRate(B_19200_BPS), fBaudRate(B_19200_BPS),
@@ -50,7 +49,9 @@ BSerialPort::BSerialPort()
} }
/* Closes the port, if it's open, and deletes the devices list */ /*! \brief Frees the resources associated with the object.
Closes the port, if it's open, and deletes the devices list.
*/
BSerialPort::~BSerialPort() BSerialPort::~BSerialPort()
{ {
if (ffd > 0) if (ffd > 0)
@@ -63,28 +64,42 @@ BSerialPort::~BSerialPort()
} }
/* Opens a serial port. @param a valid port name */ /*! \brief Opens a serial port.
\param portName A valid port name
(i.e."/dev/ports/serial2", "serial2", ...)
\return
- A positive number if the serialport has been succesfully opened.
- An errorcode (negative integer) if not.
*/
status_t status_t
BSerialPort::Open(const char *portName) BSerialPort::Open(const char *portName)
{ {
char buf[64]; char buf[64];
//TODO: Check if portName is a valid name if (portName == NULL)
sprintf(buf, SERIAL_DIR"/%s", portName); return B_BAD_VALUE; // Heheee, we won't crash
if (portName[0] != '/')
sprintf(buf, SERIAL_DIR"/%s", portName);
else
// A name like "/dev/ports/serial2" was passed
sprintf(buf, "%s", portName);
if (ffd > 0) //If this port is already open, close it if (ffd > 0) //If this port is already open, close it
close(ffd); close(ffd);
ffd = open(buf, O_RDWR|O_NONBLOCK); //R5 seem to use this mask // We want "open()" to return immediately
ffd = open(buf, O_RDWR|O_NONBLOCK);
if (ffd > 0) if (ffd > 0)
DriverControl(); //Setup the port DriverControl(); //Setup the port
return (ffd < 0) ? ffd : B_OK; return (ffd > 0) ? ffd : errno;
} }
/* Closes the port */ /*! \brief Closes the port.
*/
void void
BSerialPort::Close(void) BSerialPort::Close(void)
{ {
@@ -94,33 +109,36 @@ BSerialPort::Close(void)
} }
/* Read some data from the serial port. */ /*! \brief Reads some bytes from the serial port.
/* @param the buffer where to transfer the data */ \param buf The buffer where to copy the data.
/* @param how many bytes to read */ \param count The maximum amount of bytes to read.
\return The amount of data read.
*/
ssize_t ssize_t
BSerialPort::Read(void *buf, size_t count) BSerialPort::Read(void *buf, size_t count)
{ {
if (ffd < 0) // We have no open port ssize_t err = read(ffd, buf, count);
return B_FILE_ERROR;
return read(ffd, buf, count); return (err >= 0) ? err : errno;
} }
/* Write some data to the serial port. */ /*! \brief Writes some bytes to the serial port.
/* @param the buffer from which transfer the data */ \param buf The buffer which copy the data from.
/* @param how many bytes to write */ \param count The amount of bytes to write.
*/
ssize_t ssize_t
BSerialPort::Write(const void *buf, size_t count) BSerialPort::Write(const void *buf, size_t count)
{ {
if (ffd < 0) // We have no open port ssize_t err = write(ffd, buf, count);
return B_FILE_ERROR;
return (err >= 0) ? err : errno;
return write(ffd, buf, count);
} }
/* Set blocking mode */ /*! \brief Set blocking mode
\param Blocking If true, enables the blocking mode. If false, disables it.
*/
void void
BSerialPort::SetBlocking(bool Blocking) BSerialPort::SetBlocking(bool Blocking)
{ {
@@ -129,8 +147,13 @@ BSerialPort::SetBlocking(bool Blocking)
} }
/* Set the timeout for the port */ /*! \brief Set the timeout for the port.
/* Valid values: B_INFINITE_TIMEOUT or any value between 0 and 25000000 */ \param microSeconds The timeout for the port.
Valid values are:
- \c B_INFINITE_TIMEOUT
- Any value between 0 and 25,000,000, but remember that the granularity
of the serial driver is 100,000 microseconds.
*/
status_t status_t
BSerialPort::SetTimeout(bigtime_t microSeconds) BSerialPort::SetTimeout(bigtime_t microSeconds)
{ {
@@ -146,7 +169,33 @@ BSerialPort::SetTimeout(bigtime_t microSeconds)
} }
/* Set the data rate (Baud rate) for the port */ /*! \brief Set the Baud rate for the port.
\param bitsPerSeconds The baud rate.
Valid values:
- \c B_0_BPS
- \c B_50_BPS
- \c B_75_BPS
- \c B_110_BPS
- \c B_134_BPS
- \c B_150_BPS
- \c B_200_BPS
- \c B_300_BPS
- \c B_600_BPS
- \c B_1200_BPS
- \c B_1800_BPS
- \c B_2400_BPS
- \c B_4800_BPS
- \c B_9600_BPS
- \c B_19200_BPS
- \c B_38400_BPS
- \c B_57600_BPS
- \c B_115200_BPS
- \c B_230400_BPS
- \c B_31250_BPS
\return
- \c B_OK if all goes fine,
- an error code if something goes wrong.
*/
status_t status_t
BSerialPort::SetDataRate(data_rate bitsPerSecond) BSerialPort::SetDataRate(data_rate bitsPerSecond)
{ {
@@ -156,7 +205,10 @@ BSerialPort::SetDataRate(data_rate bitsPerSecond)
} }
/* Get the data rate (Baud Rate) */ /*! \brief Get the current Baud Rate.
\return The current Baud Rate.
*/
data_rate data_rate
BSerialPort::DataRate(void) BSerialPort::DataRate(void)
{ {
@@ -173,7 +225,9 @@ BSerialPort::SetDataBits(data_bits numBits)
} }
/* Get the data bits */ /*! \brief Get the current data bits.
\return The current data bits.
*/
data_bits data_bits
BSerialPort::DataBits(void) BSerialPort::DataBits(void)
{ {
@@ -181,7 +235,12 @@ BSerialPort::DataBits(void)
} }
/* Set the stop bits (1 or 2) */ /*! \brief Set the stop bits.
\param numBits The number of stop bits
Valid values:
- \c B_STOP_BITS_1 (or \c B_STOP_BIT_1)
- \c B_STOP_BITS_2
*/
void void
BSerialPort::SetStopBits(stop_bits numBits) BSerialPort::SetStopBits(stop_bits numBits)
{ {
@@ -190,7 +249,9 @@ BSerialPort::SetStopBits(stop_bits numBits)
} }
/* Get the stop bits */ /*! \brief Get the current stop bits.
\return The current stop bits.
*/
stop_bits stop_bits
BSerialPort::StopBits(void) BSerialPort::StopBits(void)
{ {
@@ -198,7 +259,13 @@ BSerialPort::StopBits(void)
} }
/* Set the parity mode (ODD, PAIR, or NONE) */ /*! \brief Set the parity mode.
\param which The parity mode to set.
Valid values:
- \c B_ODD_PARITY
- \c B_EVEN_PARITY
- \c B_NO_PARITY
*/
void void
BSerialPort::SetParityMode(parity_mode which) BSerialPort::SetParityMode(parity_mode which)
{ {
@@ -207,7 +274,9 @@ BSerialPort::SetParityMode(parity_mode which)
} }
/* Get the parity mode */ /*! \brief Get the parity mode.
\return The current parity mode.
*/
parity_mode parity_mode
BSerialPort::ParityMode(void) BSerialPort::ParityMode(void)
{ {
@@ -215,7 +284,8 @@ BSerialPort::ParityMode(void)
} }
/* Clear the input buffer */ /*! \brief Clear the input buffer.
*/
void void
BSerialPort::ClearInput(void) BSerialPort::ClearInput(void)
{ {
@@ -223,7 +293,8 @@ BSerialPort::ClearInput(void)
} }
/* Clear the output buffer */ /*! \brief Clear the output buffer.
*/
void void
BSerialPort::ClearOutput(void) BSerialPort::ClearOutput(void)
{ {
@@ -231,7 +302,13 @@ BSerialPort::ClearOutput(void)
} }
/* Set the flow control (HARDWARE, SOFTWARE, or NONE) */ /*! \brief Set the flow control
\param method The type of flow control.
Valid values:
- \c B_HARDWARE_CONTROL
- \c B_SOFTWARE_CONTROL
- \c B_NOFLOW_CONTROL
*/
void void
BSerialPort::SetFlowControl(uint32 method) BSerialPort::SetFlowControl(uint32 method)
{ {
@@ -240,7 +317,9 @@ BSerialPort::SetFlowControl(uint32 method)
} }
/* Get the flow control */ /*! \brief Returns the selected flow control.
\return The flow control for the current open port.
*/
uint32 uint32
BSerialPort::FlowControl(void) BSerialPort::FlowControl(void)
{ {
@@ -268,8 +347,11 @@ BSerialPort::SetRTS(bool asserted)
} }
/* See how many chars are queued on the serial port, */ /*! \brief See how many chars are queued on the serial port.
/* waiting to be read */ \param wait_until_this_many A pointer to an int32 where you want
that value stored.
\return ?
*/
status_t status_t
BSerialPort::NumCharsAvailable(int32 *wait_until_this_many) BSerialPort::NumCharsAvailable(int32 *wait_until_this_many)
{ {
@@ -282,7 +364,9 @@ BSerialPort::NumCharsAvailable(int32 *wait_until_this_many)
} }
/* See if CTS is set */ /*! \brief See if the Clear to Send pin is asserted.
\return true if CTS is asserted, false if not.
*/
bool bool
BSerialPort::IsCTS(void) BSerialPort::IsCTS(void)
{ {
@@ -295,7 +379,9 @@ BSerialPort::IsCTS(void)
} }
/* See if DSR is set */ /*! \brief See if the Data Set Ready pin is asserted.
\return true if DSR is asserted, false if not.
*/
bool bool
BSerialPort::IsDSR(void) BSerialPort::IsDSR(void)
{ {
@@ -308,7 +394,9 @@ BSerialPort::IsDSR(void)
} }
/* See if RI is set */ /*! \brief See if the Ring Indicator pin is asserted.
\return true if RI is asserted, false if not.
*/
bool bool
BSerialPort::IsRI(void) BSerialPort::IsRI(void)
{ {
@@ -321,7 +409,9 @@ BSerialPort::IsRI(void)
} }
/* See if DCD is set */ /*! \brief See if the Data Carrier Detect pin is asserted.
\return true if DCD is asserted, false if not.
*/
bool bool
BSerialPort::IsDCD(void) BSerialPort::IsDCD(void)
{ {
@@ -334,10 +424,12 @@ BSerialPort::IsDCD(void)
} }
/* Wait until there's something to read from the serial port. */ /*! \brief Wait until there's something to read from the serial port.
/* If no data is ready, it will always block, ignoring the */ If no data is ready, it will always block, ignoring the
/* value of SetBlocking(); however, it respects the timeout */ value of SetBlocking(); however, it respects the timeout
/* set by SetTimeout(). */ set by SetTimeout().
\return The number of bytes available to be read.
*/
ssize_t ssize_t
BSerialPort::WaitForInput(void) BSerialPort::WaitForInput(void)
{ {
@@ -348,7 +440,10 @@ BSerialPort::WaitForInput(void)
} }
/* Returns the number of available Serial Ports. */ /*! \brief Count the number of available Serial Ports.
\return An integer which represents the number of available
serial ports.
*/
int32 int32
BSerialPort::CountDevices() BSerialPort::CountDevices()
{ {
@@ -361,11 +456,14 @@ BSerialPort::CountDevices()
} }
/* Get the device name for the given device.*/ /*! \brief Get the device name for the given device.
/* The first parameter is the number of the device */ \param n Number of the device you want to know the name of.
/* you want to know the name, the second is the buffer */ \param name The buffer where you want to store the name.
/* where you want to store the name, and the third is */ \param bufSize The size of the buffer.
/* the length of that buffer. */ \return
- \c B_ERROR if something goes wrong
- \c B_OK if all goes fine.
*/
status_t status_t
BSerialPort::GetDeviceName(int32 n, char *name, size_t bufSize) BSerialPort::GetDeviceName(int32 n, char *name, size_t bufSize)
{ {
@@ -375,7 +473,8 @@ BSerialPort::GetDeviceName(int32 n, char *name, size_t bufSize)
if (_fDevices != NULL) if (_fDevices != NULL)
dev = static_cast<char*>(_fDevices->ItemAt(n)); dev = static_cast<char*>(_fDevices->ItemAt(n));
if (dev != NULL && name != NULL) { if (dev != NULL && name != NULL)
{
strncpy(name, dev, bufSize); strncpy(name, dev, bufSize);
result = B_OK; result = B_OK;
} }
@@ -385,8 +484,10 @@ BSerialPort::GetDeviceName(int32 n, char *name, size_t bufSize)
/* Private or Reserved */ /* Private or Reserved */
/* Query the serial driver about the available devices, */ /*! \brief Build a list of available serial ports.
/* and build a list of them. */ Query the serial driver about the available devices,
and build a list of them.
*/
void void
BSerialPort::ScanDevices() BSerialPort::ScanDevices()
{ {
@@ -407,75 +508,80 @@ BSerialPort::ScanDevices()
} }
/* Send the options to the serial driver. */ /*! \brief Send the selected options to the serial driver.
/* Returns B_OK if all goes fine, an error code */ \return
/* if something goes wrong. */ - \c B_OK if all goes fine,
- an error code if something goes wrong.
*/
int int
BSerialPort::DriverControl() BSerialPort::DriverControl()
{ {
struct termio termioControl; struct termio options;
int err; int err;
if (ffd < 0) if (ffd < 0)
return B_NO_INIT; return B_NO_INIT;
//Load the current settings //Load the current settings
err = ioctl(ffd, TCGETA, &termioControl); err = tcgetattr(ffd, &options);
if (err < 0) if (err < 0)
return errno; return errno;
// Reset all flags // Reset all flags
termioControl.c_cflag &= ~(CRTSCTS | CSIZE | CBAUD | CSTOPB | PARODD | PARENB); options.c_cflag &= ~(CRTSCTS | CSIZE | CBAUD | CSTOPB | PARODD | PARENB);
termioControl.c_iflag &= ~(IXON | IXOFF | IXANY | INPCK); options.c_iflag &= ~(IXON | IXOFF | IXANY | INPCK);
termioControl.c_lflag &= ~(ECHO | ECHONL | ISIG | ICANON); options.c_lflag &= ~(ECHO | ECHONL | ISIG | ICANON);
//Set the flags to the wanted values //Set the flags to the wanted values
if (fFlow & B_HARDWARE_CONTROL) if (fFlow & B_HARDWARE_CONTROL)
termioControl.c_cflag |= CRTSCTS; options.c_cflag |= CRTSCTS;
if (fFlow & B_SOFTWARE_CONTROL) if (fFlow & B_SOFTWARE_CONTROL)
termioControl.c_iflag |= (IXON | IXOFF); options.c_iflag |= (IXON | IXOFF);
if (fStopBits & B_STOP_BITS_2) if (fStopBits & B_STOP_BITS_2)
termioControl.c_cflag |= CSTOPB; // We want 2 stop bits options.c_cflag |= CSTOPB; // Set 2 stop bits
if (fDataBits == B_DATA_BITS_8) if (fDataBits & B_DATA_BITS_8)
termioControl.c_cflag |= CS8; // We want 8 data bits options.c_cflag |= CS8; // Set 8 data bits
//Ok, set the parity now //Ok, set the parity now
if (fParityMode != B_NO_PARITY) if (fParityMode != B_NO_PARITY)
{ {
termioControl.c_cflag |= PARENB; //Enable parity options.c_cflag |= PARENB; //Enable parity
if (fParityMode == B_ODD_PARITY) if (fParityMode == B_ODD_PARITY)
termioControl.c_cflag |= PARODD; //Select odd parity options.c_cflag |= PARODD; //Select odd parity
} }
//Set the baud rate //Set the baud rate
termioControl.c_cflag |= (fBaudRate & CBAUD); cfsetispeed(&options, fBaudRate);
cfsetospeed(&options, fBaudRate);
//options.c_cflag |= (fBaudRate & CBAUD);
//Set the timeout //Set the timeout
if (fBlocking) if (fBlocking)
{ {
if (fTimeout == B_INFINITE_TIMEOUT) if (fTimeout == B_INFINITE_TIMEOUT)
{ {
termioControl.c_cc[VTIME] = 0; options.c_cc[VTIME] = 0;
termioControl.c_cc[VMIN] = 1; options.c_cc[VMIN] = 1;
} }
else if (fTimeout == 0) else if (fTimeout == 0)
termioControl.c_cc[VMIN] = 0; options.c_cc[VMIN] = 0;
else else
{ {
int t = fTimeout / 100000; int timeout = fTimeout / 100000;
termioControl.c_cc[VTIME] = (t == 0) ? 1 : t; options.c_cc[VTIME] = (timeout == 0) ? 1 : timeout;
termioControl.c_cc[VMIN] = 1; options.c_cc[VMIN] = 1;
} }
} else } else
termioControl.c_cc[VMIN] = 0; options.c_cc[VMIN] = 0;
//Ok, finished. Now tell the driver what we decided //Ok, finished. Now tell the driver what we decided
err = ioctl(ffd, TCSETA, &termioControl); err = tcsetattr(ffd, TCSANOW, &options);
return err > 0 ? err : errno; return (err > 0) ? err : errno;
} }