log0.3
This commit is contained in:
67
src/hardware/drivers/serial/SerialCapabilities.h
Normal file
67
src/hardware/drivers/serial/SerialCapabilities.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <QString>
|
||||
|
||||
namespace softbus::hardware::drivers::serial::capabilities
|
||||
{
|
||||
|
||||
struct SerialDefaults
|
||||
{
|
||||
int baudRate = 115200;
|
||||
int dataBits = 8;
|
||||
const char* parity = "none";
|
||||
int stopBits = 1;
|
||||
const char* flowControl = "none";
|
||||
};
|
||||
|
||||
inline constexpr SerialDefaults kDefaults{};
|
||||
|
||||
inline constexpr std::array<int, 5> kBaudRates{9600, 19200, 38400, 57600, 115200};
|
||||
inline constexpr std::array<int, 4> kDataBits{5, 6, 7, 8};
|
||||
inline constexpr std::array<const char*, 3> kParity{"none", "even", "odd"};
|
||||
inline constexpr std::array<int, 2> kStopBits{1, 2};
|
||||
inline constexpr std::array<const char*, 3> kFlowControl{"none", "hardware", "software"};
|
||||
|
||||
inline bool isValidBaud(int v)
|
||||
{
|
||||
for (int b : kBaudRates) {
|
||||
if (b == v) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool isValidDataBits(int v)
|
||||
{
|
||||
for (int b : kDataBits) {
|
||||
if (b == v) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool isValidParity(const QString& s)
|
||||
{
|
||||
for (const char* p : kParity) {
|
||||
if (s == QLatin1String(p)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool isValidStopBits(int v)
|
||||
{
|
||||
for (int b : kStopBits) {
|
||||
if (b == v) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool isValidFlowControl(const QString& s)
|
||||
{
|
||||
for (const char* f : kFlowControl) {
|
||||
if (s == QLatin1String(f)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace softbus::hardware::drivers::serial::capabilities
|
||||
|
||||
138
src/hardware/drivers/serial/SerialQtDriver.cpp
Normal file
138
src/hardware/drivers/serial/SerialQtDriver.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
#include "hardware/drivers/serial/SerialQtDriver.h"
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
#include "utils/logs/logging.h"
|
||||
|
||||
namespace softbus::hardware::drivers::serial
|
||||
{
|
||||
|
||||
SerialQtDriver::SerialQtDriver(QObject* parent)
|
||||
: QObject(parent),
|
||||
m_port(this)
|
||||
{
|
||||
connect(&m_port, &QSerialPort::readyRead, this, &SerialQtDriver::handleReadyRead);
|
||||
connect(&m_port, &QSerialPort::errorOccurred, this, &SerialQtDriver::handleError);
|
||||
}
|
||||
|
||||
SerialQtDriver::~SerialQtDriver()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool SerialQtDriver::Open(const std::string& endpoint)
|
||||
{
|
||||
if (m_port.isOpen()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
m_port.setPortName(QString::fromStdString(endpoint));
|
||||
if (!m_port.open(QIODevice::ReadWrite)) {
|
||||
if (m_errorCallback) {
|
||||
m_errorCallback(m_port.errorString().toStdString());
|
||||
}
|
||||
LOG_WARNING() << "SerialQtDriver: failed to open port" << m_port.portName() << ":" << m_port.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_DEBUG() << "SerialQtDriver: opened port" << m_port.portName();
|
||||
return true;
|
||||
}
|
||||
|
||||
void SerialQtDriver::Close()
|
||||
{
|
||||
if (m_port.isOpen()) {
|
||||
const QString name = m_port.portName();
|
||||
m_port.close();
|
||||
LOG_DEBUG() << "SerialQtDriver: closed port" << name;
|
||||
}
|
||||
}
|
||||
|
||||
bool SerialQtDriver::Write(const std::vector<std::uint8_t>& data)
|
||||
{
|
||||
if (!m_port.isOpen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const QByteArray bytes(reinterpret_cast<const char*>(data.data()), static_cast<int>(data.size()));
|
||||
const qint64 written = m_port.write(bytes);
|
||||
if (written != bytes.size()) {
|
||||
LOG_WARNING() << "SerialQtDriver: partial write on" << m_port.portName() << "written" << written << "of"
|
||||
<< bytes.size();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SerialQtDriver::SetReadCallback(ReadCallback cb)
|
||||
{
|
||||
m_readCallback = std::move(cb);
|
||||
}
|
||||
|
||||
void SerialQtDriver::SetErrorCallback(ErrorCallback cb)
|
||||
{
|
||||
m_errorCallback = std::move(cb);
|
||||
}
|
||||
|
||||
void SerialQtDriver::SetBaudRate(QSerialPort::BaudRate baud)
|
||||
{
|
||||
m_port.setBaudRate(baud);
|
||||
}
|
||||
|
||||
void SerialQtDriver::SetDataBits(QSerialPort::DataBits bits)
|
||||
{
|
||||
m_port.setDataBits(bits);
|
||||
}
|
||||
|
||||
void SerialQtDriver::SetParity(QSerialPort::Parity parity)
|
||||
{
|
||||
m_port.setParity(parity);
|
||||
}
|
||||
|
||||
void SerialQtDriver::SetStopBits(QSerialPort::StopBits stopBits)
|
||||
{
|
||||
m_port.setStopBits(stopBits);
|
||||
}
|
||||
|
||||
void SerialQtDriver::SetFlowControl(QSerialPort::FlowControl flow)
|
||||
{
|
||||
m_port.setFlowControl(flow);
|
||||
}
|
||||
|
||||
void SerialQtDriver::handleReadyRead()
|
||||
{
|
||||
if (!m_readCallback) {
|
||||
const QByteArray data = m_port.readAll();
|
||||
LOG_DEBUG() << "SerialQtDriver: dropped" << data.size() << "bytes on" << m_port.portName()
|
||||
<< "because no read callback is set";
|
||||
return;
|
||||
}
|
||||
|
||||
const QByteArray data = m_port.readAll();
|
||||
if (data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::uint8_t> buffer(reinterpret_cast<const std::uint8_t*>(data.constData()),
|
||||
reinterpret_cast<const std::uint8_t*>(data.constData()) + data.size());
|
||||
m_readCallback(buffer);
|
||||
}
|
||||
|
||||
void SerialQtDriver::handleError(QSerialPort::SerialPortError error)
|
||||
{
|
||||
if (error == QSerialPort::NoError) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QString msg =
|
||||
QStringLiteral("SerialQtDriver error on %1: %2").arg(m_port.portName(), m_port.errorString());
|
||||
|
||||
LOG_WARNING() << msg;
|
||||
|
||||
if (m_errorCallback) {
|
||||
m_errorCallback(msg.toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace softbus::hardware::drivers::serial
|
||||
|
||||
85
src/hardware/drivers/serial/SerialQtDriver.h
Normal file
85
src/hardware/drivers/serial/SerialQtDriver.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QSerialPort>
|
||||
#include <QString>
|
||||
|
||||
#include "hardware/interfaces/IStreamDriver.h"
|
||||
|
||||
// 这里的串口的唯一标识是串口的端口名,如 /dev/ttyUSB0, can0, tcp://...
|
||||
// 串口的endpoint是串口的端口名,如 /dev/ttyUSB0, can0, tcp://...
|
||||
// 使用说明:
|
||||
// 1. 创建一个SerialQtDriver对象
|
||||
// 2. 调用Open方法打开串口
|
||||
// 3. 调用Write方法写数据
|
||||
// 4. 调用SetReadCallback方法设置读回调
|
||||
// 5. 调用SetErrorCallback方法设置错误回调
|
||||
// 6. 调用Close方法关闭串口
|
||||
// 7. 调用SetBaudRate方法设置波特率
|
||||
// 8. 调用SetDataBits方法设置数据位
|
||||
// 9. 调用SetParity方法设置校验位
|
||||
// 10. 调用SetStopBits方法设置停止位
|
||||
// 11. 调用SetFlowControl方法设置流控制
|
||||
// eg:
|
||||
// SerialQtDriver driver;
|
||||
// driver.Open("/dev/ttyUSB0");
|
||||
// driver.Write({0x01, 0x02, 0x03});
|
||||
// driver.SetReadCallback([](const std::vector<std::uint8_t>& data) {
|
||||
// std::cout << "read data: " << data << std::endl;
|
||||
// });
|
||||
// driver.SetErrorCallback([](const std::string& error) {
|
||||
// std::cout << "error: " << error << std::endl;
|
||||
// });
|
||||
// driver.Close();
|
||||
// 12. 调用SetBaudRate方法设置波特率
|
||||
// 13. 调用SetDataBits方法设置数据位
|
||||
// 14. 调用SetParity方法设置校验位
|
||||
// 15. 调用SetStopBits方法设置停止位
|
||||
// 16. 调用SetFlowControl方法设置流控制
|
||||
// eg:
|
||||
// driver.SetBaudRate(QSerialPort::Baud115200);
|
||||
// driver.SetDataBits(QSerialPort::Data8);
|
||||
// driver.SetParity(QSerialPort::NoParity);
|
||||
// driver.SetStopBits(QSerialPort::OneStop);
|
||||
// driver.SetFlowControl(QSerialPort::NoFlowControl);
|
||||
// driver.Close();
|
||||
|
||||
namespace softbus::hardware::drivers::serial
|
||||
{
|
||||
|
||||
// 基于 Qt 的串口驱动实现:只负责串口 open/read/write,不包含设备注册、数据库或协议逻辑
|
||||
class SerialQtDriver : public QObject, public softbus::hardware::interfaces::IStreamDriver
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SerialQtDriver(QObject* parent = nullptr);
|
||||
~SerialQtDriver() override;
|
||||
|
||||
bool Open(const std::string& endpoint) override;
|
||||
void Close() override;
|
||||
|
||||
bool Write(const std::vector<std::uint8_t>& data) override;
|
||||
|
||||
void SetReadCallback(ReadCallback cb) override;
|
||||
void SetErrorCallback(ErrorCallback cb) override;
|
||||
|
||||
// 允许上层配置串口参数(最小集合)
|
||||
void SetBaudRate(QSerialPort::BaudRate baud);
|
||||
void SetDataBits(QSerialPort::DataBits bits);
|
||||
void SetParity(QSerialPort::Parity parity);
|
||||
void SetStopBits(QSerialPort::StopBits stopBits);
|
||||
void SetFlowControl(QSerialPort::FlowControl flow);
|
||||
|
||||
private slots:
|
||||
void handleReadyRead();
|
||||
void handleError(QSerialPort::SerialPortError error);
|
||||
|
||||
private:
|
||||
QSerialPort m_port;
|
||||
ReadCallback m_readCallback;
|
||||
ErrorCallback m_errorCallback;
|
||||
};
|
||||
|
||||
} // namespace softbus::hardware::drivers::serial
|
||||
|
||||
37
src/hardware/interfaces/IDeviceWatcher.h
Normal file
37
src/hardware/interfaces/IDeviceWatcher.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace softbus::hardware::interfaces
|
||||
{
|
||||
|
||||
struct DiscoveredDevice
|
||||
{
|
||||
std::string id; // 稳定 ID(如序列号、路径)
|
||||
std::string endpoint; // 打开所需的 endpoint(如 /dev/ttyUSB0, can0, tcp://...)
|
||||
std::string type; // 设备类型:serial / can / ethernet / usb 等
|
||||
};
|
||||
|
||||
// 设备发现 / 监控接口:负责发现插拔事件,不负责创建设备或驱动实例
|
||||
class IDeviceWatcher
|
||||
{
|
||||
public:
|
||||
using DeviceAttachedCallback = std::function<void(const DiscoveredDevice&)>;
|
||||
using DeviceDetachedCallback = std::function<void(const DiscoveredDevice&)>;
|
||||
|
||||
virtual ~IDeviceWatcher() = default;
|
||||
|
||||
virtual bool Start() = 0;
|
||||
virtual void Stop() = 0;
|
||||
|
||||
virtual void SetDeviceAttachedCallback(DeviceAttachedCallback cb) = 0;
|
||||
virtual void SetDeviceDetachedCallback(DeviceDetachedCallback cb) = 0;
|
||||
};
|
||||
|
||||
} // namespace softbus::hardware::interfaces
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
41
src/hardware/interfaces/IFrameDriver.h
Normal file
41
src/hardware/interfaces/IFrameDriver.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace softbus::hardware::interfaces
|
||||
{
|
||||
|
||||
struct Frame
|
||||
{
|
||||
std::vector<std::uint8_t> payload;
|
||||
std::uint32_t id{0}; // 如 CAN ID
|
||||
std::uint64_t timestamp{0};
|
||||
};
|
||||
|
||||
// 面向帧设备(如 CAN 总线)的统一驱动接口
|
||||
class IFrameDriver
|
||||
{
|
||||
public:
|
||||
using FrameCallback = std::function<void(const Frame&)>;
|
||||
using ErrorCallback = std::function<void(const std::string& message)>;
|
||||
|
||||
virtual ~IFrameDriver() = default;
|
||||
|
||||
virtual bool Open(const std::string& endpoint) = 0;
|
||||
virtual void Close() = 0;
|
||||
|
||||
virtual bool WriteFrame(const Frame& frame) = 0;
|
||||
|
||||
virtual void SetFrameCallback(FrameCallback cb) = 0;
|
||||
virtual void SetErrorCallback(ErrorCallback cb) = 0;
|
||||
};
|
||||
|
||||
} // namespace softbus::hardware::interfaces
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
34
src/hardware/interfaces/IStreamDriver.h
Normal file
34
src/hardware/interfaces/IStreamDriver.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace softbus::hardware::interfaces
|
||||
{
|
||||
|
||||
// 面向字节流设备的统一驱动接口:串口 / TCP / UDP 等
|
||||
class IStreamDriver
|
||||
{
|
||||
public:
|
||||
using ReadCallback = std::function<void(const std::vector<std::uint8_t>&)>;
|
||||
using ErrorCallback = std::function<void(const std::string& message)>;
|
||||
|
||||
virtual ~IStreamDriver() = default;
|
||||
|
||||
virtual bool Open(const std::string& endpoint) = 0;
|
||||
virtual void Close() = 0;
|
||||
|
||||
virtual bool Write(const std::vector<std::uint8_t>& data) = 0;
|
||||
|
||||
virtual void SetReadCallback(ReadCallback cb) = 0;
|
||||
virtual void SetErrorCallback(ErrorCallback cb) = 0;
|
||||
};
|
||||
|
||||
} // namespace softbus::hardware::interfaces
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
Reference in New Issue
Block a user