Rabbit Remote Control 0.1.0-bate9
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)
15 : QEvent((QEvent::Type)TERMWIDGET_EVENT_TYPE)
16 , m_Data(data, len)
17 {
18 }
19
20 QByteArray m_Data;
21};
22
23CBackendSSH::CBackendSSH(COperateSSH *pOperate)
24 : CBackend(pOperate)
25 , m_pOperate(pOperate)
26 , m_pPara(nullptr)
27 , m_pChannelSSH(nullptr)
28 , m_pTerminal(nullptr)
29{
30 qDebug(log) << Q_FUNC_INFO;
31 m_pPara = qobject_cast<CParameterTerminalSSH*>(pOperate->GetParameter());
32 m_pTerminal = qobject_cast<QTermWidget*>(m_pOperate->GetViewer());
33}
34
35CBackendSSH::~CBackendSSH()
36{
37 qDebug(log) << Q_FUNC_INFO;
38}
39
40CBackendSSH::OnInitReturnValue CBackendSSH::OnInit()
41{
42 bool check = false;
43 if(!m_pTerminal)
44 {
45 Q_ASSERT(m_pTerminal);
46 return OnInitReturnValue::Fail;
47 }
48
49 m_pChannelSSH = new CChannelSSHTerminal(this, &m_pPara->m_SSH);
50 if(!m_pChannelSSH) {
51 qCritical(log) << "new CChannelSSH fail";
52 return OnInitReturnValue::Fail;
53 }
54
55 check = connect(m_pChannelSSH, &CChannelSSHTerminal::sigSecurityLevel,
57 Q_ASSERT(check);
58
59 check = connect(m_pChannelSSH, &CChannelSSHTerminal::sigConnected,
60 this, [&](){
61 if(!m_pPara->GetCommands().isEmpty()) {
62 foreach (auto c, m_pPara->GetCommands()) {
63 emit m_pTerminal->sendData(c.toStdString().c_str(), c.length());
64 emit m_pTerminal->sendData("\r", 1);
65 }
66 }
67 emit sigRunning();
68 });
69 Q_ASSERT(check);
70 check = connect(m_pChannelSSH, &CChannelSSHTerminal::readyRead,
71 this, [&](){
72 char* buf = nullptr;
73 qint64 nLen = 0;
74 qint64 nRet = 0;
75 if(m_pChannelSSH) {
76 nLen = m_pChannelSSH->bytesAvailable();
77 if(nLen <= 0) {
78 qDebug(log) << "No data";
79 return;
80 }
81 buf = new char[nLen];
82 nRet = m_pChannelSSH->read(buf, nLen);
83 }
84 if(m_pTerminal && nRet > 0) {
85 QByteArray data(buf, nRet);
86 if(m_pOperate) {
87 emit m_pOperate->sigReceiveData(data);
88 if(m_pOperate->GetStats())
89 m_pOperate->GetStats()->AddReceives(nRet);
90 }
91 } else
92 qCritical(log) << "The m_pTerminal is nullptr or nRet <= 0";
93 //qDebug(log) << "Write data to QTermWidget: " << nRet << nLen;
94 if(buf)
95 delete []buf;
96 });
97 Q_ASSERT(check);
98 check = connect(m_pTerminal, &QTermWidget::sendData,
99 this, [&](const char* data, int len){
100 QEventTerminal* d = new QEventTerminal((char*)data, len);
101 QCoreApplication::postEvent(this, d);
102 if(m_pOperate && m_pOperate->GetStats())
103 m_pOperate->GetStats()->AddSends(len);
104 m_pChannelSSH->WakeUp();
105 }, Qt::DirectConnection);
106 Q_ASSERT(check);
107
108 m_pChannelSSH->SetSize(m_pTerminal->screenLinesCount(),
109 m_pTerminal->screenColumnsCount());
110
111 if(!m_pChannelSSH->open(QIODevice::ReadWrite)) {
112 qCritical(log) << "Open ssh channel fail";
113 return OnInitReturnValue::Fail;
114 }
115
116 m_pTerminal->startTerminalTeletype();
117
118 return OnInitReturnValue::UseOnProcess;
119}
120
122{
123 int nRet = 0;
124 if(m_pChannelSSH)
125 nRet = m_pChannelSSH->OnProcess(DEFAULT_TIMEOUT);
126 return nRet;
127}
128
130{
131 int nRet = 0;
132
133 if(m_pChannelSSH) {
134 m_pChannelSSH->close();
135 m_pChannelSSH->deleteLater();
136 m_pChannelSSH = nullptr;
137 }
138 return nRet;
139}
140
141bool CBackendSSH::event(QEvent *event)
142{
143 switch (event->type()) {
144 case TERMWIDGET_EVENT_TYPE:
145 {
146 QEventTerminal *d = (QEventTerminal*)event;
147 if(m_pChannelSSH && d->m_Data.length() > 0) {
148 qint64 nRet = m_pChannelSSH->write(d->m_Data.data(), d->m_Data.length());
149 Q_UNUSED(nRet);
150 //qDebug(log) << "Write data to ssh channel:" << nRet << d->m_Data.length();
151 } else {
152 //qDebug(log) << "m_pChannelSSH && len <= 0";
153 }
154 break;
155 }
156 default:
157 return QObject::event(event);
158 }
159
160 event->accept();
161 return true;
162}
163
165{
166 if(m_pChannelSSH)
167 m_pChannelSSH->WakeUp();
168 return 0;
169}
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 sigSecurityLevel(CSecurityLevel::Levels level)
Triggered when the security level changes.
void sigConnected()
emit when the channel is connected.
void sigSecurityLevel(CSecurityLevel::Levels level)
Triggered when the security level changes.
virtual CParameterTerminalBase * GetParameter() const
Get parameters.