玉兔远程控制 0.1.0-bate8
载入中...
搜索中...
未找到
BackendSSH.cpp
1// Author: Kang Lin <kl222@126.com>
2
3#include "BackendSSH.h"
4#include <QLoggingCategory>
5#include <QCoreApplication>
6
7static Q_LOGGING_CATEGORY(log, "Plugin.SSH.Backend")
8
9#define TERMWIDGET_EVENT_TYPE (QEvent::User + 1976)
10
11class QEventTerminal: public QEvent
12{
13public:
14 explicit QEventTerminal(char* data, int len) : QEvent((QEvent::Type)TERMWIDGET_EVENT_TYPE)
15 , m_Data(data, len)
16 {
17 }
18
19 QByteArray m_Data;
20};
21
22CBackendSSH::CBackendSSH(COperateSSH *pOperate)
23 : CBackend(pOperate)
24 , m_pOperate(pOperate)
25 , m_pPara(nullptr)
26 , m_pChannelSSH(nullptr)
27 , m_pTerminal(nullptr)
28{
29 qDebug(log) << Q_FUNC_INFO;
30 m_pPara = qobject_cast<CParameterTerminalSSH*>(pOperate->GetParameter());
31 m_pTerminal = qobject_cast<QTermWidget*>(m_pOperate->GetViewer());
32}
33
34CBackendSSH::~CBackendSSH()
35{
36 qDebug(log) << Q_FUNC_INFO;
37}
38
39CBackendSSH::OnInitReturnValue CBackendSSH::OnInit()
40{
41 bool check = false;
42 if(!m_pTerminal)
43 {
44 Q_ASSERT(m_pTerminal);
45 return OnInitReturnValue::Fail;
46 }
47
48 m_pChannelSSH = new CChannelSSHTerminal(this, &m_pPara->m_SSH);
49 if(!m_pChannelSSH) {
50 qCritical(log) << "new CChannelSSH fail";
51 return OnInitReturnValue::Fail;
52 }
53
54 check = connect(m_pChannelSSH, &CChannelSSHTerminal::sigSecurityLevel,
56 Q_ASSERT(check);
57
58 check = connect(m_pChannelSSH, &CChannelSSHTerminal::sigConnected,
59 this, [&](){
60 if(!m_pPara->GetCommands().isEmpty()) {
61 foreach (auto c, m_pPara->GetCommands()) {
62 emit m_pTerminal->sendData(c.toStdString().c_str(), c.length());
63 emit m_pTerminal->sendData("\r", 1);
64 }
65 }
66 emit sigRunning();
67 });
68 Q_ASSERT(check);
69 check = connect(m_pChannelSSH, &CChannelSSHTerminal::readyRead,
70 this, [&](){
71 char* buf = nullptr;
72 qint64 nLen = 0;
73 qint64 nRet = 0;
74 if(m_pChannelSSH) {
75 nLen = m_pChannelSSH->bytesAvailable();
76 if(nLen <= 0) {
77 qDebug(log) << "No data";
78 return;
79 }
80 buf = new char[nLen];
81 nRet = m_pChannelSSH->read(buf, nLen);
82 }
83 if(m_pTerminal && nRet > 0) {
84 QByteArray data(buf, nRet);
85 if(m_pOperate) {
86 emit m_pOperate->sigReceiveData(data);
87 if(m_pOperate->GetStats())
88 m_pOperate->GetStats()->AddReceives(nRet);
89 }
90 } else
91 qCritical(log) << "The m_pTerminal is nullptr or nRet <= 0";
92 //qDebug(log) << "Write data to QTermWidget: " << nRet << nLen;
93 if(buf)
94 delete []buf;
95 });
96 Q_ASSERT(check);
97 check = connect(m_pTerminal, &QTermWidget::sendData,
98 this, [&](const char* data, int len){
99 QEventTerminal* d = new QEventTerminal((char*)data, len);
100 QCoreApplication::postEvent(this, d);
101 if(m_pOperate && m_pOperate->GetStats())
102 m_pOperate->GetStats()->AddSends(len);
103 m_pChannelSSH->WakeUp();
104 }, Qt::DirectConnection);
105 Q_ASSERT(check);
106
107 m_pChannelSSH->SetSize(m_pTerminal->screenLinesCount(),
108 m_pTerminal->screenColumnsCount());
109
110 if(!m_pChannelSSH->open(QIODevice::ReadWrite)) {
111 qCritical(log) << "Open ssh channel fail";
112 return OnInitReturnValue::Fail;
113 }
114
115 m_pTerminal->startTerminalTeletype();
116
117 return OnInitReturnValue::UseOnProcess;
118}
119
121{
122 int nRet = 0;
123 if(m_pChannelSSH)
124 nRet = m_pChannelSSH->OnProcess(DEFAULT_TIMEOUT);
125 return nRet;
126}
127
129{
130 int nRet = 0;
131
132 if(m_pChannelSSH) {
133 m_pChannelSSH->close();
134 m_pChannelSSH->deleteLater();
135 m_pChannelSSH = nullptr;
136 }
137 return nRet;
138}
139
140bool CBackendSSH::event(QEvent *event)
141{
142 switch (event->type()) {
143 case TERMWIDGET_EVENT_TYPE:
144 {
145 QEventTerminal *d = (QEventTerminal*)event;
146 if(m_pChannelSSH && d->m_Data.length() > 0) {
147 qint64 nRet = m_pChannelSSH->write(d->m_Data.data(), d->m_Data.length());
148 Q_UNUSED(nRet);
149 //qDebug(log) << "Write data to ssh channel:" << nRet << d->m_Data.length();
150 } else {
151 //qDebug(log) << "m_pChannelSSH && len <= 0";
152 }
153 break;
154 }
155 default:
156 return QObject::event(event);
157 }
158
159 event->accept();
160 return true;
161}
162
164{
165 if(m_pChannelSSH)
166 m_pChannelSSH->WakeUp();
167 return 0;
168}
virtual int OnProcess() override
具体操作处理
virtual OnInitReturnValue OnInit() override
初始化
virtual int WakeUp() override
Wake up.
virtual int OnClean() override
清理
后端接口。它由协议插件实现。 它默认启动一个定时器来开启一个非 Qt 事件循环(就是普通的循环处理)。 详见: Start()、 slotTimeOut()、 OnProcess() 。 当然,它仍然支...
Definition Backend.h:42
void sigRunning()
当插件开始成功后触发。仅由插件触发
void sigSecurityLevel(CSecurityLevel::Levels level)
当安全级别改变时触发
void sigConnected()
emit when the channel is connected.
void sigSecurityLevel(CSecurityLevel::Levels level)
当安全级别改变时触发
virtual CParameterTerminalBase * GetParameter() const
Get parameters