|
|
|
/*
|
|
|
|
|
|
|
|
Network Interface
|
|
|
|
|
|
|
|
Generic wrapper around a specific network device.
|
|
|
|
|
|
|
|
A Network Interface (representing the physical network device) returns a
|
|
|
|
connecting or listening Network Connection (representing a socket in either
|
|
|
|
client or server state).
|
|
|
|
|
|
|
|
Author:
|
|
|
|
|
|
|
|
Philip Lindsay <follower@rancidbacon.com>
|
|
|
|
|
|
|
|
License:
|
|
|
|
|
|
|
|
Copyright 2007-2008 // LGPL
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "interface.h"
|
|
|
|
|
|
|
|
#define HANDLE_BAD_ERROR() while (1) {};
|
|
|
|
|
|
|
|
NetworkInterface::NetworkInterface(W5100Device& networkDevice) : device (networkDevice) {
|
|
|
|
/*
|
|
|
|
|
|
|
|
Initialise the physical device with default network details.
|
|
|
|
|
|
|
|
Note: The "weirdness" in this function declaration is a "initalization list",
|
|
|
|
i.e. this bit:
|
|
|
|
|
|
|
|
) : device (networkDevice) {
|
|
|
|
|
|
|
|
it is needed to give the 'device' Reference a value supplied to the method
|
|
|
|
rather than having a new 'W5100Device' instance created.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// This may not be the best place to do all this, but it'll do for now:
|
|
|
|
device.setMac(0x02,0xDE,0xAD,0xBE,0xEF,0x00);
|
|
|
|
|
|
|
|
device.setIp(169,254,254,169); // A local-link IP -- NOTE: This is out of spec.
|
|
|
|
device.setMask(255,255,0,0); // Matches local-link IP /16
|
|
|
|
|
|
|
|
device.setGateway(0,0,0,0); // We can't even guess this, so just skip it.
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
NetworkConnection NetworkInterface::listen(uint16_t port) {
|
|
|
|
/*
|
|
|
|
|
|
|
|
Start to listen for a request from a client.
|
|
|
|
|
|
|
|
|
|
|
|
NOTE: For reasons I don't understand, this FAILS TO WORK if port >255.
|
|
|
|
The port that gets opened is ~(port mod 255) but if you limit
|
|
|
|
port to be uint8_t for example you don't get an error until
|
|
|
|
the port number is bigger than 'long'.
|
|
|
|
|
|
|
|
TODO: Track and fix this for port numbers > 255.
|
|
|
|
|
|
|
|
|
|
|
|
Returns a NetworkConnection listening on the specified TCP port.
|
|
|
|
|
|
|
|
*/
|
|
|
|
NetworkConnection connection = NetworkConnection(port);
|
|
|
|
|
|
|
|
// TODO: How to best handle errors?
|
|
|
|
// There's two major categories I can think of currently:
|
|
|
|
// 1) A socket wasn't available to listen in the first place
|
|
|
|
// 2) The listen attempt failed for some reason
|
|
|
|
// Using 'HANDLE_BAD_ERROR()' (currently an infinite loop) is
|
|
|
|
// not ideal but should prevent the above errors slipping by unnoticed.
|
|
|
|
if (!connection.listen()) {
|
|
|
|
HANDLE_BAD_ERROR();
|
|
|
|
}
|
|
|
|
|
|
|
|
return connection;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NetworkConnection NetworkInterface::connect(byte b0, byte b1, byte b2, byte b3, uint16 port) {
|
|
|
|
/*
|
|
|
|
|
|
|
|
Connect to a server.
|
|
|
|
|
|
|
|
*/
|
|
|
|
NetworkConnection connection = NetworkConnection(4000);
|
|
|
|
|
|
|
|
byte _scratchBuffer[4]; // TODO: Move this?
|
|
|
|
|
|
|
|
// TODO: Better?
|
|
|
|
_scratchBuffer[0] = b0;
|
|
|
|
_scratchBuffer[1] = b1;
|
|
|
|
_scratchBuffer[2] = b2;
|
|
|
|
_scratchBuffer[3] = b3;
|
|
|
|
|
|
|
|
if (!connection.connect(_scratchBuffer, port)) {
|
|
|
|
HANDLE_BAD_ERROR();
|
|
|
|
}
|
|
|
|
|
|
|
|
return connection;
|
|
|
|
}
|
|
|
|
|
|
|
|
//#include "w5100_device.h"
|
|
|
|
|
|
|
|
//NetworkInterface Network = NetworkInterface(W5100);
|