此篇是1-4 《半导体》的会和处啦,我们有了协议库,也有了通讯库,这不得快乐的玩一把~
一、先创建一个从站,也就是我们的Equipment端
QT -= gui
CONFIG += c++11 console
CONFIG -= app_bundle
CONFIG += no_debug_release # 不会生成debug 和 release 文件目录
DESTDIR = $${PWD}/../../deploy/bin
OBJECTS_DIR = $${PWD}/../../build/sample/Equipment/tmp/obj
MOC_DIR = $${PWD}/../../build/sample/Equipment/tmp/obj
UI_DIR = $${PWD}/../../build/sample/Equipment/tmp/obj
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
win32:CONFIG(release, debug|release){
win32: LIBS += -L$$PWD/../../deploy/lib/Release -lJC_Commucation
win32: LIBS += -L$$PWD/../../deploy/lib/Release -lJcHsms
}
else:win32:CONFIG(debug, debug|release){
win32: LIBS += -L$$PWD/../../deploy/lib/Debug -lJC_Commucation
win32: LIBS += -L$$PWD/../../deploy/lib/Debug -lJcHsms
}
INCLUDEPATH += $$PWD/../../deploy/include
DEPENDPATH += $$PWD/../../deploy/include
#include <QCoreApplication>
#include <QDebug>
#include <iostream>
#include <QByteArray>
#include <string>
#include <QTimer>
using namespace std;
#include "../../SemiGeneralStandardLibrary/JcGemSecsLibrary/Commucation/commucation.h"
#include "../../SemiGeneralStandardLibrary/JcGemSecsLibrary/Driver/JcHsms/hsmsincludes.h"
/**
* @brief OnStateChanged 连接状态改变回调事件
* @param pComm
* @param nState 0: 连接 1:断开连接
* @param cSocket
*/
void OnStateChanged(ICommucation* pComm, __int32 nState, void *cSocket)
{
SOCKET* c = (SOCKET*) cSocket;
std::string str = nState == 0 ? std::string(" connected to ") : std::string(" disconnected from ");
std::cout << "[OnStateChanged Event] : " << c << str << (void*)pComm << std::endl;
}
/// 无符号字节数组转16进制字符串
std::string bytesToHexString(const char* bytes,const int length)
{
if (bytes == NULL) return "";
std::string buff;
const int len = length;
for (int j = 0; j < len; j++) {
int high = bytes[j]/16, low = bytes[j]%16;
buff += (high<10) ? ('0' + high) : ('a' + high - 10);
buff += (low<10) ? ('0' + low) : ('a' + low - 10);
buff += " ";
}
return buff;
}
/*!
* \brief onMessageRecived 接收到消息的回调事件
* \param pComm
* \param recvedMsg
* \param cSocket
*/
void onMessageRecived(ICommucation* pComm, char* message,int iRecvSize, void * cSocket)
{
JcHsms ho(0,QString("JC Gem/Secs Test"),QString("1.0.1"));
HsmsMessage hmsg = ho.interpretMessage(QByteArray(message,iRecvSize));
HsmsMessage rsp = hmsg.dispatch();
QByteArray responseByteArray = rsp.toByteArray();
QString smlString = rsp.SmlString();
string rHexString = bytesToHexString(message,iRecvSize);
// qDebug().noquote() << "recv message ==> " << QString::fromStdString(rHexString);
// qDebug().noquote() << "send message ==> " << responseByteArray.toHex(' ');
qDebug().noquote() << QString("RECV S%1F%2 SystemBytes=%3").arg(QString::number((int)hmsg.GetHeader().Getstream()),
QString::number((int)hmsg.GetHeader().Getfunction()),
QString::number(hmsg.GetHeader().GetSystemBytes()));
qDebug().noquote() << hmsg.SmlString();
qDebug().noquote() << QString("SEND S%1F%2 SystemBytes=%3").arg(QString::number((int)rsp.GetHeader().Getstream()),
QString::number((int)rsp.GetHeader().Getfunction()),
QString::number( rsp.GetHeader().GetSystemBytes()));
qDebug().noquote() << rsp.SmlString();
int slen = responseByteArray.length();
if(slen){
int rslen = pComm->SendData(*((SOCKET*) cSocket),responseByteArray.data(),responseByteArray.length());
if(rslen <= 0) {
qDebug() << "Send Reply Message failed.";
}
}
}
/*!
* \brief OnAsyncMsgTimeout 消息超时
* \param pComm
* \param nTransfer 消息ID
* \param pClientData
*/
void OnAsyncMsgTimeout(ICommucation* pComm, __int32 nTransfer, void *pClientData)
{
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
const char* comm_dll_version = JC_CommDllVersion();
qDebug() << comm_dll_version;
/// [1] 建立通讯连接(以单个通讯连接对象为例)
CommucationParam setting;
EthernetCommucationParam eParam = {
45000,10000,5000,10000,5000, /* timeout */
0 /* PASSIVE */,
5555, /* port */
1 /* DEVID */,
"Device Host",
"127.0.0.1"
};
SerialCommucationParam sParam = {2,9600,'N',8,1};
setting.eParam = eParam;
setting.sParam = sParam;
/// 创建通讯对象
ICommucation* o = NULL;
o = JC_CreatCommObject(TcpServer,setting);
/// 为通讯连接对象注册事件回调
JC_SetEventCallBack(o,onMessageRecived,OnStateChanged,OnAsyncMsgTimeout);
/// 启动监听
JC_RunListenThread(o);
/// 测试修改 Selected Equipment Status Data(SSD),线程安全
float x[] = {12.3025,55.12,56.478,63.54};
QTimer timer;
timer.setInterval(300);
QObject::connect(&timer,&QTimer::timeout,[&x](){
static int i = 0;
HsmsDataManager::Instance().UpdateSsdMap(1022,HsmsDataManager::ESD{F4,QVariant(x[++i%4])});
});
timer.start();
QObject::connect(qApp,&QCoreApplication::aboutToQuit,[&o](){
/// 释放通讯连接对象,结束通讯连接
JC_ReleaseCommObject(o);
});
return a.exec();
}
二、创建一个主站,也就是我们的Host端
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
DESTDIR = $${PWD}/../../deploy/bin
OBJECTS_DIR = $${PWD}/../../build/sample/Host/tmp/obj
MOC_DIR = $${PWD}/../../build/sample/Host/tmp/obj
UI_DIR = $${PWD}/../../build/sample/Host/tmp/obj
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mcwidget.cpp
HEADERS += \
mcwidget.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
win32:CONFIG(release, debug|release){
win32: LIBS += -L$$PWD/../../deploy/lib/Release -lJC_Commucation
win32: LIBS += -L$$PWD/../../deploy/lib/Release -lJcHsms
}
else:win32:CONFIG(debug, debug|release){
win32: LIBS += -L$$PWD/../../deploy/lib/Debug -lJC_Commucation
win32: LIBS += -L$$PWD/../../deploy/lib/Debug -lJcHsms
}
INCLUDEPATH += $$PWD/../../deploy/include
DEPENDPATH += $$PWD/../../deploy/include
// mcwidget.h
#ifndef MCWIDGET_H
#define MCWIDGET_H
#include <QWidget>
#include <QTcpServer>
#include <QLabel>
#include <QHBoxLayout>
#include <QTimer>
#include <iostream>
#include <QDebug>
#include <string>
#include <QByteArray>
#include <QList>
#include "../../SemiGeneralStandardLibrary/JcGemSecsLibrary/Commucation/commucation.h"
#include "../../SemiGeneralStandardLibrary/JcGemSecsLibrary/Driver/JcHsms/hsmsincludes.h"
class TransHelper: public QObject
{
Q_OBJECT
public:
TransHelper(){
qRegisterMetaType<HsmsMessage>("qRegisterMetaType");
//qRegisterMetaType<HsmsMessage>("qRegisterMetaType&");
}
void RecivedMsgObject(HsmsMessage msg){
emit RecivedMsgObjectSig(msg);
}
signals:
void RecivedMsgObjectSig(HsmsMessage);
};
class MyLabel : public QWidget
{
Q_OBJECT
public:
MyLabel(QString labName,QString labval,QWidget* parent = nullptr)
:m_labname(labName),m_labVal(labval),QWidget(parent){
m_nameLab = new QLabel(m_labname);
m_valLab = new QLabel(m_labVal);
m_nameLab->setFixedWidth(200);
m_valLab->setFixedWidth(100);
QHBoxLayout* ly = new QHBoxLayout;
ly->addWidget(m_nameLab);
ly->addWidget(m_valLab);
ly->setContentsMargins(0,0,0,0);
this->setContentsMargins(0,0,0,0);
setLayout(ly);
}
void setValue(QString val)
{
m_labVal = val;
m_valLab->setText(m_labVal);
}
private:
QString m_labname;
QString m_labVal;
QLabel* m_nameLab;
QLabel* m_valLab;
};
class McWidget : public QWidget
{
Q_OBJECT
public:
McWidget(QWidget *parent = nullptr);
~McWidget();
void initUi();
static TransHelper transhelper;
private:
ICommucation* o = NULL;
QTimer linktesttimer;
QTimer s1f3Rqtimer;
QList<MyLabel*> llabs;
};
#endif // MCWIDGET_H
// mcwidget.cpp
#include "mcwidget.h"
#include <QDebug>
#include <functional>
#include <QVBoxLayout>
TransHelper McWidget::transhelper;
/**
* @brief OnStateChanged 连接状态改变回调事件
* @param pComm
* @param nState 0: 连接 1:断开连接
* @param cSocket
*/
void OnStateChanged(ICommucation* pComm, __int32 nState, void *cSocket)
{
SOCKET* c= (SOCKET*) cSocket;
std::string str = nState == 0 ? std::string(" connected to ") : std::string(" disconnected from ");
std::cout << "[OnStateChanged ] : " << c << str << (void*)pComm << str << std::endl;
}
/*!
* \brief onMessageRecived 接收到消息的回调事件
* \param pComm
* \param recvedMsg
* \param cSocket
*/
void onMessageRecived(ICommucation* pComm,char* recvedMsg, int iRecvsize,void * cSocket)
{
SOCKET* c= (SOCKET*) cSocket;
// std::cout << "[onMessageRecived ] : " << (void*)pComm << " <-- " << c << " : "
// << recvedMsg << " len=" << iRecvsize << std::endl;
/// 通过gemsecs的协议进行解析和应答
JcHsms ho(0,QString("JC Gem/Secs Test"),QString("1.0.1"));
HsmsMessage hmsg = ho.interpretMessage(QByteArray(recvedMsg,iRecvsize));
if(hmsg.GetHeader().Getstream() == 0x1
&& hmsg.GetHeader().Getfunction() == 0x4)
{ // S1F4
McWidget::transhelper.RecivedMsgObject(hmsg);
}
}
/*!
* \brief OnAsyncMsgTimeout 消息超时
* \param pComm
* \param nTransfer 消息ID
* \param pClientData
*/
void OnAsyncMsgTimeout(ICommucation* pComm, __int32 nTransfer, void *pClientData)
{
qDebug() << QStringLiteral("同步发送请求消息超时");
}
McWidget::McWidget(QWidget *parent)
: QWidget(parent)
{
initUi();
CommucationParam setting;
EthernetCommucationParam eParam = {
45000,10000,5000,10000,5000, /* timeout */
0 /* PASSIVE */,
5555, /* port */
1 /* DEVID */,
"Device Host",
"127.0.0.1"
};
SerialCommucationParam sParam = {2,9600,'N',8,1};
setting.eParam = eParam;
setting.sParam = sParam;
o = JC_CreatCommObject(TcpClient,setting);
/// 注册回调事件
JC_SetEventCallBack(o,onMessageRecived,OnStateChanged,OnAsyncMsgTimeout);
/// 启动监听
JC_RunListenThread(o);
/// 发送 select.req 请求
JcHsms ho(0,QString("JC Gem/Secs Test"),QString("1.0.1"));
HsmsMessage srmsg = HsmsMessageDispatcher::selectReq(ho.unique_sessionID);
QByteArray srbytes = srmsg.toByteArray();
std::string rbuf;
bool ok = o->SendSyncMessage(srbytes.toStdString(),true,rbuf,10);
std::cout << "recv reply buf :" << rbuf << std::endl;
qDebug("send status:%s\n",ok ? "success" : "failed");
std::function<void()> flinktest = [=](){
HsmsMessage lktestMgr = HsmsMessageDispatcher::linktestReq();
QByteArray lktestBytes = lktestMgr.toByteArray();
#if 0 /// 同步发送/接收消息
std::string rbuf;
bool ok = o->SendSyncMessage(lktestBytes.toStdString(),true,rbuf,10);
std::cout << "recv reply buf :" << rbuf << std::endl;
qDebug("send status:%s\n",ok ? "success" : "failed");
#else
/// 异步发送接收消息(消息接收回调事件)
o->SendData(0,lktestBytes.constData(),lktestBytes.length());
#endif
};
/// 立即执行一次
if(ok) flinktest();
/// 定时触发
linktesttimer.setInterval(10000);// 10s
QObject::connect(&linktesttimer,&QTimer::timeout,flinktest);
linktesttimer.start();
/// 定时发送S1F3 请求最新SSD
std::function<void()> fs1f3Rq = [=,&ho]()
{
HsmsMessage s1f3ReqtMgr = HsmsMessageDispatcher::S1F3(ho.unique_sessionID);
QByteArray s1f3ReqBytes = s1f3ReqtMgr.toByteArray();
#if 0 /// 同步发送/接收消息
std::string rbuf;
bool ok = o->SendSyncMessage(lktestBytes.toStdString(),true,rbuf,10);
std::cout << "recv reply buf :" << rbuf << std::endl;
qDebug("send status:%s\n",ok ? "success" : "failed");
#else
/// 异步发送接收消息(消息接收回调事件)
o->SendData(0,s1f3ReqBytes.constData(),s1f3ReqBytes.length());
#endif
};
s1f3Rqtimer.setInterval(30);
QObject::connect(&s1f3Rqtimer,&QTimer::timeout,fs1f3Rq);
s1f3Rqtimer.start();
/// S1F4 Recived
connect(&transhelper,&TransHelper::RecivedMsgObjectSig,[=](HsmsMessage hm){
Secs2Item item = hm.GetItem();
QVector<Secs2Item> v = item.GetItems();
if(v.isEmpty() || v.length() != 23 ) return;
llabs[0]->setValue(QString::number( v[0].toInt32().first()));
for(int i =1;i<=3;++i){ // bool
llabs[i]->setValue(QString::number(v[i].toBoolean().first()));
}
for(int i =4;i<=20;++i){ // int32
llabs[i]->setValue(QString::number(v[i].toInt32().first()));
}
for(int i = 21;i <= 22;++i){ // float
llabs[i]->setValue(QString::number(v[i].toFloat().first()));
}
});
}
McWidget::~McWidget()
{
}
void McWidget::initUi()
{
llabs.clear();
QVBoxLayout* vly = new QVBoxLayout;
for(int i = 1001;i <= 1023; ++i){
MyLabel* labptr = new MyLabel(QString::number(i),QString("0"));
llabs.append(labptr);
labptr->setFixedHeight(30);
labptr->setFixedWidth(300);
vly->addWidget(labptr);
}
setLayout(vly);
}
// main.cpp
#include "mcwidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
McWidget w;
w.show();
return a.exec();
}
三、演示结果
perfect!!!