V148

Fork of RadioHead-148 by David Rimer

Committer:
davidr99
Date:
Thu Oct 15 01:27:00 2015 +0000
Revision:
0:ab4e012489ef
Messy start, but a port for RadioHead.; Currently the SPI modulus are the only ones that work.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davidr99 0:ab4e012489ef 1 // RH_TCP.h
davidr99 0:ab4e012489ef 2 // Author: Mike McCauley (mikem@aierspayce.com)
davidr99 0:ab4e012489ef 3 // Copyright (C) 2014 Mike McCauley
davidr99 0:ab4e012489ef 4 // $Id: RH_TCP.h,v 1.4 2015/08/13 02:45:47 mikem Exp $
davidr99 0:ab4e012489ef 5 #ifndef RH_TCP_h
davidr99 0:ab4e012489ef 6 #define RH_TCP_h
davidr99 0:ab4e012489ef 7
davidr99 0:ab4e012489ef 8 #include <RHGenericDriver.h>
davidr99 0:ab4e012489ef 9 #include <RHTcpProtocol.h>
davidr99 0:ab4e012489ef 10
davidr99 0:ab4e012489ef 11 /////////////////////////////////////////////////////////////////////
davidr99 0:ab4e012489ef 12 /// \class RH_TCP RH_TCP.h <RH_TCP.h>
davidr99 0:ab4e012489ef 13 /// \brief Driver to send and receive unaddressed, unreliable datagrams via sockets on a Linux simulator
davidr99 0:ab4e012489ef 14 ///
davidr99 0:ab4e012489ef 15 /// \par Overview
davidr99 0:ab4e012489ef 16 ///
davidr99 0:ab4e012489ef 17 /// This class is intended to support the testing of RadioHead manager classes and simulated sketches
davidr99 0:ab4e012489ef 18 /// on a Linux host.
davidr99 0:ab4e012489ef 19 /// RH_TCP class sends messages to and from other simulator sketches via sockets to a 'Luminiferous Ether'
davidr99 0:ab4e012489ef 20 /// simulator server (provided).
davidr99 0:ab4e012489ef 21 /// Multiple instances of simulated clients and servers can run on a single Linux server,
davidr99 0:ab4e012489ef 22 /// passing messages to each other via the etherSimulator.pl server.
davidr99 0:ab4e012489ef 23 ///
davidr99 0:ab4e012489ef 24 /// Simple RadioHead sketches can be compiled and run on Linux using a build script and some support files.
davidr99 0:ab4e012489ef 25 ///
davidr99 0:ab4e012489ef 26 /// \par Running simulated sketches
davidr99 0:ab4e012489ef 27 ///
davidr99 0:ab4e012489ef 28 /// \code
davidr99 0:ab4e012489ef 29 /// cd whatever/RadioHead
davidr99 0:ab4e012489ef 30 /// # build the client for Linux:
davidr99 0:ab4e012489ef 31 /// tools/simBuild examples/simulator/simulator_reliable_datagram_client/simulator_reliable_datagram_client.pde
davidr99 0:ab4e012489ef 32 /// # build the server for Linux:
davidr99 0:ab4e012489ef 33 /// tools/simBuild examples/simulator/simulator_reliable_datagram_server/simulator_reliable_datagram_server.pde
davidr99 0:ab4e012489ef 34 /// # in one window, run the simulator server:
davidr99 0:ab4e012489ef 35 /// tools/etherSimulator.pl
davidr99 0:ab4e012489ef 36 /// # in another window, run the server
davidr99 0:ab4e012489ef 37 /// ./simulator_reliable_datagram_server
davidr99 0:ab4e012489ef 38 /// # in another window, run the client:
davidr99 0:ab4e012489ef 39 /// ./simulator_reliable_datagram_client
davidr99 0:ab4e012489ef 40 /// # see output:
davidr99 0:ab4e012489ef 41 /// Sending to simulator_reliable_datagram_server
davidr99 0:ab4e012489ef 42 /// got reply from : 0x02: And hello back to you
davidr99 0:ab4e012489ef 43 /// Sending to simulator_reliable_datagram_server
davidr99 0:ab4e012489ef 44 /// got reply from : 0x02: And hello back to you
davidr99 0:ab4e012489ef 45 /// Sending to simulator_reliable_datagram_server
davidr99 0:ab4e012489ef 46 /// got reply from : 0x02: And hello back to you
davidr99 0:ab4e012489ef 47 /// ...
davidr99 0:ab4e012489ef 48 /// \endcode
davidr99 0:ab4e012489ef 49 ///
davidr99 0:ab4e012489ef 50 /// You can change the listen port and the simulated baud rate with
davidr99 0:ab4e012489ef 51 /// command line arguments passed to etherSimulator.pl
davidr99 0:ab4e012489ef 52 ///
davidr99 0:ab4e012489ef 53 /// \par Implementation
davidr99 0:ab4e012489ef 54 ///
davidr99 0:ab4e012489ef 55 /// etherServer.pl is a conventional server written in Perl.
davidr99 0:ab4e012489ef 56 /// listens on a TCP socket (defaults to port 4000) for connections from sketch simulators
davidr99 0:ab4e012489ef 57 /// using RH_TCP as theur driver.
davidr99 0:ab4e012489ef 58 /// The simulated sketches send messages out to the 'ether' over the TCP connection to the etherServer.
davidr99 0:ab4e012489ef 59 /// etherServer manages the delivery of each message to any other RH_TCP sketches that are running.
davidr99 0:ab4e012489ef 60 ///
davidr99 0:ab4e012489ef 61 /// \par Prerequisites
davidr99 0:ab4e012489ef 62 ///
davidr99 0:ab4e012489ef 63 /// g++ compiler installed and in your $PATH
davidr99 0:ab4e012489ef 64 /// Perl
davidr99 0:ab4e012489ef 65 /// Perl POE library
davidr99 0:ab4e012489ef 66 ///
davidr99 0:ab4e012489ef 67 class RH_TCP : public RHGenericDriver
davidr99 0:ab4e012489ef 68 {
davidr99 0:ab4e012489ef 69 public:
davidr99 0:ab4e012489ef 70 /// Constructor
davidr99 0:ab4e012489ef 71 /// \param[in] server Name and optionally the port number of the ether simulator server to contact.
davidr99 0:ab4e012489ef 72 /// Format is "name[:port]", where name can be any valid host name or address (IPV4 or IPV6).
davidr99 0:ab4e012489ef 73 /// The trailing :port is optional, and port can be any valid
davidr99 0:ab4e012489ef 74 /// port name or port number.
davidr99 0:ab4e012489ef 75 RH_TCP(const char* server = "localhost:4000");
davidr99 0:ab4e012489ef 76
davidr99 0:ab4e012489ef 77 /// Initialise the Driver transport hardware and software.
davidr99 0:ab4e012489ef 78 /// Make sure the Driver is properly configured before calling init().
davidr99 0:ab4e012489ef 79 /// \return true if initialisation succeeded.
davidr99 0:ab4e012489ef 80 virtual bool init();
davidr99 0:ab4e012489ef 81
davidr99 0:ab4e012489ef 82 /// Tests whether a new message is available
davidr99 0:ab4e012489ef 83 /// from the Driver.
davidr99 0:ab4e012489ef 84 /// On most drivers, this will also put the Driver into RHModeRx mode until
davidr99 0:ab4e012489ef 85 /// a message is actually received by the transport, when it will be returned to RHModeIdle.
davidr99 0:ab4e012489ef 86 /// This can be called multiple times in a timeout loop
davidr99 0:ab4e012489ef 87 /// \return true if a new, complete, error-free uncollected message is available to be retreived by recv()
davidr99 0:ab4e012489ef 88 virtual bool available();
davidr99 0:ab4e012489ef 89
davidr99 0:ab4e012489ef 90 /// Wait until a new message is available from the driver.
davidr99 0:ab4e012489ef 91 /// Blocks until a complete message is received as reported by available()
davidr99 0:ab4e012489ef 92 virtual void waitAvailable();
davidr99 0:ab4e012489ef 93
davidr99 0:ab4e012489ef 94 /// Wait until a new message is available from the driver
davidr99 0:ab4e012489ef 95 /// or the timeout expires
davidr99 0:ab4e012489ef 96 /// Blocks until a complete message is received as reported by available()
davidr99 0:ab4e012489ef 97 /// \param[in] timeout The maximum time to wait in milliseconds
davidr99 0:ab4e012489ef 98 /// \return true if a message is available as reported by available()
davidr99 0:ab4e012489ef 99 virtual bool waitAvailableTimeout(uint16_t timeout);
davidr99 0:ab4e012489ef 100
davidr99 0:ab4e012489ef 101 /// Turns the receiver on if it not already on.
davidr99 0:ab4e012489ef 102 /// If there is a valid message available, copy it to buf and return true
davidr99 0:ab4e012489ef 103 /// else return false.
davidr99 0:ab4e012489ef 104 /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
davidr99 0:ab4e012489ef 105 /// You should be sure to call this function frequently enough to not miss any messages
davidr99 0:ab4e012489ef 106 /// It is recommended that you call it in your main loop.
davidr99 0:ab4e012489ef 107 /// \param[in] buf Location to copy the received message
davidr99 0:ab4e012489ef 108 /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.
davidr99 0:ab4e012489ef 109 /// \return true if a valid message was copied to buf
davidr99 0:ab4e012489ef 110 virtual bool recv(uint8_t* buf, uint8_t* len);
davidr99 0:ab4e012489ef 111
davidr99 0:ab4e012489ef 112 /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().
davidr99 0:ab4e012489ef 113 /// Then loads a message into the transmitter and starts the transmitter. Note that a message length
davidr99 0:ab4e012489ef 114 /// of 0 is NOT permitted. If the message is too long for the underlying radio technology, send() will
davidr99 0:ab4e012489ef 115 /// return false and will not send the message.
davidr99 0:ab4e012489ef 116 /// \param[in] data Array of data to be sent
davidr99 0:ab4e012489ef 117 /// \param[in] len Number of bytes of data to send (> 0)
davidr99 0:ab4e012489ef 118 /// \return true if the message length was valid and it was correctly queued for transmit
davidr99 0:ab4e012489ef 119 virtual bool send(const uint8_t* data, uint8_t len);
davidr99 0:ab4e012489ef 120
davidr99 0:ab4e012489ef 121 /// Returns the maximum message length
davidr99 0:ab4e012489ef 122 /// available in this Driver.
davidr99 0:ab4e012489ef 123 /// \return The maximum legal message length
davidr99 0:ab4e012489ef 124 virtual uint8_t maxMessageLength();
davidr99 0:ab4e012489ef 125
davidr99 0:ab4e012489ef 126 /// Sets the address of this node. Defaults to 0xFF. Subclasses or the user may want to change this.
davidr99 0:ab4e012489ef 127 /// This will be used to test the adddress in incoming messages. In non-promiscuous mode,
davidr99 0:ab4e012489ef 128 /// only messages with a TO header the same as thisAddress or the broadcast addess (0xFF) will be accepted.
davidr99 0:ab4e012489ef 129 /// In promiscuous mode, all messages will be accepted regardless of the TO header.
davidr99 0:ab4e012489ef 130 /// In a conventional multinode system, all nodes will have a unique address
davidr99 0:ab4e012489ef 131 /// (which you could store in EEPROM).
davidr99 0:ab4e012489ef 132 /// You would normally set the header FROM address to be the same as thisAddress (though you dont have to,
davidr99 0:ab4e012489ef 133 /// allowing the possibilty of address spoofing).
davidr99 0:ab4e012489ef 134 /// \param[in] address The address of this node.
davidr99 0:ab4e012489ef 135 void setThisAddress(uint8_t address);
davidr99 0:ab4e012489ef 136
davidr99 0:ab4e012489ef 137 protected:
davidr99 0:ab4e012489ef 138
davidr99 0:ab4e012489ef 139 private:
davidr99 0:ab4e012489ef 140 /// Connect to the address and port specified by the server constructor argument.
davidr99 0:ab4e012489ef 141 /// Prepares the socket for use.
davidr99 0:ab4e012489ef 142 bool connectToServer();
davidr99 0:ab4e012489ef 143
davidr99 0:ab4e012489ef 144 /// Check for new messages from the ether simulator server
davidr99 0:ab4e012489ef 145 void checkForEvents();
davidr99 0:ab4e012489ef 146
davidr99 0:ab4e012489ef 147 /// Clear the receive buffer
davidr99 0:ab4e012489ef 148 void clearRxBuf();
davidr99 0:ab4e012489ef 149
davidr99 0:ab4e012489ef 150 /// Sends thisAddress to the ether simulator server
davidr99 0:ab4e012489ef 151 /// in a RHTcpThisAddress message.
davidr99 0:ab4e012489ef 152 /// \param[in] thisAddress The node address of this node
davidr99 0:ab4e012489ef 153 /// \return true if successful
davidr99 0:ab4e012489ef 154 bool sendThisAddress(uint8_t thisAddress);
davidr99 0:ab4e012489ef 155
davidr99 0:ab4e012489ef 156 /// Sends a message to the ether simulator server for delivery to
davidr99 0:ab4e012489ef 157 /// other nodes
davidr99 0:ab4e012489ef 158 /// \param[in] data Array of data to be sent
davidr99 0:ab4e012489ef 159 /// \param[in] len Number of bytes of data to send (> 0)
davidr99 0:ab4e012489ef 160 /// \return true if successful
davidr99 0:ab4e012489ef 161 bool sendPacket(const uint8_t* data, uint8_t len);
davidr99 0:ab4e012489ef 162
davidr99 0:ab4e012489ef 163 /// Address and port of the server to which messages are sent
davidr99 0:ab4e012489ef 164 /// and received using the protocol RHTcpPRotocol
davidr99 0:ab4e012489ef 165 const char* _server;
davidr99 0:ab4e012489ef 166
davidr99 0:ab4e012489ef 167 /// The TCP socket used to communicate with the message server
davidr99 0:ab4e012489ef 168 int _socket;
davidr99 0:ab4e012489ef 169
davidr99 0:ab4e012489ef 170 /// Buffer to receive RHTcpProtocol messages
davidr99 0:ab4e012489ef 171 uint8_t _rxBuf[RH_TCP_MAX_PAYLOAD_LEN + 5];
davidr99 0:ab4e012489ef 172 uint16_t _rxBufLen;
davidr99 0:ab4e012489ef 173 bool _rxBufValid;
davidr99 0:ab4e012489ef 174
davidr99 0:ab4e012489ef 175 /// Check whether the latest received message is complete and uncorrupted
davidr99 0:ab4e012489ef 176 void validateRxBuf();
davidr99 0:ab4e012489ef 177
davidr99 0:ab4e012489ef 178 // Used in the interrupt handlers
davidr99 0:ab4e012489ef 179 /// Buf is filled but not validated
davidr99 0:ab4e012489ef 180 volatile bool _rxBufFull;
davidr99 0:ab4e012489ef 181
davidr99 0:ab4e012489ef 182 };
davidr99 0:ab4e012489ef 183
davidr99 0:ab4e012489ef 184 /// @example simulator_reliable_datagram_client.pde
davidr99 0:ab4e012489ef 185 /// @example simulator_reliable_datagram_server.pde
davidr99 0:ab4e012489ef 186
davidr99 0:ab4e012489ef 187 #endif