Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of MTS-Socket by
Revision 1:096f484f3ae6, committed 2014-05-19
- Comitter:
- Mike Fiore
- Date:
- Mon May 19 12:36:11 2014 -0500
- Parent:
- 0:eef30dbe1130
- Child:
- 2:ebc6129de4e8
- Commit message:
- add socket code
Changed in this revision
--- a/CommInterface.h Thu May 15 22:02:08 2014 +0000
+++ b/CommInterface.h Mon May 19 12:36:11 2014 -0500
@@ -1,4 +1,38 @@
#ifndef COMMINTERFACE_H
#define COMMINTERFACE_H
-#endif
\ No newline at end of file
+#include "mbed.h"
+
+/** This pure virtual class for communications link of interface. This class
+* should be derived from when creating a class to manage the underlying connection
+* of a new link type.
+*/
+class CommInterface
+{
+public:
+ /** This method is used to establish a connection on a communications link. Required
+ * configurations and settings should be done in other calls or an init function.
+ *
+ * @returns true if the connection was successfully established, otherwise false.
+ */
+ virtual bool connect() = 0;
+
+ /** This method is used to disconnect a communications like. This includes
+ * any cleanup required before another connection can be made.
+ */
+ virtual void disconnect() = 0;
+
+ /** This method is used to check if the link is currently connected.
+ *
+ * @returns true if currently connected, otherwise false.
+ */
+ virtual bool isConnected() = 0;
+
+ /** This method is used to reset the device that provides the communications
+ * capability. Note that this call should block until the commincations device
+ * is ready for use.
+ */
+ virtual void reset() = 0;
+};
+
+#endif /* COMMINTERFACE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Endpoint.cpp Mon May 19 12:36:11 2014 -0500
@@ -0,0 +1,46 @@
+#include "Socket.h"
+#include "Endpoint.h"
+#include "MTSLog.h"
+#include <cstring>
+
+using std::memset;
+using namespace mts;
+
+Endpoint::Endpoint()
+{
+ reset_address();
+}
+
+Endpoint::~Endpoint()
+{
+}
+
+void Endpoint::reset_address(void)
+{
+ _ipAddress[0] = '\0';
+ _port = 0;
+}
+
+int Endpoint::set_address(const char* host, const int port)
+{
+ int length = strlen(host) + 1; // size of host including terminating character
+ if (length > sizeof(_ipAddress)) {
+ logError("could not set address because the hostname is too long");
+ return -1;
+ } else {
+ strncpy((char*) _ipAddress, host, length);
+ _ipAddress[length] = '\0';
+ _port = port;
+ }
+ return 0;
+}
+
+char* Endpoint::get_address()
+{
+ return _ipAddress;
+}
+
+int Endpoint::get_port()
+{
+ return _port;
+}
--- a/Endpoint.h Thu May 15 22:02:08 2014 +0000
+++ b/Endpoint.h Mon May 19 12:36:11 2014 -0500
@@ -1,4 +1,47 @@
-#ifndef ENDPOINT_H
-#define ENDPOINT_H
-
-#endif
\ No newline at end of file
+#ifndef ENDPOINT_H
+#define ENDPOINT_H
+
+#include "mbed.h"
+
+class UDPSocket;
+
+/**
+IP Endpoint (address, port)
+*/
+class Endpoint {
+ friend class UDPSocket;
+
+public:
+ /** IP Endpoint (address, port)
+ */
+ Endpoint(void);
+
+ ~Endpoint(void);
+
+ /** Reset the address of this endpoint
+ */
+ void reset_address(void);
+
+ /** Set the address of this endpoint
+ \param host The endpoint address (it can either be an IP Address or a hostname that will be resolved with DNS).
+ \param port The endpoint port
+ \return 0 on success, -1 on failure (when an hostname cannot be resolved by DNS).
+ */
+ int set_address(const char* host, const int port);
+
+ /** Get the IP address of this endpoint
+ \return The IP address of this endpoint.
+ */
+ char* get_address(void);
+
+ /** Get the port of this endpoint
+ \return The port of this endpoint
+ */
+ int get_port(void);
+
+protected:
+ char _ipAddress[128];
+ int _port;
+};
+
+#endif
--- a/IPStack.h Thu May 15 22:02:08 2014 +0000
+++ b/IPStack.h Mon May 19 12:36:11 2014 -0500
@@ -1,4 +1,119 @@
#ifndef IPSTACK_H
#define IPSTACK_H
-#endif
\ No newline at end of file
+#include "mbed.h"
+#include <string>
+#include "CommInterface.h"
+
+/** This class is a pure virtual class that should be inherited from when implementing
+* a communications device with an onboard IP stack. Examples of this would be a Wi-Fi
+* or Cellular radio. The inheriting class should map the device commands and functionality
+* to the pure virtual methods provided here. There should also be at least one or more calls
+* to setup the communication link specific paramters as an init method for example. This
+* would do things like configure the APN in a cellular radio or set the ssid for a WiFi device,
+* which cannot be accounted for in an abstract class like this one. Note that to provide physical
+* connection management methods this class inherits from CommInterface.
+*/
+class IPStack : public CommInterface
+{
+public:
+ /// An enumeration for selecting the Socket Mode of TCP or UDP.
+ enum Mode {
+ TCP, UDP
+ };
+
+ /** This method is used to set the local port for the UDP or TCP socket connection.
+ * The connection can be made using the open method.
+ *
+ * @param port the local port of the socket as an int.
+ */
+ virtual bool bind(unsigned int port) = 0;
+
+ /** This method is used to open a socket connection with the given parameters.
+ *
+ * @param address is the address you want to connect to in the form of xxx.xxx.xxx.xxx
+ * or a URL. If using a URL make sure the device supports DNS and is properly configured
+ * for that mode.
+ * @param port the remote port you want to connect to.
+ * @param mode an enum that specifies whether this socket connection is type TCP or UDP.
+ * @returns true if the connection was successfully opened, otherwise false.
+ */
+ virtual bool open(const std::string& address, unsigned int port, Mode mode) = 0;
+
+ /** This method is used to determine if a socket connection is currently open.
+ *
+ * @returns true if the socket is currently open, otherwise false.
+ */
+ virtual bool isOpen() = 0;
+
+ /** This method is used to close a socket connection that is currently open.
+ *
+ * @returns true if successfully closed, otherwise returns false on an error.
+ */
+ virtual bool close() = 0;
+
+ /** This method is used to read data off of a socket, assuming a valid socket
+ * connection is already open.
+ *
+ * @param data a pointer to the data buffer that will be filled with the read data.
+ * @param max the maximum number of bytes to attempt to read, typically the same as
+ * the size of the passed in data buffer.
+ * @param timeout the amount of time in milliseconds to wait in trying to read the max
+ * number of bytes. If set to -1 the call blocks until it receives the max number of bytes
+ * or encounters and error.
+ * @returns the number of bytes read and stored in the passed in data buffer. Returns
+ * -1 if there was an error in reading.
+ */
+ virtual int read(char* data, int max, int timeout = -1) = 0;
+
+ /** This method is used to write data to a socket, assuming a valid socket
+ * connection is already open.
+ *
+ * @param data a pointer to the data buffer that will be written to the socket.
+ * @param length the size of the data buffer to be written.
+ * @param timeout the amount of time in milliseconds to wait in trying to write the entire
+ * number of bytes. If set to -1 the call blocks until it writes all of the bytes or
+ * encounters and error.
+ * @returns the number of bytes written to the socket's write buffer. Returns
+ * -1 if there was an error in writing.
+ */
+ virtual int write(const char* data, int length, int timeout = -1) = 0;
+
+ /** This method is used to get the number of bytes available to read off the
+ * socket.
+ *
+ * @returns the number of bytes available, 0 if there are no bytes to read.
+ */
+ virtual unsigned int readable() = 0;
+
+ /** This method is used to get the space available to write bytes to the socket.
+ *
+ * @returns the number of bytes that can be written, 0 if unable to write.
+ */
+ virtual unsigned int writeable() = 0;
+
+ /** This method is used test network connectivity by pinging a server.
+ *
+ * @param address the address of the server in format xxx.xxx.xxx.xxx. The
+ * default 8.8.8.8 which is Google's DNS Server.
+ * @returns true if the ping was successful, otherwise false.
+ */
+ virtual bool ping(const std::string& address = "8.8.8.8") = 0;
+
+ /** This method is used to get the IP address of the device, which can be
+ * set either statically or via DHCP after connecting to a network.
+ *
+ * @returns the devices IP address.
+ */
+ virtual std::string getDeviceIP() = 0;
+
+ /** This method is used to set the IP address or puts the module in DHCP mode.
+ *
+ * @param address the IP address you want to use in the form of xxx.xxx.xxx.xxx or DHCP
+ * if you want to use DHCP. The default is DHCP.
+ * @returns true if successful, otherwise returns false.
+ */
+ virtual bool setDeviceIP(std::string address = "DHCP") = 0;
+};
+
+#endif /* IPSTACK_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket.cpp Mon May 19 12:36:11 2014 -0500
@@ -0,0 +1,20 @@
+#include "Socket.h"
+#include <cstring>
+#include "Transport.h"
+
+Socket::Socket() : _blocking(true), _timeout(1500) {
+ ip = Transport::getInstance();
+}
+
+void Socket::set_blocking(bool blocking, unsigned int timeout) {
+ _blocking = blocking;
+ _timeout = timeout;
+}
+
+int Socket::close() {
+ return (ip->close()) ? 0 : -1;
+}
+
+Socket::~Socket() {
+ close(); //Don't want to leak
+}
--- a/Socket.h Thu May 15 22:02:08 2014 +0000
+++ b/Socket.h Mon May 19 12:36:11 2014 -0500
@@ -1,4 +1,35 @@
-#ifndef SOCKET_H
-#define SOCKET_H
-
-#endif
\ No newline at end of file
+#ifndef SOCKET_H
+#define SOCKET_H
+
+#include "mbed.h"
+#include "IPStack.h"
+
+/** Socket file descriptor and select wrapper
+ */
+class Socket {
+public:
+ /** Socket
+ */
+ Socket();
+
+ /** Set blocking or non-blocking mode of the socket and a timeout on
+ blocking socket operations
+ \param blocking true for blocking mode, false for non-blocking mode.
+ \param timeout timeout in ms [Default: (1500)ms].
+ */
+ void set_blocking(bool blocking, unsigned int timeout=1500);
+
+ /** Close the socket file descriptor
+ */
+ int close();
+
+ ~Socket();
+
+protected:
+ bool _blocking;
+ int _timeout;
+ IPStack * ip;
+};
+
+
+#endif /* SOCKET_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TCPSocketConnection.cpp Mon May 19 12:36:11 2014 -0500
@@ -0,0 +1,81 @@
+#include "TCPSocketConnection.h"
+#include <algorithm>
+
+TCPSocketConnection::TCPSocketConnection()
+{
+}
+
+int TCPSocketConnection::connect(const char* host, const int port)
+{
+ if (!ip->open(host, port, IPStack::TCP)) {
+ return -1;
+ }
+ return 0;
+}
+
+bool TCPSocketConnection::is_connected(void)
+{
+ return ip->isOpen();
+}
+
+int TCPSocketConnection::send(char* data, int length)
+{
+ Timer tmr;
+
+ if (!_blocking) {
+ tmr.start();
+ while (tmr.read_ms() < _timeout) {
+ if (ip->writeable())
+ break;
+ }
+ if (tmr.read_ms() >= _timeout) {
+ return -1;
+ }
+ }
+ return ip->write(data, length, 0);
+}
+
+// -1 if unsuccessful, else number of bytes written
+int TCPSocketConnection::send_all(char* data, int length)
+{
+ if (_blocking) {
+ return ip->write(data, length, -1);
+ } else {
+ return ip->write(data, length, _timeout);
+ }
+}
+
+// -1 if unsuccessful, else number of bytes received
+int TCPSocketConnection::receive(char* data, int length)
+{
+ Timer tmr;
+ int time = -1;
+
+ if (!_blocking) {
+ tmr.start();
+ while (time < _timeout + 20) {
+ if (ip->readable()) {
+ break;
+ }
+ time = tmr.read_ms();
+ }
+ if (time >= _timeout + 20) {
+ return -1;
+ }
+ } else {
+ while(!ip->readable());
+ }
+
+ return ip->read(data, length, 0);
+}
+
+
+// -1 if unsuccessful, else number of bytes received
+int TCPSocketConnection::receive_all(char* data, int length)
+{
+ if (_blocking) {
+ return ip->read(data, length, -1);
+ } else {
+ return ip->read(data, length, _timeout);
+ }
+}
--- a/TCPSocketConnection.h Thu May 15 22:02:08 2014 +0000
+++ b/TCPSocketConnection.h Mon May 19 12:36:11 2014 -0500
@@ -1,4 +1,59 @@
-#ifndef TCPSOCKETCONNECTION_H
-#define TCPSOCKETCONNECTION_H
-
-#endif
\ No newline at end of file
+#ifndef TCPSOCKETCONNECTION_H
+#define TCPSOCKETCONNECTION_H
+
+#include "mbed.h"
+#include "Socket.h"
+#include "Endpoint.h"
+
+/**
+TCP socket connection
+*/
+class TCPSocketConnection: public Socket, public Endpoint {
+
+public:
+ /** TCP socket connection
+ */
+ TCPSocketConnection();
+
+ /** Connects this TCP socket to the server
+ \param host The host to connect to. It can either be an IP Address or a hostname that will be resolved with DNS.
+ \param port The host's port to connect to.
+ \return 0 on success, -1 on failure.
+ */
+ int connect(const char* host, const int port);
+
+ /** Check if the socket is connected
+ \return true if connected, false otherwise.
+ */
+ bool is_connected(void);
+
+ /** Send data to the remote host.
+ \param data The buffer to send to the host.
+ \param length The length of the buffer to send.
+ \return the number of written bytes on success (>=0) or -1 on failure
+ */
+ int send(char* data, int length);
+
+ /** Send all the data to the remote host.
+ \param data The buffer to send to the host.
+ \param length The length of the buffer to send.
+ \return the number of written bytes on success (>=0) or -1 on failure
+ */
+ int send_all(char* data, int length);
+
+ /** Receive data from the remote host.
+ \param data The buffer in which to store the data received from the host.
+ \param length The maximum length of the buffer.
+ \return the number of received bytes on success (>=0) or -1 on failure
+ */
+ int receive(char* data, int length);
+
+ /** Receive all the data from the remote host.
+ \param data The buffer in which to store the data received from the host.
+ \param length The maximum length of the buffer.
+ \return the number of received bytes on success (>=0) or -1 on failure
+ */
+ int receive_all(char* data, int length);
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Transport.cpp Mon May 19 12:36:11 2014 -0500
@@ -0,0 +1,14 @@
+#include "Transport.h"
+
+IPStack* Transport::transport = NULL;
+
+void Transport::setTransport(IPStack* type)
+{
+ transport = type;
+}
+
+IPStack* Transport::getInstance()
+{
+ return transport;
+}
+
--- a/Transport.h Thu May 15 22:02:08 2014 +0000
+++ b/Transport.h Mon May 19 12:36:11 2014 -0500
@@ -1,4 +1,36 @@
#ifndef TRANSPORT_H
#define TRANSPORT_H
-#endif
\ No newline at end of file
+#include "mbed.h"
+#include "IPStack.h"
+
+/** This class has been added to the standard mbed Socket library enabling people
+* to use the Socket library interfaces for different transports. Use this class prior
+* to instantiating any of the other classes in this folder to determine the underlying
+* transport that will be used by them. It is important to know that the transport classes
+* themsleves which derive from IPStack.h, must be properly initialized and connected before any
+* of the Socket package classes can be used.
+*/
+class Transport
+{
+public:
+ /** This method allows you to set the transport to be used when creatin other
+ * objects from the Socket folder like TCPSocketConnection and UDPSocket.
+ *
+ * @param type the type of underlying transport to be used as an IPStack object.
+ */
+ static void setTransport(IPStack* type);
+
+ /** This method is used within the Socket class to get the appropraite transport
+ * as an IPStack object. In general you do not need to call this directly, but
+ * simply use the other classes in this folder.
+ *
+ * @returns a pointer to an object that implements IPStack.
+ */
+ static IPStack* getInstance();
+
+private:
+ static IPStack* transport; //Member variable that holds an custom transport type.
+};
+
+#endif /* TRANSPORT_H */
--- a/UDPSocket.h Thu May 15 22:02:08 2014 +0000 +++ b/UDPSocket.h Mon May 19 12:36:11 2014 -0500 @@ -1,4 +1,6 @@ #ifndef UDPSOCKET_H #define UDPSOCKET_H -#endif \ No newline at end of file +#include "mbed.h" + +#endif
