Skip to content

Commit f562db2

Browse files
committed
WIP: Add initial UPnP resolver
1 parent aa8c142 commit f562db2

File tree

8 files changed

+1024
-0
lines changed

8 files changed

+1024
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ add_subdirectory(http)
9999
add_subdirectory(mdns)
100100
add_subdirectory(qnc)
101101
add_subdirectory(ssdp)
102+
add_subdirectory(upnp)
102103
add_subdirectory(xml)
103104

104105
if (NOT IOS) # FIXME Figure out code signing on Github

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
add_subdirectory(auto)
2+
add_subdirectory(manual)

tests/manual/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
qnc_add_executable(upnpparsertest upnpparsertest.cpp)
2+
target_link_libraries(upnpparsertest PRIVATE QncUpnp)

tests/manual/upnpparsertest.cpp

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/* QtNetworkCrumbs - Some networking toys for Qt
2+
* Copyright (C) 2019-2024 Mathias Hasselmann
3+
*/
4+
5+
// QtNetworkCrumbs headers
6+
#include "qncliterals.h"
7+
#include "upnpresolver.h"
8+
9+
// Qt headers
10+
#include <QCommandLineParser>
11+
#include <QCoreApplication>
12+
#include <QDir>
13+
14+
namespace qnc::upnp::tests {
15+
namespace {
16+
17+
class ParserTest : public QCoreApplication
18+
{
19+
public:
20+
using QCoreApplication::QCoreApplication;
21+
22+
int run()
23+
{
24+
const auto ssdpDir = QCommandLineOption{"ssdp"_L1, tr("directory with SSDP files"), tr("DIRPATH")};
25+
const auto scpdDir = QCommandLineOption{"scpd"_L1, tr("directory with SCPD files"), tr("DIRPATH")};
26+
const auto controlDir = QCommandLineOption{"control"_L1, tr("directory with control files"), tr("DIRPATH")};
27+
const auto eventingDir = QCommandLineOption{"eventing"_L1, tr("directory with eventing files"), tr("DIRPATH")};
28+
29+
auto commandLine = QCommandLineParser{};
30+
31+
commandLine.addOption(ssdpDir);
32+
commandLine.addOption(scpdDir);
33+
commandLine.addOption(controlDir);
34+
commandLine.addOption(eventingDir);
35+
commandLine.addHelpOption();
36+
37+
commandLine.process(arguments());
38+
39+
if (!commandLine.positionalArguments().isEmpty()) {
40+
commandLine.showHelp(EXIT_FAILURE);
41+
return EXIT_FAILURE;
42+
}
43+
44+
if (commandLine.isSet(ssdpDir) && !readTestData(commandLine.value(ssdpDir), &ssdpParse))
45+
return EXIT_FAILURE;
46+
if (commandLine.isSet(scpdDir) && !readTestData(commandLine.value(scpdDir), &scpdParse))
47+
return EXIT_FAILURE;
48+
49+
return EXIT_SUCCESS;
50+
}
51+
52+
private:
53+
static bool readTestData(const QString &path, bool (* parse)(QFile *))
54+
{
55+
const auto fileInfo = QFileInfo{path};
56+
57+
if (fileInfo.isDir()) {
58+
const auto &fileInfoList = QDir{path}.entryInfoList(QDir::Files);
59+
60+
for (const auto &fileInfo : fileInfoList) {
61+
if (!readFile(fileInfo, parse))
62+
return false;
63+
}
64+
65+
return true;
66+
} else {
67+
return readFile(fileInfo, parse);
68+
}
69+
}
70+
71+
static bool readFile(const QFileInfo &fileInfo, bool (* parse)(QFile *))
72+
{
73+
qInfo() << QUrl::fromPercentEncoding(fileInfo.fileName().toUtf8());
74+
75+
auto file = QFile{fileInfo.filePath()};
76+
qInfo() << file.fileName();
77+
78+
if (!file.open(QFile::ReadOnly)) {
79+
qWarning() << file.errorString();
80+
return false;
81+
}
82+
83+
if (!parse(&file))
84+
return false;
85+
86+
return true;
87+
}
88+
89+
static bool ssdpParse(QFile *file)
90+
{
91+
const auto &deviceList = DeviceDescription::parse(file);
92+
93+
if (deviceList.isEmpty())
94+
return false;
95+
96+
for (const auto &device : deviceList) {
97+
qInfo() << "-"
98+
<< device.specVersion
99+
<< device.displayName
100+
<< device.deviceType;
101+
102+
for (const auto &service : device.services) {
103+
qInfo() << " -"
104+
<< service.type
105+
<< service.id;
106+
}
107+
}
108+
109+
return true;
110+
}
111+
112+
static bool scpdParse(QFile *file)
113+
{
114+
const auto controlPoint = ControlPointDescription::parse(file);
115+
116+
if (!controlPoint)
117+
return false;
118+
119+
qInfo() << "- actions:";
120+
for (const auto &action : controlPoint->actions) {
121+
qInfo() << " -"
122+
<< action.name
123+
<< action.flags;
124+
125+
for (const auto &argument : action.arguments) {
126+
qInfo() << " -"
127+
<< argument.name
128+
// FIXME: << argument.direction
129+
<< argument.stateVariable;
130+
}
131+
}
132+
133+
qInfo() << "- variables:";
134+
for (const auto &variable : controlPoint->stateVariables) {
135+
qInfo() << " -"
136+
<< variable.name
137+
// FIXME: << variable.dataType
138+
<< variable.defaultValue
139+
<< variable.flags
140+
<< variable.allowedValues
141+
<< variable.valueRange.minimum
142+
<< variable.valueRange.maximum
143+
<< variable.valueRange.step;
144+
}
145+
146+
return true;
147+
}
148+
};
149+
150+
} // namespace
151+
} // namespace qnc::upnp::tests
152+
153+
int main(int argc, char *argv[])
154+
{
155+
return qnc::upnp::tests::ParserTest{argc, argv}.run();
156+
}
157+

upnp/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
qnc_add_library(
2+
QncUpnp STATIC
3+
upnpresolver.cpp
4+
upnpresolver.h
5+
)
6+
7+
target_link_libraries(QncUpnp PUBLIC QncSsdp QncXml)
8+
9+
if (NOT IOS) # FIXME Figure out code signing on Github
10+
qnc_add_executable(UPNPResolverDemo TYPE tool upnpresolverdemo.cpp)
11+
target_link_libraries(UPNPResolverDemo PRIVATE QncUpnp)
12+
endif()

0 commit comments

Comments
 (0)