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++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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=================================