Commit 59ea8f13 by wuyang.zou

New Feature: Tcp Socket + Ssl CertOpt

Current Can't Run Normal

Temporary Storage Code Into Git
parent 215db0a4
Pipeline #31596 failed with stage
in 0 seconds
#include "SocketCommunicate.h"
#include <QEventLoop>
#include <QStringList>
#include <QSslConfiguration>
#include <QTimer>
#include <QJsonObject>
#include <QJsonArray>
#include "QsLog.h"
#include "preDefine.h"
#include "Network/billSocket.h"
#include "configManger.h"
SocketCommunicate::SocketCommunicate(ThreadSocket *parent) : ThreadSocket(parent)
{
_ip = "";
_port = 0;
_sslSocket = NULL;
_needTcpLogin = 1;
_httpLoginResult = false;
_domainName.clear();
_isTimeout = true;
_networkErrIndex = 0;
}
SocketCommunicate::~SocketCommunicate()
{
while(!_stoped) {
_stopFlag = true;
emit quit();
EVENTWAIT(10);
}
}
void SocketCommunicate::setPosMetaData(const QVariantMap &posMetaData)
{
_posMetaData = posMetaData;
}
bool SocketCommunicate::connectTcpSvr()
{
if( 0 == _ip.length() || 0 == _port ) {
QLOG_ERROR() << "connectTcpSvr:: HostIp / port Is Invalid";
return false;
}
QLOG_INFO() << "connectTcpSvr:: ip: " << _ip << " ; port: " << _port;
_sslSocket = new QSslSocket();
connect(_sslSocket, &QSslSocket::connected, [this] () {
_isTimeout = false;
emit connected();
});
// 绑定 sslSocket 异常时 触发 SocketCommunicate::quit 信号函数
connect(_sslSocket, static_cast<void (QSslSocket::*)(QAbstractSocket::SocketError)>(&QSslSocket::error), this, &SocketCommunicate::quit);
// 绑定 sslSocket 读数据成功后的 触发 Lambda 槽函数: <1> 重置超时标志: _isTimeout 为 False; <2> 发出读完成信号中断阻塞模式;
connect(_sslSocket, &QSslSocket::readyRead, [this] () {
_isTimeout = false;
emit readReady();
});
// 绑定 sslSocket 写数据成功后的 触发 Lambda 槽函数: <1> 重置超时标志: _isTimeout 为 False; <2> 发出写完成信号中断阻塞模式;
connect(_sslSocket, &QSslSocket::bytesWritten, [this] (quint64 writebyte) {
Q_UNUSED(writebyte);
_isTimeout = false;
emit writeReady();
});
//下载证书接口待调试:
_sslSocket->addCaCertificates(qApp->applicationDirPath() + "/" + "microwstest.sandload.cn.pem");
QLOG_WARN() << _sslSocket->errorString();
_sslSocket->ignoreSslErrors();
QSslConfiguration config = QSslConfiguration::defaultConfiguration();
config.setPeerVerifyMode(QSslSocket::VerifyNone);
_sslSocket->setSslConfiguration(config);
QLOG_WARN() << _sslSocket->errorString();
_isTimeout = true;
_sslSocket->connectToHostEncrypted(_ip, _port);
{
QEventLoop loop;
QTimer timer;
connect(this, &SocketCommunicate::quit, &loop, &QEventLoop::quit);
connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
connect(this, &SocketCommunicate::connected, &loop, &QEventLoop::quit);
timer.start(60*1000);
loop.exec();
}
// Connect Tcp Svr Success, Then Lambda Fuc Will Change Flag: _isTimeout = false;
if ( _isTimeout )
QLOG_ERROR() <<" ErrorMsg: "<< _sslSocket->errorString() << " ErrorCode: "<<_sslSocket->sslErrors() << " Timeout: "<< _isTimeout;
return !_isTimeout;
}
void SocketCommunicate::networkOuttime(bool timeOut)
{
if( !timeOut ) {
_networkErrIndex = 0;
} else {
_networkErrIndex++;
QLOG_INFO() << "SocketCommunicate::networkOuttime:: _networkErrIndex = "<< _networkErrIndex;
}
}
bool SocketCommunicate::loginTcpSvr()
{
QByteArray requestdata;
QJsonObject json;
SocketCommuProcess::getJsonFormatLoginReq(_posMetaData, json);
QLOG_INFO() << "loginTcpServer:: Get Request Json: " << json;
SocketCommuProcess::getByteFormatLoginReq(json, requestdata);
QLOG_INFO() << "loginTcpSvr:: Tcp Login Request: " << requestdata.toHex();
_isTimeout = true;
_sslSocket->write(requestdata);
{
QEventLoop loop; QTimer timer;
connect(this, &SocketCommunicate::quit, &loop, &QEventLoop::quit);
connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
connect(this, &SocketCommunicate::writeReady, &loop, &QEventLoop::quit);
timer.start(10*1000);
loop.exec();
}
// Login Tcp Svr Success, Then Lambda Fuc Will Change Flag: _isTimeout = false;
if(_isTimeout) {
QLOG_ERROR() << "loginTcpServer:: Send Msg To Service Failed: " << _sslSocket->errorString();
return false;
}
_isTimeout = true;
{
QEventLoop loop;
QTimer timer;
connect(this, &SocketCommunicate::quit, &loop, &QEventLoop::quit);
connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
connect(this, &SocketCommunicate::readReady, &loop, &QEventLoop::quit);
timer.start(30*1000);
loop.exec();
}
if(_isTimeout) {
QLOG_ERROR() << "loginTcpServer:: Receive Msg From Service Failed, TimeOut: " << _sslSocket->errorString();
return false;
}
QByteArray headByteData = _sslSocket->read(sizeof(Data_Head));
Data_Head outDataHead = {0};
if ( !SocketCommuProcess::getHeadAllData( headByteData, outDataHead ) )
{
if ( CMD_AUTH_LOGIN_RESP != outDataHead.type) {
QLOG_ERROR() << "loginTcpServer:: Login Receive Head Failed / Not Login Response ";
return false;
}
}
QByteArray body = _sslSocket->read(outDataHead.length);
QJsonDocument jsonDocument = QJsonDocument::fromJson(body);
if(jsonDocument.isNull()) {
QLOG_ERROR() << "loginTcpServer:: Login Receive Body Is Null / Empty";
return false;
}
QJsonObject rspJson = jsonDocument.object();
QLOG_INFO() << "loginTcpServer:: Login Receive Json : " << rspJson;
if ( rspJson.contains(JSON_TCP_STA_RST) && rspJson[JSON_TCP_STA_RST].toBool() == TRUE )
return true;
return false;
}
void SocketCommunicate::acceptTcpSvrSendMsg()
{
while(!_stopFlag && !_needTcpLogin)
{
QLOG_INFO() << "acceptTcpSvrSendMsg:: Wait Recv Json ...";
_isTimeout = true;
{
QEventLoop loop;
QTimer timer;
connect(this, &SocketCommunicate::quit, &loop, &QEventLoop::quit);
connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
connect(this, &SocketCommunicate::readReady, &loop, &QEventLoop::quit);
timer.start(75*1000);
loop.exec();
}
if(_isTimeout)
break ;
QByteArray headByteData = _sslSocket->read(sizeof(Data_Head));
Data_Head outDataHead = {0};
if ( !SocketCommuProcess::getHeadAllData( headByteData, outDataHead ) )
{
//清空内部缓冲器重新读
QLOG_ERROR() << "loginTcpServer:: Login Receive Head Failed / Not Login Response ";
_sslSocket->readAll();
continue;
}
if(outDataHead.type == CMD_RECV_HEARTBEAT_REQ)
{
_sslSocket->read(outDataHead.length);
QByteArray data;
// Prepare Response Server Heart Beat
SocketCommuProcess::getByteFormatHeartResp(data);
QLOG_INFO() << "Prepare Response Data For Server Heart Beat: " << data.toHex();
int len = _sslSocket->write(data);
QLOG_INFO() << "Write Response Data Len : " << len;
_isTimeout = true;
{
QEventLoop loop;
QTimer timer;
connect(this, &SocketCommunicate::quit, &loop, &QEventLoop::quit);
connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
connect(this, &SocketCommunicate::writeReady, &loop, &QEventLoop::quit);
timer.start(30*1000);
loop.exec();
}
QLOG_INFO() << "Socket Write Heart Beat Data " << ( _isTimeout ? "TimeOut" : " Success") ;
continue;
}
else if(outDataHead.type == CMD_RECV_MSG_REQ)
{
// Recv Server Push OrderStatus Msg;
QByteArray msgData = _sslSocket->read(outDataHead.length);
QLOG_INFO() << "Recv Server Push OrderStatus Msg: " << msgData.data();
// Check Server Push Msg Is Valid
checkRecvMsgValid(msgData);
// Prepare Response Data For Server Push OrderStatus;
QByteArray data;
SocketCommuProcess::getByteFormatMsgResp(data, outDataHead.sequence );
QLOG_INFO() << "Prepare Response Data For Server Push OrderStatus:: " << data.toHex();
_sslSocket->write(data);
_isTimeout = true;
{
QEventLoop loop;
QTimer timer;
connect(this, &SocketCommunicate::quit, &loop, &QEventLoop::quit);
connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
connect(this, &SocketCommunicate::writeReady, &loop, &QEventLoop::quit);
timer.start(30*1000);
loop.exec();
}
QLOG_INFO() << "Socket Write OrderStatus Resp Data " << ( _isTimeout ? "TimeOut" : " Success" ) ;
continue;
}
else if(outDataHead.type == CMD_AUTH_LOGIN_RESP)
{
// Recv Server Response Msg Of Self Login Request ;
QByteArray msgData = _sslSocket->read(outDataHead.length);
// Process Login's Response;
// needPostDriverEvent(msgdata);
// Prepare Response Data For Server Response Login Request;
QByteArray data;
SocketCommuProcess::getByteFormatMsgResp(data, outDataHead.sequence);
QLOG_INFO() << "Prepare Response Data For Server Response Login Request: " << data.toHex();
_sslSocket->write(data);
_isTimeout = true;
{
QEventLoop loop;
QTimer timer;
connect(this, &SocketCommunicate::quit, &loop, &QEventLoop::quit);
connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
connect(this, &SocketCommunicate::writeReady, &loop, &QEventLoop::quit);
timer.start(30*1000);
loop.exec();
}
QLOG_INFO() << "Socket Write Login Resp'Resp Data (Impossible Occur) " << ( _isTimeout ? "TimeOut" : " Success") ;
continue;
}
QLOG_ERROR() << "acceptTcpSvrSendMsg:: Not Support This Command Type: "<< outDataHead.type;
_sslSocket->readAll();
break;
}
}
bool SocketCommunicate::checkRecvMsgValid(const QByteArray &msgData)
{
QLOG_INFO() << "checkRecvMsgValid:: msgData: " << msgData;
QJsonDocument document = QJsonDocument::fromJson(msgData);
QJsonObject object = document.object();
// Parse Doc Key And Value;
int type = object["type"].toInt();
QLOG_DEBUG() << "TYPE" << type;
QJsonObject content = object["content"].toObject();
QLOG_DEBUG() << "deliveryStatus" << content["deliveryStatus"].toInt();
//解析收到的消息,deliveryStatus字段为2时推送拉取骑手信息事件
if(content.contains("deliveryStatus") && content["deliveryStatus"].toInt() == 2)
{
}
return true;
}
bool SocketCommunicate::GetSvrIpPort()
{
// Get Url Address; Host Ip + Port;
// ip = "wmpos.sandload.cn" -> 123.207.193.166 port = ?;
// Starbucks Temp DevMachine: [10.92.192.235] + 8888
// stgUrl = posagent.stg.starbucks.net [ 10.92.222.118 ]
// uatUrl = posagent.uat.starbucks.net [ 10.92.222.119 ]
// proUrl = posagent.starbucks.net [ 10.92.222.48 ]
_domainName = ConfigManger::GetInstance().GetPosAgentDomainName();
// test
_domainName = "wmpos.sandload.cn";
QHostInfo info=QHostInfo::fromName(_domainName);
foreach(QHostAddress address, info.addresses()) {
if(address.protocol() == QAbstractSocket::IPv4Protocol) {
QLOG_INFO()<<QString("[<<<<---SocketCommunicate::GetSvrIpPort : %1--->>>>]").arg(address.toString());
//1.1.1.1 > length > 7
if(address.toString().length()>7 && address.toString()!= "127.0.0.1" ) {
_ip = address.toString();
break;
}
}
}
_port = ConfigManger::GetInstance().GetPosAgentSvrPort();
if ( !_ip.length() && !_port) {
QLOG_INFO()<<" GetSvrIpPort Failed, Can't Analysis _domainName: "<< _domainName<< " / error _port: "<<_port;
return false;
}
QLOG_INFO()<<" GetSvrIpPort Success: "<< _ip << " : " << _port;
return true;
}
void SocketCommunicate::onFlowControlLoginSuccess(bool fcLoginResult) {
// 只有 FlowControl Http 登录成功后, FlowControl 才会发生信号 过来(跨线程);
_httpLoginResult = fcLoginResult;
}
void SocketCommunicate::threadStart()
{
QLOG_INFO() << "SocketCommunicate::threadStart:: " << QThread::currentThreadId();
// <1> 获取长连接的目标 IP + 端口;
while( !_httpLoginResult && !_stopFlag && !GetSvrIpPort())
{
QLOG_ERROR() << "Waitting HttpLogin Success / GetSvrIpPort Failed, Wait 20 sec";
QEventLoop loop;
connect(this, &SocketCommunicate::quit, &loop,&QEventLoop::quit);
QTimer::singleShot(20000, &loop, SLOT(quit()));
loop.exec();
}
QLOG_INFO() << "SocketCommunicate::threadStart:: _stopFlag = " << _stopFlag;
// <2> 向目标 IP + 端口发起长连接 与 登录请求, 登录成功后接受 Server Response Msg;
while(!_stopFlag) {
do {
// <2.1> Connect Svr , Establish Connection;
if(!connectTcpSvr()) {
networkOuttime(true);
QLOG_ERROR() << "connectTcpSvr Failed";
break;
} else {
networkOuttime(false);
}
// <2.2> Send Login Request;
if(!loginTcpSvr()) {
QLOG_ERROR() << "loginTcpSvr Failed";
break ;
}
_needTcpLogin = 0;
// <2.3> Accept Svr Send Msg;
acceptTcpSvrSendMsg();
networkOuttime(true);
} while(0);
//网络异常断开重连
CLOSE_SOCKES(_sslSocket);
if(_stopFlag)
break;
{
QEventLoop loop;
connect(this, &SocketCommunicate::quit, &loop,&QEventLoop::quit);
QTimer::singleShot(60000, &loop, SLOT(quit()));
loop.exec();
}
}
_stoped = true;
}
#ifndef SOCKETCOMMUNICATE_H
#define SOCKETCOMMUNICATE_H
#include <QObject>
#include <QMap>
#include <QTcpSocket>
#include <QJsonObject>
#include <QVariantMap>
#include <QJsonDocument>
#include <QSslSocket>
#include <QApplication>
#include <QHostInfo>
#include <QThread>
#include <QDebug>
#include <WinSock.h>
#include "preDefine.h"
#include "Network\ThreadSocket.h"
#include "QsLog.h"
#define CLOSE_SOCKES(socket) do{ \
if(socket != NULL && socket->isOpen()){ \
socket->close(); \
delete socket; \
socket = NULL; \
} \
} while(0)
#define DATAHEAD_INIT(head, mgc, ver, seq, cmd, serize, len) do{ \
head.magic = mgc; \
head.version = ver; \
head.sequence = seq; \
head.type = cmd; \
head.serialize = serize; \
head.length = htonl(len); \
} while(0)
//防止内存对齐
#ifdef WIN32
#pragma pack(push)
#pragma pack(1)
#else
__attribute__ ((aligned (push)))
__attribute__ ((aligned (1)))
#endif
typedef struct
{
quint16 magic;
quint8 version;
quint8 sequence;
quint8 type;
quint8 serialize;
quint32 length;
} Data_Head;
//恢复内存对齐方式
#ifdef WIN32
#pragma pack(pop)
#else
__attribute__ ((aligned (pop)))
#endif
// Command Type Define;
#define CMD_MIN 0
#define CMD_AUTH_LOGIN_REQ 1
#define CMD_AUTH_LOGIN_RESP 2
// Plugin Send Heart Beat To Svr;
#define CMD_SEND_HEARTBEAT_REQ 3
#define CMD_SEND_HEARTBEAT_RESP 4
// Plugin Recv Heart Beat From Svr;
#define CMD_RECV_HEARTBEAT_REQ 3
#define CMD_RECV_HEARTBEAT_RESP 4
// Send / Recv Error Resp;
#define CMD_SEND_ERR_RESP 5
#define CMD_RECV_ERR_RESP 5
// Recv Svr Request;
#define CMD_RECV_MSG_REQ 6
#define CMD_RECV_MSG_RESP 7
#define CMD_MAX 2000
// Default Version
#define DEFT_VERSION 1
#define DEFT_MAGIC 0XAAAA
// 接受OMS订单推送消息, 阻塞模式必须拥有单独线程
class SocketCommunicate : public ThreadSocket
{
Q_OBJECT
public:
explicit SocketCommunicate(ThreadSocket *parent = 0);
~SocketCommunicate();
void setPosMetaData(const QVariantMap &posMetaData);
void networkOuttime(bool timeOut);
private:
//<1> 链接到服务器
bool connectTcpSvr();
//<2> 登录及身份信息验证
bool loginTcpSvr();
//<3> 长连接建立后 接受服务端发出的消息;
void acceptTcpSvrSendMsg();
//检查 Server 推送的 MSG 是否有效;
bool checkRecvMsgValid(const QByteArray &msgData);
private:
bool GetSvrIpPort();
public slots:
//Socket Thread Recv Msg Entry
void threadStart();
void onFlowControlLoginSuccess(bool fcLoginResult);
signals:
void connected();
void writeReady();
void readReady();
private:
//门店信息
QVariantMap _posMetaData;
//重新登录标识
qint8 _needTcpLogin;
//Http 门店POS插件登录结果;
bool _httpLoginResult;
//超时标识
bool _isTimeout;
//长连接套接字
QSslSocket *_sslSocket;
//获取服务器列表地址
QString _domainName;
// 通过域名解析得到 Host Ip ; 默认端口: 8888
QString _ip;
int _port;
//网络异常编号;
int _networkErrIndex;
};
class SocketCommuProcess {
public:
friend class SocketCommunicate;
private:
static bool getRealLen(QByteArray array, quint32 &len) {
if(array.size() != sizeof(len))
return false;
quint32 tmplen = 0;
memcpy((void *)&tmplen, (void *)array.data(), sizeof(len));
len = ntohl(tmplen);
return true;
}
//获取 Login 请求数据
static void getByteFormatLoginReq(const QJsonObject &json, QByteArray &data)
{
Data_Head head = {0};
QByteArray tmpdata = QString(QJsonDocument(json).toJson(QJsonDocument::Compact)).toUtf8();
char *buf = (char *)calloc(1, sizeof(Data_Head) + tmpdata.size() + 1);
DATAHEAD_INIT( head, DEFT_MAGIC , DEFT_VERSION, 0, CMD_AUTH_LOGIN_REQ, 1, tmpdata.size() );
// Copy Data Head;
memcpy(buf, (void *)&head, sizeof(Data_Head));
// Copy Data Body;
memcpy(buf + sizeof(Data_Head), tmpdata.data(), tmpdata.size());
data = QByteArray(buf, sizeof(Data_Head) + tmpdata.size());
qDebug() << data.toHex();
free(buf);
}
//获取心跳响应包
static void getByteFormatHeartResp(QByteArray &data)
{
Data_Head head = {0};
char *buf = (char *)calloc(1, sizeof(Data_Head) + 1);
DATAHEAD_INIT( head, DEFT_MAGIC , DEFT_VERSION, 1, CMD_RECV_HEARTBEAT_RESP, 1, 0+2 );
memcpy(buf, (void *)&head, sizeof(Data_Head));
data = QByteArray(buf, sizeof(Data_Head));
free(buf);
}
//获取消息响应
static void getByteFormatMsgResp(QByteArray &data, quint32 sequence)
{
Data_Head head = {0};
char *buf = (char *)calloc(1, sizeof(Data_Head) + 1);
DATAHEAD_INIT( head, DEFT_MAGIC , DEFT_VERSION, sequence, CMD_RECV_MSG_RESP, 1, 0+2 );
memcpy(buf, (void *)&head, sizeof(Data_Head) + 1);
data = QByteArray(buf, sizeof(Data_Head));
free(buf);
}
//检查头部数据
//检查并获取头部全部信息
// static bool getHeadAllData(const QByteArray &data, quint16 &magic, quint8 &version, quint8 &sequence, quint8 &type, quint8 &serialize,quint32 &length)
static bool getHeadAllData(const QByteArray &data, Data_Head &outHead)
{
if(data.size() < sizeof(Data_Head)) {
QLOG_ERROR() << "getHeadAllData:: Origin Data Size Too Short :" << data.toHex();
return false;
}
Data_Head head = {0};
memcpy(&head, data.data(), sizeof(Data_Head));
outHead.magic = head.magic;
outHead.version = head.version;
outHead.sequence = head.sequence;
outHead.type = head.type;
outHead.serialize = head.serialize;
outHead.length = ntohl(head.length);
QLOG_INFO() << "getHeadAllData:: Origin Data : " << data.toHex() <<" ;\n Get-AllData: magic: "<<outHead.magic
<<" version: "<<outHead.version<<" sequence: "<<outHead.sequence << " type: "<<outHead.type << " serialize: "
<<outHead.serialize<<" length: "<<outHead.length;
return ( (head.type >= CMD_MIN && head.type <= CMD_MAX) && head.version == DEFT_VERSION);
}
static bool getJsonFormatLoginReq(QVariantMap map, QJsonObject &json )
{
Q_UNUSED(json);
if(!map.contains(JSON_STOREID))
return false;
//json.insert(TCPJSON_KEY_STOREID, map[JSON_STOREID].toString());
//json.insert(TCPJSON_KEY_TOKEN, token);
return true;
}
};
#endif // SOCKETCOMMUNICATE_H
......@@ -23,7 +23,7 @@
#include <DTools/printMsgQueueDB.h>
#include <DTools/PrintOrderPromotionDB.h>
#include <QHostInfo>
#include "SocketCommunicate.h"
FlowControl &FlowControl::GetInstance()
{
......@@ -810,6 +810,13 @@ bool FlowControl::_Login()
}
QLOG_INFO() << QString("[<<<<---Login--->>>>][m_bLoginResult:%1]")<<m_bLoginResult;
/*
if ( result ) {
emit doLoginSuccess(true);
}
*/
return result;
}
......
......@@ -171,6 +171,9 @@ signals:
// 发送信号给自己 做登陆
void doLogin();
// http门店POS登录成功后 发送信号给 SocketCommunicate;
void doLoginSuccess(bool loginResult);
/* 功能:隐藏通知窗口
* 参数:NULL
* 返回:NULL
......
......@@ -191,9 +191,13 @@ int ConfigManger::GetNoHurryRecordPos()
}
int ConfigManger::GetPosAgentSvrPort()
{
return m_config->value(INI_POSAGENTSVR_PORT).toUInt();
}
QString ConfigManger::GetPosAgentDomainName()
{
return m_config->value(INI_POSAGENTSVR_DOMAIN_NAME).toString();
}
......@@ -144,6 +144,10 @@ public:
int GetSkipRecordPos();
int GetNoHurryRecordPos();
// 长连接连接 PosAgent 配置端口;
int GetPosAgentSvrPort();
QString GetPosAgentDomainName();
private:
ConfigManger();
ConfigManger(ConfigManger const&);
......
#include "SysTray.h"
#include <QApplication>
#include <QThread>
extern QThread tcpThread;
extern QThread workThread;
......
#include "ThreadSocket.h"
#include <QThread>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QJsonDocument>
#include "preDefine.h"
#include "QsLog.h"
ThreadSocket::ThreadSocket(QObject *parent) : QObject(parent)
{
_stopFlag = false;
_stoped = false;
}
ThreadSocket::~ThreadSocket()
{
emit threadClose();
if(this->thread() != QThread::currentThread())
{
this->thread()->wait(20);
}
}
void ThreadSocket::moveToThread(QThread *thread, bool with_thread_start)
{
if(with_thread_start)
{
connect(thread, &QThread::started, this, &ThreadSocket::threadStart);
connect(this, &ThreadSocket::threadClose, thread, &QThread::quit);
}
QObject::moveToThread(thread);
}
bool ThreadSocket::S_PostRequest(const QJsonObject &requestJson, QJsonObject &recvJson, QString url, QString &error, QByteArray contentype)
{
QNetworkAccessManager m_networkManger;
if(QNetworkAccessManager::Accessible != m_networkManger.networkAccessible())
{
m_networkManger.setNetworkAccessible(QNetworkAccessManager::Accessible);
}
QNetworkRequest networkRequest;
networkRequest.setUrl(url);
networkRequest.setRawHeader("Content-Type",contentype);
QByteArray sendArray = QJsonDocument(requestJson).toJson(QJsonDocument::Compact);
QEventLoop eventLoop;
QNetworkReply *reply = m_networkManger.post(networkRequest , sendArray);
connect(&m_networkManger, SIGNAL(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)), &eventLoop, SLOT(quit()));
connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), &eventLoop, SLOT(quit()));
connect(this, &ThreadSocket::quit, &eventLoop,&QEventLoop::quit);
// 加用定时器防止网络出现异常长时间不返回导致的阻塞
QTimer::singleShot(SOCKET_POST_TIMEOUT, &eventLoop, &QEventLoop::quit);
eventLoop.exec();
if(reply->error() != QNetworkReply::NoError)
{
error = reply->errorString();
return false;
}
QByteArray recvArray = reply->readAll();
if(recvArray.size() == 0)
{
error = "Nothing Recved";
QLOG_ERROR() << "S_PostRequest Nothing Recved ";
return false;
}
recvJson = QJsonDocument::fromJson(recvArray).object();
QLOG_DEBUG() << "S_PostRequest: "<<recvJson;
reply->deleteLater();
return true;
}
bool ThreadSocket::S_GetRequest(const QString &url, QByteArray &out, QString &error)
{
QNetworkAccessManager m_networkManger;
if(QNetworkAccessManager::Accessible != m_networkManger.networkAccessible())
{
m_networkManger.setNetworkAccessible(QNetworkAccessManager::Accessible);
}
QNetworkRequest networkRequest;
networkRequest.setUrl(url);
QEventLoop eventLoop;
QNetworkReply *reply = m_networkManger.get(networkRequest);
connect(&m_networkManger, SIGNAL(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)), &eventLoop, SLOT(quit()));
connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), &eventLoop, SLOT(quit()));
connect(this, &ThreadSocket::quit, &eventLoop,&QEventLoop::quit);
// 加用定时器防止网络出现异常长时间不返回导致的阻塞
QTimer::singleShot(SOCKET_GET_TIMEOUT, &eventLoop, &QEventLoop::quit);
eventLoop.exec();
if(reply->error() != QNetworkReply::NoError)
{
error = reply->errorString();
return false;
}
QByteArray recvArray = reply->readAll();
if(recvArray.size() == 0)
{
error = "Nothing Recved";
QLOG_ERROR() << "S_GetRequest Nothing Recved ";
return false;
}
out = recvArray;
QLOG_DEBUG() << "S_GetRequest Success";
reply->deleteLater();
return true;
}
void ThreadSocket::threadStart()
{
_stoped = true;
}
#ifndef THREADSOCKET_H
#define THREADSOCKET_H
#include <QObject>
#include <QEventLoop>
#include <QJsonObject>
#include <QTimer>
#define EVENTWAIT(timer) do{ \
QEventLoop loop; \
QTimer::singleShot(timer, &loop, SLOT(quit())); \
loop.exec(); \
} while(0)
class ThreadSocket : public QObject
{
Q_OBJECT
public:
explicit ThreadSocket(QObject *parent = 0);
~ThreadSocket();
/* 功能:重载移动到线程的方法
* 参数:[1]线程编号[2]是否在退出时触发线程退出
* 返回:void
* */
void moveToThread(QThread *thread, bool with_thread_start);
bool S_PostRequest(const QJsonObject &requestJson, QJsonObject &recvJson, QString url, QString &error, QByteArray contentype = QByteArray("application/json"));
bool S_GetRequest(const QString& url, QByteArray& out,QString& error);
signals:
/* 功能:触发QThread退出的信号
* 参数:NULL
* 返回:void
* */
void threadClose();
void quit();
public slots:
virtual void threadStart();
protected:
bool _stopFlag;
bool _stoped;
};
#endif // THREADSOCKET_H
#ifndef MACTOOL
#define MACTOOL
#include <winsock2.h>
#include <iphlpapi.h>
#include <Windows.h>
#include <string>
#include <QString>
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
class MacTool
{
public:
static void GetPath(QString &path)
{
char tmppath[MAX_PATH] = {0};
GetProcPath(tmppath);
path = QString(tmppath);
}
static void GetProcPath(char * pathBuf)
{
int curPos;
GetModuleFileNameA((HMODULE)&__ImageBase, pathBuf, MAX_PATH);
curPos = strlen(pathBuf) - 1;
while('\\' != pathBuf[curPos]) {
curPos--;
}
curPos++;
pathBuf[curPos] = '\0';
}
static int GetMacByAdaptersAddresses(std::string& macOut)
{
bool ret = 0;
ULONG outBufLen = sizeof(IP_ADAPTER_ADDRESSES);
PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
if (pAddresses == NULL)
return 0;
// Make an initial call to GetAdaptersAddresses to get the necessary size into the ulOutBufLen variable
if(GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW)
{
free(pAddresses);
pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
if (pAddresses == NULL)
return 0;
}
if(GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == NO_ERROR)
{
for(PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses; pCurrAddresses != NULL; pCurrAddresses = pCurrAddresses->Next)
{
if(pCurrAddresses->PhysicalAddressLength != 6)
continue;
char acMAC[32];
sprintf(acMAC, "%02X-%02X-%02X-%02X-%02X-%02X",
int (pCurrAddresses->PhysicalAddress[0]),
int (pCurrAddresses->PhysicalAddress[1]),
int (pCurrAddresses->PhysicalAddress[2]),
int (pCurrAddresses->PhysicalAddress[3]),
int (pCurrAddresses->PhysicalAddress[4]),
int (pCurrAddresses->PhysicalAddress[5]));
macOut = acMAC;
ret = 1;
break;
}
}
free(pAddresses);
return ret;
}
};
#endif // MACTOOL
#ifndef ALGORITHM_PROCESS_H
#define ALGORITHM_PROCESS_H
#include <string>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/des.h>
#include <sstream>
#include "preDefine.h"
#include <QJsonObject>
#include <QString>
#include <QStringList>
class AlgorithmProcess
{
public:
static int base64(const char *input, size_t length, char *result, size_t size)
{
BIO * bmem = NULL;
BIO * b64 = NULL;
BUF_MEM * bptr = NULL;
int len = 0;
if(input == NULL)
return 0;
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
if (NULL == b64 || NULL == bmem) {
perror("BIO_new");
return 0;
}
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
b64 = BIO_push(b64, bmem);
BIO_write(b64, input, length);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
if ((unsigned int)(bptr->length + 1) > size) {
BIO_free_all(b64);
return 0;
}
memcpy(result, bptr->data, bptr->length);
result[bptr->length] = 0;
len = bptr->length;
BIO_free_all(b64);
return len;
}
static int debase64(const char *input, size_t length, char *result, size_t size)
{
BIO * b64 = NULL;
BIO * bmem = NULL;
int len;
if(input == NULL)
return 0;
if (length > size)
return 0;
memset(result, 0, size);
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new_mem_buf((void *)input, length);
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
if (NULL == b64 || NULL == bmem) {
perror("BIO_new");
return 0;
}
bmem = BIO_push(b64, bmem);
len = BIO_read(bmem, result, length);
BIO_free_all(b64);
return len;
}
static int RSASign(const char *text, char *signature, size_t size,const char *private_key)
{
RSA *rsa;
unsigned char *sig;
unsigned int len;
unsigned int length = 0;
BIO* in = NULL;
unsigned char sha1[32] = { '\0' };
char tmpprivatekey[MAX_RSA_KEY_LEN] = {0};
if(GetPEMKey(private_key, strlen(private_key), tmpprivatekey, MAX_RSA_KEY_LEN, 0) == 0)
return 0;
OpenSSL_add_all_algorithms();
in = BIO_new_mem_buf((void*)tmpprivatekey, -1);
if (in == NULL) {
perror("read private failed");
return 0;
}
rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL);
if (in != NULL)
BIO_free(in);
if (rsa == NULL) {
perror("PEM_read_bio_RSAPrivateKey");
return 0;
}
if (NULL == (sig = (unsigned char*)malloc(RSA_size(rsa)))) {
RSA_free(rsa);
return 0;
}
SHA256((const unsigned char *)text, strlen(text), sha1);
if (1 != RSA_sign(NID_sha256, sha1, 32, sig, &len, rsa)) {
free(sig);
RSA_free(rsa);
printf("RSA_sign error.\n");
return 0;
}
if ((length= base64((char *)sig, 128, signature, size)) == 0) {
free(sig);
RSA_free(rsa);
printf("base64 error.\n");
return 0;
}
free(sig);
RSA_free(rsa);
return length;
}
static int RSAVerify(const char *text,const char *signature, const char *public_key)
{
RSA *rsa;
BIO* in = NULL;
char * sig_debase = NULL;
unsigned char sha1[32];
char tmppublickey[MAX_RSA_KEY_LEN] = {0};
if(GetPEMKey(public_key, strlen(public_key), tmppublickey, MAX_RSA_KEY_LEN, 1) == 0)
return 0;
in = BIO_new_mem_buf((void*)tmppublickey, -1);
if (NULL == in) {
printf("BIO_read_filename error.\n");
return 0;
}
rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
if (in != NULL) BIO_free(in);
if (rsa == NULL) {
printf("PEM_read_bio_RSA_PUBKEY error.\n");
return 0;
}
sig_debase = (char *)malloc(250 * sizeof(char));
if (NULL == debase64(signature, strlen((char *)signature), sig_debase, 250)) {
RSA_free(rsa);
printf("debase64 error.\n");
return 0;
}
SHA256((const unsigned char *)text, strlen(text), sha1);
if (1 != RSA_verify(NID_sha256, sha1, 32, (unsigned char *)sig_debase, 128, rsa)) {
free(sig_debase);
RSA_free(rsa);
printf("RSA_verify error.\n");
return 0;
}
free(sig_debase);
RSA_free(rsa);
return 1;
}
static int AESDecode(const unsigned char *key, unsigned char *iv,const unsigned char *in, int inlen, unsigned char *out, int outmaxlen)
{
int iOutLen = 0;
int iTmpLen = 0;
int length = 0;
char tmpiv[16] = { 0 };
memcpy(tmpiv, iv, 16);
unsigned char *tmp = (unsigned char *)malloc(outmaxlen * sizeof(unsigned char));
memset(tmp, 0, outmaxlen);
char sha1[32] = { '\0' };
SHA256((const unsigned char *)key, strlen((const char *)key), (unsigned char *)sha1);
qDebug() << sha1;
if((length = debase64((const char *)in, inlen, (char *)tmp, outmaxlen)) == 0)
{
perror("debase64 failed");
return 0;
}
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL,(const unsigned char *)sha1, (const unsigned char *)tmpiv);
if(!EVP_DecryptUpdate(&ctx, (unsigned char*)out, &iOutLen, (const unsigned char *)tmp, length))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
if(!EVP_DecryptFinal_ex(&ctx, (unsigned char *)(out + iOutLen), &iTmpLen))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
iOutLen += iTmpLen;
EVP_CIPHER_CTX_cleanup(&ctx);
out[iOutLen] = 0;
return iOutLen;
}
static int AESEncode(const unsigned char *key, unsigned char *iv,const unsigned char *in, int inlen, unsigned char *out, int outmaxlen)
{
int iOutLen = 0;
int iTmpLen = 0;
int len;
char tmpiv[16] = { 0 };
memcpy(tmpiv, iv, 16);
unsigned char *tmp = (unsigned char *)malloc(outmaxlen * sizeof(unsigned char));
memset(tmp, 0, outmaxlen);
EVP_CIPHER_CTX ctx;
char sha1[32] = { '\0' };
SHA256((const unsigned char *)key, strlen((const char *)key), (unsigned char *)sha1);
qDebug() << sha1;
QByteArray array(sha1);
qDebug() << array.toBase64();
EVP_CIPHER_CTX_init(&ctx);
EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, (const unsigned char *)sha1, (const unsigned char *)tmpiv);
if(!EVP_EncryptUpdate(&ctx, (unsigned char*)tmp, &iOutLen, (const unsigned char *)in, inlen))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
if(!EVP_EncryptFinal_ex(&ctx, (unsigned char *)(tmp + iOutLen), &iTmpLen))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
iOutLen += iTmpLen;
EVP_CIPHER_CTX_cleanup(&ctx);
len = base64((char *)tmp, iOutLen, (char *)out, outmaxlen);
qDebug() << (char *)out;
free(tmp);
return len;
}
static int DES3Encode(const unsigned char *key,const char *in, int inlen, unsigned char *out, int outmaxlen)
{
int iOutLen = 0;
int iTmpLen = 0;
int len;
char iv[DES3_KEY_SIZE] = {0};
unsigned char *tmp = (unsigned char *)malloc(outmaxlen * sizeof(unsigned char));
memset(tmp, 0, outmaxlen);
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_EncryptInit_ex(&ctx, EVP_des_ede3_ecb(), NULL, (const unsigned char *)key, (const unsigned char *)iv);
if(!EVP_EncryptUpdate(&ctx, (unsigned char*)tmp, &iOutLen, (const unsigned char *)in, inlen))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
if(!EVP_EncryptFinal_ex(&ctx, (unsigned char *)(tmp + iOutLen), &iTmpLen))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
iOutLen += iTmpLen;
EVP_CIPHER_CTX_cleanup(&ctx);
len = base64((char *)tmp, iOutLen, (char *)out, outmaxlen);
free(tmp);
return len;
}
static int DES3Decode(const unsigned char *key,const char * in, int inlen, unsigned char *out, int outmaxlen)
{
int iOutLen = 0;
int iTmpLen = 0;
int length = 0;
char iv[DES3_KEY_SIZE] = {0};
unsigned char *tmp = (unsigned char *)malloc(outmaxlen * sizeof(unsigned char));
memset(tmp, 0, outmaxlen);
if((length = debase64(in, inlen, (char *)tmp, outmaxlen)) == 0)
{
perror("debase64 failed");
return 0;
}
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_DecryptInit_ex(&ctx, EVP_des_ede3_ecb(), NULL, (const unsigned char *)key, (const unsigned char *)iv);
if(!EVP_DecryptUpdate(&ctx, (unsigned char*)out, &iOutLen, (const unsigned char *)tmp, length))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
if(!EVP_DecryptFinal_ex(&ctx, (unsigned char *)(out + iOutLen), &iTmpLen))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
iOutLen += iTmpLen;
EVP_CIPHER_CTX_cleanup(&ctx);
out[iOutLen] = 0;
return iOutLen;
}
static int GetPEMKey(const char *key, int keylen, char *outpemkey, int outpemkeymaxlen, int ispublickey)
{
std::stringstream sstm;
std::string str(key, keylen);
if (keylen > outpemkeymaxlen) {
return 0;
}
if(ispublickey == 0) {
int i = 0;
sstm << "-----BEGIN RSA PRIVATE KEY-----\n";
while(i + 64 < keylen) {
sstm << str.substr(i, 64) << "\n";
i += 64;
}
if(keylen - i > 0)
sstm << str.substr(i, keylen - i) << "\n";
sstm << "-----END RSA PRIVATE KEY-----\n";
} else {
int i = 0;
sstm << "-----BEGIN PUBLIC KEY-----\n";
while(i + 64 < keylen) {
sstm << str.substr(i, 64) << "\n";
i += 64;
}
if(keylen - i > 0)
sstm << str.substr(i, keylen - i) << "\n";
sstm << "-----END PUBLIC KEY-----\n";
}
if(strlen(sstm.str().c_str()) > (unsigned int)outpemkeymaxlen)
return 0;
strcpy(outpemkey, sstm.str().c_str());
return 1;
}
static void GetKeyListFromJson(QStringList &keys, QJsonObject &json)
{
QJsonObject::Iterator it;
keys.clear();
for(it = json.begin(); it != json.end(); ++it) {
if(it.value().isString() || it.value().isDouble())
keys.append(it.key());
}
}
static void SortString(QStringList &keys) {
keys.removeOne(JSON_KEY_SIGN);
keys.sort();
}
static void GetValueListFromJson(const QStringList &keys, const QJsonObject &json, QString &values) {
values.clear();
for(int i = 0; i < keys.length(); ++i) {
if(json[keys[i]].isString()) {
values.append(json[keys[i]].toString());
values.append("|");
} else if ( json[keys[i]].isDouble() ) {
values.append(QString::number(json[keys[i]].toInt()));
values.append("|");
}
}
values = values.left(values.length() - 1);
qDebug() << values;
}
};
#endif //ALGORITHM_PROCESS_H
#ifndef CERTIFICATE_OPERATE
#define CERTIFICATE_OPERATE
#include <string>
#include <QFile>
#include <QString>
#include <QJsonObject>
#include <QJsonDocument>
#include "QsLog.h"
#include "MacTool.h"
#include "AlgorithmProcess.h"
/*
下载证书时: 将请求 json 组合拼装好,额外对 Mac 地址加密后,添加到 json中,进行证书 的下载【Svr的公钥 + Client的私钥】
CretOperate::GetDES3MAC(json, _posPartnerRegion, iv);
*/
/*
业务数据交互: 将请求 json 组合拼装好,额外对 Mac 地址,添加到 json中,对登录请求报文【使用 Client的私钥 进行加签】
CretOperate::GetMAC(tmpjson); // add json Key-Value: "mac": "**-**-**-**-**-**-**-**"
CretOperate::GetSign(tmpjson, iv); // RSASign And add json Key-Value: "sign": "*"
*/
class CertificateOperate
{
public:
static bool GetDES3MAC(QJsonObject &json, const int region , QString iv )
{
std::string tmpmac;
if(MacTool::GetMacByAdaptersAddresses(tmpmac) == 0) {
QLOG_ERROR() << "Get MAC Failed";
return false;
}
QLOG_INFO() << tmpmac.data();
char tmpiv[16] = {0};
memcpy(tmpiv, iv.toUtf8().data(), iv.toUtf8().size() > 16 ? 16 : iv.toUtf8().size());
char outmsg[4096] = {0};
QString aes_key = EC_ADES3_KEY; // CCO_ADES3_KEY;
if(AlgorithmProcess::AESEncode((const unsigned char *)aes_key.toUtf8().data(), (unsigned char *)tmpiv,
(const unsigned char *)tmpmac.data(), strlen(tmpmac.data()), (unsigned char *)outmsg, 4096) == 0)
{
QLOG_ERROR() << "AES MAC Failed";
return false;
}
QString macAfterAES = QString(outmsg);
json.insert(JSON_KEY_MAC, macAfterAES);
QLOG_INFO() << macAfterAES;
return true;
}
static bool GetMAC(QJsonObject &json)
{
std::string tmpmac;
if(MacTool::GetMacByAdaptersAddresses(tmpmac) == 0) {
QLOG_ERROR() << "Get MAC Failed";
return false;
}
QString mac = QString::fromStdString(tmpmac);
json.insert(JSON_KEY_MAC, mac);
QLOG_INFO() << mac;
return true;
}
static bool GetCertifiSign( QJsonObject &json, QString iv )
{
QString serpbk, clipbk;
if(!GetCertificate(iv, serpbk, clipbk))
return false;
QStringList list;
QString values;
AlgorithmProcess::GetKeyListFromJson(list, json);
AlgorithmProcess::SortString(list);
AlgorithmProcess::GetValueListFromJson(list, json, values);
QByteArray array = values.toUtf8();
char tmp[MAX_SIGN_LEN] = { 0 };
if(AlgorithmProcess::RSASign(array.data(), tmp, MAX_SIGN_LEN, clipbk.toUtf8().data()) == 0) {
QLOG_ERROR() << "Get RSASign Failed";
return false;
}
QLOG_INFO() << "Get RSA Sign: " << tmp;
QString sign = QString(tmp);
json.insert(JSON_KEY_SIGN, sign);
return true;
}
static bool SaveRSACertificate(QByteArray &des3text, const int region , QString iv)
{
QByteArray array = des3text;
char rps[MAX_BUF_LEN] = {0};
char *buf = (char *)calloc(array.size() + 100, sizeof(char));
strcpy(buf, array.data());
char tmpiv[16] = {0};
char tmpiv1[16] = {0};
memcpy(tmpiv, iv.toUtf8().data(), iv.toUtf8().size() > 16 ? 16 : iv.toUtf8().size());
memcpy(tmpiv1, iv.toUtf8().data(), iv.toUtf8().size() > 16 ? 16 : iv.toUtf8().size());
QString aes_key = EC_ADES3_KEY; // CCO_ADES3_KEY;
if(AlgorithmProcess::AESDecode((const unsigned char *)aes_key.toUtf8().data(), (unsigned char *)tmpiv,
(const unsigned char *)buf, strlen(buf), (unsigned char *)rps, MAX_BUF_LEN) == 0)
{
QLOG_ERROR() << "AESDecode AEStext Failed";
return false;
}
QJsonDocument jsonDocument = QJsonDocument::fromJson(QByteArray(rps));
if( jsonDocument.isNull() ) {
QLOG_ERROR() << "AESDecode Not Json:" << rps;
return false;
}
QJsonObject json = jsonDocument.object();
if(!json.contains(JSON_KEY_STATUS) || json[JSON_KEY_STATUS].toInt() != 100) {
QLOG_ERROR() << "Error des3text File:" << json;
return false;
}
//验证证书合法性在此添加
QByteArray data = QJsonDocument(json).toJson(QJsonDocument::Compact);
char prtrps[MAX_BUF_LEN] = {0};
if(AlgorithmProcess::AESEncode((const unsigned char *)AES_KEY_PRT, (unsigned char *)tmpiv1,
(const unsigned char *)data.data(), strlen(data.data()), (unsigned char *)prtrps, MAX_BUF_LEN) == 0)
{
QLOG_ERROR() << "AESEncode Private simphonyclient.p12 Failed:" << json;
return false;
}
char path[MAX_PATH] = { 0 };
MacTool::GetProcPath(path);
QString p12path(path);
p12path.append(CRET_FILE_NAME);
QFile file(p12path);
if(!file.open(QFile::WriteOnly)) {
QLOG_ERROR() << QString("Open %1 Failed").arg(p12path);
return false;
}
file.write(prtrps);
file.flush();
file.close();
QLOG_INFO() << "Write simphonyclient.p12 Success";
return true;
}
private:
static bool GetCertificate(QString iv, QString &serpublickey, QString &cleprivatekey)
{
if(iv.isEmpty()) {
QLOG_ERROR() << "GetCret:: AES cbc iv Is Empty";
return false;
}
char path[MAX_PATH] = { 0 };
MacTool::GetProcPath(path);
QString p12path(path);
p12path.append(CRET_FILE_NAME);
QFile file(p12path);
if(!file.open(QFile::ReadOnly)) {
QLOG_ERROR() << QString("GetCret:: Open %1 Failed").arg(p12path);
return false;
}
QByteArray array = file.readAll();
file.close();
char rps[MAX_BUF_LEN] = {0};
char *buf = (char *)calloc(array.size() + 100, sizeof(char));
strcpy(buf, array.data());
char tmpiv[16] = {0};
memcpy(tmpiv, iv.toUtf8().data(), iv.toUtf8().size() > 16 ? 16 : iv.toUtf8().size());
if(AlgorithmProcess::AESDecode((const unsigned char *)AES_KEY_PRT, (unsigned char *)tmpiv,
(const unsigned char *)buf, strlen(buf), (unsigned char *)rps, MAX_BUF_LEN) == 0)
{
QLOG_ERROR() << "GetCret:: AESDecode AEStext Failed";
return false;
}
QJsonDocument jsonDocument = QJsonDocument::fromJson(QByteArray(rps));
if( jsonDocument.isNull() ) {
QLOG_ERROR() << "GetCret:: AESDecode Not Json:" << rps;
return false;
}
QJsonObject json = jsonDocument.object();
if(!json.contains(JSON_KEY_STATUS) || json[JSON_KEY_STATUS].toInt() != 100) {
QLOG_ERROR() << "GetCret:: Error simphonyclient.p12 File:" << json;
return false;
}
serpublickey = json[JSON_KEY_SERPBLICKEY].toString();
cleprivatekey = json[JSON_KEY_CLIENTPRIKEY].toString();
return true;
}
};
#endif // CERTIFICATE_OPERATE
......@@ -9,7 +9,6 @@
#include <QProcess>
#include <QThread>
extern QThread tcpThread;
extern QThread workThread;
FloatForm::FloatForm(QWidget *parent) :
......
......@@ -22,90 +22,123 @@ INCLUDEPATH += DTools
LIBS += -luser32
LIBS += -lUserenv -ldbghelp
LIBS += -L$$PWD/lib -llibeay32 -lssleay32 -lwinspool -lWs2_32
DEFINES += TEST TODO
SOURCES += main.cpp\
mainForm.cpp \
alertForm.cpp \
DTools/configManger.cpp \
Control/flowControl.cpp \
LocalServer/loaclHttpServer.cpp \
Network/billSocket.cpp \
Control/SocketCommunicate.cpp \
DTools/clickedLineEdit.cpp \
DTools/configManger.cpp \
DTools/dataManger.cpp \
Model/orderObject.cpp \
DTools/getCaboxAReAuth.cpp \
DTools/gethascashboxandrefundauth.cpp \
DTools/headframe.cpp \
DTools/printCupStickPosDB.cpp \
DTools/printMsgQueueDB.cpp \
DTools/PrintOrderPromotionDB.cpp \
DTools/printSumBillPosDB.cpp \
DTools/simProcOrderDB.cpp \
DTools/sysTray.cpp \
DTools/util.cpp \
JQLibrary/src/JQHttpServer.cpp \
JQLibrary/src/JQNet.cpp \
LocalServer/loaclHttpServer.cpp \
Model/baseObject.cpp \
Model/cashierObject.cpp \
Model/couponsObject.cpp \
Model/dailyObject.cpp \
Model/deliverObject.cpp \
Model/dishesObject.cpp \
DTools/util.cpp \
settingForm.cpp \
floatForm.cpp \
detailForm.cpp \
DTools/sysTray.cpp \
padForm.cpp \
DTools/clickedLineEdit.cpp \
RejectForm.cpp \
DTools/headframe.cpp \
Model/orderObject.cpp \
Model/paymentObject.cpp \
Model/productObject.cpp \
Model/PromotionItemObject.cpp \
Model/singleProductObject.cpp \
Network/billSocket.cpp \
Network/ThreadSocket.cpp \
QsLog/QsLog.cpp \
QsLog/QsLogDest.cpp \
QsLog/QsLogDestConsole.cpp \
QsLog/QsLogDestFile.cpp \
QsLog/QsLogDestFunctor.cpp \
alertForm.cpp \
bstatusForm.cpp \
bstatusItem.cpp \
dailyreportForm.cpp \
detailForm.cpp \
dishesForm.cpp \
dishesItem.cpp \
disTabWdg.cpp \
floatForm.cpp \
mainForm.cpp \
padForm.cpp \
pickForm.cpp \
refdishesForm.cpp \
refuseForm.cpp \
dailyreportForm.cpp \
Model/dailyObject.cpp \
DTools/simProcOrderDB.cpp \
DTools/printSumBillPosDB.cpp \
DTools/getCaboxAReAuth.cpp \
Model/couponsObject.cpp \
Model/singleProductObject.cpp \
Model/paymentObject.cpp \
DTools/printCupStickPosDB.cpp \
DTools/printMsgQueueDB.cpp \
Model/PromotionItemObject.cpp \
DTools/PrintOrderPromotionDB.cpp
RejectForm.cpp \
settingForm.cpp
HEADERS += \
mainForm.h \
preDefine.h \
alertForm.h \
DTools/configManger.h \
Control/flowControl.h \
LocalServer/loaclHttpServer.h \
Network/billSocket.h \
Control/SocketCommunicate.h \
DTools/clickedLineEdit.h \
DTools/configManger.h \
DTools/dataManger.h \
Model/orderObject.h \
DTools/dump.h \
DTools/getCaboxAReAuth.h \
DTools/headframe.h \
DTools/printCupStickPosDB.h \
DTools/printMsgQueueDB.h \
DTools/PrintOrderPromotionDB.h \
DTools/printSumBillPosDB.h \
DTools/simProcOrderDB.h \
DTools/sysTray.h \
DTools/util.h \
SslOperate/MacTool.h \
SslOperate/CertificateOperate.h \
SslOperate/AlgorithmProcess.h \
JQLibrary/include/JQHttpServer.h \
JQLibrary/include/JQNet.h \
LocalServer/loaclHttpServer.h \
Model/baseObject.h \
Model/cashierObject.h \
Model/couponsObject.h \
Model/dailyObject.h \
Model/deliverObject.h \
Model/dishesObject.h \
DTools/util.h \
settingForm.h \
floatForm.h \
detailForm.h \
DTools/sysTray.h \
padForm.h \
DTools/clickedLineEdit.h \
RejectForm.h \
DTools/headframe.h \
Model/orderObject.h \
Model/paymentObject.h \
Model/productObject.h \
Model/PromotionItemObject.h \
Model/singleProductObject.h \
Network/billSocket.h \
Network/ThreadSocket.h \
QsLog/QsLog.h \
QsLog/QsLogDest.h \
QsLog/QsLogDestConsole.h \
QsLog/QsLogDestFile.h \
QsLog/QsLogDestFunctor.h \
QsLog/QsLogDisableForThisFile.h \
QsLog/QsLogLevel.h \
alertForm.h \
bstatusForm.h \
bstatusItem.h \
dailyreportForm.h \
detailForm.h \
dishesForm.h \
dishesItem.h \
disTabWdg.h \
floatForm.h \
mainForm.h \
padForm.h \
pickForm.h \
preDefine.h \
refdishesForm.h \
refuseForm.h \
dailyreportForm.h \
Model/dailyObject.h \
DTools/dump.h \
DTools/simProcOrderDB.h \
DTools/printSumBillPosDB.h \
DTools/getCaboxAReAuth.h \
Model/couponsObject.h \
Model/singleProductObject.h \
Model/paymentObject.h \
DTools/printCupStickPosDB.h \
DTools/printMsgQueueDB.h \
Model/PromotionItemObject.h \
DTools/PrintOrderPromotionDB.h
RejectForm.h \
settingForm.h \
FORMS += mainForm.ui \
alertForm.ui \
......
......@@ -6,6 +6,7 @@
#include "QsLog.h"
#include "preDefine.h"
#include "Control/flowControl.h"
#include "Control/SocketCommunicate.h"
#include "floatForm.h"
#include "DTools/configManger.h"
#include <windows.h>
......@@ -101,6 +102,10 @@ int main(int argc, char *argv[])
FlowControl::GetInstance().moveToThread(&workThread);
workThread.start();
// 等插件正常登录成功后,才能发起 长连接业务;
//SocketCommunicate sockCommunicate;
//sockCommunicate.moveToThread(&tcpThread, true);
FloatForm f;
MainForm w;
QObject::connect(&w, &MainForm::showFloatForm, &f, &FloatForm::onShow);
......@@ -116,6 +121,9 @@ int main(int argc, char *argv[])
QObject::connect(&w, &MainForm::startRemind, &f, &FloatForm::onStartRemind);
QObject::connect(&w, &MainForm::stopRemind, &f, &FloatForm::onStopRemind);
QObject::connect(&f, &FloatForm::showMainForm, &w, &MainForm::show);
//QObject::connect(&FlowControl::GetInstance(), &FlowControl::doLoginSuccess, &sockCommunicate, &SocketCommunicate::onFlowControlLoginSuccess);
w.MyShow();
return a.exec();
......
......@@ -11,7 +11,6 @@
#include <QProcess>
#include <QThread>
extern QThread tcpThread;
extern QThread workThread;
MainForm::MainForm(QWidget *parent) :
......
......@@ -34,7 +34,8 @@
//#define APP_VERSION "2.2020.12.18"
//#define APP_VERSION "2.2021.1.11"
//#define APP_VERSION "2.2021.2.22"
#define APP_VERSION "2.2021.2.26"
//#define APP_VERSION "2.2021.2.26"
#define APP_VERSION "2.2021.4.12"
//修正版本号时,切记修正 FmTakeout.rc 中的版本号
......@@ -80,7 +81,6 @@
#define INI_HTTPSERVERPORT "HttpServer/port"
#define INI_PUSHSERVERPORT "PushServer/port"
#define JSON_REQTYPE "reqtype"
#define JSON_CURRENTUSER "currentUser"
#define JSON_STOREID "storeId"
......@@ -164,6 +164,34 @@
#define JSON_FAILEDSUM "fail_total_fee"
#define JSON_DAILYSUMMARYS "daily_summarys"
// PosAgent : Tcp Socket Begin;
#define INI_POSAGENTSVR_PORT "PosAgentSvr/port"
#define INI_POSAGENTSVR_DOMAIN_NAME "PosAgentSvr/domainName"
#define JSON_TCP_STA_RST "ok"
#define JSON_TCP_STA_CODE "code"
// 长连接Post请求超时 设置为 30s
#define SOCKET_POST_TIMEOUT 30000
// 长连接Get请求超时 设置为 10s
#define SOCKET_GET_TIMEOUT 10000
// ssl证书相关宏;
#define DES3_KEY_SIZE 24
#define MAX_RSA_KEY_LEN 2048
#define MAX_BUF_LEN 25600
#define MAX_SIGN_LEN 256
#define CCO_ADES3_KEY "ABCD@#9876DFSAAWKLDEOPDD"
#define EC_ADES3_KEY "DDDDEEEE45LPODDCXZZLKDDO"
#define AES_KEY_PRT "1JG23G12Y12V123G123F1DI1"
#define CONF_VALUE_URL "all/url"
#define CONF_VALUE_URL_CRET "all/creturl"
#define CRET_FILE_NAME "simphonyclient.p12"
#define JSON_KEY_MAC "mac"
#define JSON_KEY_SIGN "sign"
#define JSON_KEY_STATUS "statusCode"
#define JSON_KEY_SERPBLICKEY "serverPublicKey"
#define JSON_KEY_CLIENTPRIKEY "clientPrivateKey"
// Ssl End;
#define MAXPUTTIMES 4
......@@ -220,8 +248,6 @@
#define REMIND_COMPLAINT_ORDER 12 // 客诉单:最多且重要的case;
#define REMIND_SIM_ORDERLIST_NOEMPTY 50 // Simphony有效队列中存在有订单待录入:就需要闪烁提醒;
// 服务器返回正确值
#define JSON_STATUSCODE_OK 100
// 默认拉取订单的间隔时间
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment