4#include "Stroika/Frameworks/StroikaPreComp.h"
11#include "Stroika/Foundation/Execution/CommandLine.h"
12#include "Stroika/Foundation/Execution/SignalHandlers.h"
13#include "Stroika/Foundation/Execution/TimeOutException.h"
14#include "Stroika/Foundation/Execution/WaitableEvent.h"
15#include "Stroika/Foundation/IO/Network/Transfer/Connection.h"
17#include "Stroika/Frameworks/UPnP/DeviceDescription.h"
26using namespace Stroika::Frameworks::UPnP;
27using namespace Stroika::Frameworks::UPnP::SSDP;
39 void DoPrintDeviceDescription_ (
const URI& deviceDescriptionURL)
42 using namespace IO::Network::Transfer;
43 Connection::Ptr c = Connection::New ();
44 Response r = c.GET (deviceDescriptionURL);
45 if (r.GetSucceeded ()) {
47 cout <<
"\t\tDevice-Decsciption: " << Characters::ToString (deviceInfo) << endl;
51 DbgTrace (
"failed to fetch description: {}"_f, Characters::ToString (current_exception ()));
57 void DoListening_ (Listener* l)
59 cout <<
"Listening..." << endl;
60 l->AddOnFoundCallback ([] (
const SSDP::Advertisement& d) {
61 lock_guard<mutex> critSection{kStdOutMutex_};
62 cout <<
"\tFound device (NOTIFY):" << endl;
63 cout <<
"\t\tUSN: " << d.fUSN.AsUTF8<
string> () << endl;
64 if (d.fAlive.has_value ()) {
65 cout <<
"\t\tAlive: " << Characters::ToString (d.fAlive).AsUTF8<
string> () << endl;
67 cout <<
"\t\tST: " << d.fTarget.AsUTF8<
string> () << endl;
68 cout <<
"\t\tLocation: " << Characters::ToString (d.fLocation).AsUTF8<
string> () << endl;
69 if (not d.fServer.empty ()) {
70 cout <<
"\t\tServer: " << d.fServer.AsUTF8<
string> () << endl;
72 DoPrintDeviceDescription_ (d.fLocation);
80 void DoSearching_ (Search* searcher,
const String& searchFor)
82 cout <<
"Searching for '" << searchFor.
AsUTF8<
string> () <<
"'..." << endl;
83 searcher->AddOnFoundCallback ([] (
const SSDP::Advertisement& d) {
84 lock_guard<mutex> critSection{kStdOutMutex_};
85 cout <<
"\tFound device (MATCHED SEARCH):" << endl;
86 cout <<
"\t\tUSN: " << d.fUSN.AsUTF8<
string> () << endl;
87 cout <<
"\t\tLocation: " << Characters::ToString (d.fLocation).AsUTF8<
string> () << endl;
88 cout <<
"\t\tST: " << d.fTarget.AsUTF8<
string> () << endl;
89 if (not d.fServer.empty ()) {
90 cout <<
"\t\tServer: " << d.fServer.AsUTF8<
string> () << endl;
92 DoPrintDeviceDescription_ (d.fLocation);
95 searcher->Start (searchFor);
99int main (
int argc,
const char* argv[])
103#if qStroika_Foundation_Common_Platform_POSIX
107 optional<String> searchFor;
111 .fSingleCharName =
'l',
114 .fSingleCharName =
's', .fSupportsArgument =
true, .fHelpArgName =
"SEARCHFOR"sv, .fHelpOptionText =
"Search for the argument UPNP name"sv};
115 const CommandLine::Option kQuitAfterO_{.fLongName =
"quit-after"sv, .fSupportsArgument =
true, .fHelpArgName =
"NSECONDS"sv};
118 listen = cmdLine.Has (kListenO_);
119 searchFor = cmdLine.GetArgument (kSearchO_);
120 if (
auto o = cmdLine.GetArgument (kQuitAfterO_)) {
121 quitAfter =
Time::DurationSeconds{Characters::FloatConversion::ToFloat<Time::DurationSeconds::rep> (*o)};
124 if (not listen and not searchFor.has_value ()) {
125 cerr <<
"Usage: SSDPClient [-l] [-s SEARCHFOR] [--quit-after N]" << endl;
126 cerr <<
" e.g. SSDPClient -l" << endl;
127 cerr <<
" e.g. SSDPClient -s \"upnp:rootdevice\"" << endl;
137 if (searchFor.has_value ()) {
138 DoSearching_ (&s, *searchFor);
140 if (listen or searchFor.has_value ()) {
144 cerr <<
"Specify -l to listen or -s STRING to search" << endl;
149 cerr <<
"Timed out - so - exiting..." << endl;
153 cerr <<
"Exception - " << Characters::ToString (current_exception ()) <<
" - terminating..." << endl;
chrono::duration< double > DurationSeconds
chrono::duration<double> - a time span (length of time) measured in seconds, but high precision.
#define Stroika_Foundation_Debug_OptionalizeTraceArgs(...)
String is like std::u32string, except it is much easier to use, often much more space efficient,...
nonvirtual T AsUTF8() const
A generalization of a vector: a container whose elements are keyed by the natural numbers.
nonvirtual void SetSignalHandlers(SignalID signal)
static const SignalHandler kIGNORED
static SignalHandlerRegistry sThe
nonvirtual void Wait(Time::DurationSeconds timeout=Time::kInfinity)