diff options
author | limasdf@gmail.com <limasdf@gmail.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-27 13:42:32 +0000 |
---|---|---|
committer | limasdf@gmail.com <limasdf@gmail.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-27 13:42:32 +0000 |
commit | 862485e5d3b6428614caef3fb4a0528a81fe64fa (patch) | |
tree | 12ca68c3341ce6d3ff7faeeaa643be0a00295a17 | |
parent | b2fe1859600335e852fc78b7361a7388c94f52db (diff) | |
download | chromium_src-862485e5d3b6428614caef3fb4a0528a81fe64fa.zip chromium_src-862485e5d3b6428614caef3fb4a0528a81fe64fa.tar.gz chromium_src-862485e5d3b6428614caef3fb4a0528a81fe64fa.tar.bz2 |
Adds Serial API to set data bits, parity, stop bits.
BUG=261688
TEST=BUILD Success, run serial.open() with options.
Review URL: https://chromiumcodereview.appspot.com/22804008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@219782 0039d316-1c4b-4281-b951-d872f2087c98
8 files changed, 212 insertions, 93 deletions
diff --git a/chrome/browser/extensions/api/serial/serial_api.cc b/chrome/browser/extensions/api/serial/serial_api.cc index b958944..3f33da4 100644 --- a/chrome/browser/extensions/api/serial/serial_api.cc +++ b/chrome/browser/extensions/api/serial/serial_api.cc @@ -12,6 +12,8 @@ using content::BrowserThread; +namespace serial = extensions::api::serial; + namespace extensions { const char kConnectionIdKey[] = "connectionId"; @@ -19,6 +21,9 @@ const char kDataKey[] = "data"; const char kBytesReadKey[] = "bytesRead"; const char kBytesWrittenKey[] = "bytesWritten"; const char kBitrateKey[] = "bitrate"; +const char kDataBitKey[] = "dataBit"; +const char kParityKey[] = "parityBit"; +const char kStopBitKey[] = "stopBit"; const char kSuccessKey[] = "success"; const char kDcdKey[] = "dcd"; const char kCtsKey[] = "cts"; @@ -83,7 +88,9 @@ bool SerialGetPortsFunction::Respond() { // But we'd like to pick something that has a chance of working, and 9600 is a // good balance between popularity and speed. So 9600 it is. SerialOpenFunction::SerialOpenFunction() - : bitrate_(9600) { + : bitrate_(9600), databit_(serial::DATA_BIT_EIGHTBIT), + parity_(serial::PARITY_BIT_NOPARITY), + stopbit_(serial::STOP_BIT_ONESTOPBIT) { } SerialOpenFunction::~SerialOpenFunction() { @@ -99,6 +106,24 @@ bool SerialOpenFunction::Prepare() { scoped_ptr<base::DictionaryValue> options = params_->options->ToValue(); if (options->HasKey(kBitrateKey)) EXTENSION_FUNCTION_VALIDATE(options->GetInteger(kBitrateKey, &bitrate_)); + if (options->HasKey(kDataBitKey)) { + std::string data; + options->GetString(kDataBitKey, &data); + if (!data.empty()) + databit_ = serial::ParseDataBit(data); + } + if (options->HasKey(kParityKey)) { + std::string parity; + options->GetString(kParityKey, &parity); + if (!parity.empty()) + parity_ = serial::ParseParityBit(parity); + } + if (options->HasKey(kStopBitKey)) { + std::string stopbit; + options->GetString(kStopBitKey, &stopbit); + if (!stopbit.empty()) + stopbit_ = serial::ParseStopBit(stopbit); + } } return true; @@ -116,6 +141,9 @@ void SerialOpenFunction::Work() { SerialConnection* serial_connection = CreateSerialConnection( params_->port, bitrate_, + databit_, + parity_, + stopbit_, extension_->id()); CHECK(serial_connection); int id = manager_->Add(serial_connection); @@ -143,8 +171,12 @@ void SerialOpenFunction::Work() { SerialConnection* SerialOpenFunction::CreateSerialConnection( const std::string& port, int bitrate, + serial::DataBit databit, + serial::ParityBit parity, + serial::StopBit stopbit, const std::string& owner_extension_id) { - return new SerialConnection(port, bitrate, owner_extension_id); + return new SerialConnection(port, bitrate, databit, parity, stopbit, + owner_extension_id); } bool SerialOpenFunction::DoesPortExist(const std::string& port) { diff --git a/chrome/browser/extensions/api/serial/serial_api.h b/chrome/browser/extensions/api/serial/serial_api.h index cd3a8bb..6798ab5 100644 --- a/chrome/browser/extensions/api/serial/serial_api.h +++ b/chrome/browser/extensions/api/serial/serial_api.h @@ -13,6 +13,8 @@ #include "chrome/common/extensions/api/serial.h" #include "net/base/io_buffer.h" +namespace serial = extensions::api::serial; + namespace extensions { class SerialConnection; @@ -69,12 +71,19 @@ class SerialOpenFunction : public SerialAsyncApiFunction { virtual SerialConnection* CreateSerialConnection( const std::string& port, int bitrate, + serial::DataBit databit, + serial::ParityBit parity, + serial::StopBit stopbit, const std::string& owner_extension_id); + virtual bool DoesPortExist(const std::string& port); private: scoped_ptr<api::serial::Open::Params> params_; int bitrate_; + api::serial::DataBit databit_; + api::serial::ParityBit parity_; + api::serial::StopBit stopbit_; }; class SerialCloseFunction : public SerialAsyncApiFunction { diff --git a/chrome/browser/extensions/api/serial/serial_apitest.cc b/chrome/browser/extensions/api/serial/serial_apitest.cc index 646dfd1..a61fb3c 100644 --- a/chrome/browser/extensions/api/serial/serial_apitest.cc +++ b/chrome/browser/extensions/api/serial/serial_apitest.cc @@ -22,6 +22,8 @@ using testing::Return; using content::BrowserThread; +namespace serial = extensions::api::serial; + namespace { class SerialApiTest : public ExtensionApiTest { @@ -52,8 +54,12 @@ class FakeEchoSerialConnection : public SerialConnection { explicit FakeEchoSerialConnection( const std::string& port, int bitrate, + serial::DataBit databit, + serial::ParityBit parity, + serial::StopBit stopbit, const std::string& owner_extension_id) - : SerialConnection(port, bitrate, owner_extension_id), + : SerialConnection(port, bitrate, databit, parity, stopbit, + owner_extension_id), opened_(true) { Flush(); opened_ = false; @@ -118,9 +124,13 @@ class FakeSerialOpenFunction : public SerialOpenFunction { virtual SerialConnection* CreateSerialConnection( const std::string& port, int bitrate, + serial::DataBit databit, + serial::ParityBit parity, + serial::StopBit stopbit, const std::string& owner_extension_id) OVERRIDE { FakeEchoSerialConnection* serial_connection = - new FakeEchoSerialConnection(port, bitrate, owner_extension_id); + new FakeEchoSerialConnection(port, bitrate, databit, parity, stopbit, + owner_extension_id); EXPECT_CALL(*serial_connection, GetControlSignals(_)). Times(1).WillOnce(Return(true)); EXPECT_CALL(*serial_connection, SetControlSignals(_)). diff --git a/chrome/browser/extensions/api/serial/serial_connection.cc b/chrome/browser/extensions/api/serial/serial_connection.cc index ffa49b8..aed373c 100644 --- a/chrome/browser/extensions/api/serial/serial_connection.cc +++ b/chrome/browser/extensions/api/serial/serial_connection.cc @@ -10,6 +10,9 @@ #include "base/lazy_instance.h" #include "base/strings/string_util.h" #include "chrome/browser/extensions/api/api_resource_manager.h" +#include "chrome/common/extensions/api/serial.h" + +namespace serial = extensions::api::serial; namespace extensions { @@ -27,8 +30,12 @@ ApiResourceManager<SerialConnection>::GetFactoryInstance() { } SerialConnection::SerialConnection(const std::string& port, int bitrate, + serial::DataBit databit, + serial::ParityBit parity, + serial::StopBit stopbit, const std::string& owner_extension_id) : ApiResource(owner_extension_id), port_(port), bitrate_(bitrate), + databit_(databit), parity_(parity), stopbit_(stopbit), file_(base::kInvalidPlatformFileValue) { CHECK_GE(bitrate, 0); } diff --git a/chrome/browser/extensions/api/serial/serial_connection.h b/chrome/browser/extensions/api/serial/serial_connection.h index 3b838ba..f881301 100644 --- a/chrome/browser/extensions/api/serial/serial_connection.h +++ b/chrome/browser/extensions/api/serial/serial_connection.h @@ -12,11 +12,14 @@ #include "base/platform_file.h" #include "chrome/browser/extensions/api/api_resource.h" #include "chrome/browser/extensions/api/api_resource_manager.h" +#include "chrome/common/extensions/api/serial.h" #include "content/public/browser/browser_thread.h" #include "net/base/io_buffer.h" using content::BrowserThread; +namespace serial = extensions::api::serial; + namespace extensions { extern const char kSerialConnectionNotFoundError[]; @@ -25,8 +28,9 @@ extern const char kSerialConnectionNotFoundError[]; // _win and _posix versions of the the .cc file. class SerialConnection : public ApiResource { public: - SerialConnection(const std::string& port, - int bitrate, + SerialConnection(const std::string& port, int bitrate, + serial::DataBit databit, serial::ParityBit parity, + serial::StopBit stopbit, const std::string& owner_extension_id); virtual ~SerialConnection(); @@ -71,6 +75,9 @@ class SerialConnection : public ApiResource { } std::string port_; int bitrate_; + serial::DataBit databit_; + serial::ParityBit parity_; + serial::StopBit stopbit_; base::PlatformFile file_; }; diff --git a/chrome/browser/extensions/api/serial/serial_connection_posix.cc b/chrome/browser/extensions/api/serial/serial_connection_posix.cc index 25c73e3..3d24700 100644 --- a/chrome/browser/extensions/api/serial/serial_connection_posix.cc +++ b/chrome/browser/extensions/api/serial/serial_connection_posix.cc @@ -9,103 +9,113 @@ namespace extensions { -bool SerialConnection::PostOpen() { - struct termios options; - - // Start with existing options and modify. - tcgetattr(file_, &options); - - // Bitrate (sometimes erroneously referred to as baud rate). - if (bitrate_ >= 0) { - int bitrate_opt_; +namespace { + int getBaudRate(int bitrate_) { switch (bitrate_) { case 0: - bitrate_opt_ = B0; - break; + return B0; case 50: - bitrate_opt_ = B50; - break; + return B50; case 75: - bitrate_opt_ = B75; - break; + return B75; case 110: - bitrate_opt_ = B110; - break; + return B110; case 134: - bitrate_opt_ = B134; - break; + return B134; case 150: - bitrate_opt_ = B150; - break; + return B150; case 200: - bitrate_opt_ = B200; - break; + return B200; case 300: - bitrate_opt_ = B300; - break; + return B300; case 600: - bitrate_opt_ = B600; - break; + return B600; case 1200: - bitrate_opt_ = B1200; - break; + return B1200; case 1800: - bitrate_opt_ = B1800; - break; + return B1800; case 2400: - bitrate_opt_ = B2400; - break; + return B2400; case 4800: - bitrate_opt_ = B4800; - break; + return B4800; case 9600: - bitrate_opt_ = B9600; - break; + return B9600; case 19200: - bitrate_opt_ = B19200; - break; + return B19200; case 38400: - bitrate_opt_ = B38400; - break; + return B38400; #if defined(OS_POSIX) && !defined(OS_MACOSX) case 57600: - bitrate_opt_ = B57600; - break; + return B57600; case 115200: - bitrate_opt_ = B115200; - break; + return B115200; case 230400: - bitrate_opt_ = B230400; - break; + return B230400; case 460800: - bitrate_opt_ = B460800; - break; + return B460800; case 576000: - bitrate_opt_ = B576000; - break; + return B576000; case 921600: - bitrate_opt_ = B921600; - break; + return B921600; default: - bitrate_opt_ = B9600; + return B9600; #else // MACOSX doesn't define constants bigger than 38400. // So if it is MACOSX and the value doesn't fit any of the defined constants // It will setup the bitrate with 'bitrate_' (just forwarding the value) default: - bitrate_opt_ = bitrate_; + return bitrate_; #endif } + } +} // namespace + +bool SerialConnection::PostOpen() { + struct termios options; + + // Start with existing options and modify. + tcgetattr(file_, &options); + + // Bitrate (sometimes erroneously referred to as baud rate). + if (bitrate_ >= 0) { + int bitrate_opt_ = getBaudRate(bitrate_); cfsetispeed(&options, bitrate_opt_); cfsetospeed(&options, bitrate_opt_); } - // 8N1 - options.c_cflag &= ~PARENB; - options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; - options.c_cflag |= CS8; + switch (databit_) { + case serial::DATA_BIT_SEVENBIT: + options.c_cflag |= CS7; + break; + case serial::DATA_BIT_EIGHTBIT: + default: + options.c_cflag |= CS8; + break; + } + switch (stopbit_) { + case serial::STOP_BIT_TWOSTOPBIT: + options.c_cflag |= CSTOPB; + break; + case serial::STOP_BIT_ONESTOPBIT: + default: + options.c_cflag &= ~CSTOPB; + break; + } + switch (parity_) { + case serial::PARITY_BIT_EVENPARITY: + options.c_cflag |= PARENB; + options.c_cflag &= ~PARODD; + break; + case serial::PARITY_BIT_ODDPARITY: + options.c_cflag |= (PARENB | PARODD); + break; + case serial::PARITY_BIT_NOPARITY: + default: + options.c_cflag &= ~(PARENB | PARODD); + break; + } options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // Enable receiver and set local mode diff --git a/chrome/browser/extensions/api/serial/serial_connection_win.cc b/chrome/browser/extensions/api/serial/serial_connection_win.cc index 87a146d..d6d9b12 100644 --- a/chrome/browser/extensions/api/serial/serial_connection_win.cc +++ b/chrome/browser/extensions/api/serial/serial_connection_win.cc @@ -10,6 +10,60 @@ namespace extensions { +namespace { +int getBaudRate(int bitrate_) { + switch (bitrate_) { + case 110: return CBR_110; + case 300: return CBR_300; + case 600: return CBR_600; + case 1200: return CBR_1200; + case 2400: return CBR_2400; + case 4800: return CBR_4800; + case 9600: return CBR_9600; + case 14400: return CBR_14400; + case 19200: return CBR_19200; + case 38400: return CBR_38400; + case 57600: return CBR_57600; + case 115200: return CBR_115200; + case 128000: return CBR_128000; + case 256000: return CBR_256000; + default: return CBR_9600; + } +} + +int getDataBit(serial::DataBit databit) { + switch (databit) { + case serial::DATA_BIT_SEVENBIT: + return 7; + case serial::DATA_BIT_EIGHTBIT: + default: + return 8; + } +} + +int getParity(serial::ParityBit parity) { + switch (parity) { + case serial::PARITY_BIT_EVENPARITY: + return EVENPARITY; + case serial::PARITY_BIT_ODDPARITY: + return SPACEPARITY; + case serial::PARITY_BIT_NOPARITY: + default: + return NOPARITY; + } +} + +int getStopBit(serial::StopBit stopbit) { + switch (stopbit) { + case serial::STOP_BIT_TWOSTOPBIT: + return TWOSTOPBITS; + case serial::STOP_BIT_ONESTOPBIT: + default: + return ONESTOPBIT; + } +} +} // namespace + bool SerialConnection::PostOpen() { // Set timeouts so that reads return immediately with whatever could be read // without blocking. @@ -23,32 +77,11 @@ bool SerialConnection::PostOpen() { if (!GetCommState(file_, &dcb)) return false; - if (bitrate_ >= 0) { - bool speed_found = true; - DWORD speed = CBR_9600; - switch (bitrate_) { - case 110: speed = CBR_110; break; - case 300: speed = CBR_300; break; - case 600: speed = CBR_600; break; - case 1200: speed = CBR_1200; break; - case 2400: speed = CBR_2400; break; - case 4800: speed = CBR_4800; break; - case 9600: speed = CBR_9600; break; - case 14400: speed = CBR_14400; break; - case 19200: speed = CBR_19200; break; - case 38400: speed = CBR_38400; break; - case 57600: speed = CBR_57600; break; - case 115200: speed = CBR_115200; break; - case 128000: speed = CBR_128000; break; - case 256000: speed = CBR_256000; break; - default: speed_found = false; break; - } - if (speed_found) - dcb.BaudRate = speed; - } - dcb.ByteSize = 8; - dcb.StopBits = ONESTOPBIT; - dcb.Parity = NOPARITY; + dcb.BaudRate = getBaudRate(bitrate_); + dcb.ByteSize = getDataBit(databit_); + dcb.Parity = getParity(parity_); + dcb.StopBits = getStopBit(stopbit_); + if (!SetCommState(file_, &dcb)) return false; diff --git a/chrome/common/extensions/api/serial.idl b/chrome/common/extensions/api/serial.idl index 1df7550..c6429ff 100644 --- a/chrome/common/extensions/api/serial.idl +++ b/chrome/common/extensions/api/serial.idl @@ -8,14 +8,25 @@ namespace serial { callback GetPortsCallback = void (DOMString[] ports); + enum DataBit { sevenbit, eightbit }; + enum ParityBit { noparity, oddparity, evenparity }; + enum StopBit { onestopbit, twostopbit }; + dictionary OpenOptions { // The requested bitrate of the connection to be opened. For compatibility // with the widest range of hardware, this number should match one of // commonly-available bitrates, such as 110, 300, 1200, 2400, 4800, 9600, // 14400, 19200, 38400, 57600, 115200. There is no guarantee, of course, // that the device connected to the serial port will support the requested - // bitrate, even if the port itself supports that bitrate. - long bitrate; + // bitrate, even if the port itself supports that bitrate. <code>9600</code> + // will be passed by default. + long? bitrate; + // <code>"eightbit"</code> will be passed by default. + DataBit? dataBit; + // <code>"noparity"</code> will be passed by default. + ParityBit? parityBit; + // <code>"onestopbit"</code> will be passed by default. + StopBit? stopBit; }; dictionary OpenInfo { |