.. _program_listing_file_src_controller_devicecontroller.cpp: Program Listing for File devicecontroller.cpp ============================================= |exhale_lsh| :ref:`Return to documentation for file ` (``src/controller/devicecontroller.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /* * SerialDevice - Utility class for managing devices connected via USB/Bluetooth. */ #include #include #include #include #include "dialog/preferencesdialog.h" #include "devicecontroller.h" #include "widget/maestrocontrolwidget.h" namespace PixelMaestroStudio { DeviceController::DeviceController(const QString& port_name) { this->port_name_ = port_name; /* * Check whether the port name is an IP address. * If so, initialize a TCP socket. * Otherwise, assume a serial device. */ QRegularExpression exp("^(?:[0-9]{1,3}.){3}[0-9]{1,3}"); bool is_network_device = exp.match(port_name).hasMatch(); if (is_network_device) { this->device_ = QSharedPointer(new QTcpSocket()); this->device_type_ = DeviceType::TCP; } else { this->device_ = QSharedPointer(new QSerialPort()); this->device_type_ = DeviceType::Serial; } // Look up the device in settings QSettings settings; int num_devices = settings.beginReadArray(PreferencesDialog::devices); for (int device = 0; device < num_devices; device++) { settings.setArrayIndex(device); QString comp_name = settings.value(PreferencesDialog::device_port).toString(); if (port_name == comp_name) { set_real_time_update(settings.value(PreferencesDialog::device_real_time_refresh).toBool()); set_autoconnect(settings.value(PreferencesDialog::device_autoconnect).toBool()); // Load Section Map model (if it exists) int num_maps = settings.beginReadArray(PreferencesDialog::section_map); if (num_maps > 0) { section_map_model = new SectionMapModel(); for (int row = 0; row < num_maps; row++) { settings.setArrayIndex(row); section_map_model->add_section(); QString remote_section = settings.value(PreferencesDialog::section_map_remote).toString(); section_map_model->item(row, 1)->setText(remote_section); } } settings.endArray(); break; } } settings.endArray(); } bool DeviceController::connect() { if (device_type_ == DeviceType::Serial) { QSerialPort* serial_device = dynamic_cast(device_.data()); if (!serial_device) return false; serial_device->setPortName(port_name_); serial_device->setBaudRate(baud_rate_); // Set comm settings serial_device->setFlowControl(QSerialPort::FlowControl::NoFlowControl); serial_device->setParity(QSerialPort::Parity::NoParity); serial_device->setDataBits(QSerialPort::DataBits::Data8); serial_device->setStopBits(QSerialPort::StopBits::OneStop); return (serial_device->open(QIODevice::WriteOnly)); } else if (device_type_ == DeviceType::TCP) { // Extract the IP address and port number QRegularExpression address_re("^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}"); QRegularExpression port_re("[^:][0-9]+$"); QString address = address_re.match(port_name_).captured(0); QString port = port_re.match(port_name_).captured(0); // If no port number is found, use the default uint16_t port_num = static_cast(port.toUInt()); if (port_num == 0) { QSettings settings; port_num = PORT_NUM; } QTcpSocket* tcp_device = dynamic_cast(device_.data()); if (!tcp_device) return false; tcp_device->connectToHost(address, port_num); // Wait for a connection // TODO: Make non-blocking return tcp_device->waitForConnected(TIMEOUT); } return false; } bool DeviceController::disconnect() { if (device_type_ == DeviceType::Serial && device_) { bool flushed = dynamic_cast(device_.data())->flush(); device_->close(); return flushed; } else if (device_type_ == DeviceType::TCP && device_) { QTcpSocket* tcp_device = dynamic_cast(device_.data()); tcp_device->flush(); tcp_device->disconnectFromHost(); return true; } return false; } bool DeviceController::get_autoconnect() const { return autoconnect_; } QIODevice* DeviceController::get_device() const { return device_.data(); } bool DeviceController::get_open() const { if (device_) { switch (device_type_) { case DeviceType::Serial: return dynamic_cast(device_.data())->isOpen(); case DeviceType::TCP: return dynamic_cast(device_.data())->state() == QAbstractSocket::ConnectedState; } } return false; } QString DeviceController::get_port_name() const { return port_name_; } bool DeviceController::get_real_time_refresh_enabled() const { return real_time_updates_; } void DeviceController::flush() { switch (device_type_) { case DeviceType::Serial: dynamic_cast(device_.data())->flush(); break; case DeviceType::TCP: dynamic_cast(device_.data())->flush(); break; } } void DeviceController::set_autoconnect(bool autoconnect) { this->autoconnect_ = autoconnect; } void DeviceController::set_port_name(const QString &port_name) { this->port_name_ = port_name; } void DeviceController::set_real_time_update(bool enabled) { this->real_time_updates_ = enabled; } }