aboutsummaryrefslogtreecommitdiffstats
path: root/ncpd/ncp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ncpd/ncp.cc')
-rw-r--r--ncpd/ncp.cc126
1 files changed, 99 insertions, 27 deletions
diff --git a/ncpd/ncp.cc b/ncpd/ncp.cc
index 76f4d63..f20ca75 100644
--- a/ncpd/ncp.cc
+++ b/ncpd/ncp.cc
@@ -31,9 +31,10 @@
#include "ncp.h"
#include "linkchan.h"
-#include <bufferstore.h>
#include "link.h"
+#include <bufferstore.h>
#include <bufferarray.h>
+#include <rfsv.h>
#define MAX_CHANNELS_PSION 256
#define MAX_CHANNELS_SIBO 8
@@ -54,6 +55,7 @@ ncp::ncp(const char *fname, int baud, unsigned short _verbose)
// until detected on receipt of INFO we use these.
maxChannels = MAX_CHANNELS_SIBO;
protocolVersion = PV_SERIES_5;
+ lChan = NULL;
// init channels
for (int i = 0; i < MAX_CHANNELS_PSION; i++)
@@ -94,6 +96,8 @@ reset() {
channelPtr[i] = NULL;
}
failed = false;
+ if (lChan)
+ delete(lChan);
lChan = NULL;
protocolVersion = PV_SERIES_5; // until detected on receipt of INFO
l->reset();
@@ -158,6 +162,35 @@ controlChannel(int chan, enum interControllerMessageType t, bufferStore & comman
l->send(open);
}
+PcServer *ncp::
+findPcServer(const char *name)
+{
+ if (name) {
+ vector<PcServer>::iterator i;
+ for (i = pcServers.begin(); i != pcServers.end(); i++)
+ if (i->getName() == name)
+ return i;
+ }
+ return NULL;
+}
+
+void ncp::
+registerPcServer(ppsocket *skt, const char *name) {
+ pcServers.push_back(PcServer(skt, name));
+}
+
+void ncp::
+unregisterPcServer(PcServer *server) {
+ if (server) {
+ vector<PcServer>::iterator i;
+ for (i = pcServers.begin(); i != pcServers.end(); i++)
+ if (i == server) {
+ pcServers.erase(i);
+ return;
+ }
+ }
+}
+
void ncp::
decodeControlMessage(bufferStore & buff)
{
@@ -169,6 +202,7 @@ decodeControlMessage(bufferStore & buff)
cout << "ncp: << " << ctrlMsgName(imt) << " " << remoteChan;
bufferStore b;
+ int localChan;
switch (imt) {
case NCON_MSG_CONNECT_TO_SERVER:
@@ -178,33 +212,51 @@ decodeControlMessage(bufferStore & buff)
cout << endl;
}
- int localChan;
-
- // Ack with connect response
- localChan = getFirstUnusedChan();
- b.addByte(remoteChan);
- b.addByte(0);
- controlChannel(localChan, NCON_MSG_CONNECT_RESPONSE, b);
-
- // NOTE: we don't allow connections from the
- // Psion to any local "processes" other than
- // LINK.* - Matt might need to change this for
- // his NCP<->TCP/IP bridge code...
-
+ failed = false;
if (!strcmp(buff.getString(0), "LINK.*")) {
if (lChan)
- failed = true;
+ localChan = lChan->getNcpChannel();
+ else
+ localChan = getFirstUnusedChan();
+
+ // Ack with connect response
+ b.addByte(remoteChan);
+ b.addByte(0);
+ controlChannel(localChan, NCON_MSG_CONNECT_RESPONSE, b);
if (verbose & NCP_DEBUG_LOG)
cout << "ncp: Link UP" << endl;
- channelPtr[localChan] = lChan = new linkChan(this, localChan);
- lChan->setVerbose(verbose);
+ // Create linkchan if it does not yet exist
+ if (!lChan) {
+ if (verbose & NCP_DEBUG_LOG)
+ cout << "ncp: new passive linkChan" << endl;
+ channelPtr[localChan] =
+ lChan = new linkChan(this, localChan);
+ lChan->setVerbose(verbose);
+ }
lChan->ncpConnectAck();
} else {
- if (verbose & NCP_DEBUG_LOG)
- cout << "ncp: REJECT connect" << endl;
- bufferStore b;
+ PcServer *s = findPcServer(buff.getString(0));
+ bool ok = false;
+
+ if (s) {
+ localChan = getFirstUnusedChan();
+ ok = s->clientConnect(localChan, remoteChan);
+ if (!ok)
+ // release channel ptr
+ channelPtr[localChan] = NULL;
+ }
b.addByte(remoteChan);
- controlChannel(0, NCON_MSG_CHANNEL_DISCONNECT, b);
+ if (ok) {
+ b.addByte(rfsv::E_PSI_GEN_NONE);
+ if (verbose & NCP_DEBUG_LOG)
+ cout << "ncp: ACCEPT client connect" << endl;
+ } else {
+ localChan = 0;
+ b.addByte(rfsv::E_PSI_FILE_NXIST);
+ if (verbose & NCP_DEBUG_LOG)
+ cout << "ncp: REJECT client connect" << endl;
+ }
+ controlChannel(localChan, NCON_MSG_CONNECT_RESPONSE, b);
}
break;
@@ -212,6 +264,7 @@ decodeControlMessage(bufferStore & buff)
int forChan;
+ failed = false;
forChan = buff.getByte(0);
if (verbose & NCP_DEBUG_LOG)
cout << " ch=" << forChan << " stat=";
@@ -237,6 +290,7 @@ decodeControlMessage(bufferStore & buff)
int ver;
+ failed = false;
ver = buff.getByte(0);
// Series 3c returns '3', as does mclink. PsiWin 1.1
// returns version 2. We return whatever version we're
@@ -263,11 +317,12 @@ decodeControlMessage(bufferStore & buff)
// Do we send a time of 0 or a real time?
// The Psion uses this to determine whether to
// restart. (See protocol docs for details)
- // b.addDWord(0);
b.addDWord(time(NULL));
controlChannel(0, NCON_MSG_NCP_INFO, b);
- } else
+ } else {
cout << "ALERT!!!! Unexpected Protocol Version!! (No Series 5/3?)!" << endl;
+ failed = true;
+ }
break;
case NCON_MSG_CHANNEL_DISCONNECT:
@@ -318,7 +373,7 @@ RegisterAck(int chan, const char *name)
cout << "ncp: RegisterAck: chan=" << chan << endl;
for (int cNum = 1; cNum < maxLinks(); cNum++) {
channel *ch = channelPtr[cNum];
- if (ch && ch->getNcpChannel() == chan) {
+ if (isValidChannel(cNum) && ch->getNcpChannel() == chan) {
ch->setNcpConnectName(name);
ch->ncpRegisterAck();
return;
@@ -420,9 +475,20 @@ stuffToSend()
bool ncp::
hasFailed()
{
- if (failed)
- return true;
- return l->hasFailed();
+ bool lfailed = l->hasFailed();
+ if (failed || lfailed) {
+ if (verbose & NCP_DEBUG_LOG)
+ cout << "ncp: hasFailed: " << failed << ", " << lfailed << endl;
+ }
+ failed |= lfailed;
+ if (failed) {
+ if (lChan) {
+ channelPtr[lChan->getNcpChannel()] = NULL;
+ delete lChan;
+ }
+ lChan = NULL;
+ }
+ return failed;
}
bool ncp::
@@ -431,6 +497,12 @@ gotLinkChannel()
return (lChan != NULL);
}
+int ncp::
+getSpeed()
+{
+ return l->getSpeed();
+}
+
char *ncp::
ctrlMsgName(unsigned char msgType)
{