diff options
Diffstat (limited to 'ncpd/ncp.cc')
| -rw-r--r-- | ncpd/ncp.cc | 126 | 
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)  { | 
