Uthernet II: handle TCP connection failure. (PR #1070)

This commit is contained in:
Andrea 2022-03-22 19:39:49 +00:00 committed by GitHub
parent cdd360bdfe
commit 500c2e50b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 21 deletions

View File

@ -31,7 +31,7 @@
<li><a href="sound.html">Sound</a>
<li><a href="clock.html">Clock</a>
<li><a href="card-ssc.html">Super Serial card</a>
<li><a href="uthernet.html">Uthernet network card</a>
<li><a href="uthernet.html">Uthernet network cards</a>
<li><a href="configuration.html">AppleWin Configuration</a>
<li><a href="dbg-toc-intro.html">Using the Debugger</a>
<li><a href="resources.html">Resources</a></li>

View File

@ -1,22 +1,23 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Uthernet network card</title>
<title>Uthernet network cards</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
</head>
<body style="FONT-FAMILY: verdana; BACKGROUND-COLOR: rgb(255,255,255)" alink="#008000"
link="#008000" vlink="#008000">
<h2 style="COLOR: rgb(0,128,0)">Uthernet network card</h2>
<h2 style="COLOR: rgb(0,128,0)">Uthernet network cards</h2>
<hr size="4">
<p style="FONT-WEIGHT: bold">Overview:
</p>
<P>The Uthernet network card coupled with the Contiki OS allows you to browse the
<P>The Uthernet network cards coupled with the Contiki OS allow you to browse the
internet on your Apple.</P>
<P style="FONT-WEIGHT: bold">Acknowledgment:
</P>
<P>Uthernet (TFE) support in Applewin was made possible by implementing the GPL
<P>Uthernet (TFE) support in AppleWin was made possible by implementing the GPL
source written by Spiro Trikaliotis for the Vice emulator - <A href="http://vice-emu.sourceforge.net/index.html#developers">
http://vice-emu.sourceforge.net/index.html#developers</A></P>
<P><A href="https://a2retrosystems.com/">Uthernet II</A> support in AppleWin has been contributed by Andrea (audetto) Odetti.</P>
<P style="FONT-WEIGHT: bold">Details:
</P>
<P>To enable ethernet support in AppleWin you must first download and install
@ -35,15 +36,15 @@
<P>After AppleWin starts, select the settings icon and then select the ethernet
settings button.
</P>
<P>Uthernet will be disabled. Select Uthernet from the list of available ethernet
emulations (currently the only one).
<P>Uthernet will be disabled. Select Uthernet or (Uthernet II) from the list of available ethernet
emulations.
</P>
<P>Select the ethernet interface you want to work with. This must be a physical
ethernet interface.
</P>
<P>If you have more than one interface you may need to select them in turn in order
to get the text description for each interface vs what Npcap likes to use for
a reference. Select Ok. and then close AppleWin.
a reference.
</P>
<P><span style="font-weight: bold;">Note:</span> Wireless does not work
with WinPcap (but see <A href="uthernet-wifi-workaround.html">WiFi Workaround</A>).
@ -56,7 +57,7 @@
also grab a copy of the Uthernet/Contiki getting started guide <A href="http://www.a2retrosystems.com/a2UtherManual.pdf">
http://www.a2retrosystems.com/a2UtherManual.pdf</A>
</P>
<P>When you run AppleWin again, select the contiki80pri.dsk image. Boot AppleWin.
<P>Select the contiki80pri.dsk image. Boot AppleWin.
</P>
<P>Once Contiki is loaded then press Enter to clear the welcome screen and press
ESC for a menu.
@ -87,5 +88,14 @@
if you are still having difficulty then you should refer to the VICE network
support page for additional information - <A href="http://vicekb.trikaliotis.net/13-005.shtml">
http://vicekb.trikaliotis.net/13-005.shtml</A></P>
</body>
<P style="FONT-WEIGHT: bold">Uthernet II:
</P>
<P>Most features of the Uthernet II are emulated, with the following caveats:
<ul>
<li>PPPoE, interrupts and SPI are not implemented</li>
<li>server side is not well tested</li>
<li>after loading a save-state file, TCP and UDP sockets are closed</li>
</ul>
</P>
</body>
</html>

View File

@ -216,31 +216,46 @@ Socket::~Socket()
clearFD();
}
bool Socket::isOpen() const
{
return (myFD != INVALID_SOCKET) &&
((sn_sr == W5100_SN_SR_ESTABLISHED) || (sn_sr == W5100_SN_SR_SOCK_UDP));
}
void Socket::process()
{
if (myFD != INVALID_SOCKET && sn_sr == W5100_SN_SR_SOCK_INIT && (myErrno == SOCK_EINPROGRESS || myErrno == SOCK_EWOULDBLOCK))
{
#ifdef _MSC_VER
FD_SET writefds;
FD_SET writefds, exceptfds;
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);
FD_SET(myFD, &writefds);
FD_SET(myFD, &exceptfds);
const timeval timeout = {0, 0};
if (select(0, NULL, &writefds, NULL, &timeout) > 0)
if (select(0, NULL, &writefds, &exceptfds, &timeout) > 0)
#else
pollfd pfd = {.fd = myFD, .events = POLLOUT};
if (poll(&pfd, 1, 0) > 0)
#endif
{
int err = 0;
socklen_t elen = sizeof err;
getsockopt(myFD, SOL_SOCKET, SO_ERROR, reinterpret_cast<char *>(&err), &elen);
socklen_t elen = sizeof(err);
const int res = getsockopt(myFD, SOL_SOCKET, SO_ERROR, reinterpret_cast<char *>(&err), &elen);
if (err == 0)
if (res == 0 && err == 0)
{
myErrno = 0;
sn_sr = W5100_SN_SR_ESTABLISHED;
#ifdef U2_LOG_STATE
LogFileOutput("U2: TCP[]: Connected\n");
#endif
}
else
{
clearFD();
#ifdef U2_LOG_STATE
LogFileOutput("U2: TCP[]: Connection error: %d - %" ERROR_FMT "\n", res, STRERROR(err));
#endif
}
}
@ -614,7 +629,7 @@ void Uthernet2::receiveOnePacketIPRaw(const size_t i, const size_t lengthOfPaylo
void Uthernet2::receiveOnePacketFromSocket(const size_t i)
{
Socket &socket = mySockets[i];
if (socket.myFD != INVALID_SOCKET)
if (socket.isOpen())
{
const uint16_t freeRoom = socket.getFreeRoom();
if (freeRoom > 32) // avoid meaningless reads
@ -718,7 +733,7 @@ void Uthernet2::sendDataMacRaw(const size_t i, std::vector<uint8_t> &packet) con
void Uthernet2::sendDataToSocket(const size_t i, std::vector<uint8_t> &data)
{
Socket &socket = mySockets[i];
if (socket.myFD != INVALID_SOCKET)
if (socket.isOpen())
{
sockaddr_in destination = {};
destination.sin_family = AF_INET;
@ -809,7 +824,7 @@ void Uthernet2::resetRXTXBuffers(const size_t i)
myMemory[socket.registerAddress + W5100_SN_RX_RD1] = 0x00;
}
void Uthernet2::openSystemSocket(const size_t i, const int type, const int protocol, const int state)
void Uthernet2::openSystemSocket(const size_t i, const int type, const int protocol, const int status)
{
Socket &s = mySockets[i];
#ifdef _MSC_VER
@ -820,7 +835,7 @@ void Uthernet2::openSystemSocket(const size_t i, const int type, const int proto
if (fd == INVALID_SOCKET)
{
#ifdef U2_LOG_STATE
const char *proto = state == W5100_SN_SR_SOCK_UDP ? "UDP" : "TCP";
const char *proto = (status == W5100_SN_SR_SOCK_UDP) ? "UDP" : "TCP";
LogFileOutput("U2: %s[%" SIZE_T_FMT "]: socket error: %" ERROR_FMT "\n", proto, i, STRERROR(sock_error()));
#endif
s.clearFD();
@ -831,7 +846,7 @@ void Uthernet2::openSystemSocket(const size_t i, const int type, const int proto
u_long on = 1;
ioctlsocket(fd, FIONBIO, &on);
#endif
s.setFD(fd, state);
s.setFD(fd, status);
}
}

View File

@ -30,6 +30,7 @@ struct Socket
socket_t myFD;
int myErrno;
bool isOpen() const;
void clearFD();
void setFD(const socket_t fd, const int status);
void process();
@ -106,7 +107,7 @@ private:
void resetRXTXBuffers(const size_t i);
void updateRSR(const size_t i);
void openSystemSocket(const size_t i, const int type, const int protocol, const int state);
void openSystemSocket(const size_t i, const int type, const int protocol, const int status);
void openSocket(const size_t i);
void closeSocket(const size_t i);
void connectSocket(const size_t i);