plptools
Loading...
Searching...
No Matches
socketchannel.cc
Go to the documentation of this file.
1/*
2 * This file is part of plptools.
3 *
4 * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com>
5 * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * along with this program; if not, see <https://www.gnu.org/licenses/>.
19 *
20 */
21#include "config.h"
22
23#include <stdio.h>
24#include <stdlib.h>
25
26#include "ncp_log.h"
27#include "ncp.h"
28#include "tcpsocket.h"
29#include "rfsv.h"
30#include "socketchannel.h"
31
32using namespace std;
33
35: channel(ncp)
36, socket_(socket) {
37 registerName_ = nullptr;
38 connectTry_ = 0;
39 isConnected_ = false;
40}
41
44 delete socket_;
45 socket_ = 0;
46 if (registerName_)
47 free(registerName_);
48}
49
51 if (registerName_ != 0) {
53 } else
54 lerr << "socketchan: Connect without name!!!\n";
55}
56
58 return registerName_;
59}
60
61// NCP Command processing
63 // str is guaranteed to begin with NCP$, and all NCP commands are
64 // greater than or equal to 8 characters in length.
65 const char *str = a.getString(4);
66 bool ok = false;
67
68 if (!strncmp(str, "INFO", 4)) {
69 // Send information discovered during the receipt of the
70 // NCON_MSG_NCP_INFO message.
71 a.init();
72 switch (ncpProtocolVersion()) {
73 case PV_SERIES_3:
74 a.addStringT("Series 3");
75 break;
76 case PV_SERIES_5:
77 a.addStringT("Series 5");
78 break;
79 default:
80 lerr << "ncpd: protocol version not known" << endl;
81 a.addStringT("Unknown!");
82 break;
83 }
85 ok = true;
86 } else if (!strncmp(str, "CONN", 4)) {
87 // Connect to a channel that was placed in 'pending' mode, by
88 // checking the channel table against the ID...
89 // DO ME LATER
90 ok = true;
91 } else if (!strncmp(str, "CHAL", 4)) {
92 // Challenge
93 // The idea is that the channel stays in 'secure' mode until a
94 // valid RESP is received
95 // DO ME LATER
96 ok = true;
97 } else if (!strncmp(str, "RESP", 4)) {
98 // Reponse - here is the plaintext as sent in the CHAL - the
99 // channel will only open up if this matches what ncpd has for
100 // the encrypted plaintext.
101 // DO ME LATER
102 ok = true;
103 } else if (!strncmp(str, "GSPD", 4)) {
104 // Get Speed of serial device
105 a.init();
106 a.addByte(rfsv::E_PSI_GEN_NONE);
107 a.addDWord(ncpGetSpeed());
109 ok = true;
110 } else if (strncmp(str, "REGS", 4) == 0) {
111
112 // Register a server-process on the PC side.
113 a.init();
114 const char *name = a.getString(8);
115 if (ncpFindPcServer(name))
116 a.addByte(rfsv::E_PSI_FILE_EXIST);
117 else {
119 a.addByte(rfsv::E_PSI_GEN_NONE);
120 }
122 ok = true;
123 }
124 if (!ok) {
125 lerr << "SocketChannel:: received unknown NCP command (" << a << ")" << endl;
126 a.init();
127 a.addByte(rfsv::E_PSI_GEN_NSUP);
129 }
130 return ok;
131}
132
135 a.addStringT("Ok");
137 isConnected_ = true;
138 connectTry_ = 3;
139}
140
143 a.addStringT("NAK");
146}
147
149 connectTry_++;
150 ncpConnect();
151}
152
154 if (!registerName_ || (connectTry_ > 1))
156 else {
157 connectTry_++;
158 connectTryTimestamp_ = time(0);
159 ncpRegister();
160 }
161}
162
164 int res;
165
166 if (registerName_ == 0) {
168 res = socket_->getBufferStore(a, false);
169 switch (res) {
170 case 1:
171 // A client has isConnected_, and is announcing who it
172 // is... e.g. "SYS$RFSV.*"
173 //
174 // An NCP Channel can be in 'Control' or 'Data' mode.
175 // Initially, it is in 'Control' mode, and can accept
176 // certain commands.
177 //
178 // When a command is received that ncpd does not
179 // understand, this is assumed to be a request to
180 // connect to the remote service of that name, and enter
181 // 'data' mode.
182 //
183 // Later, there might be an explicit command to enter
184 // 'data' mode, and also a challenge-response protocol
185 // before any connection can be made.
186 //
187 // All commands begin with "NCP$".
188
189 if (memchr(a.getString(), 0, a.getLen()) == 0) {
190 // Not 0 terminated, -> invalid
191 lerr << "ncpd: command " << a << " unrecognized."
192 << endl;
193 return;
194 }
195
196 // There is a magic process name called "NCP$INFO.*"
197 // which is announced by the rfsvfactory. This causes a
198 // response to be issued containing the NCP version
199 // number. The rfsvfactory will create the correct type
200 // of RFSV protocol handler, which will then announce
201 // itself. So, first time in here, we might get the
202 // NCP$INFO.*
203 if (a.getLen() > 8 && !strncmp(a.getString(), "NCP$", 4)) {
204 if (!ncpCommand(a))
205 lerr << "ncpd: command " << a << " unrecognized."
206 << endl;
207 return;
208 }
209
210 // This isn't a command, it's a remote process. Connect.
211 registerName_ = strdup(a.getString());
212 connectTry_++;
213
214 // If this is SYS$RFSV, we immediately connect. In all
215 // other cases, we first perform a registration. Connect
216 // is then triggered by RegisterAck and uses the name
217 // we received from the Psion.
218 connectTryTimestamp_ = time(0);
219 if (strncmp(registerName_, "SYS$RFSV", 8) == 0)
220 ncpConnect();
221 else
222 ncpRegister();
223 break;
224 case -1:
226 break;
227 }
228 } else if (isConnected_) {
230 res = socket_->getBufferStore(a, false);
231 if (res == -1) {
234 } else if (res == 1) {
235 if (a.getLen() > 8 && !strncmp(a.getString(), "NCP$", 4)) {
236 if (!ncpCommand(a))
237 lerr << "ncpd: command " << a << " unrecognized."
238 << endl;
239 return;
240 }
241 ncpSend(a);
242 }
243 } else if (time(0) > (connectTryTimestamp_ + 15))
245}
246
248 return isConnected_;
249}
Definition: ncp.h:54
virtual ~SocketChannel()
TCPSocket * socket_
Definition: socketchannel.h:47
void ncpConnectNak()
SocketChannel(TCPSocket *socket, NCP *ncp)
void ncpConnectAck()
const char * getNcpRegisterName()
int connectTryTimestamp_
Definition: socketchannel.h:51
bool ncpCommand(bufferStore &a)
void ncpConnectTerminate()
void ncpDataCallback(bufferStore &a)
void ncpRegisterAck()
bool isConnected() const
char * registerName_
Definition: socketchannel.h:48
A class for dealing with sockets.
Definition: tcpsocket.h:38
bool closeSocket(void)
Closes the connection.
Definition: tcpsocket.cc:374
int getBufferStore(bufferStore &a, bool wait=true)
Receive data into a bufferStore .
Definition: tcpsocket.cc:289
bool sendBufferStore(const bufferStore &a)
Sends data from a bufferStore .
Definition: tcpsocket.cc:325
A generic container for an array of bytes.
Definition: bufferstore.h:37
void ncpSend(bufferStore &a)
Definition: channel.cc:46
void ncpRegisterPcServer(TCPSocket *skt, const char *name)
Definition: channel.cc:94
void ncpDisconnect()
Definition: channel.cc:82
void ncpConnect()
Definition: channel.cc:64
PcServer * ncpFindPcServer(const char *name)
Definition: channel.cc:88
void terminateWhenAsked()
Definition: channel.cc:58
short int ncpProtocolVersion()
Definition: channel.cc:112
int ncpGetSpeed()
Definition: channel.cc:106
void ncpRegister()
Definition: channel.cc:70
@ E_PSI_GEN_NSUP
Definition: rfsv.h:114
@ E_PSI_GEN_NONE
Definition: rfsv.h:110
@ E_PSI_FILE_EXIST
Definition: rfsv.h:134
Definition: doctest.h:522
std::ostream lerr
static rfsv * a
Definition: main.cc:53