From 2f89280f3958b86dbe453957a3ce776702e5c51f Mon Sep 17 00:00:00 2001 From: Valerio Pastore Date: Fri, 12 Jan 2024 16:56:50 +0100 Subject: [PATCH 1/2] adding doxygen --- include/UDP_Protocol.h | 202 +++++++++++++++++++++++++++++++++++++++++ src/UDP_Protocol.cpp | 35 ++++--- 2 files changed, 224 insertions(+), 13 deletions(-) diff --git a/include/UDP_Protocol.h b/include/UDP_Protocol.h index 693f382..be8d6ad 100755 --- a/include/UDP_Protocol.h +++ b/include/UDP_Protocol.h @@ -4,6 +4,208 @@ #include #include +/** + * @brief The UDPProtocol class is a derived class of BaseReceiver and represents a UDP protocol receiver. + * check the Base_Receiver.h file for more information. + */ +namespace inaf::oasbo::Receivers { + +class UDPProtocol: public BaseReceiver { +protected: + /** + * @brief Constructs a UDPProtocol object with the specified IP and port. + * + * @param ip The IP address to bind the UDP socket to. + * @param prt The port number to bind the UDP socket to. + */ + UDPProtocol(std::string ip, int prt); + + /** + * @brief Constructs a UDPProtocol object with default IP and port. + */ + UDPProtocol(); + + int srv_sock; /**< The server socket descriptor. */ + std::string ip { }; /**< The IP address to bind the UDP socket to. */ + int port; /**< The port number to bind the UDP socket to. */ + + struct sockaddr_in cliaddr; /**< The client address structure. */ + struct sockaddr_in srvaddr; /**< The server address structure. */ + bool checkIncomingPackets = true; /**< Flag that tells if it has to check for incoming udp packets. Set to false when calling closeConnectionToClient. + * Used to avoid the infinite loop in receiveAtLeastNbytes. + */ + /** + * @brief Splits the IP and port from the given IP:port string. + * + * @param ip_port The IP:port string to split. + * @param ip The extracted IP address. + * @param port The extracted port number. + * @return true if the IP and port were successfully extracted, false otherwise. + */ + bool split_ip_port(const std::string &ip_port, std::string &ip, int &port); + + /** + * @brief Receives at least the specified number of bytes from the client. + * Helper function to receive at least the header of the packet. + * @param buff The buffer to store the received data. + * @param n_bytes The number of bytes to receive. + * @param max_size The max size of bytes to receive. + * @return The number of bytes received. + */ + int receiveAtLeastNbytes(uint8_t *buff, int n_bytes, int max_size); + + /** + * @brief Resets the packet object and sets the number of bytes received. + * + * @param packet The packet object to reset. + * @param bytes The number of bytes received. + */ + void resetPacket(PacketLib::BasePacket& packet, int bytes); + +public: + /** + * @brief Destroys the UDPProtocol object. + */ + ~UDPProtocol(); + + /** + * @brief Gets the host name or IP address that the UDP socket is bound to. + * + * @return The host name or IP address. + */ + std::string getHost() override; + + /** + * @brief Sets the host name or IP address to bind the UDP socket to. + * + * @param host The host name or IP address. + */ + void setHost(std::string host) override; + + /** + * @brief Sets the IP address to bind the UDP socket to. + * + * @param ip The IP address. + */ + void setIp(std::string ip); + + /** + * @brief Gets the IP address that the UDP socket is bound to. + * + * @return The IP address. + */ + std::string getIp(){return this->ip;} + + /** + * @brief Sets the port number to bind the UDP socket to. + * + * @param port The port number. + */ + void setPort(int port); + + /** + * @brief Gets the port number that the UDP socket is bound to. + * + * @return The port number. + */ + int getPort(){return this->port;} + + /** + * @brief Connects to the client. + * + * @return 0 if the connection is successful, -1 otherwise. + */ + int connectToClient() override; + + /** + * @brief Closes the connection to the client. + * + * @return 0 if the connection is closed successfully, -1 otherwise. + */ + int closeConnectionToClient() override; + + /** + * @brief Checks if the UDP socket is connected to the client. + * + * @return true if the UDP socket is connected to the client, false otherwise. + */ + bool isConnectedToClient() const override; + + /** + * @brief Receives a packet from the client. + * + * @param packet The packet object to store the received data. + * @return The number of bytes received. + */ + int receiveFromClient(PacketLib::BasePacket& packet) override; + + friend class UDPProtocolBuilder; +}; + +class UDPProtocolBuilder { +protected: + UDPProtocol *protocol; /**< The UDPProtocol object being built. */ +public: + std::string config_target {"udpreceiver"}; /**< The configuration target. */ + std::string ip_key { "ip" }; /**< The configuration key for IP address. */ + std::string port_key { "port" }; /**< The configuration key for port number. */ + + /** + * @brief Constructs a UDPProtocolBuilder object. + */ + UDPProtocolBuilder(); + + /** + * @brief Constructs a UDPProtocolBuilder object with the specified IP and port. + * + * @param ip The IP address to bind the UDP socket to. + * @param port The port number to bind the UDP socket to. + */ + UDPProtocolBuilder(std::string ip, int port); + + /** + * @brief Destroys the UDPProtocolBuilder object. + */ + ~UDPProtocolBuilder(); + + /** + * @brief Resets the UDPProtocolBuilder object. + */ + void reset(); + + /** + * @brief Configures the UDPProtocolBuilder object from a configurator. + * + * @param conf The configurator object. + * @return A pointer to the UDPProtocolBuilder object. + */ + UDPProtocolBuilder* configFrom(Configurators::BaseConfigurator &conf); + + /** + * @brief Sets the IP address to bind the UDP socket to. + * + * @param ip The IP address. + * @return A pointer to the UDPProtocolBuilder object. + */ + UDPProtocolBuilder* setIp(std::string ip); + + /** + * @brief Sets the port number to bind the UDP socket to. + * + * @param port The port number. + * @return A pointer to the UDPProtocolBuilder object. + */ + UDPProtocolBuilder* setPort(int port); + + /** + * @brief Gets the UDPProtocol object that has been built. + * + * @return A pointer to the UDPProtocol object. + */ + UDPProtocol* getReceiver(); +}; + +} namespace inaf::oasbo::Receivers { class UDPProtocol: public BaseReceiver { diff --git a/src/UDP_Protocol.cpp b/src/UDP_Protocol.cpp index 2b434f6..040ff36 100755 --- a/src/UDP_Protocol.cpp +++ b/src/UDP_Protocol.cpp @@ -33,12 +33,12 @@ UDPProtocol::~UDPProtocol() { closeConnectionToClient(); } -int UDPProtocol::receiveAtLeastHeaderSizeBytes(uint8_t *buff, int headerSize, - int packetSize) { +int UDPProtocol::receiveAtLeastNbytes(uint8_t *buff, int n_bytes, + int max_size) { int bytercv = 0; socklen_t len = sizeof(cliaddr); - while (bytercv < headerSize) { - int rcv = recvfrom(srv_sock, &buff[bytercv], packetSize + 1, // +1 to recognized if there are more bytes than expected + while (bytercv < n_bytes && this->checkIncomingPackets) { + int rcv = recvfrom(srv_sock, &buff[bytercv], max_size + 1, // +1 to recognized if there are more bytes than expected 0, (struct sockaddr*) &cliaddr, &len); bytercv += rcv; @@ -46,23 +46,26 @@ int UDPProtocol::receiveAtLeastHeaderSizeBytes(uint8_t *buff, int headerSize, return -1; } } + if(!this->checkIncomingPackets){ // interrupted by closeConnectionToClient before receiving all the N bytes. + return -1; + } return bytercv; } int UDPProtocol::receiveFromClient(PacketLib::BasePacket &pack) { - bool headerFlag = false; + bool headerFlag = false; // tells if the header has been received uint headerSize = pack.getHeaderSize(); uint packSize = pack.getPacketStructureByteSize(); uint tailSize = pack.getTailSize(); uint payloadSize = 0; uint totPacketSize = 0; ssize_t to_be_received = 0; - uint8_t *buff = new uint8_t[(packSize + headerSize) * headerSize]; // to avoid overflow + uint8_t *buff = new uint8_t[(packSize + headerSize) * headerSize]; // * headerSize to avoid overflow int tot_byte_rcv = 0; - while (true) { + while (this->checkIncomingPackets) { while (!headerFlag) { // until the header has not received - int rcv = receiveAtLeastHeaderSizeBytes(buff, headerSize, packSize); // receive at least headerSize byte, maximum packSize for each udp rcv. - if (rcv == -1) { + int rcv = receiveAtLeastNBytes(buff, headerSize, packSize); // receive at least headerSize byte, maximum packSize for each udp rcv. + if (rcv < 0) { delete[] buff; return -1; } @@ -79,25 +82,30 @@ int UDPProtocol::receiveFromClient(PacketLib::BasePacket &pack) { to_be_received = totPacketSize - tot_byte_rcv; // Calculate how much is still left to read } - if (to_be_received == 0) { // whole packet has been received. + if (to_be_received == 0) { // whole packet has been received, we can return. pack.copyToMemory(&buff[headerSize], tot_byte_rcv - headerSize, headerSize); // copy the buffer into packet except already copied header delete[] buff; return tot_byte_rcv; } - if (to_be_received < 0) { // error,received more bytes then expected. + if (to_be_received < 0) { // error,received more bytes then expected, we can return. resetPacket(pack, tot_byte_rcv); delete[] buff; return -1; } - uint8_t *tmp_buff = new uint8_t[packSize + headerSize]; // maximum receivable in receiveAtLeastHeaderSizeBytes - int rcv = receiveAtLeastHeaderSizeBytes(tmp_buff, headerSize, packSize); + + // go ahead until the rest of the packet received or connection terminates or another header is received. + uint8_t *tmp_buff = new uint8_t[packSize + headerSize]; // maximum receivable in receiveAtLeastNBytes + int rcv = receiveAtLeastNbytes(tmp_buff, headerSize, packSize); if (rcv == -1) { delete[] buff; delete[] tmp_buff; resetPacket(pack, tot_byte_rcv); return -1; } + + // copy the content of the buffer into a vector to check if it is a header. If it is, + // save it and discard previous data, otherwise append to current buff. std::vector vec; std::copy(tmp_buff, tmp_buff + headerSize, std::back_inserter(vec)); if (pack.isRecognizedHeader(vec)) { //another header received, save it and discard previous data. @@ -154,6 +162,7 @@ int UDPProtocol::connectToClient() { } int UDPProtocol::closeConnectionToClient() { + checkIncomingPackets = false; if (srv_sock != -1) { ::close(srv_sock); srv_sock = -1; -- GitLab From 1c075ab31001a7b1d9b269ec35e095b2169e9367 Mon Sep 17 00:00:00 2001 From: valerio pastore Date: Fri, 12 Jan 2024 17:22:44 +0100 Subject: [PATCH 2/2] . --- deps/Base-DAQ | 2 +- include/UDP_Protocol.h | 83 +++++------------------------------------- src/UDP_Protocol.cpp | 20 +++++----- 3 files changed, 22 insertions(+), 83 deletions(-) diff --git a/deps/Base-DAQ b/deps/Base-DAQ index 8a0ea2d..a00f9a2 160000 --- a/deps/Base-DAQ +++ b/deps/Base-DAQ @@ -1 +1 @@ -Subproject commit 8a0ea2d0e699863df5fe1c91caf2d7b0855957be +Subproject commit a00f9a27afbf5f75dab7db2368b9b9b6fcb395e1 diff --git a/include/UDP_Protocol.h b/include/UDP_Protocol.h index be8d6ad..567e59e 100755 --- a/include/UDP_Protocol.h +++ b/include/UDP_Protocol.h @@ -1,4 +1,3 @@ - #pragma once #include @@ -33,7 +32,7 @@ protected: struct sockaddr_in srvaddr; /**< The server address structure. */ bool checkIncomingPackets = true; /**< Flag that tells if it has to check for incoming udp packets. Set to false when calling closeConnectionToClient. * Used to avoid the infinite loop in receiveAtLeastNbytes. - */ + */ /** * @brief Splits the IP and port from the given IP:port string. * @@ -60,7 +59,7 @@ protected: * @param packet The packet object to reset. * @param bytes The number of bytes received. */ - void resetPacket(PacketLib::BasePacket& packet, int bytes); + void resetPacket(Packets::BasePacket &packet, int bytes); public: /** @@ -94,7 +93,9 @@ public: * * @return The IP address. */ - std::string getIp(){return this->ip;} + std::string getIp() { + return this->ip; + } /** * @brief Sets the port number to bind the UDP socket to. @@ -108,7 +109,9 @@ public: * * @return The port number. */ - int getPort(){return this->port;} + int getPort() { + return this->port; + } /** * @brief Connects to the client. @@ -137,7 +140,7 @@ public: * @param packet The packet object to store the received data. * @return The number of bytes received. */ - int receiveFromClient(PacketLib::BasePacket& packet) override; + int receiveFromClient(Packets::BasePacket &packet) override; friend class UDPProtocolBuilder; }; @@ -146,7 +149,7 @@ class UDPProtocolBuilder { protected: UDPProtocol *protocol; /**< The UDPProtocol object being built. */ public: - std::string config_target {"udpreceiver"}; /**< The configuration target. */ + std::string config_target { "udpreceiver" }; /**< The configuration target. */ std::string ip_key { "ip" }; /**< The configuration key for IP address. */ std::string port_key { "port" }; /**< The configuration key for port number. */ @@ -204,70 +207,4 @@ public: */ UDPProtocol* getReceiver(); }; - -} -namespace inaf::oasbo::Receivers { - -class UDPProtocol: public BaseReceiver { -protected: - UDPProtocol(std::string ip, int prt); - UDPProtocol(); - int srv_sock; - std::string ip { }; - int port; - - struct sockaddr_in cliaddr; - struct sockaddr_in srvaddr; - bool split_ip_port(const std::string &ip_port, std::string &ip, - int &port); - int receiveAtLeastHeaderSizeBytes(uint8_t *buff, int headerSize, - int packetSize); - void resetPacket(PacketLib::BasePacket&, int bytes); - - - -public: - - - ~UDPProtocol(); - - std::string getHost() override; - void setHost(std::string host) override; - - void setIp(std::string); - std::string getIp(){return this->ip;} - void setPort(int); - int getPort(){return this->port;} - int connectToClient() override; - int closeConnectionToClient() override; - bool isConnectedToClient() const override; - int receiveFromClient(PacketLib::BasePacket&) override; - - friend class UDPProtocolBuilder; -}; - -class UDPProtocolBuilder { -protected: - UDPProtocol *protocol; -public: - - std::string config_target {"udpreceiver"}; - std::string ip_key { "ip" }; - std::string port_key { "port" }; - - UDPProtocolBuilder(); - UDPProtocolBuilder(std::string ip, int port); - ~UDPProtocolBuilder(); - - void reset(); - - UDPProtocolBuilder* configFrom(Configurators::BaseConfigurator &conf); - - UDPProtocolBuilder* setIp(std::string ip); - - UDPProtocolBuilder* setPort(int port); - - UDPProtocol* getReceiver(); -}; - } diff --git a/src/UDP_Protocol.cpp b/src/UDP_Protocol.cpp index 040ff36..ed002a4 100755 --- a/src/UDP_Protocol.cpp +++ b/src/UDP_Protocol.cpp @@ -46,13 +46,13 @@ int UDPProtocol::receiveAtLeastNbytes(uint8_t *buff, int n_bytes, return -1; } } - if(!this->checkIncomingPackets){ // interrupted by closeConnectionToClient before receiving all the N bytes. + if (!this->checkIncomingPackets) { // interrupted by closeConnectionToClient before receiving all the N bytes. return -1; } return bytercv; } -int UDPProtocol::receiveFromClient(PacketLib::BasePacket &pack) { +int UDPProtocol::receiveFromClient(Packets::BasePacket &pack) { bool headerFlag = false; // tells if the header has been received uint headerSize = pack.getHeaderSize(); uint packSize = pack.getPacketStructureByteSize(); @@ -64,7 +64,7 @@ int UDPProtocol::receiveFromClient(PacketLib::BasePacket &pack) { int tot_byte_rcv = 0; while (this->checkIncomingPackets) { while (!headerFlag) { // until the header has not received - int rcv = receiveAtLeastNBytes(buff, headerSize, packSize); // receive at least headerSize byte, maximum packSize for each udp rcv. + int rcv = receiveAtLeastNbytes(buff, headerSize, packSize); // receive at least headerSize byte, maximum packSize for each udp rcv. if (rcv < 0) { delete[] buff; return -1; @@ -83,12 +83,12 @@ int UDPProtocol::receiveFromClient(PacketLib::BasePacket &pack) { } if (to_be_received == 0) { // whole packet has been received, we can return. - pack.copyToMemory(&buff[headerSize], - tot_byte_rcv - headerSize, headerSize); // copy the buffer into packet except already copied header + pack.copyToMemory(&buff[headerSize], tot_byte_rcv - headerSize, + headerSize); // copy the buffer into packet except already copied header delete[] buff; return tot_byte_rcv; } - if (to_be_received < 0) { // error,received more bytes then expected, we can return. + if (to_be_received < 0) {// error,received more bytes then expected, we can return. resetPacket(pack, tot_byte_rcv); delete[] buff; return -1; @@ -105,7 +105,7 @@ int UDPProtocol::receiveFromClient(PacketLib::BasePacket &pack) { } // copy the content of the buffer into a vector to check if it is a header. If it is, - // save it and discard previous data, otherwise append to current buff. + // save it and discard previous data, otherwise append to current buff. std::vector vec; std::copy(tmp_buff, tmp_buff + headerSize, std::back_inserter(vec)); if (pack.isRecognizedHeader(vec)) { //another header received, save it and discard previous data. @@ -124,6 +124,7 @@ int UDPProtocol::receiveFromClient(PacketLib::BasePacket &pack) { } delete[] tmp_buff; } + return -1; // connection interrupted by closeConnectionToClient } int UDPProtocol::connectToClient() { @@ -144,7 +145,8 @@ int UDPProtocol::connectToClient() { sizeof tv) < 0) { time_t now = time(nullptr); std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") - << "]\t[UDP Receiver]\t" << "Error setting timeout to socket" << std::endl; + << "]\t[UDP Receiver]\t" << "Error setting timeout to socket" + << std::endl; return -1; } @@ -174,7 +176,7 @@ bool UDPProtocol::isConnectedToClient() const { return srv_sock != -1; } -void UDPProtocol::resetPacket(PacketLib::BasePacket &pack, int bytes) { +void UDPProtocol::resetPacket(Packets::BasePacket &pack, int bytes) { uint8_t *buff = new uint8_t[bytes]; std::memset(buff, 0, bytes); int toBeReset = std::min( -- GitLab