-
Notifications
You must be signed in to change notification settings - Fork 78
N: Theory of Operation
The N: Device is somewhat different from the other devices implemented by #FujiNet, in that multiple network protocols are supported by the filespec passed into the explicit OPEN command. Because of this, a theory of operation must be discussed for the N: device.
To open a network connection, a Network Open command must be issued. For CIO, this maps directly to a CIO OPEN command. This command is translated to a Network Open ('O' aka $4E) command by the CIO handler into SIO.
Aux1 and aux2 are literally passed through as daux1 and daux2 to the SIO Command $4E Network Open command.
Since this is primarily intended to be used by CIO, AUX1 works as expected, with bit 2 specifying read, and bit 3 specifying write. If both bits are set, then reading and writing is allowed on the network socket.
Aux1 is handled by the sioNetwork base class, and should set appropriate flags to check if reading and writing are allowed for a device.
The definition of aux2 is entirely protocol specific, and is passed through verbatim to the protocol handler.
SIO Command $4E Network Open explicitly wants a 256 byte buffer containing the Devicespec to open. It must be null terminated, but can (and most likely will) contain an EOL ($9B) character.
The network filespec is of one of two possible forms, for client connections which do not open listening sockets, and server connections, which do not connect to a specific host, but open a listening socket. Not all protocols support both connection methods, and any attempt to open an unsupported filespec to a protocol should return an SIO error, which can have its status returned by a SIO STATUS command (and pulled from the fourth byte of DVSTAT)
Nx:PROTOCOL:PATH:PORTNUM
Where:
- x specifies the device #. Either N:, N1:, N2:, N3:, N4:, N5:, N6:, N7: or N8:, N: implies N1:
- PROTOCOL is a protocol identifier, examples of protocol identifiers are given below.
- PATH is passed directly to the protocol handler and may be up to 232 bytes long, and must not contain a a colon. If one is required, then the protocol handler must provide a way to escape the colon character.
- PORTNUM is a number between 1 to 65535 specifying the port number intended to open.
- To open a TCP connection to BBS.FOZZTEXX.COM port 23: N:TCP:FOZZTEXX.COM:23
- To open a UDP connection to 192.168.1.8 port 2000: N:UDP:192.168.1.8:2000
- To open an HTTP connection to WWW.GOOGLE.COM: N:HTTP://WWW.GOOGLE.COM:80
Nx:PROTOCOL:PORT
Where:
- x specifies the device #. Either N:, N1:, N2:, N3:, N4:, N5:, N6:, N7: or N8:, N: implies N1:
- PROTOCOL is a protocol identifier, examples of protocol identifiers are given below.
- PORTNUM is a number between 1 to 65535 specifying the port number intended to open.
Because #FujiNet network interfaces aren't planned to be multi-homed, I do not see a rationale to specify a path (which would ostensibly specify a network interface to listen upon.)
- To listen for a TCP connection on port 2000: N:TCP:2000
- To listen for UDP packets on port 2000 N:UDP:2000
So, from BASIC, the command:
OPEN #1,12,0,"N:TCP:192.168.1.8:2000"
Would be interpreted by the CIO handler as a READ/WRITE channel, and would emit the following SIO request:
char* pathspec[256]="N:TCP:192.168.1.8:2000"
OS.dcb.ddevic=0x71;
OS.dcb.dunit=1;
OS.dcb.dcomnd='O';
OS.dcb.dstats=0x80;
OS.dcb.dbuf=&pathspec;
OS.dcb.dbyt=256;
OS.dcb.dtimlo=0x0F; // 16 second timeout
OS.dcb.daux1=12;
OS.dcb.daux2=0;
siov();
The SIO handler should then process the pathspec buffer passed in, removing EOL from its stream, and parsing the result. An example tokenizer/parser:
/**
* Parse deviceSpecs of the format
* Nx:PROTO:PATH:PORT or
* Nx:PROTO:PORT
*/
bool sioNetwork::parse_deviceSpec(char *tmp)
{
char *p;
char i = 0;
char d = 0;
p = strtok(tmp, ":"); // Get Device spec
if (p[0] != 'N')
return false;
else
strcpy(deviceSpec.device, p);
while (p != NULL)
{
i++;
p = strtok(NULL, ":");
switch (i)
{
case 1:
strcpy(deviceSpec.protocol, p);
break;
case 2:
for (d = 0; d < strlen(p); d++)
if (!isdigit(p[d]))
{
strcpy(deviceSpec.path, p);
break;
}
deviceSpec.port = atoi(p);
return true;
case 3:
deviceSpec.port = atoi(p);
return true;
break;
default:
return false; // Too many parameters.
}
}
}
Once parsed, the protocol handler should be determined, and its open handler called. If the open handler fails, then an sio_error() should be emitted, the CIO handler should receive the resulting Error 144, which should cause the CIO handler to ask for a SIO STATUS command. The fourth byte of DVSTAT should contain the error number of what happened.
unsigned char err;
OS.dcb.ddevic=0x71;
OS.dcb.dunit=1;
OS.dcb.dcomnd='S';
OS.dcb.dstats=0x40;
OS.dcb.dbuf=&OS.dvstat;
OS.dcb.dbyt=4;
OS.dcb.dtimlo=0x0f;
OS.dcb.daux=0;
siov();
err=OS.dvstat[3];
Error codes I can think of:
- Error 128 - No active connection
- Error 165 - Invalid Device spec.
- Error 138 - Timeout
- Error 170 - Invalid path (e.g. unknown host)
- Error 171 - Connection immediately closed (is there something more appropriate for this?)
- Error 172 - Could not allocate buffers
Copyright 2024 Contributors to the FujiNetWIFI project.
Join us on Discord: https://discord.gg/7MfFTvD
- Home
- What is FujiNet?
- The Definition of Done
- Board bring up for FujiNet Platform.IO code
- The Complete Linux CLI Guide
- The Complete macOS CLI Guide
- Development Env for Apps
- FujiNet-Development-Guidelines
- System Quickstarts
- FujiNet Flasher
- Setting up a TNFS Server
- FujiNet Configuration File: fnconfig.ini
- AppKey Registry - SIO Command $DC Open App Key
- CP-M Support
- BBS
- Official Hardware Versions
- Prototype Board Revisions
- FujiNet Development Guidelines
- Atari Programming
- Apple Programming
- C64 Programming
- ADAM Programming
- Testing Plan
- Hacker List
- FujiNet VirtualMachine