Rabbit Remote Control 0.1.0-alpha
Loading...
Searching...
No Matches
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::sigConnected,
55 this, [&](){
56 if(!m_pPara->GetCommands().isEmpty()) {
57 foreach (auto c, m_pPara->GetCommands()) {
58 emit m_pTerminal->sendData(c.toStdString().c_str(), c.length());
59 emit m_pTerminal->sendData("\r", 1);
60 }
61 }
62 emit sigRunning();
63 });
64 Q_ASSERT(check);
65 check = connect(m_pChannelSSH, &CChannelSSHTerminal::readyRead,
66 this, [&](){
67 char* buf = nullptr;
68 qint64 nLen = 0;
69 qint64 nRet = 0;
70 if(m_pChannelSSH) {
71 nLen = m_pChannelSSH->bytesAvailable();
72 if(nLen <= 0) {
73 qDebug(log) << "No data";
74 return;
75 }
76 buf = new char[nLen];
77 nRet = m_pChannelSSH->read(buf, nLen);
78 }
79 if(m_pTerminal && nRet > 0) {
80 QByteArray data(buf, nRet);
81 if(m_pOperate) {
82 emit m_pOperate->sigReceiveData(data);
83 if(m_pOperate->GetStats())
84 m_pOperate->GetStats()->AddReceives(nRet);
85 }
86 } else
87 qCritical(log) << "The m_pTerminal is nullptr or nRet <= 0";
88 //qDebug(log) << "Write data to QTermWidget: " << nRet << nLen;
89 if(buf)
90 delete []buf;
91 });
92 Q_ASSERT(check);
93 check = connect(m_pTerminal, &QTermWidget::sendData,
94 this, [&](const char* data, int len){
95 QEventTerminal* d = new QEventTerminal((char*)data, len);
96 QCoreApplication::postEvent(this, d);
97 if(m_pOperate && m_pOperate->GetStats())
98 m_pOperate->GetStats()->AddSends(len);
99 m_pChannelSSH->WakeUp();
100 }, Qt::DirectConnection);
101 Q_ASSERT(check);
102
103 m_pChannelSSH->SetSize(m_pTerminal->screenLinesCount(),
104 m_pTerminal->screenColumnsCount());
105
106 if(!m_pChannelSSH->open(QIODevice::ReadWrite)) {
107 qCritical(log) << "Open ssh channel fail";
108 return OnInitReturnValue::Fail;
109 }
110
111 m_pTerminal->startTerminalTeletype();
112
113 return OnInitReturnValue::UseOnProcess;
114}
115
117{
118 int nRet = 0;
119 if(m_pChannelSSH)
120 nRet = m_pChannelSSH->OnProcess(DEFAULT_TIMEOUT);
121 return nRet;
122}
123
125{
126 int nRet = 0;
127
128 if(m_pChannelSSH) {
129 m_pChannelSSH->close();
130 m_pChannelSSH->deleteLater();
131 m_pChannelSSH = nullptr;
132 }
133 return nRet;
134}
135
136bool CBackendSSH::event(QEvent *event)
137{
138 switch (event->type()) {
139 case TERMWIDGET_EVENT_TYPE:
140 {
141 QEventTerminal *d = (QEventTerminal*)event;
142 if(m_pChannelSSH && d->m_Data.length() > 0) {
143 qint64 nRet = m_pChannelSSH->write(d->m_Data.data(), d->m_Data.length());
144 Q_UNUSED(nRet);
145 //qDebug(log) << "Write data to ssh channel:" << nRet << d->m_Data.length();
146 } else {
147 //qDebug(log) << "m_pChannelSSH && len <= 0";
148 }
149 break;
150 }
151 default:
152 return QObject::event(event);
153 }
154
155 event->accept();
156 return true;
157}
158
160{
161 if(m_pChannelSSH)
162 m_pChannelSSH->WakeUp();
163 return 0;
164}
virtual int OnProcess() override
Specific operation processing of plug-in.
virtual OnInitReturnValue OnInit() override
Initialization.
virtual int WakeUp() override
Wake up.
virtual int OnClean() override
Clean.
Backend interface.
Definition Backend.h:42
void sigRunning()
Emitted when the plugin is successfully started.
void sigConnected()
emit when the channel is connected.
virtual CParameterTerminalBase * GetParameter()
Get parameters.