#ifndef WIFIMANAGE_H
#define WIFIMANAGE_H
#include <QObject>
#include <QAbstractListModel>
#include <QVariantMap>
#include <QSharedPointer>
#include <QTimer>
class Wifi : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(bool isLock READ isLock WRITE setIsLock NOTIFY isLockChanged)
Q_PROPERTY(int rssi READ rssi WRITE setRssi NOTIFY rssiChanged)
Q_PROPERTY(QString ip READ ip WRITE setIp NOTIFY ipChanged)
Q_PROPERTY(QString mac READ mac WRITE setMac NOTIFY macChanged)
public:
Wifi() {}
Wifi(const QString &name, const bool &isLock, const int &rssi, const QString &ip, const QString &mac, QObject *parent = nullptr);
Wifi(const Wifi &wifi, QObject *parent = nullptr);
void operator=(const Wifi &wifi);
QString name() const;
void setName(QString name);
bool isLock() const;
void setIsLock(bool isLock);
int rssi() const;
void setRssi(int rssi);
QString ip() const;
void setIp(QString ip);
QString mac() const;
void setMac(QString mac);
signals:
void nameChanged(QString);
void isLockChanged(bool);
void rssiChanged(int);
void ipChanged(QString);
void macChanged(QString);
private:
QString m_wifiName;
bool m_isLock;
int m_rssi;
QString m_ip;
QString m_mac;
};
class WifiModel : public QAbstractListModel
{
Q_OBJECT
public:
enum WifiRoles {
NameRole = Qt::UserRole + 1,
IsLockRole,
RssiRole,
IpRole,
MacRole
};
Q_ENUM(WifiRoles)
static WifiModel* getInstance();
WifiModel(QObject *parent = 0);
void addWifi(const Wifi &wifi);
void clear();
virtual int rowCount(const QModelIndex & parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
protected:
virtual QHash<int, QByteArray> roleNames() const;
private:
QList<Wifi> m_wifiList;
};
class WifiManage : public QObject
{
Q_OBJECT
Q_PROPERTY(bool enable READ enable WRITE setEnable NOTIFY enableChanged)
Q_PROPERTY(Wifi *currWifi READ currWifi NOTIFY currWifiChanged)
Q_PROPERTY(int wifiStatus READ wifiStatus WRITE setWifiStatus NOTIFY wifiStatusChanged)
Q_PROPERTY(bool online READ online WRITE setOnline NOTIFY onlineChanged)
public:
enum WifiStatus {
WifiNoConnected = 0, // 未连接WIFI
WifiLinking, // wifi连接中
WifiLinkFailed, // 连接失败
WifiPasswordErr, // 密码错误连接失败
WifiConnected, // 连接成功
WifiRouterConnected, // 路由连接成功
WifiInterrupt // 连接断开
};
Q_ENUM(WifiStatus)
explicit WifiManage(QObject *parent = nullptr);
bool enable() const;
void setEnable(bool);
Wifi *currWifi() const;
int wifiStatus() const;
void setWifiStatus(int wifiStatus);
bool online() const;
void setOnline(bool online);
signals:
void enableChanged(bool enable);
void wifiStatusChanged(int wifiStatus);
void getWifiListEnd();
void currWifiChanged(Wifi *wifi);
void onlineChanged(bool online);
void wifiError(int wifiStatus);
public slots:
void parseWifiData(QVariantMap vMap);
void pingBaidu();
private:
int getWifiPower(int rssi);
void setNetStatus(int connectState, bool netState);
private:
bool m_enable{true}; // wifi开关使能
QSharedPointer<Wifi> m_currWifi;
int m_wifiStatus{WifiNoConnected};
bool m_isOnline{false}; // 联网状态
QTimer m_pingTimer;
};
#endif // WIFIMANAGE_H
#include "wifimanage.h"
#include <QDebug>
#include <QJsonArray>
#include <QJsonObject>
#include <QHostInfo>
#include "msgqueue.h"
/**********************************************************************
* 功能描述: 构造函数
* 输入参数: name: WIFI名
* isLock: 是否有密码
* rssi: 信号强度
* 输出参数: 无
* 返 回 值: 无
* 其它说明: 无
***********************************************************************/
Wifi::Wifi(const QString &name, const bool &isLock, const int &rssi, const QString &ip, const QString &mac, QObject *parent)
: QObject(parent), m_wifiName(name), m_isLock(isLock), m_rssi(rssi), m_ip(ip), m_mac(mac)
{
}
/**********************************************************************
* 功能描述: 默认构造函数
* 输入参数: parent:父类
* 输出参数: 无
* 返 回 值: 无
* 其它说明: 无
***********************************************************************/
Wifi::Wifi(const Wifi &wifi, QObject *parent) : QObject(parent)
{
m_wifiName = wifi.name();
m_isLock = wifi.isLock();
m_rssi = wifi.rssi();
m_ip = wifi.ip();
m_mac = wifi.mac();
}
/**********************************************************************
* 功能描述: 赋值构造函数
* 输入参数: wifi:需要赋值的wifi
* 输出参数: 无
* 返 回 值: 无
* 其它说明: 无
***********************************************************************/
void Wifi::operator=(const Wifi &wifi)
{
m_wifiName = wifi.name();
m_isLock = wifi.isLock();
m_rssi = wifi.rssi();
}
/**********************************************************************
* 功能描述: 获取WIFI名
* 输入参数: 无
* 输出参数: 无
* 返 回 值: WIFI名
* 其它说明: 无
***********************************************************************/
QString Wifi::name() const
{
return m_wifiName;
}
void Wifi::setName(QString name)
{
if (m_wifiName != name) {
m_wifiName = name;
emit nameChanged(name);
}
}
/**********************************************************************
* 功能描述: 获取WIFI是否有锁
* 输入参数: 无
* 输出参数: 无
* 返 回 值: WIFI是否有锁
* 其它说明: 无
***********************************************************************/
bool Wifi::isLock() const
{
return m_isLock;
}
void Wifi::setIsLock(bool isLock)
{
if (m_isLock != isLock) {
m_isLock = isLock;
emit isLockChanged(isLock);
}
}
/**********************************************************************
* 功能描述: 获取WIFI信号强度
* 输入参数: 无
* 输出参数: 无
* 返 回 值: WIFI信号强度
* 其它说明: 无
***********************************************************************/
int Wifi::rssi() const
{
return m_rssi;
}
void Wifi::setRssi(int rssi)
{
if (m_rssi != rssi) {
m_rssi = rssi;
emit rssiChanged(rssi);
}
}
QString Wifi::ip() const
{
return m_ip;
}
void Wifi::setIp(QString ip)
{
if (m_ip != ip) {
m_ip = ip;
emit ipChanged(ip);
}
}
QString Wifi::mac() const
{
return m_mac;
}
void Wifi::setMac(QString mac)
{
if (m_mac != mac) {
m_mac = mac;
emit macChanged(mac);
}
}
/**********************************************************************
* 功能描述: 默认构造函数
* 输入参数: parent:父类
* 输出参数: 无
* 返 回 值: 无
* 其它说明: 无
***********************************************************************/
WifiModel::WifiModel(QObject *parent) : QAbstractListModel(parent)
{
m_wifiList.clear();
for (int i = 0; i < 10; ++i) {
QString ip = QString("192.168.0.%1").arg(i+1);
QString mac = QString("00:0c:29:3f:60:%1").arg(i+1);
Wifi wifi(QString("wifi_%1").arg(i+1), i % 2, i % 5+1, ip, mac);
m_wifiList << wifi;
}
}
WifiModel *WifiModel::getInstance()
{
static WifiModel instance;
return &instance;
}
/**********************************************************************
* 功能描述: 添加WIFI
* 输入参数: wifi:需要添加的WIFI
* 输出参数: 无
* 返 回 值: 无
* 其它说明: 无
***********************************************************************/
void WifiModel::addWifi(const Wifi &wifi)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_wifiList << wifi;
endInsertRows();
}
void WifiModel::clear()
{
beginResetModel();
m_wifiList.clear();
endResetModel();
}
/**********************************************************************
* 功能描述: 返回WIFI列表的总计数
* 输入参数: parent:父类
* 输出参数: 无
* 返 回 值: WIFI列表的总计数
* 其它说明: 无
***********************************************************************/
int WifiModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return m_wifiList.count();
}
/**********************************************************************
* 功能描述: 根据WIFI的属性获取对应的值
* 输入参数: index:坐标定位 role:WIFI属性
* 输出参数: 无
* 返 回 值: WIFI属性对应的值
* 其它说明: 无
***********************************************************************/
QVariant WifiModel::data(const QModelIndex &index, int role) const
{
if (index.row() < 0 || index.row() >= m_wifiList.count()) {
return QVariant();
}
const Wifi &wifi = m_wifiList[index.row()];
if (role == NameRole) {
return wifi.name();
} else if (role == IsLockRole) {
return wifi.isLock();
} else if (role == RssiRole) {
return wifi.rssi();
} else if (role == IpRole) {
return wifi.ip();
} else if (role == MacRole) {
return wifi.mac();
}
return QVariant();
}
/**********************************************************************
* 功能描述: 获取WIFI属性
* 输入参数: 无
* 输出参数: 无
* 返 回 值: WIFI属性
* 其它说明: 无
***********************************************************************/
QHash<int, QByteArray> WifiModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[NameRole] = "name";
roles[IsLockRole] = "isLock";
roles[RssiRole] = "rssi";
roles[IpRole] = "ip";
roles[MacRole] = "mac";
return roles;
}
WifiManage::WifiManage(QObject *parent)
: QObject{parent}
{
m_currWifi = QSharedPointer<Wifi>(new Wifi("test", true, 3, "192.168.0.1", "00:0c:29:3f:60:b3"));
connect(MsgQueue::getInstance(), &MsgQueue::sig_recvCmd, this, &WifiManage::parseWifiData);
connect(&m_pingTimer, &QTimer::timeout, this, &WifiManage::pingBaidu);
m_pingTimer.start(5000);
}
/**********************************************************************
* 功能描述: 获取WIFI管理使能开关
* 输入参数: 无
* 输出参数: 无
* 返 回 值: true:WIFI开 false:WIFI关
* 其它说明: 无
***********************************************************************/
bool WifiManage::enable() const
{
return m_enable;
}
/**********************************************************************
* 功能描述: 设置WIFI使能开关
* 输入参数: enable:需要设置的WIFI使能开关
* 输出参数: 无
* 返 回 值: 无
* 其它说明: 无
***********************************************************************/
void WifiManage::setEnable(bool enable)
{
if (m_enable != enable) {
m_enable = enable;
emit enableChanged(enable);
}
}
/**********************************************************************
* 功能描述: 获取当前连接WIFI
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 当前连接WIFI
* 其它说明: 无
***********************************************************************/
Wifi *WifiManage::currWifi() const
{
return m_currWifi.data();
}
/**********************************************************************
* 功能描述: 获取当前连接WIFI状态
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 当前连接WIFI状态
* 其它说明: 无
***********************************************************************/
int WifiManage::wifiStatus() const
{
return m_wifiStatus;
}
void WifiManage::setWifiStatus(int wifiStatus)
{
if (m_wifiStatus != wifiStatus) {
// 连接异常
if (m_wifiStatus == WifiLinking || m_wifiStatus == WifiConnected) {
if (wifiStatus == WifiLinkFailed || wifiStatus == WifiPasswordErr
|| wifiStatus == WifiInterrupt || wifiStatus == WifiNoConnected) {
emit wifiError(wifiStatus);
}
}
m_wifiStatus = wifiStatus;
emit wifiStatusChanged(wifiStatus);
}
}
bool WifiManage::online() const
{
return m_isOnline;
}
void WifiManage::setOnline(bool online)
{
if (m_isOnline != online) {
m_isOnline = online;
emit onlineChanged(online);
}
}
void WifiManage::parseWifiData(QVariantMap vMap)
{
int type = vMap.value("type").toInt();
int command = vMap.value("command").toInt();
if (type == 5 && command == 2) { // 主动上报网络信息
QJsonObject obj = vMap.value("payload").toJsonObject();
int connectState = obj.value("connectstate").toInt();
QString mac = obj.value("bssid").toString();
QString wifiName = obj.value("ssid").toString();
QString ip = obj.value("ip").toString();
int rssi = obj.value("rssi").toInt();
int isLock = obj.value("flags").toInt();
// 设置网络状态
setNetStatus(connectState, m_isOnline);
int power = getWifiPower(rssi);
bool lock = (isLock == 0 ? false : true);
m_currWifi->setName(wifiName);
m_currWifi->setIsLock(lock);
m_currWifi->setRssi(power);
m_currWifi->setIp(ip);
m_currWifi->setMac(mac);
emit currWifiChanged(m_currWifi.data());
} else if (type == 4 && command == 34) { // 读取wifi列表
WifiModel *model = WifiModel::getInstance();
model->clear();
QJsonArray payload = vMap.value("payload").toJsonArray();
foreach (QJsonValue val, payload) {
if (val.isObject()) {
QJsonObject obj = val.toObject();
QString wifiName = obj.value("ssid").toString();
QString mac = obj.value("bssid").toString();
int rssi = obj.value("rssi").toInt();
int isLock = obj.value("flags").toInt();
int power = getWifiPower(rssi);
model->addWifi(Wifi(wifiName, isLock, power, "", mac));
}
}
emit getWifiListEnd();
} else if (type == 2 && command == 0x20) { // wifi使能
int result = vMap.value("result").toInt();
if (!m_enable) { // wifi关闭
if (result == 1) { // 成功
setWifiStatus(WifiNoConnected);
setOnline(false);
}
}
}
}
void WifiManage::pingBaidu()
{
QHostInfo::lookupHost("www.baidu.com", this, [this](QHostInfo host){
bool online = false;
if (host.error() != QHostInfo::NoError) {
online = false;
} else {
online = true;
}
setOnline(online);
});
}
// 判断wifi强度
int WifiManage::getWifiPower(int rssi)
{
if (rssi < -85) { // 极差
return 1;
} else if (rssi >= -85 && rssi < -75) { // 差
return 2;
} else if (rssi >= -75 && rssi < -65) { // 中等
return 3;
} else if (rssi >= -65 && rssi < -50) { // 良
return 4;
} else { // 优
return 5;
}
}
void WifiManage::setNetStatus(int connectState, bool netState)
{
if (connectState == 0) {
setWifiStatus(WifiNoConnected);
} else if (connectState == 4 && netState == false) {
setWifiStatus(WifiRouterConnected);
} else if (connectState == 4 && netState == true) {
setWifiStatus(WifiConnected);
} else if (connectState == 1) {
setWifiStatus(WifiLinking);
} else if (connectState == 2) {
setWifiStatus(WifiLinkFailed);
} else if (connectState == 3) {
setWifiStatus(WifiPasswordErr);
} else if (connectState == 5) {
setWifiStatus(WifiInterrupt);
} else {
QString err= QString("Wifi Status Code Error, connectState: %1, netState: %2")
.arg(connectState).arg(netState);
qDebug()<<__func__<<__LINE__<<err;
}
}