Skip to content
GitLab
Explore
Sign in
Commits on Source (3)
adding doxygen
· 2f89280f
Valerio Pastore
authored
Jan 12, 2024
2f89280f
.
· 1c075ab3
Valerio Pastore
authored
Jan 12, 2024
1c075ab3
Merge branch 'dev' into 'main'
· 3fdf438d
Valerio Pastore
authored
Jan 14, 2024
Dev See merge request
!2
3fdf438d
Hide whitespace changes
Inline
Side-by-side
Base-DAQ
@
a00f9a27
Compare
8a0ea2d0
...
a00f9a27
Subproject commit
8
a0
ea2d0e699863df5fe1c91caf2d7b0855957be
Subproject commit a0
0f9a27afbf5f75dab7db2368b9b9b6fcb395e1
include/UDP_Protocol.h
View file @
3fdf438d
#pragma once
#pragma once
#include
<Base_Receiver.h>
#include
<Base_Receiver.h>
#include
<Base_Configurator.h>
#include
<Base_Configurator.h>
/**
* @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
{
namespace
inaf
::
oasbo
::
Receivers
{
class
UDPProtocol
:
public
BaseReceiver
{
class
UDPProtocol
:
public
BaseReceiver
{
protected:
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
);
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
);
/**
* @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
(
Packets
::
BasePacket
&
packet
,
int
bytes
);
public
:
public
:
/**
* @brief Destroys the UDPProtocol object.
*/
~
UDPProtocol
();
~
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
;
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
;
void
setHost
(
std
::
string
host
)
override
;
void
setIp
(
std
::
string
);
/**
std
::
string
getIp
(){
return
this
->
ip
;}
* @brief Sets the IP address to bind the UDP socket to.
void
setPort
(
int
);
*
int
getPort
(){
return
this
->
port
;}
* @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
;
int
connectToClient
()
override
;
/**
* @brief Closes the connection to the client.
*
* @return 0 if the connection is closed successfully, -1 otherwise.
*/
int
closeConnectionToClient
()
override
;
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
;
bool
isConnectedToClient
()
const
override
;
int
receiveFromClient
(
PacketLib
::
BasePacket
&
)
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
(
Packets
::
BasePacket
&
packet
)
override
;
friend
class
UDPProtocolBuilder
;
friend
class
UDPProtocolBuilder
;
};
};
class
UDPProtocolBuilder
{
class
UDPProtocolBuilder
{
protected:
protected:
UDPProtocol
*
protocol
;
UDPProtocol
*
protocol
;
/**< The UDPProtocol object being built. */
public:
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. */
std
::
string
config_target
{
"udpreceiver"
};
/**
std
::
string
ip_key
{
"ip"
};
* @brief Constructs a UDPProtocolBuilder object.
std
::
string
port_key
{
"port"
};
*/
UDPProtocolBuilder
();
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
);
UDPProtocolBuilder
(
std
::
string
ip
,
int
port
);
/**
* @brief Destroys the UDPProtocolBuilder object.
*/
~
UDPProtocolBuilder
();
~
UDPProtocolBuilder
();
/**
* @brief Resets the UDPProtocolBuilder object.
*/
void
reset
();
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
);
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
);
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
);
UDPProtocolBuilder
*
setPort
(
int
port
);
/**
* @brief Gets the UDPProtocol object that has been built.
*
* @return A pointer to the UDPProtocol object.
*/
UDPProtocol
*
getReceiver
();
UDPProtocol
*
getReceiver
();
};
};
}
}
src/UDP_Protocol.cpp
View file @
3fdf438d
...
@@ -33,12 +33,12 @@ UDPProtocol::~UDPProtocol() {
...
@@ -33,12 +33,12 @@ UDPProtocol::~UDPProtocol() {
closeConnectionToClient
();
closeConnectionToClient
();
}
}
int
UDPProtocol
::
receiveAtLeast
HeaderSizeB
ytes
(
uint8_t
*
buff
,
int
headerSize
,
int
UDPProtocol
::
receiveAtLeast
Nb
ytes
(
uint8_t
*
buff
,
int
n_bytes
,
int
packetS
ize
)
{
int
max_s
ize
)
{
int
bytercv
=
0
;
int
bytercv
=
0
;
socklen_t
len
=
sizeof
(
cliaddr
);
socklen_t
len
=
sizeof
(
cliaddr
);
while
(
bytercv
<
headerSize
)
{
while
(
bytercv
<
n_bytes
&&
this
->
checkIncomingPackets
)
{
int
rcv
=
recvfrom
(
srv_sock
,
&
buff
[
bytercv
],
packetS
ize
+
1
,
// +1 to recognized if there are more bytes than expected
int
rcv
=
recvfrom
(
srv_sock
,
&
buff
[
bytercv
],
max_s
ize
+
1
,
// +1 to recognized if there are more bytes than expected
0
,
(
struct
sockaddr
*
)
&
cliaddr
,
&
len
);
0
,
(
struct
sockaddr
*
)
&
cliaddr
,
&
len
);
bytercv
+=
rcv
;
bytercv
+=
rcv
;
...
@@ -46,23 +46,26 @@ int UDPProtocol::receiveAtLeastHeaderSizeBytes(uint8_t *buff, int headerSize,
...
@@ -46,23 +46,26 @@ int UDPProtocol::receiveAtLeastHeaderSizeBytes(uint8_t *buff, int headerSize,
return
-
1
;
return
-
1
;
}
}
}
}
if
(
!
this
->
checkIncomingPackets
)
{
// interrupted by closeConnectionToClient before receiving all the N bytes.
return
-
1
;
}
return
bytercv
;
return
bytercv
;
}
}
int
UDPProtocol
::
receiveFromClient
(
Packet
Lib
::
BasePacket
&
pack
)
{
int
UDPProtocol
::
receiveFromClient
(
Packet
s
::
BasePacket
&
pack
)
{
bool
headerFlag
=
false
;
bool
headerFlag
=
false
;
// tells if the header has been received
uint
headerSize
=
pack
.
getHeaderSize
();
uint
headerSize
=
pack
.
getHeaderSize
();
uint
packSize
=
pack
.
getPacketStructureByteSize
();
uint
packSize
=
pack
.
getPacketStructureByteSize
();
uint
tailSize
=
pack
.
getTailSize
();
uint
tailSize
=
pack
.
getTailSize
();
uint
payloadSize
=
0
;
uint
payloadSize
=
0
;
uint
totPacketSize
=
0
;
uint
totPacketSize
=
0
;
ssize_t
to_be_received
=
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
;
int
tot_byte_rcv
=
0
;
while
(
t
rue
)
{
while
(
t
his
->
checkIncomingPackets
)
{
while
(
!
headerFlag
)
{
// until the header has not received
while
(
!
headerFlag
)
{
// until the header has not received
int
rcv
=
receiveAtLeast
HeaderSizeB
ytes
(
buff
,
headerSize
,
packSize
);
// receive at least headerSize byte, maximum packSize for each udp rcv.
int
rcv
=
receiveAtLeast
Nb
ytes
(
buff
,
headerSize
,
packSize
);
// receive at least headerSize byte, maximum packSize for each udp rcv.
if
(
rcv
==
-
1
)
{
if
(
rcv
<
0
)
{
delete
[]
buff
;
delete
[]
buff
;
return
-
1
;
return
-
1
;
}
}
...
@@ -79,25 +82,30 @@ int UDPProtocol::receiveFromClient(PacketLib::BasePacket &pack) {
...
@@ -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
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
],
pack
.
copyToMemory
(
&
buff
[
headerSize
],
tot_byte_rcv
-
headerSize
,
tot_byte_rcv
-
headerSize
,
headerSize
);
// copy the buffer into packet except already copied header
headerSize
);
// copy the buffer into packet except already copied header
delete
[]
buff
;
delete
[]
buff
;
return
tot_byte_rcv
;
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
);
resetPacket
(
pack
,
tot_byte_rcv
);
delete
[]
buff
;
delete
[]
buff
;
return
-
1
;
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
)
{
if
(
rcv
==
-
1
)
{
delete
[]
buff
;
delete
[]
buff
;
delete
[]
tmp_buff
;
delete
[]
tmp_buff
;
resetPacket
(
pack
,
tot_byte_rcv
);
resetPacket
(
pack
,
tot_byte_rcv
);
return
-
1
;
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
<
uint8_t
>
vec
;
std
::
vector
<
uint8_t
>
vec
;
std
::
copy
(
tmp_buff
,
tmp_buff
+
headerSize
,
std
::
back_inserter
(
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.
if
(
pack
.
isRecognizedHeader
(
vec
))
{
//another header received, save it and discard previous data.
...
@@ -116,6 +124,7 @@ int UDPProtocol::receiveFromClient(PacketLib::BasePacket &pack) {
...
@@ -116,6 +124,7 @@ int UDPProtocol::receiveFromClient(PacketLib::BasePacket &pack) {
}
}
delete
[]
tmp_buff
;
delete
[]
tmp_buff
;
}
}
return
-
1
;
// connection interrupted by closeConnectionToClient
}
}
int
UDPProtocol
::
connectToClient
()
{
int
UDPProtocol
::
connectToClient
()
{
...
@@ -136,7 +145,8 @@ int UDPProtocol::connectToClient() {
...
@@ -136,7 +145,8 @@ int UDPProtocol::connectToClient() {
sizeof
tv
)
<
0
)
{
sizeof
tv
)
<
0
)
{
time_t
now
=
time
(
nullptr
);
time_t
now
=
time
(
nullptr
);
std
::
cerr
<<
"["
<<
std
::
put_time
(
localtime
(
&
now
),
"%Y-%m-%d %H:%M:%S"
)
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
;
return
-
1
;
}
}
...
@@ -154,6 +164,7 @@ int UDPProtocol::connectToClient() {
...
@@ -154,6 +164,7 @@ int UDPProtocol::connectToClient() {
}
}
int
UDPProtocol
::
closeConnectionToClient
()
{
int
UDPProtocol
::
closeConnectionToClient
()
{
checkIncomingPackets
=
false
;
if
(
srv_sock
!=
-
1
)
{
if
(
srv_sock
!=
-
1
)
{
::
close
(
srv_sock
);
::
close
(
srv_sock
);
srv_sock
=
-
1
;
srv_sock
=
-
1
;
...
@@ -165,7 +176,7 @@ bool UDPProtocol::isConnectedToClient() const {
...
@@ -165,7 +176,7 @@ bool UDPProtocol::isConnectedToClient() const {
return
srv_sock
!=
-
1
;
return
srv_sock
!=
-
1
;
}
}
void
UDPProtocol
::
resetPacket
(
Packet
Lib
::
BasePacket
&
pack
,
int
bytes
)
{
void
UDPProtocol
::
resetPacket
(
Packet
s
::
BasePacket
&
pack
,
int
bytes
)
{
uint8_t
*
buff
=
new
uint8_t
[
bytes
];
uint8_t
*
buff
=
new
uint8_t
[
bytes
];
std
::
memset
(
buff
,
0
,
bytes
);
std
::
memset
(
buff
,
0
,
bytes
);
int
toBeReset
=
std
::
min
(
int
toBeReset
=
std
::
min
(
...
...