mirror of
https://github.com/opnsense/src.git
synced 2026-03-02 21:31:02 -05:00
(A number of files not required for the FreeBSD build have been removed.) Sponsored by: DARPA, AFRL
415 lines
16 KiB
C++
415 lines
16 KiB
C++
//===-- Communication.h -----------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef liblldb_Communication_h_
|
|
#define liblldb_Communication_h_
|
|
|
|
// C Includes
|
|
// C++ Includes
|
|
#include <string>
|
|
|
|
// Other libraries and framework includes
|
|
// Project includes
|
|
#include "lldb/lldb-private.h"
|
|
#include "lldb/Core/Broadcaster.h"
|
|
#include "lldb/Core/Error.h"
|
|
#include "lldb/Host/Mutex.h"
|
|
#include "lldb/lldb-private.h"
|
|
|
|
namespace lldb_private {
|
|
|
|
//----------------------------------------------------------------------
|
|
/// @class Communication Communication.h "lldb/Core/Communication.h"
|
|
/// @brief An abstract communications class.
|
|
///
|
|
/// Communication is an class that handles data communication
|
|
/// between two data sources. It uses a Connection class to do the
|
|
/// real communication. This approach has a couple of advantages: it
|
|
/// allows a single instance of this class to be used even though its
|
|
/// connection can change. Connections could negotiate for different
|
|
/// connections based on abilities like starting with Bluetooth and
|
|
/// negotiating up to WiFi if available. It also allows this class to be
|
|
/// subclassed by any interfaces that don't want to give bytes but want
|
|
/// to validate and give out packets. This can be done by overriding:
|
|
///
|
|
/// AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast);
|
|
///
|
|
/// Communication inherits from Broadcaster which means it can be
|
|
/// used in conjunction with Listener to wait for multiple broadcaster
|
|
/// objects and multiple events from each of those objects.
|
|
/// Communication defines a set of pre-defined event bits (see
|
|
/// enumerations definitions that start with "eBroadcastBit" below).
|
|
///
|
|
/// There are two modes in which communications can occur:
|
|
/// @li single-threaded
|
|
/// @li multi-threaded
|
|
///
|
|
/// In single-threaded mode, all reads and writes happen synchronously
|
|
/// on the calling thread.
|
|
///
|
|
/// In multi-threaded mode, a read thread is spawned that continually
|
|
/// reads data and caches any received bytes. To start the read thread
|
|
/// clients call:
|
|
///
|
|
/// bool Communication::StartReadThread (Error *);
|
|
///
|
|
/// If true is returned a read thead has been spawned that will
|
|
/// continually execute a call to the pure virtual DoRead function:
|
|
///
|
|
/// size_t Communication::ReadFromConnection (void *, size_t, uint32_t);
|
|
///
|
|
/// When bytes are received the data gets cached in \a m_bytes and this
|
|
/// class will broadcast a \b eBroadcastBitReadThreadGotBytes event.
|
|
/// Clients that want packet based communication should override
|
|
/// AppendBytesToCache. The subclasses can choose to call the
|
|
/// built in AppendBytesToCache with the \a broadcast parameter set to
|
|
/// false. This will cause the \b eBroadcastBitReadThreadGotBytes event
|
|
/// not get broadcast, and then the subclass can post a \b
|
|
/// eBroadcastBitPacketAvailable event when a full packet of data has
|
|
/// been received.
|
|
///
|
|
/// If the connection is disconnected a \b eBroadcastBitDisconnected
|
|
/// event gets broadcast. If the read thread exits a \b
|
|
/// eBroadcastBitReadThreadDidExit event will be broadcast. Clients
|
|
/// can also post a \b eBroadcastBitReadThreadShouldExit event to this
|
|
/// object which will cause the read thread to exit.
|
|
//----------------------------------------------------------------------
|
|
class Communication : public Broadcaster
|
|
{
|
|
public:
|
|
enum {
|
|
eBroadcastBitDisconnected = (1 << 0), ///< Sent when the communications connection is lost.
|
|
eBroadcastBitReadThreadGotBytes = (1 << 1), ///< Sent by the read thread when bytes become available.
|
|
eBroadcastBitReadThreadDidExit = (1 << 2), ///< Sent by the read thread when it exits to inform clients.
|
|
eBroadcastBitReadThreadShouldExit = (1 << 3), ///< Sent by clients that need to cancel the read thread.
|
|
eBroadcastBitPacketAvailable = (1 << 4), ///< Sent when data received makes a complete packet.
|
|
kLoUserBroadcastBit = (1 << 16),///< Subclasses can used bits 31:16 for any needed events.
|
|
kHiUserBroadcastBit = (1 << 31),
|
|
eAllEventBits = 0xffffffff
|
|
};
|
|
|
|
typedef void (*ReadThreadBytesReceived) (void *baton, const void *src, size_t src_len);
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
/// Construct the Communication object with the specified name for
|
|
/// the Broadcaster that this object inherits from.
|
|
///
|
|
/// @param[in] broadcaster_name
|
|
/// The name of the broadcaster object. This name should be as
|
|
/// complete as possible to uniquely identify this object. The
|
|
/// broadcaster name can be updated after the connect function
|
|
/// is called.
|
|
//------------------------------------------------------------------
|
|
Communication(const char * broadcaster_name);
|
|
|
|
//------------------------------------------------------------------
|
|
/// Destructor.
|
|
///
|
|
/// The destructor is virtual since this class gets subclassed.
|
|
//------------------------------------------------------------------
|
|
virtual
|
|
~Communication();
|
|
|
|
void
|
|
Clear ();
|
|
|
|
//------------------------------------------------------------------
|
|
/// Connect using the current connection by passing \a url to its
|
|
/// connect function.
|
|
/// string.
|
|
///
|
|
/// @param[in] url
|
|
/// A string that contains all information needed by the
|
|
/// subclass to connect to another client.
|
|
///
|
|
/// @return
|
|
/// \b True if the connect succeeded, \b false otherwise. The
|
|
/// internal error object should be filled in with an
|
|
/// appropriate value based on the result of this function.
|
|
///
|
|
/// @see Error& Communication::GetError ();
|
|
/// @see bool Connection::Connect (const char *url);
|
|
//------------------------------------------------------------------
|
|
lldb::ConnectionStatus
|
|
Connect (const char *url, Error *error_ptr);
|
|
|
|
//------------------------------------------------------------------
|
|
/// Disconnect the communications connection if one is currently
|
|
/// connected.
|
|
///
|
|
/// @return
|
|
/// \b True if the disconnect succeeded, \b false otherwise. The
|
|
/// internal error object should be filled in with an
|
|
/// appropriate value based on the result of this function.
|
|
///
|
|
/// @see Error& Communication::GetError ();
|
|
/// @see bool Connection::Disconnect ();
|
|
//------------------------------------------------------------------
|
|
lldb::ConnectionStatus
|
|
Disconnect (Error *error_ptr = NULL);
|
|
|
|
//------------------------------------------------------------------
|
|
/// Check if the connection is valid.
|
|
///
|
|
/// @return
|
|
/// \b True if this object is currently connected, \b false
|
|
/// otherwise.
|
|
//------------------------------------------------------------------
|
|
bool
|
|
IsConnected () const;
|
|
|
|
bool
|
|
HasConnection () const;
|
|
|
|
lldb_private::Connection *
|
|
GetConnection ()
|
|
{
|
|
return m_connection_sp.get();
|
|
}
|
|
//------------------------------------------------------------------
|
|
/// Read bytes from the current connection.
|
|
///
|
|
/// If no read thread is running, this function call the
|
|
/// connection's Connection::Read(...) function to get any available.
|
|
///
|
|
/// If a read thread has been started, this function will check for
|
|
/// any cached bytes that have already been read and return any
|
|
/// currently available bytes. If no bytes are cached, it will wait
|
|
/// for the bytes to become available by listening for the \a
|
|
/// eBroadcastBitReadThreadGotBytes event. If this function consumes
|
|
/// all of the bytes in the cache, it will reset the
|
|
/// \a eBroadcastBitReadThreadGotBytes event bit.
|
|
///
|
|
/// @param[in] dst
|
|
/// A destination buffer that must be at least \a dst_len bytes
|
|
/// long.
|
|
///
|
|
/// @param[in] dst_len
|
|
/// The number of bytes to attempt to read, and also the max
|
|
/// number of bytes that can be placed into \a dst.
|
|
///
|
|
/// @param[in] timeout_usec
|
|
/// A timeout value in micro-seconds.
|
|
///
|
|
/// @return
|
|
/// The number of bytes actually read.
|
|
///
|
|
/// @see size_t Connection::Read (void *, size_t);
|
|
//------------------------------------------------------------------
|
|
size_t
|
|
Read (void *dst,
|
|
size_t dst_len,
|
|
uint32_t timeout_usec,
|
|
lldb::ConnectionStatus &status,
|
|
Error *error_ptr);
|
|
|
|
//------------------------------------------------------------------
|
|
/// The actual write function that attempts to write to the
|
|
/// communications protocol.
|
|
///
|
|
/// Subclasses must override this function.
|
|
///
|
|
/// @param[in] src
|
|
/// A source buffer that must be at least \a src_len bytes
|
|
/// long.
|
|
///
|
|
/// @param[in] src_len
|
|
/// The number of bytes to attempt to write, and also the
|
|
/// number of bytes are currently available in \a src.
|
|
///
|
|
/// @return
|
|
/// The number of bytes actually Written.
|
|
//------------------------------------------------------------------
|
|
size_t
|
|
Write (const void *src,
|
|
size_t src_len,
|
|
lldb::ConnectionStatus &status,
|
|
Error *error_ptr);
|
|
|
|
//------------------------------------------------------------------
|
|
/// Sets the connection that it to be used by this class.
|
|
///
|
|
/// By making a communication class that uses different connections
|
|
/// it allows a single communication interface to negotiate and
|
|
/// change its connection without any interruption to the client.
|
|
/// It also allows the Communication class to be subclassed for
|
|
/// packet based communication.
|
|
///
|
|
/// @param[in] connection
|
|
/// A connection that this class will own and destroy.
|
|
///
|
|
/// @see
|
|
/// class Connection
|
|
//------------------------------------------------------------------
|
|
void
|
|
SetConnection (Connection *connection);
|
|
|
|
//------------------------------------------------------------------
|
|
/// Starts a read thread whose sole purpose it to read bytes from
|
|
/// the current connection. This function will call connection's
|
|
/// read function:
|
|
///
|
|
/// size_t Connection::Read (void *, size_t);
|
|
///
|
|
/// When bytes are read and cached, this function will call:
|
|
///
|
|
/// Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast);
|
|
///
|
|
/// Subclasses should override this function if they wish to override
|
|
/// the default action of caching the bytes and broadcasting a \b
|
|
/// eBroadcastBitReadThreadGotBytes event.
|
|
///
|
|
/// @return
|
|
/// \b True if the read thread was successfully started, \b
|
|
/// false otherwise.
|
|
///
|
|
/// @see size_t Connection::Read (void *, size_t);
|
|
/// @see void Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast);
|
|
//------------------------------------------------------------------
|
|
virtual bool
|
|
StartReadThread (Error *error_ptr = NULL);
|
|
|
|
//------------------------------------------------------------------
|
|
/// Stops the read thread by cancelling it.
|
|
///
|
|
/// @return
|
|
/// \b True if the read thread was successfully canceled, \b
|
|
/// false otherwise.
|
|
//------------------------------------------------------------------
|
|
virtual bool
|
|
StopReadThread (Error *error_ptr = NULL);
|
|
|
|
virtual bool
|
|
JoinReadThread (Error *error_ptr = NULL);
|
|
//------------------------------------------------------------------
|
|
/// Checks if there is a currently running read thread.
|
|
///
|
|
/// @return
|
|
/// \b True if the read thread is running, \b false otherwise.
|
|
//------------------------------------------------------------------
|
|
bool
|
|
ReadThreadIsRunning ();
|
|
|
|
//------------------------------------------------------------------
|
|
/// The static read thread function. This function will call
|
|
/// the "DoRead" function continuously and wait for data to become
|
|
/// avaialble. When data is received it will append the available
|
|
/// data to the internal cache and broadcast a
|
|
/// \b eBroadcastBitReadThreadGotBytes event.
|
|
///
|
|
/// @param[in] comm_ptr
|
|
/// A pointer to an instance of this class.
|
|
///
|
|
/// @return
|
|
/// \b NULL.
|
|
///
|
|
/// @see void Communication::ReadThreadGotBytes (const uint8_t *, size_t);
|
|
//------------------------------------------------------------------
|
|
static lldb::thread_result_t
|
|
ReadThread (lldb::thread_arg_t comm_ptr);
|
|
|
|
void
|
|
SetReadThreadBytesReceivedCallback (ReadThreadBytesReceived callback,
|
|
void *callback_baton);
|
|
|
|
static const char *
|
|
ConnectionStatusAsCString (lldb::ConnectionStatus status);
|
|
|
|
bool
|
|
GetCloseOnEOF () const
|
|
{
|
|
return m_close_on_eof;
|
|
}
|
|
|
|
void
|
|
SetCloseOnEOF (bool b)
|
|
{
|
|
m_close_on_eof = b;
|
|
}
|
|
|
|
static ConstString &GetStaticBroadcasterClass ();
|
|
|
|
virtual ConstString &GetBroadcasterClass() const
|
|
{
|
|
return GetStaticBroadcasterClass();
|
|
}
|
|
|
|
private:
|
|
//------------------------------------------------------------------
|
|
// For Communication only
|
|
//------------------------------------------------------------------
|
|
DISALLOW_COPY_AND_ASSIGN (Communication);
|
|
|
|
|
|
protected:
|
|
lldb::ConnectionSP m_connection_sp; ///< The connection that is current in use by this communications class.
|
|
lldb::thread_t m_read_thread; ///< The read thread handle in case we need to cancel the thread.
|
|
bool m_read_thread_enabled;
|
|
std::string m_bytes; ///< A buffer to cache bytes read in the ReadThread function.
|
|
Mutex m_bytes_mutex; ///< A mutex to protect multi-threaded access to the cached bytes.
|
|
Mutex m_write_mutex; ///< Don't let multiple threads write at the same time...
|
|
ReadThreadBytesReceived m_callback;
|
|
void *m_callback_baton;
|
|
bool m_close_on_eof;
|
|
|
|
size_t
|
|
ReadFromConnection (void *dst,
|
|
size_t dst_len,
|
|
uint32_t timeout_usec,
|
|
lldb::ConnectionStatus &status,
|
|
Error *error_ptr);
|
|
//------------------------------------------------------------------
|
|
/// Append new bytes that get read from the read thread into the
|
|
/// internal object byte cache. This will cause a \b
|
|
/// eBroadcastBitReadThreadGotBytes event to be broadcast if \a
|
|
/// broadcast is true.
|
|
///
|
|
/// Subclasses can override this function in order to inspect the
|
|
/// received data and check if a packet is available.
|
|
///
|
|
/// Subclasses can also still call this function from the
|
|
/// overridden method to allow the caching to correctly happen and
|
|
/// suppress the broadcasting of the \a eBroadcastBitReadThreadGotBytes
|
|
/// event by setting \a broadcast to false.
|
|
///
|
|
/// @param[in] src
|
|
/// A source buffer that must be at least \a src_len bytes
|
|
/// long.
|
|
///
|
|
/// @param[in] src_len
|
|
/// The number of bytes to append to the cache.
|
|
//------------------------------------------------------------------
|
|
virtual void
|
|
AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast, lldb::ConnectionStatus status);
|
|
|
|
//------------------------------------------------------------------
|
|
/// Get any available bytes from our data cache. If this call
|
|
/// empties the data cache, the \b eBroadcastBitReadThreadGotBytes event
|
|
/// will be reset to signify no more bytes are available.
|
|
///
|
|
/// @param[in] dst
|
|
/// A destination buffer that must be at least \a dst_len bytes
|
|
/// long.
|
|
///
|
|
/// @param[in] dst_len
|
|
/// The number of bytes to attempt to read from the cache,
|
|
/// and also the max number of bytes that can be placed into
|
|
/// \a dst.
|
|
///
|
|
/// @return
|
|
/// The number of bytes extracted from the data cache.
|
|
//------------------------------------------------------------------
|
|
size_t
|
|
GetCachedBytes (void *dst, size_t dst_len);
|
|
};
|
|
|
|
} // namespace lldb_private
|
|
|
|
#endif // liblldb_Communication_h_
|