Files
BloomPatched/src/DebugServers/GdbRsp/Connection.hpp

140 lines
4.0 KiB
C++
Raw Normal View History

2021-04-04 21:04:12 +01:00
#pragma once
#include <sys/socket.h>
#include <netinet/in.h>
2021-04-04 21:04:12 +01:00
#include <cstdint>
#include <utility>
2021-04-04 21:04:12 +01:00
#include <vector>
#include <queue>
#include <array>
#include <chrono>
2021-04-04 21:04:12 +01:00
#include "src/Helpers/EventNotifier.hpp"
#include "src/Helpers/EpollInstance.hpp"
#include "src/DebugServers/GdbRsp/Packet.hpp"
2021-04-04 21:04:12 +01:00
#include "src/DebugServers/GdbRsp/ResponsePackets/ResponsePacket.hpp"
namespace Bloom::DebugServers::Gdb
{
/**
* The Connection class represents an active connection between the GDB RSP server and client.
*/
class Connection
{
public:
explicit Connection(int serverSocketFileDescriptor, EventNotifier& interruptEventNotifier);
2021-04-04 21:04:12 +01:00
Connection() = delete;
Connection(const Connection&) = delete;
Connection& operator = (Connection&) = delete;
Connection& operator = (Connection&&) = delete;
Connection(Connection&& other) noexcept
: interruptEventNotifier(other.interruptEventNotifier)
, socketFileDescriptor(other.socketFileDescriptor)
, epollInstance(std::move(other.epollInstance))
, readInterruptEnabled(other.readInterruptEnabled)
{
other.socketFileDescriptor = std::nullopt;
}
~Connection();
2021-04-04 21:04:12 +01:00
/**
* Obtains the human readable IP address of the connected client.
*
* @return
*/
[[nodiscard]] std::string getIpAddress() const;
2021-04-04 21:04:12 +01:00
/**
* Waits for incoming data from the client and returns the raw GDB packets.
2021-04-04 21:04:12 +01:00
*
* @return
*/
std::vector<RawPacketType> readRawPackets();
2021-04-04 21:04:12 +01:00
/**
* Sends a response packet to the client.
*
* @param packet
*/
void writePacket(const ResponsePackets::ResponsePacket& packet);
2021-04-04 21:04:12 +01:00
[[nodiscard]] int getMaxPacketSize() const {
2021-04-04 21:04:12 +01:00
return this->maxPacketSize;
}
private:
std::optional<int> socketFileDescriptor;
EpollInstance epollInstance = EpollInstance();
struct sockaddr_in socketAddress = {};
int maxPacketSize = 1024;
/**
* The interruptEventNotifier allows us to interrupt blocking IO calls on the GDB debug server.
* Under the hood, this is just a wrapper for a Linux event notifier. See the EventNotifier class for more.
*/
EventNotifier& interruptEventNotifier;
bool readInterruptEnabled = false;
/**
* Accepts a connection on serverSocketFileDescriptor.
*
* @param serverSocketFileDescriptor
*/
void accept(int serverSocketFileDescriptor);
/**
* Closes the connection with the client.
*/
void close() noexcept;
/**
* Reads data from the client into a raw buffer.
*
* @param bytes
* Number of bytes to read.
*
* @param interruptible
* If this flag is set to false, no other component within Bloom will be able to gracefully interrupt
* the read (via means of this->interruptEventNotifier). This flag has no effect if this->readInterruptEnabled
* is false.
*
* @param timeout
* The timeout in milliseconds. If not supplied, no timeout will be applied.
*
* @return
*/
2022-03-27 18:34:08 +01:00
std::vector<unsigned char> read(
std::size_t bytes = 0,
bool interruptible = true,
std::optional<std::chrono::milliseconds> timeout = std::nullopt
2022-03-27 18:34:08 +01:00
);
/**
* Does the same as Connection::read(), but only reads a single byte.
*
* @param interruptible
* See Connection::read().
*
* @return
*/
std::optional<unsigned char> readSingleByte(bool interruptible = true);
/**
* Writes data from a raw buffer to the client connection.
*
* @param buffer
*/
void write(const std::vector<unsigned char>& buffer);
void disableReadInterrupts();
void enableReadInterrupts();
2021-04-04 21:04:12 +01:00
};
}