增加ip输入校验。

This commit is contained in:
luocai 2024-08-21 16:03:49 +08:00
parent 6289b66ac5
commit 0c823a85b3
14 changed files with 318 additions and 148 deletions

View File

@ -155,10 +155,14 @@ void Application::connectToDevice(int index) {
disconnect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea); disconnect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea);
disconnect(device.get(), &DeviceConnection::networkInfomationChanged, this, disconnect(device.get(), &DeviceConnection::networkInfomationChanged, this,
&Application::onDeviceNetworkInfomation); &Application::onDeviceNetworkInfomation);
disconnect(device.get(), &DeviceConnection::firmwareChanged, this, &Application::onDeviceFirmware);
disconnect(device.get(), &DeviceConnection::otaProgressChanged, this, disconnect(device.get(), &DeviceConnection::otaProgressChanged, this,
&Application::currentDeviceOtaProgressChanged); &Application::currentDeviceOtaProgressChanged);
device->setH264FrameCallback(DeviceConnection::H264FrameCallback()); device->setH264FrameCallback(DeviceConnection::H264FrameCallback());
device->setLiveStreamEnabled(false); device->setLiveStreamEnabled(false);
if (!m_currentFirmware.isEmpty()) {
m_currentFirmware.clear();
}
} }
if (index >= 0) { if (index >= 0) {
auto device = m_devices->device(index); auto device = m_devices->device(index);
@ -169,6 +173,7 @@ void Application::connectToDevice(int index) {
connect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea); connect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea);
connect(device.get(), &DeviceConnection::networkInfomationChanged, this, connect(device.get(), &DeviceConnection::networkInfomationChanged, this,
&Application::onDeviceNetworkInfomation); &Application::onDeviceNetworkInfomation);
connect(device.get(), &DeviceConnection::firmwareChanged, this, &Application::onDeviceFirmware);
connect(device.get(), &DeviceConnection::otaProgressChanged, this, connect(device.get(), &DeviceConnection::otaProgressChanged, this,
&Application::currentDeviceOtaProgressChanged); &Application::currentDeviceOtaProgressChanged);
device->setH264FrameCallback([this](const char *data, uint32_t size) { device->setH264FrameCallback([this](const char *data, uint32_t size) {
@ -180,7 +185,6 @@ void Application::connectToDevice(int index) {
}); });
device->setLiveStreamEnabled(true); device->setLiveStreamEnabled(true);
auto area = device->area(); auto area = device->area();
m_currentOpenDoorAreaWay = area.openDoorAreaWay; m_currentOpenDoorAreaWay = area.openDoorAreaWay;
m_currentOpenDoorAreaPoints = area.openDoorArea; m_currentOpenDoorAreaPoints = area.openDoorArea;
m_currentShieldedAreaEnabled = area.shieldedAreaEnabled; m_currentShieldedAreaEnabled = area.shieldedAreaEnabled;
@ -188,6 +192,7 @@ void Application::connectToDevice(int index) {
m_currentAntiClipAreaEnabled = area.antiClipAreaEnabled; m_currentAntiClipAreaEnabled = area.antiClipAreaEnabled;
m_currentAntiClipAreaPoints = area.antiClipArea; m_currentAntiClipAreaPoints = area.antiClipArea;
m_currentNetworkInfomation = device->networkInfomation(); m_currentNetworkInfomation = device->networkInfomation();
m_currentFirmware = device->infomation().firmwareVersion;
emit currentOpenDoorAreaPointsChanged(); emit currentOpenDoorAreaPointsChanged();
emit currentShieldedAreaPointsChanged(); emit currentShieldedAreaPointsChanged();
emit currentAntiClipAreaPointsChanged(); emit currentAntiClipAreaPointsChanged();
@ -196,6 +201,7 @@ void Application::connectToDevice(int index) {
emit currentAntiClipAreaEnabledChanged(); emit currentAntiClipAreaEnabledChanged();
emit currentNetworkInfomationChanged(); emit currentNetworkInfomationChanged();
} }
emit currentFirmwareChanged();
} }
void Application::startSearchDevice() { void Application::startSearchDevice() {
@ -216,7 +222,6 @@ void Application::onDeviceOpenDoorArea(DeviceConnection::AreaWay way, const QLis
} }
void Application::onDeviceShieldedArea(bool enabled, const QList<QPointF> &points) { void Application::onDeviceShieldedArea(bool enabled, const QList<QPointF> &points) {
LOG(info) << "onDeviceShieldedArea: " << points.size();
setCurrentShieldedAreaEnabled(enabled); setCurrentShieldedAreaEnabled(enabled);
setCurrentShieldedAreaPoints(points); setCurrentShieldedAreaPoints(points);
} }
@ -231,6 +236,13 @@ void Application::onDeviceNetworkInfomation(const NetworkInfomation &info) {
emit currentNetworkInfomationChanged(); emit currentNetworkInfomationChanged();
} }
void Application::onDeviceFirmware(const QString &firmware) {
if (m_currentFirmware != firmware) {
m_currentFirmware = firmware;
emit currentFirmwareChanged();
}
}
int Application::exec() { int Application::exec() {
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
engine.addImageProvider("videoframe", m_videoFrameProvider); engine.addImageProvider("videoframe", m_videoFrameProvider);

View File

@ -37,6 +37,7 @@ class Application : public QObject {
setCurrentAntiClipAreaPoints NOTIFY currentAntiClipAreaPointsChanged) setCurrentAntiClipAreaPoints NOTIFY currentAntiClipAreaPointsChanged)
Q_PROPERTY( Q_PROPERTY(
NetworkInfomation currentNetworkInfomation READ currentNetworkInfomation NOTIFY currentNetworkInfomationChanged) NetworkInfomation currentNetworkInfomation READ currentNetworkInfomation NOTIFY currentNetworkInfomationChanged)
Q_PROPERTY(QString currentFirmware MEMBER m_currentFirmware NOTIFY currentFirmwareChanged)
friend class Amass::Singleton<Application>; friend class Amass::Singleton<Application>;
public: public:
@ -82,6 +83,7 @@ signals:
void currentShieldedAreaEnabledChanged(); void currentShieldedAreaEnabledChanged();
void currentAntiClipAreaEnabledChanged(); void currentAntiClipAreaEnabledChanged();
void currentNetworkInfomationChanged(); void currentNetworkInfomationChanged();
void currentFirmwareChanged();
void currentDeviceOtaProgressChanged(bool status, int progress, const QString &message); void currentDeviceOtaProgressChanged(bool status, int progress, const QString &message);
protected: protected:
@ -90,6 +92,7 @@ protected:
void onDeviceShieldedArea(bool enabled, const QList<QPointF> &points); void onDeviceShieldedArea(bool enabled, const QList<QPointF> &points);
void onDeviceAntiClipArea(bool enabled, const QList<QPointF> &points); void onDeviceAntiClipArea(bool enabled, const QList<QPointF> &points);
void onDeviceNetworkInfomation(const NetworkInfomation &info); void onDeviceNetworkInfomation(const NetworkInfomation &info);
void onDeviceFirmware(const QString &firmware);
private: private:
std::shared_ptr<QGuiApplication> m_app; std::shared_ptr<QGuiApplication> m_app;
@ -106,6 +109,7 @@ private:
bool m_currentAntiClipAreaEnabled = false; bool m_currentAntiClipAreaEnabled = false;
QList<QPointF> m_currentAntiClipAreaPoints; QList<QPointF> m_currentAntiClipAreaPoints;
NetworkInfomation m_currentNetworkInfomation; NetworkInfomation m_currentNetworkInfomation;
QString m_currentFirmware;
}; };
#endif // APPLICATION_H #endif // APPLICATION_H

