Dependencies: EthernetNetIf mbed
Revision 0:fcd581e3ad7d, committed 2011-06-13
- Comitter:
- naegawa
- Date:
- Mon Jun 13 06:47:43 2011 +0000
- Commit message:
- test1
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EchoServer.cpp Mon Jun 13 06:47:43 2011 +0000 @@ -0,0 +1,60 @@ +#include "EchoServer.h" +#include "lwip/ip_addr.h" +EchoServer::EchoServer() { + // Create the sockets and set the callbacks + tcpSock = new TCPSocket; + tcpSock->setOnEvent(this, &EchoServer::onNetTcpSocketEvent); + udpSock = new UDPSocket; + udpSock->setOnEvent(this, &EchoServer::onNetUdpSocketEvent); +} + +EchoServer::~EchoServer() { + // Delete the sockets on destruction + delete tcpSock; + delete udpSock; +} + +void EchoServer::bind(int tcpPort, int udpPort) { + // bind and listen on TCP + tcpSock->bind(Host(IP_ADDR_ANY, tcpPort)); + tcpSock->listen(); + // bind UDP + udpSock->bind(Host(IP_ADDR_ANY, udpPort)); +} + +void EchoServer::onNetTcpSocketEvent(TCPSocketEvent e) { + // We're only interested in the ACCEPT event where we need to accept + // the incoming connection + if ( e == TCPSOCKET_ACCEPT ) { + TCPSocket* tcpClientSocket; + Host client; + if ( tcpSock->accept(&client, &tcpClientSocket) ) { + printf("onNetTcpSocketEvent : Could not accept connection.\r\n"); + return; //Error in accept, discard connection + } + // We can find out from where the connection is coming by looking at the + // Host parameter of the accept() method + IpAddr clientIp = client.getIp(); + printf("Incoming TCP connection from %d.%d.%d.%d\r\n", clientIp[0], clientIp[1], clientIp[2], clientIp[3]); + // Create TCPEchoHandler and pass client socket + TCPEchoHandler* tcpHandler = new TCPEchoHandler(tcpClientSocket); //TCPSocket ownership is passed to handler + // The handler object will destroy itself when done, or will be destroyed on Server destruction + } +} + +void EchoServer::onNetUdpSocketEvent(UDPSocketEvent e) { + // We're only interested in the READABLE event (it's the only one) + if ( e == UDPSOCKET_READABLE ) { + // No need for a handler for UDP - set up a buffer and check client + char buff[128]; + Host client; + IpAddr clientIp = client.getIp(); + printf("Incoming UDP connection from %d.%d.%d.%d\r\n", clientIp[0], clientIp[1], clientIp[2], clientIp[3]); + // Keep reading while there's data to be read + while ( int len = udpSock->recvfrom(buff, 128, &client) ) { + if ( len > 0 ) + // If there's data, send it straight back out + udpSock->sendto(buff, len, &client); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EchoServer.h Mon Jun 13 06:47:43 2011 +0000 @@ -0,0 +1,53 @@ +#ifndef ECHO_SERVER_H +#define ECHO_SERVER_H + +#include "mbed.h" +#include "TCPSocket.h" +#include "UDPSocket.h" +#include "EthernetNetIf.h" + +#include "TCPEchoHandler.h" +#include <netservice.h> +/* + Class: EchoServer + Binds itself to port 7 on TCP and UDP and listens for + incoming connections +*/ +class EchoServer { +public: + // Constructor: EchoServer + // Creates the TCP and UDP sockets and wires up + // the event callback methods + EchoServer(); + // Destructor: ~EchoServer + // Deletes the TCP and UDP sockets + ~EchoServer(); + /* + Function: bind + Binds the sockets to the specified ports + Parameters: + tcpPort - The TCP port to bind to (default 7 as per RFC862) + udpPort - The UDP port to bind to (default 7 as per RFC862) + */ + void bind(int tcpPort=7, int udpPort=7); +private: + // Variable: tcpSock + // The TCP server socket + TCPSocket* tcpSock; + // Variable: udpSock + // The UDP socket + UDPSocket* udpSock; + + // Function: onNetTcpSocketEvent + // The callback function called by the network stack whenever an + // event occurs on the TCP socket + // Parameter: e - The event that has occurred + void onNetTcpSocketEvent(TCPSocketEvent e); + // Function: onNetUdpSocketEvent + // The callback function called by the network stack whenever an + // event occurs on the UDP socket + // Parameter: e - The event that has occurred + void onNetUdpSocketEvent(UDPSocketEvent e); +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EthernetNetIf.lib Mon Jun 13 06:47:43 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/donatien/code/EthernetNetIf/#bc7df6da7589
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TCPEchoHandler.cpp Mon Jun 13 06:47:43 2011 +0000 @@ -0,0 +1,69 @@ +#include "TCPEchoHandler.h" + +// When the constructor's called, initialise the member variables +TCPEchoHandler::TCPEchoHandler(TCPSocket* tcpClientSocket) + : NetService() + , clientSocket(tcpClientSocket) + , closed(0) + , timeoutWatchdog() { + // Wire up the event handler on the client TCP socket + clientSocket->setOnEvent(this, &TCPEchoHandler::onTCPSocketEvent); +} + +TCPEchoHandler::~TCPEchoHandler() { + // Close the socket on destruction + close(); +} + +void TCPEchoHandler::onTCPSocketEvent(TCPSocketEvent e) { + switch (e) { + // If the socket is readable, do stuff + case TCPSOCKET_READABLE: + // Disable the timeout watchdog timer + timeoutWatchdog.detach(); + // Read in any available data into the buffer + char buff[128]; + while ( int len = clientSocket->recv(buff, 128) ) { + // And send straight back out again + clientSocket->send(buff, len); + } + // Reset timeout countdown + setTimeout(ECHO_TIMEOUT); + break; + case TCPSOCKET_CONTIMEOUT: + case TCPSOCKET_CONRST: + case TCPSOCKET_CONABRT: + case TCPSOCKET_ERROR: + case TCPSOCKET_DISCONNECTED: + // Close the socket on any terminal TCP event + close(); + break; + } + +} + +void TCPEchoHandler::close() { + // Prevent recursive calling or calling on an object being destructed by someone else + if ( closed ) + return; + closed = 1; + timeoutWatchdog.detach(); + if ( clientSocket ) { + clientSocket->resetOnEvent(); + clientSocket->close(); + delete clientSocket; //This fn might have been called by this socket (through an event), so DO NOT DESTROY IT HERE + } + // Flags this service as closed - will be destructed and deleted on + // the next call of NetService::poll() by Net::poll() + NetService::close(); +} + +void TCPEchoHandler::setTimeout(unsigned int timeout) { + // Attach our timeout handler to the timeout watchdog timer to close the socket if no activity + timeoutWatchdog.attach_us<TCPEchoHandler>(this, &TCPEchoHandler::onTimeout, ECHO_TIMEOUT * 1000); +} + +void TCPEchoHandler::onTimeout() { + // Nothing fancy, just close the socket and mark this class for destruction + close(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TCPEchoHandler.h Mon Jun 13 06:47:43 2011 +0000 @@ -0,0 +1,52 @@ +#ifndef TCP_ECHO_HANDLER_H +#define TCP_ECHO_HANDLER_H + +#include "mbed.h" +#include "TCPSocket.h" +#include <netservice.h> +// Constant: ECHO_TIMOUT +// The timeout period for inactivity in milliseconds +#define ECHO_TIMEOUT 5000 + +/* + Class: TCPEchoHandler + A class instantiated to handle the incoming TCP client connection + Extends NetService to hook into the TCP/IP stack's polling + and destruction service +*/ +class TCPEchoHandler : public NetService { +public: + // Constructor: TCPEchoHandler + // Setup and handle the incoming connection + TCPEchoHandler(TCPSocket*); + virtual ~TCPEchoHandler(); +private: + // Variable: clientSocket + // The incoming TCP socket from the client + TCPSocket* clientSocket; + // Variable: closed + // A marker to say whether this socket is already closed + int closed; + // Variable: timeoutWatchdog + // A timer to countdown from during inactivity and close + // dormant connections + Timeout timeoutWatchdog; + + // Function: onNetTcpSocketEvent + // The callback function called by the network stack whenever an + // event occurs on the TCP socket + // Parameter: e - The event that has occurred + void onTCPSocketEvent(TCPSocketEvent e); + // Function: close + // Closes the client socket and marks this class as done with + // for the TCP/IP stack to destroy + virtual void close(); + // Function: setTimeout + // Parameter: timeout - The length of time to wait for more activity in milliseconds + void setTimeout(unsigned int timeout); + // Function: onTimeout + // The handler called by the timeout watchdog to close the connection when timed out + void onTimeout(); +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Jun 13 06:47:43 2011 +0000 @@ -0,0 +1,53 @@ +/* + * Echo server + * Listens on TCP and UDP ports 7 for any incoming connections + * Re-transmits any incoming bytes + */ + +#include "mbed.h" +#include "EthernetNetIf.h" + +#include "EchoServer.h" + +// Our Echo server +EchoServer server; + +/* + Function: main + + Sets up the Ethernet interface using DHCP, reports the assigned + IP address via serial, binds the Echo server to port 7 on + TCP and UDP and then sits in a loop calling Net::poll() to + keep the network stack doing its thing +*/ +int main() { + printf("\r\nSetting up...\r\n"); + /* + //use DHCP + + // Our Ethernet interface + EthernetNetIf eth; + EthernetErr ethErr = eth.setup(); + if (ethErr) { + printf("Error %d in setup.\n", ethErr); + return -1; + } + IpAddr ip = eth.getIp(); + */ + IpAddr ip(192,168,0,100);// = eth.getIp(); + EthernetNetIf eth(ip,IpAddr(255,255,255,0),IpAddr(192,168,0,1),IpAddr(192,168,0,1)); + EthernetErr ethErr = eth.setup(); + if (ethErr) { + printf("Error %d in setup.\n", ethErr); + return -1; + } + + printf("mbed IP Address is %d.%d.%d.%d\r\n", ip[0], ip[1], ip[2], ip[3]); + + server.bind(777,666); + + printf("Entering while loop Net::poll()ing\r\n"); + while (1) { + Net::poll(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Jun 13 06:47:43 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/029aa53d7323