You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
PayloadAPP/rescueload.cpp

359 lines
11 KiB
C++

#include "rescueload.h"
#include <QDateTime>
#include <QDir>
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMessageBox>
// ==================== ImsiData数据类 start =======================
QHash<QString, QString> ImsiData::operatorMap = {
{"00", "移动"}, {"02", "移动"}, {"04", "移动"}, {"07", "移动"}, {"08", "移动"}, {"13", "移动"},
{"01", "联通"}, {"06", "联通"}, {"09", "联通"}, {"10", "联通"},
{"03", "电信"}, {"05", "电信"}, {"11", "电信"}, {"12", "电信"},
{"15", "广电"}, {"20","铁通"}
};
ImsiData::ImsiData(const QJsonObject& json)
{
if (json.contains("latitude"))
this->latitude = json.value("latitude").toString();
if (json.contains("longitude"))
this->longitude = json.value("longitude").toString();
if (json.contains("altitude"))
this->altitude = json.value("altitude").toInt();
if (json.contains("create_date"))
this->createDate = json.value("create_date").toString();
if (json.contains("rssi"))
this->rssi = json.value("rssi").toInt();
if (json.contains("fcn"))
this->fcn = json.value("fcn").toString();
if (json.contains("imsi"))
this->imsi = json.value("imsi").toString();
this->operatorName = getOperatorNameByImsi(this->imsi); // 第4、5位
}
ImsiData::ImsiData(const ImsiData& from)
{
this->latitude = from.latitude;
this->longitude = from.longitude;
this->altitude = from.altitude;
this->createDate = from.createDate;
this->rssi = from.rssi;
this->fcn = from.fcn;
this->imsi = from.imsi;
this->operatorName = from.operatorName;
}
QString ImsiData::getOperatorNameByImsi(QString imsi)
{
return operatorMap.value(imsi.mid(3,2));
}
// ==================== ImsiData数据类 end =======================
// ===================== ImsiTableModel start ==================================
ImsiTableModel::ImsiTableModel(QObject *parent)
: QAbstractTableModel(parent)
{
// Set names to the role name hash container (QHash<int, QByteArray>)
// model.name, model.hue, model.saturation, model.brightness
m_roleNames[imsiRole] = "imsi";
m_roleNames[latitudeRole] = "latitude";
m_roleNames[longitudeRole] = "longitude";
m_roleNames[dateRole] = "createDate";
m_roleNames[altitudeRole] = "altitude";
m_roleNames[rssiRole] = "rssi";
m_roleNames[fcnRole] = "fcn";
m_roleNames[operatorRole] = "operator";
m_horizontalHeader = {"IMSI", "运营商"};
m_defaultDir = QString("./搜救信息"); // 默认目录
// 检查并创建默认目录
QDir dir(m_defaultDir);
if (!dir.exists()) {
dir.mkpath(".");
}
}
ImsiTableModel::~ImsiTableModel()
{
QString timeStr = QDateTime::currentDateTime().toString("yyyy-MM-ddThh-mm-ss");
QString defaultPath = QString("%1/搜救信息%2.csv").arg(getSaveDir(), timeStr);
saveDataListToCsv(defaultPath);
}
QVariant ImsiTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if(orientation == Qt::Horizontal) { //水平表头
if(Qt::DisplayRole == role && section < m_horizontalHeader.count()) {
return m_horizontalHeader[section];
}
}
return QAbstractItemModel::headerData(section,orientation,role);
}
int ImsiTableModel::rowCount(const QModelIndex &parent) const
{
// For list models only the root node (an invalid parent) should return the list's size. For all
// other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
Q_UNUSED(parent)
return m_dataMap.count();
}
int ImsiTableModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return 2;
}
QVariant ImsiTableModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
int column = index.column();
int row = index.row();
QString imsi = m_imsiList.at(row);
ImsiData data = m_dataMap.value(imsi);
switch (role) {
case Qt::DisplayRole:
if (column == 1) {
return data.operatorName;
} else if (column == 0) {
return data.imsi;
}
break;
// 对齐处理
case Qt::TextAlignmentRole:
return Qt::AlignCenter;
break;
case imsiRole:
return data.imsi;
case latitudeRole:
return data.latitude;
case longitudeRole:
return data.longitude;
case dateRole:
return data.createDate;
case altitudeRole:
return data.altitude;
case rssiRole:
return data.rssi;
case fcnRole:
return data.fcn;
default:
break;
}
return QVariant();
}
QModelIndex ImsiTableModel::index(int row, int column, const QModelIndex &parent) const
{
if (parent.isValid() || row < 0 || column < 0 || row >= rowCount() || column >= columnCount())
return QModelIndex();
// Create and return a QModelIndex for the given row and column
return createIndex(row, column);
}
void ImsiTableModel::setDataMap(const QHash<QString, ImsiData> &dataMap)
{
beginResetModel();
this->m_dataMap = dataMap;
this->m_imsiList = dataMap.keys();
for (int i = 0; i < m_imsiList.size(); ++i) {
m_imsiIndex.insert(m_imsiList[i], i);
}
endResetModel();
}
void ImsiTableModel::updateData(const ImsiData &data)
{
QString imsi = data.imsi;
if (m_dataMap.contains(imsi)) {
// 更新现有数据
m_dataMap[imsi] = data;
int row = m_imsiIndex.value(imsi);
emit dataChanged(index(row, 0), index(row, columnCount() - 1));
} else {
// 插入新数据
beginInsertRows(QModelIndex(), m_imsiList.size(), m_imsiList.size());
m_imsiList.append(imsi);
m_dataMap.insert(imsi, data);
endInsertRows();
}
}
int ImsiTableModel::getRole(QString rolename)
{
if (rolename == "latitude")
return latitudeRole;
else if (rolename == "longitude")
return longitudeRole;
else
return -1;
}
QHash<int, QByteArray> ImsiTableModel::roleNames() const
{
return m_roleNames;
}
void ImsiTableModel::saveDataListToCsv(const QString& filePath, const QString& delimiter) {
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qWarning("Could not open file for writing.");
return;
}
QTextStream out(&file);
QStringList row;
row << "IMSI" << "运营商" << "经度" << "纬度" << "海拔高度" << "频点" << "强度" << "记录时间"; // CSV header
out << row.join(delimiter) << "\n";
for (const QString& imsi : m_imsiList) {
row.clear();
ImsiData data = m_dataMap.value(imsi);
row << data.imsi
<< data.operatorName
<< data.longitude
<< data.latitude
<< QString::number(data.altitude)
<< data.fcn
<< QString::number(data.rssi)
<< data.createDate;
out << row.join(delimiter) << "\n";
}
file.close();
}
// ======================= ImsiTableModel end=====================
// ======================= RescuLoad start===========================
RescueLoad::RescueLoad(QObject *parent)
:QObject(parent), remoteIp("10.10.10.50"), remotePort(8056)
{
// remoteIp = "127.0.0.1";
}
RescueLoad::~RescueLoad() {}
void RescueLoad::startCommunication()
{
udpSocket = new QUdpSocket(this);
connect(udpSocket, &QUdpSocket::readyRead, this, &RescueLoad::readData);
}
void RescueLoad::sendMessage(const QString &message)
{
QByteArray datagram = message.toUtf8();
udpSocket->writeDatagram(datagram, QHostAddress(remoteIp), remotePort);
}
void RescueLoad::sendMessage(const QByteArray &datagram)
{
udpSocket->writeDatagram(datagram, QHostAddress(remoteIp), remotePort);
}
void RescueLoad::readData()
{
while (udpSocket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
// qDebug() << "Received response from" << sender.toString() << ":" << senderPort;
// qDebug() << "Data:" << datagram;
handleMessage(datagram);
}
}
void RescueLoad::handleMessage(const QByteArray &datagram) {
QJsonParseError json_error;
QJsonDocument jsonDoc(QJsonDocument::fromJson(datagram, &json_error));
if(json_error.error != QJsonParseError::NoError || !jsonDoc.isObject()){
qDebug() << "json error!";
return;
}
QJsonObject baseObj = jsonDoc.object();
QJsonValue vType = baseObj.value("type");
QJsonValue vMsg = baseObj.value("msg");
// if (!vType.isDouble() || !vMsg.isString()) return;
int type = vType.toInt();
QString msg = vMsg.toString();
// if ("success" != msg) return;
switch (type) {
case 1: // 4G心跳包
// todo
sendMessage(QString("{\"cmd\": \"heartbeat\"}")); // 定时回心跳,或者单独开定时器
break;
case 2: // 5G心跳包
sendMessage(QString("{\"cmd\": \"heartbeat\"}"));
break;
case 3:{ // IMSI数据
QJsonArray array = baseObj.value("data").toArray();
for (int i = 0; i < array.size(); i++){
QJsonObject json = array.at(i).toObject();
ImsiData data(json);
// ImsiData data;
emit dataUpdate(data);
}
break;
}
default:
break;
}
}
void RescueLoad::syncTime()
{
QString timeStr = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
QJsonObject timeObj;
timeObj.insert("datetime", timeStr);
QJsonObject sendObj;
sendObj.insert("cmd", "syncTime");
sendObj.insert("params", timeObj);
sendMessage(QJsonDocument(sendObj).toJson(QJsonDocument::Compact));
}
/**
* @brief RescueLoad::sendNameList
* @param action: 'reject'/'block'/'reject2lte'/'release2lte', #imsi
* @param type: 'ADD'/'SUB'/'SAVE' #ADD:SUB:SAVE:
* @param wnamelist: IMSI
* @param bnamelist: IMSI
*/
void RescueLoad::sendNameList(const QString action, const QString type, const QList<QString> &wnamelist, const QList<QString> &bnamelist)
{
QJsonObject paramsObj;
paramsObj.insert("action", action);
paramsObj.insert("type", type);
paramsObj.insert("wnamelist", QJsonArray::fromStringList(wnamelist));
paramsObj.insert("bnamelist", QJsonArray::fromStringList(bnamelist));
QJsonObject sendObj;
sendObj.insert("cmd", "msg_set_namelist");
sendObj.insert("params", paramsObj);
sendMessage(QJsonDocument(sendObj).toJson(QJsonDocument::Compact));
}
// ============================ RescueLoad end=================================