-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgrouplistener.cpp
More file actions
86 lines (78 loc) · 2.81 KB
/
grouplistener.cpp
File metadata and controls
86 lines (78 loc) · 2.81 KB
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
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "grouplistener.h"
#define FIND_MESSAGE "usbip-find"
#define BIND_PORT_ADM "usbip-bind-adm"
#define IM_A_HOST "usbip-host"
#define LIST_OUT "usbip-list"
#define USB_CHANGE "usb-host-change"
#include <QNetworkDatagram>
#include <QJsonDocument>
#include <QTimer>
extern "C" {
#include "usbip_bind.c"
#include "usbip_list.c"
}
GroupListener::GroupListener(QString groupIpv4Host, qint16 hostPort): QObject(nullptr), groupAddress(groupIpv4Host), hostPort(hostPort)
{
listener.bind(QHostAddress::AnyIPv4, hostPort, QUdpSocket::ShareAddress);
connect(&listener, &QUdpSocket::readyRead, this, &GroupListener::dataRecieved);
connect(&monitor, &UdevMonitor::update, this, &GroupListener::monitorUpdate);
usbip_names_init((char*)USBIDS_FILE);
joinMulticast();
}
void GroupListener::dataRecieved()
{
while(listener.hasPendingDatagrams()) {
QNetworkDatagram dgram(listener.receiveDatagram());
if (dgram.data().contains(IM_A_HOST)) {
continue;
}
if (dgram.data().contains(FIND_MESSAGE)) {
listener.writeDatagram(dgram.makeReply(IM_A_HOST));
}
else if (dgram.data().contains(BIND_PORT_ADM)) {
const char* bus = QJsonDocument::fromJson(dgram.data())["bus"].toString().toStdString().c_str();
auto bindRes = usbip_bind((char*)bus);
auto result = QJsonDocument::fromVariant(QVariantMap({
{"process", "usbip-bind-ack"},
{"recieved", bindRes}
}));
listener.writeDatagram(dgram.makeReply(result.toJson()));
}
else if (dgram.data().contains(LIST_OUT)) {
QVariantList devices;
usbip_external_list* linked_device = list_devices();
usbip_external_list* current_device = nullptr;
while(linked_device != nullptr) {
devices.push_back(QVariantMap({
{"product_name", linked_device->product_name},
{"busid", linked_device->busid},
{"vendor", linked_device->idVendor},
{"product", linked_device->idProduct}
}));
current_device = linked_device;
linked_device = linked_device->next;
usbip_external_list_free(current_device);
}
listener.writeDatagram(dgram.makeReply(QJsonDocument::fromVariant(devices).toJson()));
}
}
}
void GroupListener::monitorUpdate(UdevMonitor::UpdateEvent updateEvent)
{
auto broadcast = QJsonDocument::fromVariant(QVariantMap({
{"message", USB_CHANGE},
{"action", updateEvent.action},
{"device", updateEvent.device}
})).toJson();
listener.writeDatagram(broadcast, groupAddress, hostPort);
}
void GroupListener::joinMulticast()
{
bool success = listener.joinMulticastGroup(groupAddress);
if (!success) {
QTimer::singleShot(1000, [this]() { joinMulticast(); });
return;
}
listener.writeDatagram(IM_A_HOST, groupAddress, hostPort);
}