-
Notifications
You must be signed in to change notification settings - Fork 0
/
packet_receiver.cpp
112 lines (95 loc) · 3.16 KB
/
packet_receiver.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "packet_receiver.h"
#include <QDebug>
PacketReceiver::PacketReceiver(QObject *parent) : QObject(parent), Socket(IOService)
{
}
PacketReceiver::~PacketReceiver()
{
this->stop();
this->Socket.close();
}
void PacketReceiver::start()
{
qDebug() << "start to collect udp data : " << this->Port;
this->waitForNextPacket();
this->Thread = std::make_unique<std::thread>([&] {
this->IOService.run();
});
}
void PacketReceiver::stop()
{
qDebug() << "stop collcting udp data";
this->Socket.close();
if (this->Thread)
{
if (this->Thread->joinable())
{
this->Thread->join();
}
}
}
void PacketReceiver::setReceiverCallback(std::function<void (NetworkPacket *)> callback)
{
this->ReceiverCallback = callback;
}
void PacketReceiver::bind(int port)
{
this->Port = port;
boost::system::error_code errCode;
boost::asio::ip::address listen_address = boost::asio::ip::address::from_string(LocalListeningAddress, errCode);
if(errCode != boost::system::errc::success)
{
qDebug() << "Listen address is not valid, listening on all local ip addresses on v6";
listen_address = boost::asio::ip::address_v6::any();
}
if (listen_address.is_v4())
{
this->Socket.open(boost::asio::ip::udp::v4());
}
else if (listen_address.is_v6())
{
this->Socket.open(boost::asio::ip::udp::v6());
if (listen_address == boost::asio::ip::address_v6::any())
{
this->Socket.set_option(boost::asio::ip::v6_only(false));
}
}
this->Socket.set_option(boost::asio::ip::udp::socket::reuse_address(true));
// default 106496 (linux) to 4194304 (4MB)
this->Socket.set_option(boost::asio::socket_base::receive_buffer_size(4194304));
boost::asio::socket_base::receive_buffer_size size_option;
this->Socket.get_option(size_option);
qDebug() << "Receive buffer size : " << size_option.value();
try
{
this->Socket.bind(boost::asio::ip::udp::endpoint(listen_address, Port));
}
catch(...)
{
qDebug() << "error while setting listening address, please correct it or leave empty to ignore";
}
}
void PacketReceiver::socketCallback(const boost::system::error_code &error, std::size_t numberOfBytes)
{
if (error)
{
return;
}
unsigned short ourPort = static_cast<unsigned short>(this->Port);
unsigned short sourcePort = this->SenderEndpoint.port();
std::array<unsigned char, 4> sourceIP = {192, 168, 0, 200};
if (this->SenderEndpoint.address().is_v4())
{
for (int i = 0; i < 4; i++)
{
sourceIP[i] = this->SenderEndpoint.address().to_v4().to_bytes()[i];
}
}
NetworkPacket* packet = NetworkPacket::BuildEthernetIP4UDP(this->RXBuffer, numberOfBytes, sourceIP, sourcePort, ourPort, this->FakeManufacturerMACAddress);
this->ReceiverCallback(packet);
this->waitForNextPacket();
}
void PacketReceiver::waitForNextPacket()
{
this->Socket.async_receive_from(boost::asio::buffer(this->RXBuffer, BUFFER_SIZE), this->SenderEndpoint, std::bind(&PacketReceiver::socketCallback, this, std::placeholders::_1, std::placeholders::_2));
}