2140 lines
92 KiB
C++
2140 lines
92 KiB
C++
#include "mainwindow.h"
|
||
#include "./ui_mainwindow.h"
|
||
|
||
#include <QMessageBox>
|
||
|
||
#include <QChartView>
|
||
#include <QValueAxis>
|
||
|
||
#include <QBarCategoryAxis>
|
||
#include <QBarSeries>
|
||
#include <QBarSet>
|
||
#include <QChart>
|
||
#include <QLegend>
|
||
|
||
#include <QAreaSeries>
|
||
#include <QLineSeries>
|
||
#include <QPolarChart>
|
||
#include <QScatterSeries>
|
||
#include <QSplineSeries>
|
||
#include <QStackedBarSeries>
|
||
#include <QSplitter>
|
||
|
||
#include <QToolTip>
|
||
#include <QtEndian>
|
||
#include <QLineEdit>
|
||
#include <QRegularExpressionValidator>
|
||
#include <QSettings>
|
||
#include <QCoreApplication>
|
||
|
||
#include "msg.h"
|
||
|
||
qreal get_rand(qreal maxValue) { return rand() * 1.0 / RAND_MAX * maxValue; }
|
||
|
||
MainWindow::MainWindow(QWidget *parent)
|
||
: QMainWindow(parent), ui(new Ui::MainWindow) {
|
||
ui->setupUi(this);
|
||
|
||
setWindowTitle("卫星终端控制软件_V1.1.0");
|
||
|
||
//创建logger窗口
|
||
m_loggerWidget = std::make_shared<LoggerWidget>();//需要在RecordQuery创建前
|
||
m_loggerWidget->hide();
|
||
connect(&*m_loggerWidget, &LoggerWidget::sendUdpRequest,
|
||
this, &MainWindow::handleUdpRequest);
|
||
//创建记录查询窗口
|
||
m_recordQueryWidget = std::make_shared<RecordQuery>();
|
||
m_recordQueryWidget->hide();
|
||
//创建参数配置窗口
|
||
m_configParamWidget = std::make_shared<ConfigParam>();
|
||
m_configParamWidget->hide();
|
||
connect(&*m_configParamWidget, &ConfigParam::sendUdpRequest,
|
||
this, &MainWindow::handleUdpRequest);
|
||
//创建并初始化图表
|
||
createBeiDouSignalStrengthChart();
|
||
createAzimuthMapChart();
|
||
|
||
createBeiDouRDSSSignalStrengthChart();
|
||
|
||
//
|
||
QSplitter *splitter = new QSplitter(Qt::Horizontal);
|
||
splitter->addWidget(ui->widgetCallAndMessage);
|
||
splitter->addWidget(ui->widgetSatelliteStatus);
|
||
setCentralWidget(splitter);
|
||
|
||
ui->lblPosition->clear();
|
||
ui->lblZhuanTaiStatus->clear();
|
||
ui->lblHydraulicCylinderHeight->clear();
|
||
ui->lblAntennaPowerSupply->clear();
|
||
ui->lblPhaseLockedLoop->clear();
|
||
|
||
//获取日志实例
|
||
m_logger = spdlog::get("logger");
|
||
|
||
//初始化其他控件
|
||
ui->lblCallDuration->hide();
|
||
ui->btnCallReject->hide();
|
||
|
||
// 禁用控件
|
||
ui->btnUHFSimCardStatus->setEnabled(false);
|
||
ui->labelUHFSimCardStatus->setEnabled(false);
|
||
|
||
// 设置透明样式
|
||
QString transparentStyle =
|
||
"QToolButton:disabled, QLabel:disabled {"
|
||
" background: transparent;"
|
||
" border: none;"
|
||
" color: transparent;"
|
||
"}";
|
||
|
||
ui->btnUHFSimCardStatus->setStyleSheet(transparentStyle);
|
||
ui->labelUHFSimCardStatus->setStyleSheet(transparentStyle);
|
||
|
||
ui->lblLinkStatus->setText("未连接");
|
||
ui->lblLinkStatus->setStyleSheet("color: red;"); // 红色
|
||
|
||
// 初始化UDP连接状态
|
||
m_udpConnected = false;
|
||
m_versionQuery = false;
|
||
m_channelQuery = false;
|
||
m_lastUdpDataTime = QDateTime::currentDateTime();
|
||
|
||
QString exeDir = QCoreApplication::applicationDirPath();
|
||
QSettings settings(exeDir + "/app.ini", QSettings::IniFormat);
|
||
m_udpIp = settings.value("Config/PeerIP","192.168.2.10").toString();
|
||
m_localPort = settings.value("Config/LocalPort",6680).toInt();
|
||
m_peerPort = settings.value("Config/PeerPort",6678).toInt();
|
||
|
||
//创建udp socket
|
||
m_udpSocket = std::make_shared<QUdpSocket>();
|
||
m_udpServerSocket = std::make_shared<QUdpSocket>();
|
||
m_udpServerSocket->bind(m_localPort);
|
||
connect(&*m_udpServerSocket, &QUdpSocket::readyRead, this, &MainWindow::readPendingDatagrams);
|
||
|
||
// 对电话号码添加校验器
|
||
// QRegularExpression regExp("[0-9A-Za-z]{1,20}");
|
||
// QRegularExpressionValidator *validator = new QRegularExpressionValidator(regExp, this);
|
||
// // 获取 QComboBox 的 lineEdit 并设置校验器
|
||
// ui->cmbCallNumber->lineEdit()->setValidator(validator);
|
||
|
||
m_talkingTimer = std::make_shared<QTimer>();
|
||
QObject::connect(&*m_talkingTimer, &QTimer::timeout, [this]() {
|
||
m_callDuration += 1;
|
||
QTime t(0,0,0);
|
||
t = t.addSecs(m_callDuration);
|
||
ui->lblCallDuration->setText(t.toString("hh:mm:ss"));
|
||
});
|
||
m_talkingTimer->stop();
|
||
|
||
m_timer = new QTimer(this);
|
||
connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimerTimeout1s()));
|
||
m_timer->start(1000);
|
||
|
||
//3秒定时状态检测
|
||
m_status_timer = new QTimer(this);
|
||
connect(m_status_timer, SIGNAL(timeout()), this, SLOT(onTimerLinkStatus()));
|
||
m_status_timer->start(3000);
|
||
//测试
|
||
//test();
|
||
|
||
ui->tabWidget->setCurrentIndex(0); //tab默认显示rdss tab
|
||
|
||
m_recordQueryWidget->setupNumberCombo(this, ui->cmbCallNumber, NumberKind::Call);
|
||
m_recordQueryWidget->setupNumberCombo(this, ui->cmbMessageNumberForUhfAndS, NumberKind::USMsg);
|
||
m_recordQueryWidget->setupNumberCombo(this, ui->cmbMessageNumberForBeiDou, NumberKind::BdMsg);
|
||
}
|
||
|
||
MainWindow::~MainWindow() { delete ui; }
|
||
|
||
void MainWindow::onTimerTimeout1s(){
|
||
//模块状态
|
||
if(m_uhfModuleStatus == ModuleStatus::kChecking || m_uhfModuleStatus == ModuleStatus::kUpgrading){
|
||
if(m_uhfModuleStatusGrayIcon){
|
||
ui->btnUHFModuleStatus->setIcon(QIcon(":/rc/res/circle_green.png"));
|
||
}else{
|
||
ui->btnUHFModuleStatus->setIcon(QIcon(":/rc/res/circle_gray.png"));
|
||
}
|
||
m_uhfModuleStatusGrayIcon = !m_uhfModuleStatusGrayIcon;
|
||
}
|
||
if(m_tiantongModuleStatus == ModuleStatus::kChecking|| m_uhfModuleStatus == ModuleStatus::kUpgrading){
|
||
if(m_tiantongModuleStatusGrayIcon){
|
||
ui->btnSModueStatus->setIcon(QIcon(":/rc/res/circle_green.png"));
|
||
}else{
|
||
ui->btnSModueStatus->setIcon(QIcon(":/rc/res/circle_gray.png"));
|
||
}
|
||
m_tiantongModuleStatusGrayIcon = !m_tiantongModuleStatusGrayIcon;
|
||
}
|
||
if(m_beidouModuleStatus == ModuleStatus::kChecking|| m_uhfModuleStatus == ModuleStatus::kUpgrading){
|
||
if(m_beidouModuleStatusGrayIcon){
|
||
ui->btnBeiDouModuleStatus->setIcon(QIcon(":/rc/res/circle_green.png"));
|
||
}else{
|
||
ui->btnBeiDouModuleStatus->setIcon(QIcon(":/rc/res/circle_gray.png"));
|
||
}
|
||
m_beidouModuleStatusGrayIcon = !m_beidouModuleStatusGrayIcon;
|
||
}
|
||
//sim卡状态
|
||
//if(m_uhfSimCardStatus == SimCardStatus::kChecking){
|
||
// if(m_uhfSimCardStatusGrayIcon){
|
||
// ui->btnUHFSimCardStatus->setIcon(QIcon(":/rc/res/card_green.png"));
|
||
// }else{
|
||
// ui->btnUHFSimCardStatus->setIcon(QIcon(":/rc/res/card_gray.png"));
|
||
// }
|
||
// m_uhfSimCardStatusGrayIcon = !m_uhfSimCardStatusGrayIcon;
|
||
//}
|
||
if(m_tiantongSimCardStatus == SimCardStatus::kChecking){
|
||
if(m_tiantongSimCardStatusGrayIcon){
|
||
ui->btnSSimCardStatus->setIcon(QIcon(":/rc/res/card_green.png"));
|
||
}else{
|
||
ui->btnSSimCardStatus->setIcon(QIcon(":/rc/res/card_gray.png"));
|
||
}
|
||
m_tiantongSimCardStatusGrayIcon = !m_tiantongSimCardStatusGrayIcon;
|
||
}
|
||
if(m_beidouSimCardStatus == SimCardStatus::kChecking){
|
||
if(m_beidouSimCardStatusGrayIcon){
|
||
ui->btnBeiDouSimCardStatus->setIcon(QIcon(":/rc/res/card_green.png"));
|
||
}else{
|
||
ui->btnBeiDouSimCardStatus->setIcon(QIcon(":/rc/res/card_gray.png"));
|
||
}
|
||
m_beidouSimCardStatusGrayIcon = !m_beidouSimCardStatusGrayIcon;
|
||
}
|
||
//m卡状态
|
||
if(m_uhfMCardStatus == MCardStatus::kChecking){
|
||
if(m_uhfMCardStatusGrayIcon){
|
||
ui->btnUHFMCardStatus->setIcon(QIcon(":/rc/res/card_green.png"));
|
||
}else{
|
||
ui->btnUHFMCardStatus->setIcon(QIcon(":/rc/res/card_gray.png"));
|
||
}
|
||
m_uhfMCardStatusGrayIcon = !m_uhfMCardStatusGrayIcon;
|
||
}
|
||
if(m_tiantongMCardStatus == MCardStatus::kChecking){
|
||
if(m_tiantongMCardStatusGrayIcon){
|
||
ui->btnSMCardStatus->setIcon(QIcon(":/rc/res/card_green.png"));
|
||
}else{
|
||
ui->btnSMCardStatus->setIcon(QIcon(":/rc/res/card_gray.png"));
|
||
}
|
||
m_tiantongMCardStatusGrayIcon = !m_tiantongMCardStatusGrayIcon;
|
||
}
|
||
// 入网状态
|
||
if(m_uhfNetworkAccessStatus == NetworkAccessStatus::kConnecting){
|
||
if(m_uhfNetworkAccessStatusGrayIcon){
|
||
ui->btnUHFNetworkAccessStatus->setIcon(QIcon(":/rc/res/net_in_no_data.png"));
|
||
}else{
|
||
ui->btnUHFNetworkAccessStatus->setIcon(QIcon(":/rc/res/net_out.png"));
|
||
}
|
||
m_uhfNetworkAccessStatusGrayIcon = !m_uhfNetworkAccessStatusGrayIcon;
|
||
}
|
||
if(m_tiantongNetworkAccessStatus == NetworkAccessStatus::kConnecting){
|
||
if(m_tiantongNetworkAccessStatusGrayIcon){
|
||
ui->btnSNetworkAccessStatus->setIcon(QIcon(":/rc/res/net_in_no_data.png"));
|
||
}else{
|
||
ui->btnSNetworkAccessStatus->setIcon(QIcon(":/rc/res/net_out.png"));
|
||
}
|
||
m_tiantongNetworkAccessStatusGrayIcon = !m_tiantongNetworkAccessStatusGrayIcon;
|
||
}
|
||
// 呼叫状态
|
||
CallStatus callStatus;
|
||
if(m_uhfCallStatus != CallStatus::kIdle){
|
||
callStatus = m_uhfCallStatus;
|
||
}else{
|
||
callStatus = m_tiantongCallStatus;
|
||
}
|
||
if(callStatus != CallStatus::kIdle && callStatus != CallStatus::kOnLine){
|
||
if(m_callStatusLabelBlack){
|
||
ui->lblCallStatus->setStyleSheet("color: green;");
|
||
}else{
|
||
ui->lblCallStatus->setStyleSheet("color: blue;");
|
||
}
|
||
m_callStatusLabelBlack = !m_callStatusLabelBlack;
|
||
}
|
||
}
|
||
|
||
void MainWindow::onTimerLinkStatus(){
|
||
// 计算当前时间与最后收到数据的时间差(秒)
|
||
qint64 secondsSinceLastData = m_lastUdpDataTime.secsTo(QDateTime::currentDateTime());
|
||
// 如果超过3秒没有收到数据,则认为连接断开
|
||
if(secondsSinceLastData >= 3) {
|
||
m_logger->info("LinkStatus: secondsSinceLastData = {}", secondsSinceLastData);
|
||
if(m_udpConnected) {
|
||
m_udpConnected = false;
|
||
m_versionQuery = false;
|
||
m_channelQuery = false;
|
||
ui->lblLinkStatus->setText("未连接");
|
||
//QMessageBox::information(this, "提示", "连接已断开");
|
||
ui->lblLinkStatus->setStyleSheet("color: red;");
|
||
|
||
m_logger->error("Link is disconnected");
|
||
}
|
||
} else {
|
||
if(!m_udpConnected) {
|
||
m_udpConnected = true;
|
||
ui->lblLinkStatus->setText("已连接");
|
||
ui->lblLinkStatus->setStyleSheet("color: green;");
|
||
//QMessageBox::information(this, "提示", "已连接");
|
||
|
||
m_logger->info("Link is Connected");
|
||
}
|
||
|
||
// 连接成功后,查询设备信息
|
||
queryDeviceInfo();
|
||
}
|
||
}
|
||
|
||
// 查询设备信息
|
||
void MainWindow::queryDeviceInfo()
|
||
{
|
||
// 如果版本号尚未查询,则发送查询命令
|
||
if(!m_versionQuery) {
|
||
sendUdpMessage(pack_config_cmd_SoftVersionGet());
|
||
}
|
||
|
||
// 如果信道类型尚未查询,则发送查询命令
|
||
if(!m_channelQuery) {
|
||
sendUdpMessage(pack_config_cmd_DefaultChannelGet());
|
||
}
|
||
}
|
||
|
||
void MainWindow::handleUdpRequest(const QByteArray &message)
|
||
{
|
||
sendUdpMessage(message); // 调用实际的发送方法
|
||
//m_loggerWidget->updateRespStatus(message);
|
||
}
|
||
|
||
//ctrl+l用于打开日志窗口
|
||
void MainWindow::keyPressEvent(QKeyEvent* event){
|
||
if(event->key() == Qt::Key_L && event->modifiers() & Qt::ControlModifier){
|
||
m_loggerWidget->show();
|
||
}else{
|
||
QWidget::keyPressEvent(event);
|
||
}
|
||
}
|
||
|
||
void MainWindow::StartupTalking(){
|
||
if(m_talkingTimer->isActive()){
|
||
ui->lblCallDuration->show();
|
||
return;
|
||
}
|
||
m_currentTalkingBeginTime = QDateTime::currentDateTime();
|
||
m_callDuration = 0;
|
||
QTime t(0,0,0);
|
||
t = t.addSecs(m_callDuration);
|
||
ui->lblCallDuration->setText(t.toString("hh:mm:ss"));
|
||
ui->lblCallDuration->show();
|
||
m_talkingTimer->start(1000);
|
||
}
|
||
void MainWindow::ShutdownTalking(){
|
||
if(!m_talkingTimer->isActive()){
|
||
return;
|
||
}
|
||
|
||
Record r;
|
||
r.beginTime = m_currentTalkingBeginTime;
|
||
r.channel = m_currentTalkingChan;
|
||
r.type = CommType::Call;
|
||
r.direction = m_currentTalkingDirection;
|
||
r.number = QString::fromStdString(m_currentTalkingNumber);
|
||
r.content = "";
|
||
r.isUnread = true;
|
||
r.callDuration = m_callDuration;
|
||
m_recordQueryWidget->InsertRecord(r);
|
||
|
||
m_talkingTimer->stop();
|
||
}
|
||
|
||
void MainWindow::readPendingDatagrams(){
|
||
while (m_udpServerSocket->hasPendingDatagrams()) {
|
||
QByteArray datagram;
|
||
datagram.resize(m_udpServerSocket->pendingDatagramSize());
|
||
|
||
QHostAddress sender;
|
||
quint16 senderPort;
|
||
|
||
// 读取数据报
|
||
m_udpServerSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
|
||
|
||
//m_logger->info("接收到udp消息, 长度 = {}, 数据 = {}",datagram.size(),datagram.toStdString());
|
||
m_logger->info("Received a udp message, len = {}, data = {}",datagram.size(),datagram.toHex(' ').toStdString());
|
||
|
||
processCommand(datagram);
|
||
}
|
||
}
|
||
|
||
void MainWindow::test() {
|
||
// 随机生成信号能量数据
|
||
setSignalStrengthValues(
|
||
QStringList{"01", "02", "03", "04", "05", "06", "07", "08", "09"},
|
||
QList{get_rand(10.0), get_rand(10.0), get_rand(10.0), get_rand(10.0),
|
||
get_rand(10.0), get_rand(10.0), get_rand(50.0), get_rand(33.0), get_rand(27.0)});
|
||
|
||
// 随机生成方向图数据
|
||
QList<QPointF> values;
|
||
for (int i = 0; i < 9; i += 1) {
|
||
values.append(QPointF(get_rand(360.0), get_rand(360.0)));
|
||
}
|
||
setAzimuthValues(values);
|
||
|
||
Record r1;
|
||
r1.beginTime = QDateTime::currentDateTime();
|
||
r1.channel = Channel::Uhf;
|
||
r1.type = CommType::ShortMessage;
|
||
r1.direction = CommDirection::Receive;
|
||
r1.number = "10001";
|
||
r1.content = "地阿斯顿发射点发大水发大水发";
|
||
r1.isUnread = true;
|
||
r1.callDuration = 0;
|
||
|
||
Record r2;
|
||
r2.beginTime = QDateTime::currentDateTime();
|
||
r2.channel = Channel::BeiDou;
|
||
r2.type = CommType::ShortMessage;
|
||
r2.direction = CommDirection::Send;
|
||
r2.number = "10002";
|
||
r2.content = "dsfgdsfgsdfgsdfgdfsgdsfgdsfg";
|
||
r2.isUnread = false;
|
||
r2.callDuration = 0;
|
||
|
||
Record r3;
|
||
r3.beginTime = QDateTime::currentDateTime();
|
||
r3.channel = Channel::S;
|
||
r3.type = CommType::Call;
|
||
r3.direction = CommDirection::Receive;
|
||
r3.number = "10003";
|
||
r3.content = "fdghfgdhfghdfghdfghdfghf";
|
||
r3.isUnread = true;
|
||
r3.callDuration = 30;
|
||
|
||
m_msgList.push_back(r1);
|
||
m_msgList.push_back(r2);
|
||
m_msgList.push_back(r3);
|
||
UpdateMessageList();
|
||
|
||
m_recordQueryWidget->InsertRecords(m_msgList);
|
||
|
||
}
|
||
|
||
void MainWindow::test1(){
|
||
// 随机生成信号能量数据
|
||
setSignalStrengthValues(
|
||
QStringList{"01", "02", "03", "04", "05", "06"},
|
||
QList{get_rand(20.0), get_rand(45.0), get_rand(50.0), get_rand(45.0),
|
||
get_rand(50.0), get_rand(40.0)});
|
||
|
||
// 随机生成方向图数据
|
||
QList<QPointF> values;
|
||
for (int i = 0; i < 6; i += 1) {
|
||
values.append(QPointF(get_rand(360.0), get_rand(360.0)));
|
||
}
|
||
setAzimuthValues(values);
|
||
|
||
Record r3;
|
||
r3.beginTime = QDateTime::currentDateTime();
|
||
r3.channel = Channel::S;
|
||
r3.type = CommType::ShortMessage;
|
||
r3.direction = CommDirection::Receive;
|
||
r3.number = "10003";// + QString::number((get_rand(8)));;
|
||
r3.content = "fdghfgdhfghdfghdfghdfghf";// + QString::number((get_rand(15)));
|
||
r3.isUnread = true;
|
||
r3.callDuration = 0;
|
||
|
||
m_msgList.push_back(r3);
|
||
UpdateMessageList();
|
||
|
||
m_recordQueryWidget->InsertRecord(m_msgList.back());
|
||
}
|
||
|
||
// 槽函数实现
|
||
void MainWindow::handleHovered(bool status, int index, QBarSet* barset)
|
||
{
|
||
if(status && barset && index >=0) {
|
||
// 获取实际数值(考虑堆叠结构)
|
||
const qreal value = barset->at(index);
|
||
|
||
// 显示定制化提示框
|
||
QToolTip::showText(QCursor::pos(),
|
||
QString("数值: %1\n阈值: %2")
|
||
.arg(value, 0, 'f', 1) // 保留1位小数
|
||
.arg(value < 36 ? "低" : "高"),
|
||
nullptr,
|
||
QRect(),
|
||
2000); // 显示持续2秒
|
||
|
||
// 添加高亮效果
|
||
//barset->setBorderWidth(2);
|
||
//barset->setColor(barset->color().lighter(110)); // 亮度提高10%
|
||
} else {
|
||
// 恢复原始样式
|
||
//if(barset) {
|
||
// 获取实际数值(考虑堆叠结构)
|
||
// const qreal value = barset->at(index);
|
||
|
||
//barset->setBorderWidth(1);
|
||
//barset->setColor(value < 36 ? QColor("#C0C0C0") : QColor("#0000FF"));
|
||
//}
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------------
|
||
//--------------------------------------------------------------------------------------
|
||
void MainWindow::createBeiDouSignalStrengthChart() {
|
||
m_signalStrengthChart = new QChart;
|
||
m_signalStrengthChart->setTitle("载噪比");
|
||
m_signalStrengthChart->legend()->setVisible(false);
|
||
m_signalStrengthChart->legend()->setAlignment(Qt::AlignBottom);
|
||
// m_signalStrengthChart->setAnimationOptions(QChart::SeriesAnimations);
|
||
|
||
m_signalStrengthChartXAxis = new QBarCategoryAxis;
|
||
m_signalStrengthChart->addAxis(m_signalStrengthChartXAxis, Qt::AlignBottom);
|
||
|
||
m_signalStrengthChartYAxis = new QValueAxis;
|
||
m_signalStrengthChartYAxis->setRange(0, 50);
|
||
m_signalStrengthChart->addAxis(m_signalStrengthChartYAxis, Qt::AlignLeft);
|
||
// series->attachAxis(axisY);
|
||
|
||
// 减小图表边距 - 这是关键设置
|
||
m_signalStrengthChart->setMargins(QMargins(0, 0, 0, 0)); // 左上右下全部设为0
|
||
|
||
QChartView *chartView = new QChartView(m_signalStrengthChart, this);
|
||
chartView->setRenderHint(QPainter::Antialiasing);
|
||
// 设置ChartView的边距
|
||
chartView->setContentsMargins(0, 0, 0, 0);
|
||
ui->vboxChannelBeidouSignalStrength->addWidget(chartView);
|
||
|
||
m_stackedSeries = new QStackedBarSeries;
|
||
connect(m_stackedSeries, &QStackedBarSeries::hovered, this, &MainWindow::handleHovered);
|
||
}
|
||
void MainWindow::setSignalStrengthValues(const QStringList &categories,
|
||
const QList<qreal> &yValues) {
|
||
// 清空旧数据
|
||
m_signalStrengthChart->removeAllSeries();
|
||
m_signalStrengthChartXAxis->clear();
|
||
|
||
// 创建数据集
|
||
QBarSet *set0 = new QBarSet("Power");
|
||
QBarSet *set1 = new QBarSet("Power2");
|
||
//set0->append(yValues);
|
||
//set1->append(yValues);
|
||
foreach (qreal val, yValues) {
|
||
if(val >= 36.0)
|
||
{
|
||
*set0 << 0;
|
||
*set1 << val;
|
||
}
|
||
else
|
||
{
|
||
*set0 << val;
|
||
*set1 << 0;
|
||
}
|
||
}
|
||
//auto set0 = new QBarSet("Power");
|
||
//set0->append(yValues);
|
||
|
||
// 动态设置柱形颜色
|
||
set0->setBrush(QBrush(QColor("#C0C0C0")));
|
||
set1->setBrush(QBrush(QColor("#0000FF")));
|
||
//for(int i = 0; i < set0->count(); ++i) {
|
||
// const qreal value = set0->at(i);
|
||
// set0->setBrush(QBrush(value < 36.0 ? QColor("#C0C0C0") : QColor("#0000FF")));
|
||
// set0->setPen(QPen(value < 36.0 ? QColor("#606060") : QColor("#0d47a1"), 1));
|
||
//}
|
||
|
||
// 创建柱状序列
|
||
//QBarSeries *series = new QBarSeries();
|
||
//series->append(set0);
|
||
//m_signalStrengthChart->addSeries(series);
|
||
|
||
// 添加对象追踪防止内存泄漏
|
||
//set0->setParent(series); // 建立父子关系
|
||
|
||
// 创建 QStackedBarSeries 对象, 保留并重用 QStackedBarSeries 对象而非每次新建
|
||
//if(m_stackedSeries == nullptr) {
|
||
// m_stackedSeries = new QStackedBarSeries();
|
||
//}
|
||
//->clear();
|
||
QStackedBarSeries *series2 = new QStackedBarSeries();
|
||
//m_stackedSeries->setBarWidth(0.8); // 设置柱子相对宽度
|
||
//m_stackedSeries->setUseOpenGL(true); // 启用GPU加速
|
||
|
||
series2->append(set0);
|
||
series2->append(set1);
|
||
|
||
// 添加对象追踪防止内存泄漏
|
||
set0->setParent(series2); // 建立父子关系
|
||
set1->setParent(series2); // 建立父子关系
|
||
|
||
m_signalStrengthChart->addSeries(series2);
|
||
|
||
//保留并重用QBarSeries对象而非每次新建
|
||
//if(m_series == nullptr) {
|
||
// m_series = new QBarSeries();
|
||
// m_chart->addSeries(m_series);
|
||
//}
|
||
//m_series->clear();
|
||
|
||
// 绑定坐标轴
|
||
//series2->attachAxis(m_signalStrengthChartXAxis);
|
||
series2->attachAxis(m_signalStrengthChartYAxis);
|
||
|
||
// 设置X轴标签
|
||
m_signalStrengthChartXAxis->append(categories);
|
||
|
||
// 动态调整Y轴范围
|
||
//qreal maxValue = *std::max_element(yValues.begin(), yValues.end());
|
||
//m_signalStrengthChartYAxis->setRange(0, maxValue * 1.2); // 留20%余量
|
||
|
||
// 优化显示效果
|
||
series2->setLabelsVisible(false); // 隐藏数值标签
|
||
m_signalStrengthChart->legend()->hide(); // 隐藏图例
|
||
|
||
// 更新卫星数量显示
|
||
ui->lblSatelliteCount->setText(QString::asprintf("%d", categories.count()));
|
||
}
|
||
void MainWindow::createBeiDouRDSSSignalStrengthChart() {
|
||
m_RDS1signalStrengthChart = new QChart;
|
||
m_RDS1signalStrengthChart->setTitle("载噪比");
|
||
m_RDS1signalStrengthChart->legend()->setVisible(false);
|
||
m_RDS1signalStrengthChart->legend()->setAlignment(Qt::AlignBottom);
|
||
// m_RDS1signalStrengthChart->setAnimationOptions(QChart::SeriesAnimations);
|
||
|
||
m_RDS1signalStrengthChartXAxis = new QBarCategoryAxis;
|
||
m_RDS1signalStrengthChart->addAxis(m_RDS1signalStrengthChartXAxis, Qt::AlignBottom);
|
||
|
||
m_RDS1signalStrengthChartYAxis = new QValueAxis;
|
||
m_RDS1signalStrengthChartYAxis->setRange(0, 50);
|
||
m_RDS1signalStrengthChart->addAxis(m_RDS1signalStrengthChartYAxis, Qt::AlignLeft);
|
||
// series->attachAxis(axisY);
|
||
|
||
// 减小图表边距 - 这是关键设置
|
||
m_RDS1signalStrengthChart->setMargins(QMargins(0, 0, 0, 0)); // 左上右下全部设为0
|
||
|
||
QChartView *chartView = new QChartView(m_RDS1signalStrengthChart, this);
|
||
chartView->setRenderHint(QPainter::Antialiasing);
|
||
// 设置ChartView的边距
|
||
chartView->setContentsMargins(0, 0, 0, 0);
|
||
ui->vboxChannelBeidouRDS1SignalStrength->addWidget(chartView);
|
||
|
||
m_RDS2signalStrengthChart = new QChart;
|
||
m_RDS2signalStrengthChart->setTitle("载噪比");
|
||
m_RDS2signalStrengthChart->legend()->setVisible(false);
|
||
m_RDS2signalStrengthChart->legend()->setAlignment(Qt::AlignBottom);
|
||
// m_RDS2signalStrengthChart->setAnimationOptions(QChart::SeriesAnimations);
|
||
|
||
m_RDS2signalStrengthChartXAxis = new QBarCategoryAxis;
|
||
m_RDS2signalStrengthChart->addAxis(m_RDS2signalStrengthChartXAxis, Qt::AlignBottom);
|
||
|
||
m_RDS2signalStrengthChartYAxis = new QValueAxis;
|
||
m_RDS2signalStrengthChartYAxis->setRange(0, 50);
|
||
m_RDS2signalStrengthChart->addAxis(m_RDS2signalStrengthChartYAxis, Qt::AlignLeft);
|
||
// series->attachAxis(axisY);
|
||
|
||
// 减小图表边距 - 这是关键设置
|
||
m_RDS2signalStrengthChart->setMargins(QMargins(0, 0, 0, 0)); // 左上右下全部设为0
|
||
|
||
QChartView *chartView2 = new QChartView(m_RDS2signalStrengthChart, this);
|
||
chartView->setRenderHint(QPainter::Antialiasing);
|
||
// 设置ChartView的边距
|
||
chartView->setContentsMargins(0, 0, 0, 0);
|
||
ui->vboxChannelBeidouRDS2SignalStrength->addWidget(chartView2);
|
||
}
|
||
void MainWindow::setRDSSSignalStrengthValues(uint8_t type, const QStringList &categories,
|
||
const QList<qreal> &yValues) {
|
||
if((type != uint8_t(RDSSType::RDSS_S1)) && (type != uint8_t(RDSSType::RDSS_S2))){
|
||
m_logger->error("RDSSType: type illegal value, type = {}", type);
|
||
return;
|
||
}
|
||
if(type == uint8_t(RDSSType::RDSS_S1))
|
||
{
|
||
// 清空旧数据
|
||
m_RDS1signalStrengthChart->removeAllSeries();
|
||
m_RDS1signalStrengthChartXAxis->clear();
|
||
}
|
||
else
|
||
{
|
||
// 清空旧数据
|
||
m_RDS2signalStrengthChart->removeAllSeries();
|
||
m_RDS2signalStrengthChartXAxis->clear();
|
||
}
|
||
|
||
// 创建数据集
|
||
QBarSet *set0 = new QBarSet("Power");
|
||
QBarSet *set1 = new QBarSet("Power2");
|
||
foreach (qreal val, yValues) {
|
||
if(val >= 36.0)
|
||
{
|
||
*set0 << 0;
|
||
*set1 << val;
|
||
}
|
||
else
|
||
{
|
||
*set0 << val;
|
||
*set1 << 0;
|
||
}
|
||
}
|
||
|
||
// 动态设置柱形颜色
|
||
set0->setBrush(QBrush(QColor("#C0C0C0")));
|
||
set1->setBrush(QBrush(QColor("#0000FF")));
|
||
|
||
QStackedBarSeries *series2 = new QStackedBarSeries();
|
||
|
||
series2->append(set0);
|
||
series2->append(set1);
|
||
|
||
// 添加对象追踪防止内存泄漏
|
||
set0->setParent(series2); // 建立父子关系
|
||
set1->setParent(series2); // 建立父子关系
|
||
|
||
if(type == uint8_t(RDSSType::RDSS_S1))
|
||
{
|
||
m_RDS1signalStrengthChart->addSeries(series2);
|
||
|
||
series2->attachAxis(m_RDS1signalStrengthChartYAxis);
|
||
|
||
// 设置X轴标签
|
||
m_RDS1signalStrengthChartXAxis->append(categories);
|
||
|
||
// 优化显示效果
|
||
series2->setLabelsVisible(false); // 隐藏数值标签
|
||
m_RDS1signalStrengthChart->legend()->hide(); // 隐藏图例
|
||
|
||
// 更新卫星数量显示
|
||
ui->rds1SatelliteCount->setText(QString::asprintf("%d", categories.count()));
|
||
}
|
||
else
|
||
{
|
||
m_RDS2signalStrengthChart->addSeries(series2);
|
||
|
||
series2->attachAxis(m_RDS2signalStrengthChartYAxis);
|
||
|
||
// 设置X轴标签
|
||
m_RDS2signalStrengthChartXAxis->append(categories);
|
||
|
||
// 优化显示效果
|
||
series2->setLabelsVisible(false); // 隐藏数值标签
|
||
m_RDS2signalStrengthChart->legend()->hide(); // 隐藏图例
|
||
|
||
// 更新卫星数量显示
|
||
ui->rds2SatelliteCount->setText(QString::asprintf("%d", categories.count()));
|
||
}
|
||
|
||
}
|
||
void MainWindow::createAzimuthMapChart() {
|
||
const qreal angularMin = 0;
|
||
const qreal angularMax = 360;
|
||
const qreal radialMin = 0;
|
||
const qreal radialMax = 90;
|
||
|
||
m_azimuthChart = new QPolarChart;
|
||
//m_azimuthChart->setTitle("");
|
||
m_azimuthChart->legend()->setVisible(false);
|
||
|
||
// 减小图表边距 - 这是关键设置
|
||
m_azimuthChart->setMargins(QMargins(0, 0, 0, 0)); // 左上右下全部设为0
|
||
|
||
auto angularAxis = new QValueAxis;
|
||
angularAxis->setTickCount(9);
|
||
angularAxis->setLabelFormat("%d");
|
||
angularAxis->setShadesVisible(true);
|
||
angularAxis->setShadesBrush(QBrush(QColor(249, 249, 255)));
|
||
m_azimuthChart->addAxis(angularAxis, QPolarChart::PolarOrientationAngular);
|
||
|
||
auto radialAxis = new QValueAxis;
|
||
radialAxis->setTickCount(7);
|
||
|
||
radialAxis->setLabelFormat("%d");
|
||
m_azimuthChart->addAxis(radialAxis, QPolarChart::PolarOrientationRadial);
|
||
|
||
radialAxis->setRange(radialMin, radialMax);
|
||
angularAxis->setRange(angularMin, angularMax);
|
||
|
||
QChartView *chartView = new QChartView(m_azimuthChart, this);
|
||
chartView->setRenderHint(QPainter::Antialiasing);
|
||
|
||
// 设置ChartView的边距
|
||
chartView->setContentsMargins(0, 0, 0, 0);
|
||
|
||
ui->vboxAzimuthMap->addWidget(chartView);
|
||
}
|
||
void MainWindow::setAzimuthValues(const QList<QPointF> &points) {
|
||
m_azimuthChart->removeAllSeries();
|
||
auto series = new QScatterSeries;
|
||
//series->setName("方位");
|
||
//series->setMarkerShape(QScatterSeries::MarkerShapeCircle); // 可选:圆形
|
||
series->setMarkerSize(10.0);
|
||
series->append(points);
|
||
m_azimuthChart->addSeries(series);
|
||
|
||
// 关联到已存在的极坐标轴
|
||
for (QAbstractAxis* ax : m_azimuthChart->axes(QPolarChart::PolarOrientationAngular))
|
||
series->attachAxis(ax);
|
||
for (QAbstractAxis* ax : m_azimuthChart->axes(QPolarChart::PolarOrientationRadial))
|
||
series->attachAxis(ax);
|
||
}
|
||
//--------------------------------------------------------------------------------------
|
||
// 消息列表操作
|
||
//--------------------------------------------------------------------------------------
|
||
void MainWindow::UpdateMessageList() {
|
||
ui->tblMessageList->clear();
|
||
QStringList column_labels;
|
||
column_labels << "读取状态"
|
||
<< "开始时间"
|
||
<< "信道"
|
||
<< "方向"
|
||
<< "号码"
|
||
<< "消息内容";
|
||
// 设置列表行数和列数
|
||
int rowCount = std::count_if(m_msgList.begin(),m_msgList.end(),[](const Record& r){ return r.type == CommType::ShortMessage;});
|
||
ui->tblMessageList->setRowCount(rowCount); // 设置行数
|
||
ui->tblMessageList->setColumnCount(column_labels.size()); // 设置列数
|
||
// 设置水平表头
|
||
ui->tblMessageList->setHorizontalHeaderLabels(column_labels);
|
||
// 设置垂直表头
|
||
int column_index = 0;
|
||
ui->tblMessageList->setColumnWidth(column_index, 80); // 读取状态
|
||
column_index = column_index + 1;
|
||
ui->tblMessageList->setColumnWidth(column_index, 180); // 开始时间
|
||
column_index = column_index + 1;
|
||
ui->tblMessageList->setColumnWidth(column_index, 60); // 信道
|
||
column_index = column_index + 1;
|
||
ui->tblMessageList->setColumnWidth(column_index, 60); // 方向
|
||
column_index = column_index + 1;
|
||
ui->tblMessageList->setColumnWidth(column_index, 120); // 号码
|
||
column_index = column_index + 1;
|
||
ui->tblMessageList->setColumnWidth(column_index, 400); // 消息内容
|
||
column_index = column_index + 1;
|
||
|
||
//插入所有项
|
||
m_unReadMsgCount = 0;
|
||
int rowIndex = 0;
|
||
for (int index = 0; index < m_msgList.size(); index++) {
|
||
Record& r = m_msgList[index];
|
||
if(r.type == CommType::Call){
|
||
continue;
|
||
}
|
||
|
||
int column_index = 0;
|
||
// 读取状态
|
||
auto item = new QTableWidgetItem(r.isUnread ? "未读" : "已读");
|
||
item->setData(Qt::UserRole,index);
|
||
item->setTextAlignment(Qt::AlignCenter);
|
||
if(r.isUnread){
|
||
item->setBackground(Qt::cyan);
|
||
++m_unReadMsgCount;
|
||
}
|
||
ui->tblMessageList->setItem(rowIndex, column_index, item);
|
||
column_index = column_index + 1;
|
||
// 开始时间
|
||
item = new QTableWidgetItem(r.beginTime.toString("yyyy-MM-dd hh:mm:ss"));
|
||
item->setTextAlignment(Qt::AlignCenter);
|
||
ui->tblMessageList->setItem(rowIndex, column_index, item);
|
||
column_index = column_index + 1;
|
||
// 信道
|
||
item = new QTableWidgetItem(r.channel == Channel::Uhf?"UHF":(r.channel==Channel::S?"S":"北斗"));
|
||
item->setTextAlignment(Qt::AlignCenter);
|
||
ui->tblMessageList->setItem(rowIndex, column_index, item);
|
||
column_index = column_index + 1;
|
||
// 方向
|
||
item = new QTableWidgetItem(r.direction==CommDirection::Receive?"接收":"发送");
|
||
item->setTextAlignment(Qt::AlignCenter);
|
||
ui->tblMessageList->setItem(rowIndex, column_index, item);
|
||
column_index = column_index + 1;
|
||
// 号码
|
||
item = new QTableWidgetItem(r.number);
|
||
item->setTextAlignment(Qt::AlignCenter);
|
||
ui->tblMessageList->setItem(rowIndex, column_index, item);
|
||
column_index = column_index + 1;
|
||
// 消息内容
|
||
item = new QTableWidgetItem(r.content);
|
||
item->setToolTip(r.content);
|
||
ui->tblMessageList->setItem(rowIndex, column_index, item);
|
||
column_index = column_index + 1;
|
||
|
||
rowIndex++;
|
||
}
|
||
ui->lblUnreadMessageCount->setText(QString("%1").arg(m_unReadMsgCount));
|
||
}
|
||
//--------------------------------------------------------------------------------------
|
||
// 槽函数
|
||
//--------------------------------------------------------------------------------------
|
||
bool MainWindow::checkNumber(const QString& number){
|
||
if (number.isEmpty()) {
|
||
QMessageBox::information(this, "错误", "请输入电话号码");
|
||
return false;
|
||
}
|
||
// 检查号码是否只包含数字 0-9
|
||
QRegularExpression digitOnly("^[0-9]*$"); // 正则表达式:只允许数字
|
||
if (!digitOnly.match(number).hasMatch()) {
|
||
QMessageBox::information(this, "错误", "电话号码只能包含数字0-9");
|
||
return false;
|
||
}
|
||
//检查号码长度
|
||
if (number.size() > 20){
|
||
QMessageBox::information(this, "错误", "电话号码长度不能超过20");
|
||
return false;
|
||
}
|
||
// TODO: 检查电话号码格式是否满足要求
|
||
return true;
|
||
}
|
||
bool MainWindow::checkMessage(const QString& message){
|
||
// 检查消息是否为空
|
||
if (message.isEmpty()) {
|
||
QMessageBox::information(this, "错误", "请输入要发送的消息");
|
||
return false;
|
||
}
|
||
// 检查消息长度
|
||
if (message.length() > 140) {
|
||
QMessageBox::information(this, "错误", "消息太长,不能超过140个字符");
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
std::pair<bool,Channel> MainWindow::selectChannel(ChannelType comm_type){
|
||
//U无SIM卡状态
|
||
bool isUhfChannelOk = (m_uhfModuleStatus == ModuleStatus::kNormal)
|
||
&& (m_uhfNetworkAccessStatus == NetworkAccessStatus::kConnectedDataIsActivated || m_uhfNetworkAccessStatus == NetworkAccessStatus::kConnectedDataIsNotActivated);
|
||
bool isSChannelOk = (m_tiantongModuleStatus == ModuleStatus::kNormal)
|
||
&& (m_tiantongSimCardStatus == SimCardStatus::kExist)
|
||
&& (m_tiantongNetworkAccessStatus == NetworkAccessStatus::kConnectedDataIsActivated || m_tiantongNetworkAccessStatus == NetworkAccessStatus::kConnectedDataIsNotActivated);
|
||
if(comm_type == ChannelType::ChannelUHF)
|
||
{
|
||
if(!isUhfChannelOk)
|
||
{
|
||
QMessageBox::information(this, "提示", "UHF通道不正常, 无法进行通信");
|
||
return std::make_pair(false,Channel::Uhf);
|
||
}
|
||
else
|
||
{
|
||
return std::make_pair(true,Channel::Uhf);
|
||
}
|
||
}
|
||
else if(comm_type == ChannelType::ChannelS)
|
||
{
|
||
if(!isSChannelOk)
|
||
{
|
||
QMessageBox::information(this, "提示", "S通道不正常, 无法进行通信");
|
||
return std::make_pair(false,Channel::S);
|
||
}
|
||
else
|
||
{
|
||
return std::make_pair(true,Channel::S);
|
||
}
|
||
}
|
||
else if(comm_type == ChannelType::ChannelAuto)
|
||
{
|
||
if(!isUhfChannelOk && !isSChannelOk){
|
||
QMessageBox::information(this, "提示", "UHF和S通道都不正常, 无法进行通信");
|
||
return std::make_pair(false,Channel::S);
|
||
}
|
||
if(isUhfChannelOk && !isSChannelOk){
|
||
return std::make_pair(true,Channel::Uhf);
|
||
}else if(!isUhfChannelOk && isSChannelOk){
|
||
return std::make_pair(true,Channel::S);
|
||
}else{
|
||
if(m_tiantongSignalStrength >= m_uhfSignalStrength){
|
||
return std::make_pair(true,Channel::S);
|
||
}else{
|
||
return std::make_pair(true,Channel::Uhf);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
QMessageBox::information(this, "提示", "通道错误, 无法进行通信");
|
||
return std::make_pair(false,Channel::Uhf);
|
||
}
|
||
}
|
||
void MainWindow::on_btnCallAnswer_clicked() {
|
||
if(m_uhfCallStatus == CallStatus::kIdle && m_tiantongCallStatus == CallStatus::kIdle){
|
||
// 检查电话号码是否为空
|
||
QString number = ui->cmbCallNumber->currentText();
|
||
if(!checkNumber(number)){
|
||
return;
|
||
}
|
||
ChannelType commtype;
|
||
// 呼叫
|
||
if(ui->rdbChannelUHF->isChecked()){
|
||
commtype = ChannelType::ChannelUHF;
|
||
}else if(ui->rdbChannelS->isChecked()){
|
||
commtype = ChannelType::ChannelS;
|
||
}else if(ui->rdbChannelAuto->isChecked()){
|
||
commtype = ChannelType::ChannelAuto;
|
||
}else{
|
||
return;
|
||
}
|
||
std::pair<bool,Channel> r = selectChannel(commtype);
|
||
if(!r.first){
|
||
return;
|
||
}
|
||
if (m_recordQueryWidget->saveNumber(NumberKind::Call, number)) {
|
||
//QMessageBox::information(this, "提示", "保存成功");
|
||
// 触发器已保证只保留最新10条
|
||
m_recordQueryWidget->refreshNumberCombo(ui->cmbCallNumber, NumberKind::Call);
|
||
}
|
||
m_currentTalkingDirection = CommDirection::Send;
|
||
if(r.second == Channel::Uhf){
|
||
sendUdpMessage(pack_uhf_dial_cmd(number.toStdString()));
|
||
}else if(r.second == Channel::S){
|
||
sendUdpMessage(pack_tiantong_dial_cmd(number.toStdString()));
|
||
}
|
||
}else if(m_uhfCallStatus == CallStatus::kCallIsComing){
|
||
sendUdpMessage(pack_uhf_answer());
|
||
}else if(m_tiantongCallStatus == CallStatus::kCallIsComing){
|
||
sendUdpMessage(pack_tiantong_answer());
|
||
}
|
||
}
|
||
|
||
void MainWindow::on_btnCallReject_clicked() {
|
||
if(m_uhfCallStatus != CallStatus::kIdle){
|
||
sendUdpMessage(pack_uhf_hang_up_cmd());
|
||
}
|
||
if(m_tiantongCallStatus != CallStatus::kIdle){
|
||
sendUdpMessage(pack_tiantong_hang_up_cmd());
|
||
}
|
||
}
|
||
|
||
void MainWindow::on_btnSendMessageByUhfOrS_clicked() {
|
||
QString number = ui->cmbMessageNumberForUhfAndS->currentText();
|
||
ChannelType commtype;
|
||
if(!checkNumber(number)){
|
||
return;
|
||
}
|
||
QString message = ui->txtMessageContentForUhfAndS->toPlainText();
|
||
if(!checkMessage(message)){
|
||
return;
|
||
}
|
||
// 发送信息
|
||
if(ui->rdbChannelUHF->isChecked()){
|
||
commtype = ChannelType::ChannelUHF;
|
||
}else if(ui->rdbChannelS->isChecked()){
|
||
commtype = ChannelType::ChannelS;
|
||
}else if(ui->rdbChannelAuto->isChecked()){
|
||
commtype = ChannelType::ChannelAuto;
|
||
}else{
|
||
return;
|
||
}
|
||
std::pair<bool,Channel> r = selectChannel(commtype);
|
||
if(!r.first){
|
||
return;
|
||
}
|
||
if (m_recordQueryWidget->saveNumber(NumberKind::USMsg, number)) {
|
||
//QMessageBox::information(this, "提示", "保存成功");
|
||
// 触发器已保证只保留最新10条
|
||
m_recordQueryWidget->refreshNumberCombo(ui->cmbMessageNumberForUhfAndS, NumberKind::USMsg);
|
||
}
|
||
if(r.second == Channel::Uhf){
|
||
sendUdpMessage(pack_uhf_short_message_cmd(number.toStdString(),message.toStdU16String()));
|
||
}else if(r.second == Channel::S){
|
||
sendUdpMessage(pack_tiantong_short_message_cmd(number.toStdString(),message.toStdU16String()));
|
||
}
|
||
}
|
||
|
||
void MainWindow::on_btnSendMessageByBeiDou_clicked()
|
||
{
|
||
QString number = ui->cmbMessageNumberForBeiDou->currentText();
|
||
if(!checkNumber(number)){
|
||
return;
|
||
}
|
||
QString message = ui->txtMessageContentForBeiDou->toPlainText();
|
||
if(!checkMessage(message)){
|
||
return;
|
||
}
|
||
if (m_recordQueryWidget->saveNumber(NumberKind::BdMsg, number)) {
|
||
//QMessageBox::information(this, "提示", "保存成功");
|
||
// 触发器已保证只保留最新10条
|
||
m_recordQueryWidget->refreshNumberCombo(ui->cmbMessageNumberForBeiDou, NumberKind::BdMsg);
|
||
}
|
||
sendUdpMessage(pack_beidou_short_message_cmd(number.toStdString(),message.toStdU16String()));
|
||
}
|
||
|
||
|
||
void MainWindow::on_tblMessageList_currentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous)
|
||
{
|
||
int currentRow = ui->tblMessageList->currentRow();
|
||
if(currentRow == -1){
|
||
ui->txtCurrentItemMessageContent->clear();
|
||
}else{
|
||
int index = ui->tblMessageList->item(currentRow,0)->data(Qt::UserRole).toInt();
|
||
ui->txtCurrentItemMessageContent->setText(m_msgList[index].content);
|
||
if(m_msgList[index].isUnread){
|
||
m_msgList[index].isUnread = false;
|
||
ui->tblMessageList->item(currentRow,0)->setText("已读");
|
||
ui->tblMessageList->item(currentRow,0)->setBackground(Qt::white);
|
||
--m_unReadMsgCount;
|
||
ui->lblUnreadMessageCount->setText(QString("%1").arg(m_unReadMsgCount));
|
||
}
|
||
}
|
||
}
|
||
|
||
void MainWindow::on_btnRecordQuery_clicked() {
|
||
m_recordQueryWidget->show();
|
||
}
|
||
//--------------------------------------------------------------------------------------
|
||
// 与底层消息交互
|
||
//--------------------------------------------------------------------------------------
|
||
bool MainWindow::sendUdpMessage(const QByteArray &udpMessage) {
|
||
const QHostAddress address(m_udpIp);
|
||
m_logger->info("send a udp message, len = {}, data = {}",udpMessage.size(),udpMessage.toHex(' ').toStdString());
|
||
if (m_udpSocket->writeDatagram(udpMessage, address, m_peerPort) !=
|
||
udpMessage.size()) {
|
||
//m_logger->error("发送udp消息错误");
|
||
m_logger->error("An error occurred when sending a udp message");
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
//--------------------------------------------------------------------------------------
|
||
// 处理命令
|
||
//--------------------------------------------------------------------------------------
|
||
void MainWindow::processCommand(QByteArray& cmd){
|
||
if(cmd.size() < 5){
|
||
return;
|
||
}
|
||
|
||
if(pack_deslip(cmd) < 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 更新最后收到数据的时间
|
||
m_lastUdpDataTime = QDateTime::currentDateTime();
|
||
|
||
// 如果当前状态是未连接,立即更新状态
|
||
if(!m_udpConnected) {
|
||
m_udpConnected = true;
|
||
ui->lblLinkStatus->setText("已连接");
|
||
ui->lblLinkStatus->setStyleSheet("color: green;");
|
||
//QMessageBox::information(this, "提示", "已连接");
|
||
m_logger->info("Link is Connected");
|
||
}
|
||
|
||
switch(uint8_t(cmd[COMMAND_TYPE_INDEX])){
|
||
case uint8_t(CommandType::kTianTongVoice):
|
||
processTianTongVoiceCmd(cmd);
|
||
break;
|
||
case uint8_t(CommandType::kUhfVoice):
|
||
processUhfVoiceCmd(cmd);
|
||
break;
|
||
case uint8_t(CommandType::kTianTongShortMessage):
|
||
processTianTongShortMessageCmd(cmd);
|
||
break;
|
||
case uint8_t(CommandType::kUhfShortMessage):
|
||
processUhfShortMessageCmd(cmd);
|
||
break;
|
||
case uint8_t(CommandType::kBeiDouShortMessage):
|
||
processBeiDouShortMessageCmd(cmd);
|
||
break;
|
||
case uint8_t(CommandType::kStatusReport):
|
||
processStatusReportCmd(cmd);
|
||
break;
|
||
case uint8_t(CommandType::kSearchSatelliteStatusReport):
|
||
processSearchSatelliteStatusReport(cmd);
|
||
break;
|
||
case uint8_t(CommandType::kSearchZhuanTaiStatusReport):
|
||
processZhuanTaiStatusReportCmd(cmd);
|
||
break;
|
||
case uint8_t(CommandType::kConfigCmdDefaultChannel):
|
||
case uint8_t(CommandType::kConfigCmdUDataChannelKeepTime):
|
||
case uint8_t(CommandType::kConfigCmdDefaultNumber):
|
||
case uint8_t(CommandType::kConfigCmdSoftVersion):
|
||
processConfigCmd(cmd);
|
||
m_configParamWidget->processConfigCmd(cmd);
|
||
break;
|
||
case uint8_t(CommandType::kDebugCmd):
|
||
processDebugCmd(cmd);
|
||
break;
|
||
}
|
||
}
|
||
void MainWindow::processTianTongVoiceCmd(const QByteArray& cmd){
|
||
switch(uint8_t(cmd[SUB_COMMAND_TYPE_INDEX])){
|
||
case uint8_t(TianTongVoiceSubCommandType::kDial):
|
||
if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kSucess)){//拨号成功
|
||
//this->m_logger->info("天通拨号成功, 号码为: {}",ui->cmbCallNumber->currentText().toStdString());
|
||
this->m_logger->info("Tiantong: dial was successful, number : {}",ui->cmbCallNumber->currentText().toStdString());
|
||
}else if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kFailure)){//拨号失败
|
||
//this->m_logger->info("天通拨号失败, 号码为: {}",ui->cmbCallNumber->currentText().toStdString());
|
||
this->m_logger->info("The Tiantong: dial was failed, number : {}",ui->cmbCallNumber->currentText().toStdString());
|
||
}
|
||
break;
|
||
case uint8_t(TianTongVoiceSubCommandType::kHangUp):
|
||
if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kSucess)){//挂机成功
|
||
//this->m_logger->info("天通挂机成功, 号码为: {}",ui->cmbCallNumber->currentText().toStdString());
|
||
this->m_logger->info("Tiantong: hang up was successful, number : {}",ui->cmbCallNumber->currentText().toStdString());
|
||
}else if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kFailure)){//挂机失败
|
||
//this->m_logger->info("天通挂机失败, 号码为: {}",ui->cmbCallNumber->currentText().toStdString());
|
||
this->m_logger->info("The Tiantong: hang up was failed, number : {}",ui->cmbCallNumber->currentText().toStdString());
|
||
}
|
||
break;
|
||
case uint8_t(TianTongVoiceSubCommandType::kAnswer):
|
||
if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kSucess)){//接听成功
|
||
//this->m_logger->info("天通接听成功, 号码为: {}",ui->cmbCallNumber->currentText().toStdString());
|
||
this->m_logger->info("Tiantong: answer was successful, number : {}",ui->cmbCallNumber->currentText().toStdString());
|
||
}else if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kFailure)){//接听失败
|
||
//this->m_logger->info("天通接听失败, 号码为: {}",ui->cmbCallNumber->currentText().toStdString());
|
||
this->m_logger->info("The Tiantong: answer was failed, number : {}",ui->cmbCallNumber->currentText().toStdString());
|
||
}
|
||
break;
|
||
case uint8_t(TianTongVoiceSubCommandType::kSendKeysWhenOnLine):
|
||
if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kSucess)){//通话中发送按键成功
|
||
//this->m_logger->info("天通按键发送成功");
|
||
this->m_logger->info("Tiantong: senting keys was successful");
|
||
}else if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kFailure)){//通话中发送按键失败
|
||
//this->m_logger->info("天通按键发送失败");
|
||
this->m_logger->info("The Tiantong: sending keys was successful");
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
void MainWindow::processUhfVoiceCmd(const QByteArray& cmd){
|
||
switch(uint8_t(cmd[SUB_COMMAND_TYPE_INDEX])){
|
||
case uint8_t(UhfVoiceSubCommandType::kDial):
|
||
if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kSucess)){//拨号成功
|
||
//this->m_logger->info("UHF拨号成功, 号码为: {}",ui->cmbCallNumber->currentText().toStdString());
|
||
this->m_logger->info("UHF: dial was successful, number : {}",ui->cmbCallNumber->currentText().toStdString());
|
||
}else if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kFailure)){//拨号失败
|
||
//this->m_logger->info("UHF拨号失败, 号码为: {}",ui->cmbCallNumber->currentText().toStdString());
|
||
this->m_logger->info("UHF: dial was failed, number : {}",ui->cmbCallNumber->currentText().toStdString());
|
||
}
|
||
break;
|
||
case uint8_t(UhfVoiceSubCommandType::kHangUp):
|
||
if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kSucess)){//挂机成功
|
||
//this->m_logger->info("UHF挂机成功, 号码为: {}",ui->cmbCallNumber->currentText().toStdString());
|
||
this->m_logger->info("UHF: hang up was successful, number : {}",ui->cmbCallNumber->currentText().toStdString());
|
||
}else if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kFailure)){//挂机失败
|
||
//this->m_logger->info("UHF挂机失败, 号码为: {}",ui->cmbCallNumber->currentText().toStdString());
|
||
this->m_logger->info("UHF: hang up was failed, number : {}",ui->cmbCallNumber->currentText().toStdString());
|
||
}
|
||
break;
|
||
case uint8_t(UhfVoiceSubCommandType::kAnswer):
|
||
if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kSucess)){//通话中发送按键成功
|
||
//this->m_logger->info("UHF接听成功, 号码为: {}",ui->cmbCallNumber->currentText().toStdString());
|
||
this->m_logger->info("UHF: answer was successful, number : {}",ui->cmbCallNumber->currentText().toStdString());
|
||
}else if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kFailure)){//通话中发送按键失败
|
||
//this->m_logger->info("UHF接听失败, 号码为: {}",ui->cmbCallNumber->currentText().toStdString());
|
||
this->m_logger->info("UHF: answer was failed, number : {}",ui->cmbCallNumber->currentText().toStdString());
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
std::pair<QString,QString> MainWindow::parseReceivedShortMessage(const QByteArray& cmd,Channel chan){
|
||
char buffer[21];
|
||
memset(buffer,0,21);
|
||
memcpy(buffer,cmd.data()+COMMAND_DATA_BEGIN_INDEX,20);
|
||
QString number = QString::fromStdString(std::string(buffer));
|
||
const char16_t * s = (char16_t*)(cmd.constData() + COMMAND_DATA_BEGIN_INDEX + 20);
|
||
size_t len = (cmd.size() - (FRAME_MIN_LEN + 20))/2;
|
||
QString message = QString::fromUtf16(s,len);
|
||
Record r;
|
||
r.beginTime = QDateTime::currentDateTime();
|
||
r.channel = chan;
|
||
r.type = CommType::ShortMessage;
|
||
r.direction = CommDirection::Receive;
|
||
r.number = number;
|
||
r.content = message;
|
||
r.isUnread = true;
|
||
r.callDuration = 0;
|
||
|
||
m_msgList.push_back(r);
|
||
UpdateMessageList();
|
||
m_recordQueryWidget->InsertRecord(m_msgList.back());
|
||
|
||
return std::make_pair(number,message);
|
||
|
||
}
|
||
|
||
void MainWindow::processTianTongShortMessageCmd(const QByteArray& cmd){
|
||
switch(uint8_t(cmd[SUB_COMMAND_TYPE_INDEX])){
|
||
case uint8_t(ShortMessageSubCommandType::kSendMessage):
|
||
if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kSucess)){//短消息发送成功
|
||
//this->m_logger->info("天通短消息发送成功, 号码为: {}",ui->cmbMessageNumberForUhfAndS->currentText().toStdString());
|
||
this->m_logger->info("Tiantong: the message was sent successfully, number: {}",ui->cmbMessageNumberForUhfAndS->currentText().toStdString());
|
||
}else if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kFailure)){//短消息发送失败
|
||
//this->m_logger->info("天通短消息发送失败, 号码为: {}",ui->cmbMessageNumberForUhfAndS->currentText().toStdString());
|
||
this->m_logger->info("Tiantong: short message sending failed, number: {}",ui->cmbMessageNumberForUhfAndS->currentText().toStdString());
|
||
}
|
||
break;
|
||
case uint8_t(ShortMessageSubCommandType::kRecvMessage):
|
||
//接收到短消息
|
||
if(cmd.size() <= FRAME_MIN_LEN + 20){
|
||
this->m_logger->error("接收的天通短消息长度不足, 长度 = {}",cmd.size());
|
||
this->m_logger->error("Tiantong: The length of the received short message is insufficient, len = {}",cmd.size());
|
||
return;
|
||
}
|
||
auto r = parseReceivedShortMessage(cmd,Channel::S);
|
||
//this->m_logger->info("从天通接收到短消息, 号码为: {}, 消息: {}",r.first.toStdString(),r.second.toStdString());
|
||
this->m_logger->info("Tiantong: Received a short message, number: {}, message: {}",r.first.toStdString(),r.second.toStdString());
|
||
break;
|
||
}
|
||
}
|
||
void MainWindow::processUhfShortMessageCmd(const QByteArray& cmd){
|
||
switch(uint8_t(cmd[SUB_COMMAND_TYPE_INDEX])){
|
||
case uint8_t(ShortMessageSubCommandType::kSendMessage):
|
||
if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kSucess)){//短消息发送成功
|
||
//this->m_logger->info("UHF短消息发送成功, 号码为: {}",ui->cmbMessageNumberForUhfAndS->currentText().toStdString());
|
||
this->m_logger->info("UHF: the message was sent successfully, number: {}",ui->cmbMessageNumberForUhfAndS->currentText().toStdString());
|
||
}else if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kFailure)){//短消息发送失败
|
||
//this->m_logger->info("UHF短消息发送失败, 号码为: {}",ui->cmbMessageNumberForUhfAndS->currentText().toStdString());
|
||
this->m_logger->info("UHF: short message sending failed, number: {}",ui->cmbMessageNumberForUhfAndS->currentText().toStdString());
|
||
}
|
||
break;
|
||
case uint8_t(ShortMessageSubCommandType::kRecvMessage):
|
||
//接收到短消息
|
||
if(cmd.size() <= FRAME_MIN_LEN + 20){
|
||
//this->m_logger->error("接收的UHF短消息长度不足, 长度 = {}",cmd.size());
|
||
this->m_logger->error("UHF: The length of the received short message is insufficient, len = {}",cmd.size());
|
||
return;
|
||
}
|
||
auto r = parseReceivedShortMessage(cmd,Channel::Uhf);
|
||
//this->m_logger->info("从UHF接收到短消息, 号码为: {}, 消息: {}",r.first.toStdString(),r.second.toStdString());
|
||
this->m_logger->info("UHF: Received a short message, number: {}, message: {}",r.first.toStdString(),r.second.toStdString());
|
||
break;
|
||
}
|
||
}
|
||
void MainWindow::processBeiDouShortMessageCmd(const QByteArray& cmd){
|
||
switch(uint8_t(cmd[SUB_COMMAND_TYPE_INDEX])){
|
||
case uint8_t(ShortMessageSubCommandType::kSendMessage):
|
||
if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kSucess)){//短消息发送成功
|
||
//this->m_logger->info("北斗短消息发送成功, 号码为: {}",ui->cmbMessageNumberForBeiDou->currentText().toStdString());
|
||
this->m_logger->info("BeiDou: the message was sent successfully, number: {}",ui->cmbMessageNumberForBeiDou->currentText().toStdString());
|
||
}else if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kFailure)){//短消息发送失败
|
||
//this->m_logger->info("北斗短消息发送失败, 号码为: {}",ui->cmbMessageNumberForBeiDou->currentText().toStdString());
|
||
this->m_logger->info("BeiDou: the message sending failed, number: {}",ui->cmbMessageNumberForBeiDou->currentText().toStdString());
|
||
}
|
||
break;
|
||
case uint8_t(ShortMessageSubCommandType::kRecvMessage):
|
||
//接收到短消息
|
||
if(cmd.size() <= FRAME_MIN_LEN + 20){
|
||
//this->m_logger->error("接收的北斗短消息长度不足, 长度 = {}",cmd.size());
|
||
this->m_logger->error("BeiDou: The length of the received short message is insufficient, len = {}",cmd.size());
|
||
return;
|
||
}
|
||
auto r = parseReceivedShortMessage(cmd,Channel::BeiDou);
|
||
//this->m_logger->info("从北斗接收到短消息, 号码为: {}, 消息: {}",r.first.toStdString(),r.second.toStdString());
|
||
this->m_logger->info("BeiDou: Received a short message, number: {}, message: {}",r.first.toStdString(),r.second.toStdString());
|
||
break;
|
||
}
|
||
}
|
||
void MainWindow::processStatusReportCmd(const QByteArray& cmd){
|
||
//QByteArray cmd = cmdinput;
|
||
if(cmd.size() != FRAME_LEN_STATUSREPORT){
|
||
//cmd.resize(FRAME_LEN_STATUSREPORT);
|
||
//m_logger->error("接收的状态包长度错误, 长度 = {}",cmd.size());
|
||
m_logger->error("The received status packet length is incorrect, len = {}",cmd.size());
|
||
//return;
|
||
}
|
||
if(uint8_t(cmd[SUB_COMMAND_TYPE_INDEX]) != 0){
|
||
return;
|
||
}
|
||
int data_index = COMMAND_DATA_BEGIN_INDEX;
|
||
//uhf状态
|
||
uint8_t uhf_module_status = cmd[data_index++];//模块状态
|
||
uint8_t uhf_network_access_status = cmd[data_index++];//入网状态
|
||
uint8_t uhf_sim_card_status = cmd[data_index++];//sim卡状态
|
||
uint8_t uhf_m_card_status = cmd[data_index++];//m卡状态
|
||
uint8_t uhf_call_status = cmd[data_index++];//通话状态
|
||
uint8_t uhf_satellite_signal_strength = cmd[data_index++];
|
||
// 使用 QByteArray 处理
|
||
QByteArray uhf_data = QByteArray::fromRawData(cmd.constData() + data_index, 20);
|
||
uhf_data.replace('\0', ""); // 移除所有空字符
|
||
// 转换为 std::string
|
||
std::string uhf_number = uhf_data.toStdString();
|
||
data_index += 20;
|
||
//天通状态
|
||
uint8_t tiantong_module_status = cmd[data_index++];//模块状态
|
||
uint8_t tiantong_network_access_status = cmd[data_index++];//入网状态
|
||
uint8_t tiantong_sim_card_status = cmd[data_index++];//sim卡状态
|
||
uint8_t tiantong_m_card_status = cmd[data_index++];//m卡状态
|
||
uint8_t tiantong_call_status = cmd[data_index++];//通话状态
|
||
uint8_t tiantong_satellite_signal_strength = cmd[data_index++];
|
||
// 使用 QByteArray 处理
|
||
QByteArray tiantong_data = QByteArray::fromRawData(cmd.constData() + data_index, 20);
|
||
tiantong_data.replace('\0', ""); // 移除所有空字符
|
||
// 转换为 std::string
|
||
std::string tiantong_number = tiantong_data.toStdString();
|
||
data_index += 20;
|
||
|
||
//北斗状态
|
||
uint8_t beidou_module_status = cmd[data_index++];//模块状态
|
||
uint8_t beidou_sim_card_status = cmd[data_index++];//sim卡状态
|
||
//位置
|
||
uint8_t beidou_pos_status = cmd[data_index++];//定位有效标志
|
||
int32_t longitude_v = qFromBigEndian<qint32>(reinterpret_cast<const uchar*>(cmd.constData()+data_index));
|
||
data_index += 4;
|
||
double longitude = longitude_v / 1e6;
|
||
int32_t latitude_v = qFromBigEndian<qint32>(reinterpret_cast<const uchar*>(cmd.constData()+data_index));
|
||
data_index += 4;
|
||
double latitude = latitude_v / 1e6;
|
||
int32_t altitude_v = qFromBigEndian<qint32>(reinterpret_cast<const uchar*>(cmd.constData()+data_index));
|
||
data_index += 4;
|
||
double altitude = altitude_v / 10.0;
|
||
//液压缸升降高度状态
|
||
int16_t oil_level_position_v = qFromBigEndian<qint16>(reinterpret_cast<const uchar*>(cmd.constData()+data_index));
|
||
data_index += 2;
|
||
//float oil_level_position = oil_level_position_v /1000.0;//米
|
||
int16_t oil_level_position = oil_level_position_v;
|
||
//自检状态
|
||
//天线电源A电压
|
||
int16_t antenna_power_supply_a_voltage_v = qFromBigEndian<qint16>(reinterpret_cast<const uchar*>(cmd.constData()+data_index));
|
||
data_index += 2;
|
||
double antenna_power_supply_a_voltage = antenna_power_supply_a_voltage_v / 1000.0;//V
|
||
//天线电源A电流
|
||
int16_t antenna_power_supply_a_current_v = qFromBigEndian<qint16>(reinterpret_cast<const uchar*>(cmd.constData()+data_index));
|
||
data_index += 2;
|
||
double antenna_power_supply_a_current = antenna_power_supply_a_current_v / 1000.0;//A
|
||
//天线电源B电压
|
||
int16_t antenna_power_supply_b_voltage_v = qFromBigEndian<qint16>(reinterpret_cast<const uchar*>(cmd.constData()+data_index));
|
||
data_index += 2;
|
||
double antenna_power_supply_b_voltage = antenna_power_supply_b_voltage_v / 1000.0;//V
|
||
//天线电源B电流
|
||
int16_t antenna_power_supply_b_current_v = qFromBigEndian<qint16>(reinterpret_cast<const uchar*>(cmd.constData()+data_index));
|
||
data_index += 2;
|
||
double antenna_power_supply_b_current = antenna_power_supply_b_current_v / 1000.0;//A
|
||
//天线温度
|
||
int16_t antenna_temperature_v = qFromBigEndian<qint16>(reinterpret_cast<const uchar*>(cmd.constData()+data_index));
|
||
double antenna_temperature = antenna_temperature_v/100.0;
|
||
data_index += 2;
|
||
//UHF发送锁相环频综状态
|
||
uint8_t phase_locked_loop_send = cmd[data_index++];
|
||
//UHF接收锁相环频综状态
|
||
uint8_t phase_locked_loop_recv = cmd[data_index++];
|
||
|
||
//处理模块状态
|
||
processUhfModuleStatus(uhf_module_status);
|
||
processTianTongModuleStatus(tiantong_module_status);
|
||
processBeiDouModuleStatus(beidou_module_status);
|
||
//处理入网状态
|
||
processUhfNetworkAccessStatus(uhf_network_access_status);
|
||
processTianTongNetworkAccessStatus(tiantong_network_access_status);
|
||
// 处理sim卡状态
|
||
//processUhfSimCardStatus(uhf_sim_card_status);
|
||
processTianTongSimCardStatus(tiantong_sim_card_status);
|
||
processBeiDouSimCardStatus(beidou_sim_card_status);
|
||
// 处理m卡状态
|
||
processUhfMCardStatus(uhf_m_card_status);
|
||
processTianTongMCardStatus(tiantong_m_card_status);
|
||
//处理呼叫状态
|
||
processCallStatus(tiantong_call_status,uhf_call_status,tiantong_number,uhf_number);
|
||
|
||
// 处理信号强度,信号强度范围转换
|
||
//m_uhfSignalStrength = uhf_satellite_signal_strength;
|
||
// 计算大致区间
|
||
if (uhf_satellite_signal_strength == 0) {
|
||
m_uhfSignalStrength = 0;
|
||
ui->btnUHFSignalStrength->setIcon(QIcon(":/rc/res/signal_0.png"));
|
||
} else if (uhf_satellite_signal_strength <= 63) {
|
||
m_uhfSignalStrength = 25;
|
||
ui->btnUHFSignalStrength->setIcon(QIcon(":/rc/res/signal_1.png"));
|
||
} else if (uhf_satellite_signal_strength <= 127) {
|
||
m_uhfSignalStrength = 50;
|
||
ui->btnUHFSignalStrength->setIcon(QIcon(":/rc/res/signal_2.png"));
|
||
} else if (uhf_satellite_signal_strength <= 191) {
|
||
m_uhfSignalStrength = 75;
|
||
ui->btnUHFSignalStrength->setIcon(QIcon(":/rc/res/signal_3.png"));
|
||
} else {
|
||
m_uhfSignalStrength = 100;
|
||
ui->btnUHFSignalStrength->setIcon(QIcon(":/rc/res/signal_4.png"));
|
||
}
|
||
ui->btnUHFSignalStrength->setToolTip(QString("%1").arg(uhf_satellite_signal_strength));
|
||
|
||
//m_tiantongSignalStrength = tiantong_satellite_signal_strength;
|
||
if (tiantong_satellite_signal_strength == 0) {
|
||
m_tiantongSignalStrength = 0;
|
||
ui->btnSSignalStrength->setIcon(QIcon(":/rc/res/signal_0.png"));
|
||
} else if (tiantong_satellite_signal_strength >= 1 && tiantong_satellite_signal_strength <= 3) {
|
||
m_tiantongSignalStrength = 25;
|
||
ui->btnSSignalStrength->setIcon(QIcon(":/rc/res/signal_1.png"));
|
||
} else if (tiantong_satellite_signal_strength > 3 && tiantong_satellite_signal_strength <= 6) {
|
||
m_tiantongSignalStrength = 50;
|
||
ui->btnSSignalStrength->setIcon(QIcon(":/rc/res/signal_2.png"));
|
||
} else if (tiantong_satellite_signal_strength > 6 && tiantong_satellite_signal_strength <= 9) {
|
||
m_tiantongSignalStrength = 75;
|
||
ui->btnSSignalStrength->setIcon(QIcon(":/rc/res/signal_3.png"));
|
||
} else if (tiantong_satellite_signal_strength > 10) {
|
||
m_tiantongSignalStrength = 100;
|
||
ui->btnSSignalStrength->setIcon(QIcon(":/rc/res/signal_4.png"));
|
||
}
|
||
ui->btnSSignalStrength->setToolTip(QString("%1").arg(tiantong_satellite_signal_strength));
|
||
|
||
// 处理来电号码,在processCallStatus中处理
|
||
//if(!uhf_number.empty()){
|
||
// ui->cmbCallNumber->setCurrentText(QString::fromStdString(uhf_number));
|
||
//}else{
|
||
// ui->cmbCallNumber->setCurrentText(QString::fromStdString(tiantong_number));
|
||
//}
|
||
|
||
// 处理位置
|
||
if(beidou_pos_status == 0x01)
|
||
{
|
||
ui->lblPosition->setText(QString("定位有效, 经度: %1, 纬度: %2, 高度: %3").arg(longitude, 0, 'f', 6).arg(latitude, 0, 'f', 6).arg(altitude, 0, 'f', 1));
|
||
}
|
||
else
|
||
{
|
||
ui->lblPosition->setText("定位无效");
|
||
}
|
||
// 处理液压缸升降高度状态
|
||
ui->lblHydraulicCylinderHeight->setText(QString("%1 毫米").arg(oil_level_position));
|
||
// 处理自检状态
|
||
ui->lblAntennaPowerSupply->setText(QString("电源A电压: %1 V, 电源A电流: %2 A, 电源B电压: %3 V, 电源B电流: %4 A, 温度: %5 ℃")
|
||
.arg(antenna_power_supply_a_voltage, 0, 'f', 3).arg(antenna_power_supply_a_current, 0, 'f', 3)
|
||
.arg(antenna_power_supply_b_voltage, 0, 'f', 3).arg(antenna_power_supply_b_current, 0, 'f', 3)
|
||
.arg(antenna_temperature, 0, 'f', 2));
|
||
QString s;
|
||
if(phase_locked_loop_send == uint8_t(PhaseLockedLoopStatus::kLocked) || phase_locked_loop_send == uint8_t(PhaseLockedLoopStatus::kUnlocked)){
|
||
s = QString("UHF发送锁相环频综: %1 ").arg(phase_locked_loop_send == uint8_t(PhaseLockedLoopStatus::kLocked)?"锁定":"失锁");
|
||
}else{
|
||
//m_logger->error("UHF发送锁相环频综非法值, phase_locked_loop_send = {}",phase_locked_loop_send);
|
||
m_logger->error("UHF: send phase locked loop illegal value, phase_locked_loop_send = {}",phase_locked_loop_send);
|
||
}
|
||
if(phase_locked_loop_recv == uint8_t(PhaseLockedLoopStatus::kLocked) || phase_locked_loop_recv == uint8_t(PhaseLockedLoopStatus::kUnlocked)){
|
||
s += QString("UHF接收锁相环频综: %1").arg(phase_locked_loop_recv == uint8_t(PhaseLockedLoopStatus::kLocked)?"锁定":"失锁");
|
||
}else{
|
||
//m_logger->error("UHF接收锁相环频综非法值, phase_locked_loop_recv = {}",phase_locked_loop_recv);
|
||
m_logger->error("UHF: recv phase locked loop illegal value, phase_locked_loop_recv = {}",phase_locked_loop_send);
|
||
}
|
||
ui->lblPhaseLockedLoop->setText(s);
|
||
}
|
||
void MainWindow::processSearchSatelliteStatusReport(const QByteArray& cmd){
|
||
int data_index, i;
|
||
uint8_t number_of_satellite, number_of_rds1satellite, number_of_rds2satellite;
|
||
std::vector<SatelliteStatus> all_satellite_status;
|
||
std::vector<RDSSSatelliteStatus> rdss_s1satellite_status, rdss_s2satellite_status;
|
||
QList<QString> categories, s1categories, s2categories;
|
||
QList<qreal> yValues, s1yValues, s2yValues;
|
||
QList<QPointF> azimuth_pitch_values;
|
||
|
||
switch(uint8_t(cmd[SUB_COMMAND_TYPE_INDEX]))
|
||
{
|
||
case uint8_t(SearchSatelliteStatusReportSubCommandType::kRnss):
|
||
if(cmd.size() < FRAME_MIN_LEN + 1){
|
||
//m_logger->error("接收的搜星状态包长度错误, 长度 = {}",cmd.size());
|
||
m_logger->error("The received search satellite status packet length is incorrect, len = {}",cmd.size());
|
||
return;
|
||
}
|
||
data_index = COMMAND_DATA_BEGIN_INDEX;
|
||
number_of_satellite = cmd[data_index++];//卫星数量
|
||
|
||
if(cmd.size() < (FRAME_MIN_LEN + 1 + 6* number_of_satellite)){
|
||
//m_logger->error("接收的rnss搜星状态包长度错误, 卫星个数 = {}, 长度 = {}",number_of_satellite,cmd.size());
|
||
m_logger->error("The received search rnss satellite status packet length is incorrect, satellite_num = {}, len = {}",number_of_satellite,cmd.size());
|
||
}
|
||
|
||
for(i = 0 ; i < number_of_satellite; i++){
|
||
SatelliteStatus status;
|
||
status.number = cmd[data_index++];//卫星编号
|
||
status.locate_flag = cmd[data_index++];//卫星定位标志
|
||
status.snr = cmd[data_index++];//卫星信噪比
|
||
status.azimuth = qFromBigEndian<quint16>(reinterpret_cast<const uchar*>(cmd.constData()+data_index));//卫星方位角
|
||
data_index += 2;
|
||
status.pitch = cmd[data_index++];//卫星俯仰角
|
||
all_satellite_status.push_back(status);
|
||
}
|
||
// 处理卫星状态
|
||
for(i = 0 ; i < all_satellite_status.size(); i++){
|
||
//categories.push_back(QString("%1").arg(i));
|
||
//categories.push_back(QString("%1").arg(all_satellite_status[i].number));
|
||
//categories.push_back(QString("%1").arg(all_satellite_status[i].number, 2, 10, QChar('0')));//与下面等效
|
||
categories.push_back(QString::asprintf("%02d", all_satellite_status[i].number));
|
||
yValues.push_back(all_satellite_status[i].snr);
|
||
azimuth_pitch_values.push_back(QPointF(all_satellite_status[i].azimuth,all_satellite_status[i].pitch));
|
||
}
|
||
// 设置信号能量
|
||
setSignalStrengthValues(categories,yValues);
|
||
// 设置方位俯仰角
|
||
setAzimuthValues(azimuth_pitch_values);
|
||
break;
|
||
case uint8_t(SearchSatelliteStatusReportSubCommandType::kRdss):
|
||
if(cmd.size() < FRAME_MIN_LEN + 2){
|
||
//m_logger->error("接收的rdss搜星状态包长度错误, 长度 = {}",cmd.size());
|
||
m_logger->error("The received search rdss satellite status packet length is incorrect, len = {}",cmd.size());
|
||
return;
|
||
}
|
||
data_index = COMMAND_DATA_BEGIN_INDEX;
|
||
number_of_rds1satellite = cmd[data_index++];//RDSS S1波束数量
|
||
number_of_rds2satellite = cmd[data_index+3*number_of_rds1satellite];//RDSS S2波束数量
|
||
|
||
if(cmd.size() < (FRAME_MIN_LEN + 2 + 3 * (number_of_rds1satellite + number_of_rds2satellite))){
|
||
//m_logger->error("接收的rdss搜星状态包长度错误, RDSS S1波束个数 = {}, RDSS S2波束个数 = {}, 长度 = {}",number_of_rds1satellite,number_of_rds1satellite,cmd.size());
|
||
m_logger->error("The received search rdss satellite status packet length is incorrect, rds1satellite_num = {}, rds2satellite_num = {}, len = {}",number_of_rds1satellite,number_of_rds2satellite,cmd.size());
|
||
}
|
||
|
||
for(i = 0 ; i < number_of_rds1satellite; i++){
|
||
RDSSSatelliteStatus s1status;
|
||
s1status.number = cmd[data_index++]; //波束编号
|
||
s1status.snr1 = cmd[data_index++]; //波束载噪比1
|
||
s1status.snr2 = cmd[data_index++]; //波束载噪比2
|
||
rdss_s1satellite_status.push_back(s1status);
|
||
}
|
||
// 处理卫星状态
|
||
for(i = 0 ; i < rdss_s1satellite_status.size(); i++){
|
||
//s1categories.push_back(QString("%1").arg(rdss_s1satellite_status[i].number, 2, 10, QChar('0')));//与下面等效
|
||
s1categories.push_back(QString::asprintf("%02d", rdss_s1satellite_status[i].number));
|
||
s1yValues.push_back(rdss_s1satellite_status[i].snr1); //两个载噪比基本一致
|
||
}
|
||
// 设置信号能量
|
||
setRDSSSignalStrengthValues(uint8_t(RDSSType::RDSS_S1), s1categories, s1yValues);
|
||
|
||
data_index++; //S2波束锁定数量
|
||
|
||
for(i = 0 ; i < number_of_rds2satellite; i++){
|
||
RDSSSatelliteStatus s2status;
|
||
s2status.number = cmd[data_index++]; //波束编号
|
||
s2status.snr1 = cmd[data_index++]; //波束载噪比1
|
||
s2status.snr2 = cmd[data_index++]; //波束载噪比2
|
||
rdss_s2satellite_status.push_back(s2status);
|
||
}
|
||
// 处理卫星状态
|
||
for(i = 0 ; i < rdss_s2satellite_status.size(); i++){
|
||
//s2categories.push_back(QString("%1").arg(rdss_s2satellite_status[i].number, 2, 10, QChar('0')));//与下面等效
|
||
s2categories.push_back(QString::asprintf("%02d", rdss_s2satellite_status[i].number));
|
||
s2yValues.push_back(rdss_s2satellite_status[i].snr1); //两个载噪比基本一致
|
||
}
|
||
setRDSSSignalStrengthValues(uint8_t(RDSSType::RDSS_S2), s2categories, s2yValues);
|
||
break;
|
||
default:
|
||
m_logger->error("SearchSatelliteStatusReportSubCommandType is incorrect, type = 0x{:02X}", cmd[SUB_COMMAND_TYPE_INDEX] & 0xFF);
|
||
break;
|
||
}
|
||
}
|
||
void MainWindow::processZhuanTaiStatusReportCmd(const QByteArray& cmd){
|
||
if(cmd.size() != FRAME_LEN_ZHUANTAISTATUSREPORT){
|
||
//m_logger->error("接收的转台状态包长度错误, 长度 = {}",cmd.size());
|
||
m_logger->error("The received zhuantai status packet length is incorrect, len = {}",cmd.size());
|
||
return;
|
||
}
|
||
int data_index = COMMAND_DATA_BEGIN_INDEX;
|
||
//通信状态
|
||
uint8_t commu_state = cmd[data_index++];
|
||
//定位状态
|
||
uint8_t locate_state = cmd[data_index++];
|
||
//避免出现符号扩展问题,使用如下方式,不能使用 ((uint16_t)cmd[data_index] << 8) | cmd[data_index+1];
|
||
uint16_t az_angle = qFromBigEndian<quint16>(reinterpret_cast<const uchar*>(cmd.constData()+data_index));
|
||
data_index += 2;
|
||
//避免出现符号扩展问题
|
||
uint16_t el_angle = qFromBigEndian<quint16>(reinterpret_cast<const uchar*>(cmd.constData()+data_index));
|
||
data_index += 2;
|
||
|
||
QString s;
|
||
if(commu_state == uint8_t(PhaseLockedLoopStatus::kLocked) || commu_state == uint8_t(PhaseLockedLoopStatus::kUnlocked)){
|
||
s = QString("通信状态: %1, ").arg(commu_state == uint8_t(PhaseLockedLoopStatus::kLocked)?"正常":"异常");
|
||
}else{
|
||
s = QString("通信状态: 未知 ");
|
||
}
|
||
if(commu_state == uint8_t(PhaseLockedLoopStatus::kLocked))
|
||
{
|
||
if(locate_state == uint8_t(PhaseLockedLoopStatus::kLocked) || locate_state == uint8_t(PhaseLockedLoopStatus::kUnlocked)){
|
||
s += QString("定位状态: %1, ").arg(locate_state == uint8_t(PhaseLockedLoopStatus::kLocked)?"锁定":"未锁定");
|
||
}else{
|
||
s += QString("定位状态: 未知, ");
|
||
}
|
||
s += QString("方位角: %1, ").arg((double)az_angle/100, 0, 'f', 2);
|
||
s += QString("俯仰角: %1 ").arg((double)el_angle/100, 0, 'f', 2);
|
||
}
|
||
ui->lblZhuanTaiStatus->setText(s);
|
||
}
|
||
|
||
void MainWindow::processConfigCmd(const QByteArray& cmd){
|
||
switch(uint8_t(cmd[COMMAND_TYPE_INDEX])){
|
||
case uint8_t(CommandType::kConfigCmdDefaultChannel):
|
||
if(cmd[SUB_COMMAND_TYPE_INDEX] == uint8_t(ConfigCommandType::kGetType))
|
||
{
|
||
int data_index = COMMAND_DATA_BEGIN_INDEX;
|
||
uint8_t channelType = cmd[data_index++];//信道类型
|
||
switch(channelType)
|
||
{
|
||
case uint8_t(ChannelType::ChannelS):
|
||
ui->rdbChannelS->setChecked(true);
|
||
break;
|
||
case uint8_t(ChannelType::ChannelUHF):
|
||
ui->rdbChannelUHF->setChecked(true);
|
||
break;
|
||
case uint8_t(ChannelType::ChannelAuto):
|
||
ui->rdbChannelAuto->setChecked(true);
|
||
break;
|
||
}
|
||
|
||
m_channelQuery = true;
|
||
}
|
||
else if(cmd[SUB_COMMAND_TYPE_INDEX] == uint8_t(ConfigCommandType::kSetType))
|
||
{
|
||
if(cmd[COMMAND_DATA_BEGIN_INDEX] == uint8_t(VoiceAndShortMessageReponse::kSucess)){//设置成功
|
||
QMessageBox::information(this, "提示", "默认信道设置成功");
|
||
}else if(cmd[COMMAND_DATA_BEGIN_INDEX] == uint8_t(VoiceAndShortMessageReponse::kFailure)){//设置失败
|
||
QMessageBox::information(this, "提示", "默认信道设置失败");
|
||
}
|
||
sendUdpMessage(pack_config_cmd_DefaultChannelGet()); //查询一次
|
||
}
|
||
break;
|
||
case uint8_t(CommandType::kConfigCmdSoftVersion):
|
||
if(cmd[SUB_COMMAND_TYPE_INDEX] == uint8_t(ConfigCommandType::kGetType))
|
||
{
|
||
int data_index = COMMAND_DATA_BEGIN_INDEX;
|
||
// U号码,使用 QByteArray 处理
|
||
QByteArray softversion_data = QByteArray::fromRawData(cmd.constData() + data_index, 32);
|
||
softversion_data.replace('\0', ""); // 移除所有空字符
|
||
// 转换为 std::string
|
||
std::string softversion = softversion_data.toStdString();
|
||
ui->lblSoftVersion->setText(QString::fromStdString(softversion));
|
||
|
||
m_versionQuery = true;
|
||
}
|
||
break;
|
||
case uint8_t(CommandType::kConfigCmdSoftReset):
|
||
if(cmd[SUB_COMMAND_TYPE_INDEX] == uint8_t(ConfigCommandType::kSetType))
|
||
{
|
||
if(cmd[COMMAND_DATA_BEGIN_INDEX] == uint8_t(VoiceAndShortMessageReponse::kSucess)){//设置成功
|
||
QMessageBox::information(this, "提示", "软件复位成功");
|
||
}else if(cmd[COMMAND_DATA_BEGIN_INDEX] == uint8_t(VoiceAndShortMessageReponse::kFailure)){//设置失败
|
||
QMessageBox::information(this, "提示", "软件复位失败");
|
||
}
|
||
}
|
||
break;
|
||
case uint8_t(CommandType::kConfigCmdSDataSwitch):
|
||
if(cmd[SUB_COMMAND_TYPE_INDEX] == uint8_t(ConfigCommandType::kSetType))
|
||
{
|
||
if(cmd[COMMAND_DATA_BEGIN_INDEX] == uint8_t(VoiceAndShortMessageReponse::kSucess)){//设置成功
|
||
QMessageBox::information(this, "提示", "S数据开关设置成功");
|
||
}else if(cmd[COMMAND_DATA_BEGIN_INDEX] == uint8_t(VoiceAndShortMessageReponse::kFailure)){//设置失败
|
||
QMessageBox::information(this, "提示", "S数据开关设置失败");
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
void MainWindow::processDebugCmd(const QByteArray& cmd){
|
||
switch(uint8_t(cmd[SUB_COMMAND_TYPE_INDEX])){
|
||
case uint8_t(DebugCommandType::kUCattierType):
|
||
case uint8_t(DebugCommandType::kURate):
|
||
case uint8_t(DebugCommandType::kSFreq):
|
||
case uint8_t(DebugCommandType::kSRate):
|
||
case uint8_t(DebugCommandType::kPASwitch):
|
||
case uint8_t(DebugCommandType::kZTCtrl):
|
||
if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kSucess)){//设置成功
|
||
//this->m_logger->info("设置成功");
|
||
m_loggerWidget->updateRespStatus("设置成功");
|
||
}else if(cmd[COMMAND_DATA_BEGIN_INDEX] == int(VoiceAndShortMessageReponse::kFailure)){//设置失败
|
||
//this->m_logger->info("设置失败");
|
||
m_loggerWidget->updateRespStatus("设置失败");
|
||
}
|
||
break;
|
||
case uint8_t(DebugCommandType::kCmdCtrl):
|
||
int data_index = COMMAND_DATA_BEGIN_INDEX;
|
||
std::string resp = std::string((cmd.data()+data_index), (cmd.length() - 5)); //去除信息长度2/命令1/命令子类型1/校验1
|
||
m_loggerWidget->updateRespStatus(resp.c_str());
|
||
break;
|
||
}
|
||
}
|
||
|
||
//--------------------------------------------------------------------------------------
|
||
//--------------------------------------------------------------------------------------
|
||
// 处理模块状态
|
||
void MainWindow::processUhfModuleStatus(uint8_t status){
|
||
if(status != uint8_t(ModuleStatus::kChecking) && status != uint8_t(ModuleStatus::kNormal)
|
||
&& status != uint8_t(ModuleStatus::kFault) && status != uint8_t(ModuleStatus::kUpgrading)){
|
||
//m_logger->error("UHF模块状态非法值, status = {}",status);
|
||
m_logger->error("UHF: module status illegal value, status = {}",status);
|
||
return;
|
||
}
|
||
m_uhfModuleStatus = ModuleStatus(status);
|
||
switch(m_uhfModuleStatus){
|
||
case ModuleStatus::kChecking:
|
||
ui->btnUHFModuleStatus->setToolTip("检测中");
|
||
break;
|
||
case ModuleStatus::kNormal:
|
||
ui->btnUHFModuleStatus->setIcon(QIcon(":/rc/res/module_ok.png"));
|
||
ui->btnUHFModuleStatus->setToolTip("正常");
|
||
break;
|
||
case ModuleStatus::kFault:
|
||
ui->btnUHFModuleStatus->setIcon(QIcon(":/rc/res/module_error.png"));
|
||
ui->btnUHFModuleStatus->setToolTip("故障");
|
||
break;
|
||
case ModuleStatus::kUpgrading:
|
||
ui->btnUHFModuleStatus->setIcon(QIcon(":/rc/res/module_update.png"));
|
||
ui->btnUHFModuleStatus->setToolTip("升级中");
|
||
break;
|
||
}
|
||
}
|
||
void MainWindow::processTianTongModuleStatus(uint8_t status){
|
||
if(status != uint8_t(ModuleStatus::kChecking) && status != uint8_t(ModuleStatus::kNormal)
|
||
&& status != uint8_t(ModuleStatus::kFault) && status != uint8_t(ModuleStatus::kUpgrading)){
|
||
//m_logger->error("天通模块状态非法值, status = {}",status);
|
||
m_logger->error("Tiantong: module status illegal value, status = {}",status);
|
||
return;
|
||
}
|
||
m_tiantongModuleStatus = ModuleStatus(status);
|
||
switch(m_tiantongModuleStatus){
|
||
case ModuleStatus::kChecking:
|
||
ui->btnSModueStatus->setToolTip("检测中");
|
||
break;
|
||
case ModuleStatus::kNormal:
|
||
ui->btnSModueStatus->setIcon(QIcon(":/rc/res/module_ok.png"));
|
||
ui->btnSModueStatus->setToolTip("正常");
|
||
break;
|
||
case ModuleStatus::kFault:
|
||
ui->btnSModueStatus->setIcon(QIcon(":/rc/res/module_error.png"));
|
||
ui->btnSModueStatus->setToolTip("故障");
|
||
break;
|
||
case ModuleStatus::kUpgrading:
|
||
ui->btnSModueStatus->setIcon(QIcon(":/rc/res/module_update.png"));
|
||
ui->btnSModueStatus->setToolTip("升级中");
|
||
break;
|
||
}
|
||
}
|
||
void MainWindow::processBeiDouModuleStatus(uint8_t status){
|
||
if(status != uint8_t(ModuleStatus::kChecking) && status != uint8_t(ModuleStatus::kNormal)
|
||
&& status != uint8_t(ModuleStatus::kFault) && status != uint8_t(ModuleStatus::kUpgrading)){
|
||
//m_logger->error("北斗模块状态非法值, status = {}",status);
|
||
m_logger->error("BeiDou: module status status illegal value, status = {}",status);
|
||
return;
|
||
}
|
||
|
||
m_beidouModuleStatus = ModuleStatus(status);
|
||
switch(m_beidouModuleStatus){
|
||
case ModuleStatus::kChecking:
|
||
ui->btnBeiDouModuleStatus->setToolTip("检测中");
|
||
break;
|
||
case ModuleStatus::kNormal:
|
||
ui->btnBeiDouModuleStatus->setIcon(QIcon(":/rc/res/module_ok.png"));
|
||
ui->btnBeiDouModuleStatus->setToolTip("正常");
|
||
break;
|
||
case ModuleStatus::kFault:
|
||
ui->btnBeiDouModuleStatus->setIcon(QIcon(":/rc/res/module_error.png"));
|
||
ui->btnBeiDouModuleStatus->setToolTip("故障");
|
||
break;
|
||
case ModuleStatus::kUpgrading:
|
||
ui->btnBeiDouModuleStatus->setIcon(QIcon(":/rc/res/module_update.png"));
|
||
ui->btnBeiDouModuleStatus->setToolTip("升级中");
|
||
break;
|
||
}
|
||
}
|
||
// 处理SIM卡状态
|
||
void MainWindow::processUhfSimCardStatus(uint8_t status){
|
||
if(status != uint8_t(SimCardStatus::kChecking) && status != uint8_t(SimCardStatus::kExist)
|
||
&& status != uint8_t(SimCardStatus::kNotExist)){
|
||
//m_logger->error("UHF SIM卡状态非法值, status = {}",status);
|
||
m_logger->error("UHF: sim card status illegal value, status = {}",status);
|
||
return;
|
||
}
|
||
m_uhfSimCardStatus = SimCardStatus(status);
|
||
switch(m_uhfSimCardStatus){
|
||
case SimCardStatus::kChecking:
|
||
ui->btnUHFSimCardStatus->setToolTip("正在检测");
|
||
break;
|
||
case SimCardStatus::kExist:
|
||
ui->btnUHFSimCardStatus->setIcon(QIcon(":/rc/res/sim_card_exist.png"));
|
||
ui->btnUHFSimCardStatus->setToolTip("存在");
|
||
break;
|
||
case SimCardStatus::kNotExist:
|
||
ui->btnUHFSimCardStatus->setIcon(QIcon(":/rc/res/sim_card_not_exist.png"));
|
||
ui->btnUHFSimCardStatus->setToolTip("不存在");
|
||
break;
|
||
}
|
||
}
|
||
void MainWindow::processTianTongSimCardStatus(uint8_t status){
|
||
if(status != uint8_t(SimCardStatus::kChecking) && status != uint8_t(SimCardStatus::kExist)
|
||
&& status != uint8_t(SimCardStatus::kNotExist)){
|
||
//m_logger->error("TianTong SIM卡状态非法值, status = {}",status);
|
||
m_logger->error("Tiantong: sim card status illegal value, status = {}",status);
|
||
return;
|
||
}
|
||
m_tiantongSimCardStatus = SimCardStatus(status);
|
||
switch(m_tiantongSimCardStatus){
|
||
case SimCardStatus::kChecking:
|
||
ui->btnSSimCardStatus->setToolTip("正在检测");
|
||
break;
|
||
case SimCardStatus::kExist:
|
||
ui->btnSSimCardStatus->setIcon(QIcon(":/rc/res/sim_card_exist.png"));
|
||
ui->btnSSimCardStatus->setToolTip("存在");
|
||
break;
|
||
case SimCardStatus::kNotExist:
|
||
ui->btnSSimCardStatus->setIcon(QIcon(":/rc/res/sim_card_not_exist.png"));
|
||
ui->btnSSimCardStatus->setToolTip("不存在");
|
||
break;
|
||
}
|
||
}
|
||
void MainWindow::processBeiDouSimCardStatus(uint8_t status){
|
||
if(status != uint8_t(SimCardStatus::kChecking) && status != uint8_t(SimCardStatus::kExist)
|
||
&& status != uint8_t(SimCardStatus::kNotExist)){
|
||
//m_logger->error("北斗 SIM卡状态非法值, status = {}",status);
|
||
m_logger->error("BeiDou: sim card status illegal value, status = {}",status);
|
||
return;
|
||
}
|
||
m_beidouSimCardStatus = SimCardStatus(status);
|
||
switch(m_beidouSimCardStatus){
|
||
case SimCardStatus::kChecking:
|
||
ui->btnBeiDouSimCardStatus->setToolTip("正在检测");
|
||
break;
|
||
case SimCardStatus::kExist:
|
||
ui->btnBeiDouSimCardStatus->setIcon(QIcon(":/rc/res/sim_card_exist.png"));
|
||
ui->btnBeiDouSimCardStatus->setToolTip("存在");
|
||
break;
|
||
case SimCardStatus::kNotExist:
|
||
ui->btnBeiDouSimCardStatus->setIcon(QIcon(":/rc/res/sim_card_not_exist.png"));
|
||
ui->btnBeiDouSimCardStatus->setToolTip("不存在");
|
||
break;
|
||
}
|
||
}
|
||
// 处理M卡状态
|
||
void MainWindow::processUhfMCardStatus(uint8_t status){
|
||
if(status != uint8_t(MCardStatus::kChecking) && status != uint8_t(MCardStatus::kExistNotEncryted)
|
||
&& status != uint8_t(MCardStatus::kExistEncryted)&& status != uint8_t(MCardStatus::kNotExist)){
|
||
//m_logger->error("UHF M卡状态非法值, status = {}",status);
|
||
m_logger->error("UHF: m card status illegal value, status = {}",status);
|
||
return;
|
||
}
|
||
m_uhfMCardStatus = MCardStatus(status);
|
||
switch(m_uhfMCardStatus){
|
||
case MCardStatus::kChecking:
|
||
ui->btnUHFMCardStatus->setToolTip("正在检测");
|
||
break;
|
||
case MCardStatus::kExistNotEncryted:
|
||
ui->btnUHFMCardStatus->setIcon(QIcon(":/rc/res/m_card_no_stick.png"));
|
||
ui->btnUHFMCardStatus->setToolTip("存在未注密");
|
||
break;
|
||
case MCardStatus::kExistEncryted:
|
||
ui->btnUHFMCardStatus->setIcon(QIcon(":/rc/res/m_card_stick.png"));
|
||
ui->btnUHFMCardStatus->setToolTip("存在已注密");
|
||
break;
|
||
case MCardStatus::kNotExist:
|
||
ui->btnUHFMCardStatus->setIcon(QIcon(":/rc/res/m_card_not_exist.png"));
|
||
ui->btnUHFMCardStatus->setToolTip("不存在");
|
||
break;
|
||
}
|
||
}
|
||
void MainWindow::processTianTongMCardStatus(uint8_t status){
|
||
if(status != uint8_t(MCardStatus::kChecking) && status != uint8_t(MCardStatus::kExistNotEncryted)
|
||
&& status != uint8_t(MCardStatus::kExistEncryted)&& status != uint8_t(MCardStatus::kNotExist)){
|
||
//m_logger->error("天通M卡状态非法值, status = {}",status);
|
||
m_logger->error("Tiantong: m card status illegal value, status = {}",status);
|
||
return;
|
||
}
|
||
m_tiantongMCardStatus = MCardStatus(status);
|
||
switch(m_tiantongMCardStatus){
|
||
case MCardStatus::kChecking:
|
||
ui->btnSMCardStatus->setToolTip("正在检测");
|
||
break;
|
||
case MCardStatus::kExistNotEncryted:
|
||
ui->btnSMCardStatus->setIcon(QIcon(":/rc/res/m_card_no_stick.png"));
|
||
ui->btnSMCardStatus->setToolTip("存在未注密");
|
||
break;
|
||
case MCardStatus::kExistEncryted:
|
||
ui->btnSMCardStatus->setIcon(QIcon(":/rc/res/m_card_stick.png"));
|
||
ui->btnSMCardStatus->setToolTip("存在已注密");
|
||
break;
|
||
case MCardStatus::kNotExist:
|
||
ui->btnSMCardStatus->setIcon(QIcon(":/rc/res/m_card_not_exist.png"));
|
||
ui->btnSMCardStatus->setToolTip("不存在");
|
||
break;
|
||
}
|
||
}
|
||
// 处理网络访问状态
|
||
void MainWindow::processUhfNetworkAccessStatus(uint8_t status){
|
||
if(status != uint8_t(NetworkAccessStatus::kNotConnected)
|
||
&& status != uint8_t(NetworkAccessStatus::kConnecting)
|
||
&& status != uint8_t(NetworkAccessStatus::kConnectedDataIsNotActivated)
|
||
&& status != uint8_t(NetworkAccessStatus::kConnectedDataIsActivated)){
|
||
//m_logger->error("uhf 入网状态非法值, status = {}",status);
|
||
m_logger->error("UHF: network access status illegal value, status = {}",status);
|
||
}
|
||
m_uhfNetworkAccessStatus = NetworkAccessStatus(status);
|
||
switch(m_uhfNetworkAccessStatus){
|
||
case NetworkAccessStatus::kNotConnected:
|
||
ui->btnUHFNetworkAccessStatus->setIcon(QIcon(":/rc/res/net_out.png"));
|
||
ui->btnUHFNetworkAccessStatus->setToolTip("未入网");
|
||
break;
|
||
case NetworkAccessStatus::kConnecting:
|
||
ui->btnUHFNetworkAccessStatus->setToolTip("正在入网");
|
||
break;
|
||
case NetworkAccessStatus::kConnectedDataIsNotActivated:
|
||
ui->btnUHFNetworkAccessStatus->setIcon(QIcon(":/rc/res/net_in_no_data.png"));
|
||
ui->btnUHFNetworkAccessStatus->setToolTip("已入网, 数据未激活");
|
||
break;
|
||
case NetworkAccessStatus::kConnectedDataIsActivated:
|
||
ui->btnUHFNetworkAccessStatus->setIcon(QIcon(":/rc/res/net_in_data.png"));
|
||
ui->btnUHFNetworkAccessStatus->setToolTip("已入网, 数据已激活");
|
||
break;
|
||
}
|
||
}
|
||
void MainWindow::processTianTongNetworkAccessStatus(uint8_t status){
|
||
if(status == uint8_t(NetworkAccessStatus::kNotConnected)
|
||
&& status == uint8_t(NetworkAccessStatus::kConnecting)
|
||
&& status == uint8_t(NetworkAccessStatus::kConnectedDataIsNotActivated)
|
||
&& status == uint8_t(NetworkAccessStatus::kConnectedDataIsActivated)){
|
||
//m_logger->error("天通入网状态非法值, status = {}",status);
|
||
m_logger->error("Tiantong: network access status illegal value, status = {}",status);
|
||
}
|
||
m_tiantongNetworkAccessStatus = NetworkAccessStatus(status);
|
||
switch(m_tiantongNetworkAccessStatus){
|
||
case NetworkAccessStatus::kNotConnected:
|
||
ui->btnSNetworkAccessStatus->setIcon(QIcon(":/rc/res/net_out.png"));
|
||
ui->btnSNetworkAccessStatus->setToolTip("未入网");
|
||
break;
|
||
case NetworkAccessStatus::kConnecting:
|
||
// ui->btnSNetworkAccessStatus->setIcon(QIcon(":/rc/res/net_out.png"));
|
||
ui->btnSNetworkAccessStatus->setToolTip("正在入网");
|
||
break;
|
||
case NetworkAccessStatus::kConnectedDataIsNotActivated:
|
||
ui->btnSNetworkAccessStatus->setIcon(QIcon(":/rc/res/net_in_no_data.png"));
|
||
ui->btnSNetworkAccessStatus->setToolTip("已入网, 数据未激活");
|
||
break;
|
||
case NetworkAccessStatus::kConnectedDataIsActivated:
|
||
ui->btnSNetworkAccessStatus->setIcon(QIcon(":/rc/res/net_in_data.png"));
|
||
ui->btnSNetworkAccessStatus->setToolTip("已入网, 数据已激活");
|
||
break;
|
||
}
|
||
}
|
||
// 处理呼叫状态
|
||
void MainWindow::processCallStatus(uint8_t tiantong_call_status,uint8_t uhf_call_status,const std::string& tiantong_number,const std::string& uhf_number){
|
||
if(tiantong_call_status != uint8_t(CallStatus::kIdle) && tiantong_call_status != uint8_t(CallStatus::kDialing)
|
||
&& tiantong_call_status != uint8_t(CallStatus::kPeerRingTheBell) && tiantong_call_status != uint8_t(CallStatus::kOnLine)
|
||
&& tiantong_call_status != uint8_t(CallStatus::kCallIsComing)){
|
||
return;
|
||
}
|
||
if(uhf_call_status != uint8_t(CallStatus::kIdle) && uhf_call_status != uint8_t(CallStatus::kDialing)
|
||
&& uhf_call_status != uint8_t(CallStatus::kPeerRingTheBell) && uhf_call_status != uint8_t(CallStatus::kOnLine)
|
||
&& uhf_call_status != uint8_t(CallStatus::kCallIsComing)){
|
||
return;
|
||
}
|
||
m_tiantongCallStatus = CallStatus(tiantong_call_status);
|
||
m_uhfCallStatus = CallStatus(uhf_call_status);
|
||
|
||
CallStatus status;
|
||
static uint8_t lastStatus = 0xFF;
|
||
Channel chan;
|
||
if(m_tiantongCallStatus != CallStatus::kIdle){
|
||
status = m_tiantongCallStatus;
|
||
chan = Channel::S;
|
||
}else{
|
||
status = m_uhfCallStatus;
|
||
chan = Channel::Uhf;
|
||
}
|
||
switch(status){
|
||
case CallStatus::kIdle://空闲
|
||
//挂断电话
|
||
ui->cmbCallNumber->setEnabled(true);
|
||
ui->btnCallAnswer->show();
|
||
ui->btnCallReject->hide();
|
||
ui->lblCallStatus->setText("空闲");
|
||
ui->lblCallStatus->setStyleSheet("color: black;");
|
||
m_callStatusLabelBlack = true;
|
||
ShutdownTalking();
|
||
ui->lblCallDuration->hide();
|
||
ui->lblCallDuration->setText(""); //清空
|
||
break;
|
||
case CallStatus::kDialing://拨号中
|
||
//拨号中
|
||
ui->cmbCallNumber->setEnabled(false);
|
||
ui->btnCallAnswer->hide();
|
||
ui->btnCallReject->show();
|
||
ui->lblCallStatus->setText("拨号中...");
|
||
ui->lblCallDuration->hide();
|
||
ui->lblCallDuration->setText(""); //清空
|
||
break;
|
||
case CallStatus::kPeerRingTheBell://对方振铃
|
||
//对方振铃中
|
||
ui->cmbCallNumber->setEnabled(false);
|
||
ui->btnCallAnswer->hide();
|
||
ui->btnCallReject->show();
|
||
ui->lblCallStatus->setText("对方振铃...");
|
||
ui->lblCallDuration->hide();
|
||
ui->lblCallDuration->setText(""); //清空
|
||
break;
|
||
case CallStatus::kOnLine://通话中
|
||
if(lastStatus == (uint8_t)CallStatus::kIdle)//避免从'空闲'直接变成'通话中'
|
||
{
|
||
m_logger->error("CallStatus is Err, lastStatus = {}, currentStatus = {}", lastStatus, (uint8_t)status);
|
||
return;
|
||
}
|
||
//通话中
|
||
if(chan == Channel::S){
|
||
m_currentTalkingNumber = tiantong_number;
|
||
ui->cmbCallNumber->setCurrentText(QString::fromStdString(tiantong_number));
|
||
}else{
|
||
m_currentTalkingNumber = uhf_number;
|
||
ui->cmbCallNumber->setCurrentText(QString::fromStdString(uhf_number));
|
||
}
|
||
m_currentTalkingChan = chan;
|
||
|
||
ui->cmbCallNumber->setEnabled(false);
|
||
ui->btnCallAnswer->hide();
|
||
ui->btnCallReject->show();
|
||
ui->lblCallStatus->setText("通话中...");
|
||
ui->lblCallStatus->setStyleSheet("color: green;");
|
||
m_callStatusLabelBlack = false;
|
||
StartupTalking();
|
||
break;
|
||
case CallStatus::kCallIsComing://来电中
|
||
//有来电
|
||
ui->cmbCallNumber->setEnabled(false);
|
||
if(chan == Channel::S){
|
||
m_currentTalkingNumber = tiantong_number;
|
||
ui->cmbCallNumber->setCurrentText(QString::fromStdString(tiantong_number));
|
||
}else{
|
||
m_currentTalkingNumber = uhf_number;
|
||
ui->cmbCallNumber->setCurrentText(QString::fromStdString(uhf_number));
|
||
}
|
||
m_currentTalkingDirection = CommDirection::Receive;
|
||
|
||
ui->btnCallAnswer->show();
|
||
ui->btnCallReject->show();
|
||
ui->lblCallStatus->setText("来电中...");
|
||
ui->lblCallDuration->hide();
|
||
ui->lblCallDuration->setText(""); //清空
|
||
break;
|
||
}
|
||
lastStatus = (uint8_t)status;
|
||
}
|
||
//--------------------------------------------------------------------------------------
|
||
//--------------------------------------------------------------------------------------
|
||
|
||
|
||
void MainWindow::on_btnConfigParam_clicked()
|
||
{
|
||
m_configParamWidget->show();
|
||
}
|
||
|
||
|
||
void MainWindow::on_rdbChannelS_clicked()
|
||
{
|
||
sendUdpMessage(pack_config_cmd_DefaultChannelSet(uint8_t(ChannelType::ChannelS)));
|
||
}
|
||
|
||
|
||
void MainWindow::on_rdbChannelUHF_clicked()
|
||
{
|
||
sendUdpMessage(pack_config_cmd_DefaultChannelSet(uint8_t(ChannelType::ChannelUHF)));
|
||
}
|
||
|
||
|
||
void MainWindow::on_rdbChannelAuto_clicked()
|
||
{
|
||
sendUdpMessage(pack_config_cmd_DefaultChannelSet(uint8_t(ChannelType::ChannelAuto)));
|
||
}
|
||
|
||
|
||
void MainWindow::on_sDataSwitch_checkStateChanged(const Qt::CheckState &arg1)
|
||
{
|
||
uint8_t onoff = 0;
|
||
if(arg1 == Qt::CheckState::Checked)
|
||
{
|
||
onoff = 1;
|
||
}
|
||
sendUdpMessage(pack_config_cmd_SDataSwitchSet(onoff));
|
||
}
|
||
|
||
|
||
void MainWindow::on_btnSoftReset_clicked()
|
||
{
|
||
// 1. 弹出确认对话框(按钮显示中文“确定/取消”)
|
||
QMessageBox msgBox(this);
|
||
msgBox.setWindowTitle("确认操作");
|
||
msgBox.setText("您确定要软件复位吗?");
|
||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||
// 通过 button() 获取按钮指针再 setText,不使用 setButtonText
|
||
msgBox.button(QMessageBox::Yes)->setText("确定");
|
||
msgBox.button(QMessageBox::No)->setText("取消");
|
||
if (msgBox.exec() != QMessageBox::Yes) {
|
||
return;
|
||
}
|
||
sendUdpMessage(pack_config_cmd_SoftResetSet());
|
||
}
|