PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
7.9KB

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