View File

@ -55,6 +55,7 @@ qt_add_qml_module(AntiClipSettings
qml/OtaPopup.qml qml/OtaPopup.qml
qml/StatusTip.qml qml/StatusTip.qml
qml/DataCollectionPopup.qml qml/DataCollectionPopup.qml
qml/IpTextField.qml
RESOURCES RESOURCES
resources/popup_close.svg resources/popup_close.svg
resources/prompt_delete.svg resources/prompt_delete.svg

View File

@ -13,7 +13,7 @@ struct NetworkInfomation {
Q_PROPERTY(QString gateway MEMBER gateway) Q_PROPERTY(QString gateway MEMBER gateway)
public: public:
bool dhcp; bool dhcp;
QString ip = "127.0..1"; QString ip;
QString netmask; QString netmask;
QString gateway; QString gateway;
}; };

View File

@ -30,7 +30,7 @@ bool DeviceConnection::isConnected() const {
void DeviceConnection::connect(const Infomation &infomation) { void DeviceConnection::connect(const Infomation &infomation) {
m_infomation = infomation; m_infomation = infomation;
m_commandSocket = new QTcpSocket(this); m_commandSocket = new QTcpSocket(this);
QObject::connect(m_commandSocket, &QTcpSocket::disconnected, this, &DeviceConnection::disconnected); QObject::connect(m_commandSocket, &QTcpSocket::disconnected, this, &DeviceConnection::onDisconnected);
QObject::connect(m_commandSocket, &QTcpSocket::errorOccurred, this, &DeviceConnection::onErrorOccurred); QObject::connect(m_commandSocket, &QTcpSocket::errorOccurred, this, &DeviceConnection::onErrorOccurred);
m_h264Socket = new QTcpSocket(this); m_h264Socket = new QTcpSocket(this);
@ -66,7 +66,9 @@ void DeviceConnection::setLiveStreamEnabled(bool enabled) {
} }
void DeviceConnection::requestOpenDoorArea() { void DeviceConnection::requestOpenDoorArea() {
auto task = [this]() { Task task;
task.command = "a03opendoor1_getdata";
task.task = [this]() {
boost::json::object request; boost::json::object request;
request["func"] = "a03opendoor1_getdata"; request["func"] = "a03opendoor1_getdata";
request["deviceid"] = "0"; request["deviceid"] = "0";
@ -74,16 +76,17 @@ void DeviceConnection::requestOpenDoorArea() {
request["data"] = std::move(data); request["data"] = std::move(data);
auto text = boost::json::serialize(request); auto text = boost::json::serialize(request);
m_commandSocket->write(text.data(), text.size()); m_commandSocket->write(text.data(), text.size());
LOG(info) << "requestOpenDoorArea";
}; };
if (m_requests.empty()) { if (m_requests.empty()) {
task(); task.task();
} }
m_requests.push(task); m_requests.push(task);
} }
void DeviceConnection::updateOpenDoorAreaPoints(AreaWay way, const QList<QPointF> &points) { void DeviceConnection::updateOpenDoorAreaPoints(AreaWay way, const QList<QPointF> &points) {
auto task = [this, way, points]() { Task task;
task.command = "a03opendoor1_setdata";
task.task = [this, way, points]() {
boost::json::object request; boost::json::object request;
request["func"] = "a03opendoor1_setdata"; request["func"] = "a03opendoor1_setdata";
request["deviceid"] = "0"; request["deviceid"] = "0";
@ -110,13 +113,15 @@ void DeviceConnection::updateOpenDoorAreaPoints(AreaWay way, const QList<QPointF
LOG(info) << "updateOpenDoorAreaPoints"; LOG(info) << "updateOpenDoorAreaPoints";
}; };
if (m_requests.empty()) { if (m_requests.empty()) {
task(); task.task();
} }
m_requests.push(task); m_requests.push(task);
} }
void DeviceConnection::requestShieldedArea() { void DeviceConnection::requestShieldedArea() {
auto task = [this]() { Task task;
task.command = "a03opendoor4_getdata";
task.task = [this]() {
boost::json::object request; boost::json::object request;
request["func"] = "a03opendoor4_getdata"; request["func"] = "a03opendoor4_getdata";
request["deviceid"] = "0"; request["deviceid"] = "0";
@ -124,16 +129,17 @@ void DeviceConnection::requestShieldedArea() {
request["data"] = std::move(data); request["data"] = std::move(data);
auto text = boost::json::serialize(request); auto text = boost::json::serialize(request);
m_commandSocket->write(text.data(), text.size()); m_commandSocket->write(text.data(), text.size());
LOG(info) << "requestShieldedArea";
}; };
if (m_requests.empty()) { if (m_requests.empty()) {
task(); task.task();
} }
m_requests.push(task); m_requests.push(task);
} }
void DeviceConnection::updateShieldedAreaPoints(bool enabled, const QList<QPointF> &points) { void DeviceConnection::updateShieldedAreaPoints(bool enabled, const QList<QPointF> &points) {
auto task = [this, enabled, points]() { Task task;
task.command = "a03opendoor4_setdata";
task.task = [this, enabled, points]() {
boost::json::object request; boost::json::object request;
request["func"] = "a03opendoor4_setdata"; request["func"] = "a03opendoor4_setdata";
request["deviceid"] = "0"; request["deviceid"] = "0";
@ -151,16 +157,17 @@ void DeviceConnection::updateShieldedAreaPoints(bool enabled, const QList<QPoint
auto text = boost::json::serialize(request); auto text = boost::json::serialize(request);
m_commandSocket->write(text.data(), text.size()); m_commandSocket->write(text.data(), text.size());
LOG(info) << "updateShieldedAreaPoints";
}; };
if (m_requests.empty()) { if (m_requests.empty()) {
task(); task.task();
} }
m_requests.push(task); m_requests.push(task);
} }
void DeviceConnection::requestAntiClipArea() { void DeviceConnection::requestAntiClipArea() {
auto task = [this]() { Task task;
task.command = "a03opendoor5_getdata";
task.task = [this]() {
boost::json::object request; boost::json::object request;
request["func"] = "a03opendoor5_getdata"; request["func"] = "a03opendoor5_getdata";
request["deviceid"] = "0"; request["deviceid"] = "0";
@ -168,16 +175,17 @@ void DeviceConnection::requestAntiClipArea() {
request["data"] = std::move(data); request["data"] = std::move(data);
auto text = boost::json::serialize(request); auto text = boost::json::serialize(request);
m_commandSocket->write(text.data(), text.size()); m_commandSocket->write(text.data(), text.size());
LOG(info) << "requestAntiClipArea";
}; };
if (m_requests.empty()) { if (m_requests.empty()) {
task(); task.task();
} }
m_requests.push(task); m_requests.push(task);
} }
void DeviceConnection::updateAntiClipAreaPoints(bool enabled, const QList<QPointF> &points) { void DeviceConnection::updateAntiClipAreaPoints(bool enabled, const QList<QPointF> &points) {
auto task = [this, enabled, points]() { Task task;
task.command = "a03opendoor5_setdata";
task.task = [this, enabled, points]() {
boost::json::object request; boost::json::object request;
request["func"] = "a03opendoor5_setdata"; request["func"] = "a03opendoor5_setdata";
request["deviceid"] = "0"; request["deviceid"] = "0";
@ -198,13 +206,15 @@ void DeviceConnection::updateAntiClipAreaPoints(bool enabled, const QList<QPoint
LOG(info) << "updateAntiClipAreaPoints"; LOG(info) << "updateAntiClipAreaPoints";
}; };
if (m_requests.empty()) { if (m_requests.empty()) {
task(); task.task();
} }
m_requests.push(task); m_requests.push(task);
} }
void DeviceConnection::requestResolution(Resolution resolution) { void DeviceConnection::requestResolution(Resolution resolution) {
auto task = [this, resolution]() { Task task;
task.command = "quality_setdata";
task.task = [this, resolution]() {
boost::json::object request; boost::json::object request;
request["func"] = "quality_setdata"; request["func"] = "quality_setdata";
request["deviceid"] = "0"; request["deviceid"] = "0";
@ -213,16 +223,37 @@ void DeviceConnection::requestResolution(Resolution resolution) {
request["data"] = std::move(data); request["data"] = std::move(data);
auto text = boost::json::serialize(request); auto text = boost::json::serialize(request);
m_commandSocket->write(text.data(), text.size()); m_commandSocket->write(text.data(), text.size());
LOG(info) << "requestShieldedArea"; LOG(info) << "requestResolution";
}; };
if (m_requests.empty()) { if (m_requests.empty()) {
task(); task.task();
}
m_requests.push(task);
}
void DeviceConnection::requestVersion() {
Task task;
task.command = "a15devicedetail_getdata";
task.task = [this]() {
boost::json::object request;
request["func"] = "a15devicedetail_getdata";
request["deviceid"] = "0";
boost::json::object data;
request["data"] = std::move(data);
auto text = boost::json::serialize(request);
m_commandSocket->write(text.data(), text.size());
LOG(info) << "requestVersion";
};
if (m_requests.empty()) {
task.task();
} }
m_requests.push(task); m_requests.push(task);
} }
void DeviceConnection::requestNetworkInfomation() { void DeviceConnection::requestNetworkInfomation() {
auto task = [this]() { Task task;
task.command = "netconfig_getdata";
task.task = [this]() {
boost::json::object request; boost::json::object request;
request["func"] = "netconfig_getdata"; request["func"] = "netconfig_getdata";
request["deviceid"] = "0"; request["deviceid"] = "0";
@ -233,14 +264,16 @@ void DeviceConnection::requestNetworkInfomation() {
LOG(info) << "requestNetworkInfomation"; LOG(info) << "requestNetworkInfomation";
}; };
if (m_requests.empty()) { if (m_requests.empty()) {
task(); task.task();
} }
m_requests.push(task); m_requests.push(task);
} }
void DeviceConnection::updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, void DeviceConnection::updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask,
const QString &gateway) { const QString &gateway) {
auto task = [this, dhcp, ip, netmask, gateway]() { Task task;
task.command = "netconfig_setdata";
task.task = [this, dhcp, ip, netmask, gateway]() {
boost::json::object request; boost::json::object request;
request["func"] = "netconfig_setdata"; request["func"] = "netconfig_setdata";
request["deviceid"] = "0"; request["deviceid"] = "0";
@ -256,7 +289,7 @@ void DeviceConnection::updateNetworkInfomation(bool dhcp, const QString &ip, con
LOG(info) << "requestUpdateNetworkInfomation"; LOG(info) << "requestUpdateNetworkInfomation";
}; };
if (m_requests.empty()) { if (m_requests.empty()) {
task(); task.task();
} }
m_requests.push(task); m_requests.push(task);
} }
@ -264,8 +297,13 @@ void DeviceConnection::updateNetworkInfomation(bool dhcp, const QString &ip, con
void DeviceConnection::requestOta(const QString &file) { void DeviceConnection::requestOta(const QString &file) {
m_otaProgress = 0; m_otaProgress = 0;
emit otaProgressChanged(true, m_otaProgress, "正在向设备发起OTA请求......"); emit otaProgressChanged(true, m_otaProgress, "正在向设备发起OTA请求......");
if (m_timerId > 0) {
auto task = [this, file]() { killTimer(m_timerId);
m_timerId = -1;
}
Task task;
task.command = "a22devicefirmware_setdata";
task.task = [this, file]() {
std::ifstream ifs(Amass::StringUtility::UTF8ToGBK(file.toStdString()), std::ifstream::binary); std::ifstream ifs(Amass::StringUtility::UTF8ToGBK(file.toStdString()), std::ifstream::binary);
m_uploadBuffer = std::vector<uint8_t>((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); m_uploadBuffer = std::vector<uint8_t>((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
m_sendedSize = 0; m_sendedSize = 0;
@ -296,7 +334,7 @@ void DeviceConnection::requestOta(const QString &file) {
LOG(info) << "requestOta: " << text << ": " << text.size(); LOG(info) << "requestOta: " << text << ": " << text.size();
}; };
if (m_requests.empty()) { if (m_requests.empty()) {
task(); task.task();
} }
m_requests.push(task); m_requests.push(task);
} }
@ -343,12 +381,13 @@ void DeviceConnection::transferBinContent() {
} }
} }
void DeviceConnection::handleCommand(const std::string_view &replyText) { QString DeviceConnection::handleCommand(const std::string_view &replyText) {
QString ret;
boost::system::error_code error; boost::system::error_code error;
auto replyValue = boost::json::parse(replyText, error); auto replyValue = boost::json::parse(replyText, error);
if (error) { if (error) {
LOG(error) << "prase [" << replyText << "] failed, message: " << error.message(); LOG(error) << "prase [" << replyText << "] failed, message: " << error.message();
return; return ret;
} }
auto &reply = replyValue.as_object(); auto &reply = replyValue.as_object();
auto &function = reply.at("func").as_string(); auto &function = reply.at("func").as_string();
@ -410,6 +449,13 @@ void DeviceConnection::handleCommand(const std::string_view &replyText) {
m_networkInfomation.gateway = data.at("gateway").as_string().c_str(); m_networkInfomation.gateway = data.at("gateway").as_string().c_str();
m_networkInfomation.netmask = data.at("netmask").as_string().c_str(); m_networkInfomation.netmask = data.at("netmask").as_string().c_str();
emit networkInfomationChanged(m_networkInfomation); emit networkInfomationChanged(m_networkInfomation);
} else if (function == "a15devicedetail_getdata") {
auto &data = reply.at("data").as_object();
auto firmware = QString::fromStdString(std::string(data.at("linux04_firmware").as_string()));
if (m_infomation.firmwareVersion != firmware) {
m_infomation.firmwareVersion = firmware;
emit firmwareChanged(m_infomation.firmwareVersion);
}
} else if (function == "a03opendoor5_setdata") { } else if (function == "a03opendoor5_setdata") {
requestAntiClipArea(); requestAntiClipArea();
} else if (function == "a03opendoor4_setdata") { } else if (function == "a03opendoor4_setdata") {
@ -442,18 +488,19 @@ void DeviceConnection::handleCommand(const std::string_view &replyText) {
} else { } else {
LOG(warning) << "unknown reply: " << replyText; LOG(warning) << "unknown reply: " << replyText;
} }
return QString::fromStdString(std::string(std::move(function)));
} }
void DeviceConnection::onConnected() { void DeviceConnection::onConnected() {
LOG(info) << "onConnected";
auto socket = dynamic_cast<QTcpSocket *>(sender()); auto socket = dynamic_cast<QTcpSocket *>(sender());
if (socket == m_commandSocket) { if (socket == m_commandSocket) {
requestVersion();
requestOpenDoorArea(); requestOpenDoorArea();
requestShieldedArea(); requestShieldedArea();
requestAntiClipArea(); requestAntiClipArea();
requestNetworkInfomation(); requestNetworkInfomation();
emit connected(); emit connected();
// m_timerId = startTimer(2500); m_timerId = startTimer(2500);
if (m_otaProgress > 0) { if (m_otaProgress > 0) {
m_otaProgress = 100; m_otaProgress = 100;
emit otaProgressChanged(true, m_otaProgress, "设备升级成功!"); emit otaProgressChanged(true, m_otaProgress, "设备升级成功!");
@ -465,6 +512,17 @@ void DeviceConnection::onConnected() {
} }
} }
void DeviceConnection::onDisconnected() {
auto socket = dynamic_cast<QTcpSocket *>(sender());
if (socket == m_commandSocket) {
if (m_timerId > 0) {
killTimer(m_timerId);
m_timerId = -1;
}
emit disconnected();
}
}
void DeviceConnection::setH264FrameCallback(H264FrameCallback &&callback) { void DeviceConnection::setH264FrameCallback(H264FrameCallback &&callback) {
m_frameCallback = std::move(callback); m_frameCallback = std::move(callback);
} }
@ -497,13 +555,16 @@ void DeviceConnection::onCommandReadyRead() {
while (!m_commandBuffer.isEmpty()) { while (!m_commandBuffer.isEmpty()) {
auto packageSize = ntohl(*reinterpret_cast<uint32_t *>(m_commandBuffer.data())); auto packageSize = ntohl(*reinterpret_cast<uint32_t *>(m_commandBuffer.data()));
if (m_commandBuffer.size() < (packageSize + sizeof(uint32_t))) break; if (m_commandBuffer.size() < (packageSize + sizeof(uint32_t))) break;
handleCommand(std::string_view(m_commandBuffer.data() + sizeof(uint32_t), packageSize)); auto command = handleCommand(std::string_view(m_commandBuffer.data() + sizeof(uint32_t), packageSize));
m_commandBuffer.remove(0, packageSize + sizeof(uint32_t)); m_commandBuffer.remove(0, packageSize + sizeof(uint32_t));
if (!m_requests.empty()) { if (!m_requests.empty()) {
auto &task = m_requests.front();
if (task.command == command) {
m_requests.pop(); m_requests.pop();
}
if (!m_requests.empty()) { if (!m_requests.empty()) {
m_requests.front()(); m_requests.front().task();
} }
} }
} }
@ -522,6 +583,14 @@ void DeviceConnection::onErrorOccurred(QAbstractSocket::SocketError socketError)
void DeviceConnection::timerEvent(QTimerEvent *event) { void DeviceConnection::timerEvent(QTimerEvent *event) {
if (isConnected()) { if (isConnected()) {
int index = heartbeats % 3;
if (index == 0) {
requestOpenDoorArea(); requestOpenDoorArea();
} else if (index == 1) {
requestShieldedArea();
} else if (index == 2) {
requestAntiClipArea();
}
heartbeats++;
} }
} }

View File

@ -67,6 +67,7 @@ public:
void requestResolution(Resolution resolution); void requestResolution(Resolution resolution);
void requestNetworkInfomation(); void requestNetworkInfomation();
void updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, const QString &gateway); void updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, const QString &gateway);
void requestVersion();
/** /**
* @brief OTA, * @brief OTA,
@ -86,13 +87,15 @@ signals:
void shieldedAreaChanged(bool enabled, const QList<QPointF> &points); void shieldedAreaChanged(bool enabled, const QList<QPointF> &points);
void antiClipAreaChanged(bool enabled, const QList<QPointF> &points); void antiClipAreaChanged(bool enabled, const QList<QPointF> &points);
void networkInfomationChanged(const NetworkInfomation &info); void networkInfomationChanged(const NetworkInfomation &info);
void firmwareChanged(const QString &firmware);
void otaProgressChanged(bool status, int progress, const QString &message); void otaProgressChanged(bool status, int progress, const QString &message);
protected: protected:
void onConnected(); void onConnected();
void onDisconnected();
void onH264ReadyRead(); void onH264ReadyRead();
void onCommandReadyRead(); void onCommandReadyRead();
void handleCommand(const std::string_view &replyText); QString handleCommand(const std::string_view &replyText);
void onErrorOccurred(QAbstractSocket::SocketError socketError); void onErrorOccurred(QAbstractSocket::SocketError socketError);
void timerEvent(QTimerEvent *event) final; void timerEvent(QTimerEvent *event) final;
void transferBinContent(); void transferBinContent();
@ -113,10 +116,17 @@ private:
int m_sendedSize = 0; int m_sendedSize = 0;
H264FrameCallback m_frameCallback; H264FrameCallback m_frameCallback;
std::queue<std::function<void()>> m_requests; class Task {
public:
QString command;
std::function<void()> task;
};
std::queue<Task> m_requests;
int m_timerId = -1; int m_timerId = -1;
int heartbeats = 0;
Area m_area; Area m_area;
NetworkInfomation m_networkInfomation; NetworkInfomation m_networkInfomation;
QString m_firmware;
}; };
#endif // DEVICECONNECTION_H #endif // DEVICECONNECTION_H

View File

@ -146,9 +146,15 @@ void DeviceListModel::onDeviceReplyReadyRead() {
auto replyVale = boost::json::parse(datagram.data().toStdString()); auto replyVale = boost::json::parse(datagram.data().toStdString());
auto &reply = replyVale.as_object(); auto &reply = replyVale.as_object();
DeviceConnection::Infomation device; DeviceConnection::Infomation device;
if (reply.contains("devid")) {
device.deviceId = QString::fromStdString(std::string(reply.at("devid").as_string())); device.deviceId = QString::fromStdString(std::string(reply.at("devid").as_string()));
}
if (reply.contains("fw_ver")) {
device.firmwareVersion = QString::fromStdString(std::string(reply.at("fw_ver").as_string())); device.firmwareVersion = QString::fromStdString(std::string(reply.at("fw_ver").as_string()));
}
if (reply.contains("sw_ver")) {
device.softwareVersion = QString::fromStdString(std::string(reply.at("sw_ver").as_string())); device.softwareVersion = QString::fromStdString(std::string(reply.at("sw_ver").as_string()));
}
device.ip = datagram.senderAddress().toString(); device.ip = datagram.senderAddress().toString();
auto iterator = std::find_if(m_devices.cbegin(), m_devices.cend(), auto iterator = std::find_if(m_devices.cbegin(), m_devices.cend(),

View File

@ -13,7 +13,7 @@ int main(int argc, char *argv[]) {
LOG(info) << "Program version: " << APP_VERSION << std::endl; LOG(info) << "Program version: " << APP_VERSION << std::endl;
auto app = Singleton<Application>::instance<Construct>(argc, argv); auto app = Singleton<Application>::instance<Construct>(argc, argv);
QQuickStyle::setStyle("Basic"); QQuickStyle::setStyle("Material");
return app->exec(); return app->exec();
} }

View File

@ -245,7 +245,11 @@ Item {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
columns: 2 columns: 2
spacing: 10 spacing: 10
Text {text: qsTr("开门区域: ")} verticalItemAlignment: Qt.AlignVCenter
Text {
text: qsTr("开门区域: ")
}
Row { Row {
enabled: root.enabled enabled: root.enabled
RadioButton { RadioButton {

34
qml/IpTextField.qml Normal file
View File

@ -0,0 +1,34 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Column {
id: root
property alias text: input.text
property bool valid: false
TextField {
height: 36
width: 350
id: input
onTextChanged: {
valid = validateIp(text);
if(!valid){
hint.text="参数配置无效"
} else {
hint.text=""
}
}
}
Text {
id: hint
color: "red"
font.pixelSize: 12
}
function validateIp(ip) {
// Regular expression for validating IP address
var regex = /^(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])$/;
return regex.test(ip);
}
}

View File

@ -9,27 +9,25 @@ ApplicationWindow {
width: 1000 width: 1000
height: 640 height: 640
visible: true visible: true
title: qsTr("Hello World") title: qsTr("T009上位机工具")
header: ToolBar { header: ToolBar {
RowLayout { RowLayout {
anchors.fill: parent anchors.fill: parent
Button { ToolButton {
text: "搜索设备" text: "搜索设备"
onClicked: { onClicked: {
deviceList.currentIndex = -1 deviceList.currentIndex = -1
App.startSearchDevice() App.startSearchDevice()
} }
} }
Text { Label {
text: `: ${deviceList.count}` text: `: ${deviceList.count}`
} }
Text { Label {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
Layout.preferredWidth: 400 Layout.preferredWidth: 280
text: deviceList.currentIndex text: App.currentFirmware.length > 0 ? `: ${App.currentFirmware}` : ""
>= 0 ? `: ${App.devices.get(
deviceList.currentIndex).softwareVersion}` : ""
} }
} }
} }
@ -97,7 +95,7 @@ ApplicationWindow {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: deviceList.right anchors.left: deviceList.right
anchors.right: parent.right anchors.right: parent.right
enabled: deviceList.currentIndex>=0 enabled: deviceList.currentIndex >= 0
openDoorAreaWay: App.currentOpenDoorAreaWay openDoorAreaWay: App.currentOpenDoorAreaWay
openDoorAreaPoints: App.currentOpenDoorAreaPoints openDoorAreaPoints: App.currentOpenDoorAreaPoints
shieldedAreaEnabled: App.currentShieldedAreaEnabled shieldedAreaEnabled: App.currentShieldedAreaEnabled
@ -110,7 +108,6 @@ ApplicationWindow {
id: networkPopup id: networkPopup
visible: false visible: false
width: 500 width: 500
height: 240
} }
OtaPopup { OtaPopup {

View File

@ -72,7 +72,7 @@ Dialog {
Button { Button {
id: cancelButton id: cancelButton
width: 72 width: 72
height: 26 height: 40
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 15 anchors.rightMargin: 15
anchors.bottom: parent.bottom anchors.bottom: parent.bottom

View File

@ -1,31 +1,27 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts
import AntiClipSettings import AntiClipSettings
Popup { Popup {
id: root id: root
parent: Overlay.overlay parent: Overlay.overlay
anchors.centerIn: Overlay.overlay anchors.centerIn: Overlay.overlay
modal: true
Rectangle { property int inputHeight: 50
width: parent.width background: Rectangle {
height: parent.height radius: 8
color: "white" }
border.color: "lightgray" contentItem: ColumnLayout {
radius: 10
Column {
anchors.centerIn: parent anchors.centerIn: parent
spacing: 10
padding: 20
Row { Row {
spacing: 10 spacing: 10
Text { Label {
text: "模式" text: "模式"
font.pointSize: 14
width: 100 width: 100
anchors.verticalCenter: parent.verticalCenter
} }
RadioButton { RadioButton {
@ -37,73 +33,103 @@ Popup {
RadioButton { RadioButton {
id: staticMode id: staticMode
text: "静态IP" text: "静态IP"
checked: !App.currentNetworkInfomation.dhcp checked: true
// checked: !App.currentNetworkInfomation.dhcp
} }
} }
Row { Row {
spacing: 5 spacing: 5
visible: staticMode.checked
Text { Label {
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -10
text: "设备IP" text: "设备IP"
font.pointSize: 14
width: 100 width: 100
} }
TextField { IpTextField {
id: ipInput id: ipInput
height: inputHeight
width: 350 width: 350
height: 30
text: App.currentNetworkInfomation.ip text: App.currentNetworkInfomation.ip
} }
} }
Row { Row {
spacing: 5 spacing: 5
Text { visible: staticMode.checked
Label {
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -10
width: 100 width: 100
text: "子网掩码" text: "子网掩码"
font.pointSize: 14
} }
TextField { IpTextField {
id: netmaskInput id: netmaskInput
width: 350 width: 350
height: 30 height: inputHeight
text: App.currentNetworkInfomation.netmask text: App.currentNetworkInfomation.netmask
} }
} }
Row { Row {
spacing: 5 spacing: 5
visible: staticMode.checked
Row { Label {
spacing: 5 anchors.verticalCenter: parent.verticalCenter
Text {
text: "设备网关" text: "设备网关"
font.pointSize: 14 anchors.verticalCenterOffset: -10
width: 100 width: 100
} }
}
TextField { IpTextField {
id: gatewayInput id: gatewayInput
width: 350 width: 350
height: 30 height: inputHeight
text: App.currentNetworkInfomation.gateway text: App.currentNetworkInfomation.gateway
} }
} }
Row { Row {
spacing: 5
visible: staticMode.checked
Label {
anchors.verticalCenter: parent.verticalCenter
text: "DNS服务器"
anchors.verticalCenterOffset: -10
width: 100
}
IpTextField {
id: dnsInput
width: 350
height: inputHeight
text: App.currentNetworkInfomation.gateway
}
}
Row {
Layout.rightMargin: 20
Layout.alignment: Qt.AlignRight
spacing: 20 spacing: 20
anchors.horizontalCenter: parent.horizontalCenter
Button { Button {
text: "保存" text: "保存"
onClicked: { onClicked: {
App.updateNetworkInfomation(dhcpMode.checked,ipInput.text,netmaskInput.text,gatewayInput.text); if (dhcpMode.checked || (staticMode.checked && ipInput.valid
&& netmaskInput.valid
&& gatewayInput.valid
&& dnsInput.valid)) {
App.updateNetworkInfomation(dhcpMode.checked,
ipInput.text,
netmaskInput.text,
gatewayInput.text)
networkPopup.close() networkPopup.close()
} else {
showMessageDialog(2, "网络设置", "请输入合法参数地址!")
}
} }
} }
@ -113,5 +139,4 @@ Popup {
} }
} }
} }
}
} }

View File

@ -14,6 +14,7 @@ Popup {
modal: true modal: true
focus: true focus: true
closePolicy: Popup.CloseOnEscape closePolicy: Popup.CloseOnEscape
property bool otaFinished: true
property var onClose property var onClose
ColumnLayout { ColumnLayout {
@ -23,9 +24,15 @@ Popup {
RowLayout { RowLayout {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
Button { IconButton {
text: "关闭" source: "../resources/popup_close.svg"
onClicked: root.close() onClicked: {
if(otaFinished){
root.close()
}else{
showMessageDialog(2,"OTA升级","设备正在升级中,请耐心等待...")
}
}
} }
} }
@ -34,7 +41,8 @@ Popup {
TextField { TextField {
id: otaFile id: otaFile
Layout.fillWidth: true Layout.fillWidth: true
placeholderText: "请选择升级文件或将文件拖入工具中" readOnly: true
placeholderText: "请选择升级bin文件"
} }
Button { Button {
text: "选择" text: "选择"
@ -99,6 +107,7 @@ Popup {
Connections { Connections {
target: App target: App
function onCurrentDeviceOtaProgressChanged (status, progress, message) { function onCurrentDeviceOtaProgressChanged (status, progress, message) {
otaFinished = !status || (progress>=100)
progressBar.value = progress progressBar.value = progress
progressText.text = `${progress}%` progressText.text = `${progress}%`
if(progress>=100){ if(progress>=100){
@ -107,7 +116,6 @@ Popup {
}else { }else {
otaMessage.text = message otaMessage.text = message
} }
} }
} }
} }