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"
25using namespace Stroika::Frameworks::UPnP;
26using namespace Stroika::Frameworks::UPnP::SSDP;
38 void DoPrintDeviceDescription_ (
const URI& deviceDescriptionURL)
41 using namespace IO::Network::Transfer;
42 Connection::Ptr c = Connection::New ();
43 Response r = c.GET (deviceDescriptionURL);
44 if (r.GetSucceeded ()) {
46 cout <<
"\t\tDevice-Decsciption: " << Characters::ToString (deviceInfo).AsNarrowSDKString () << endl;
50 DbgTrace (
"failed to fetch description: {}"_f, Characters::ToString (current_exception ()));
56 void DoListening_ (Listener* l)
58 cout <<
"Listening..." << endl;
59 l->AddOnFoundCallback ([] (
const SSDP::Advertisement& d) {
60 lock_guard<mutex> critSection{kStdOutMutex_};
61 cout <<
"\tFound device (NOTIFY):" << endl;
62 cout <<
"\t\tUSN: " << d.fUSN.AsUTF8<
string> () << endl;
63 if (d.fAlive.has_value ()) {
64 cout <<
"\t\tAlive: " << Characters::ToString (d.fAlive).AsUTF8<
string> () << endl;
66 cout <<
"\t\tST: " << d.fTarget.AsUTF8<
string> () << endl;
67 cout <<
"\t\tLocation: " << Characters::ToString (d.fLocation).AsUTF8<
string> () << endl;
68 if (not d.fServer.empty ()) {
69 cout <<
"\t\tServer: " << d.fServer.AsUTF8<
string> () << endl;
71 DoPrintDeviceDescription_ (d.fLocation);
79 void DoSearching_ (Search* searcher,
const String& searchFor)
81 cout <<
"Searching for '" << searchFor.
AsUTF8<
string> () <<
"'..." << endl;
82 searcher->AddOnFoundCallback ([] (
const SSDP::Advertisement& d) {
83 lock_guard<mutex> critSection{kStdOutMutex_};
84 cout <<
"\tFound device (MATCHED SEARCH):" << endl;
85 cout <<
"\t\tUSN: " << d.fUSN.AsUTF8<
string> () << endl;
86 cout <<
"\t\tLocation: " << Characters::ToString (d.fLocation).AsUTF8<
string> () << endl;
87 cout <<
"\t\tST: " << d.fTarget.AsUTF8<
string> () << endl;
88 if (not d.fServer.empty ()) {
89 cout <<
"\t\tServer: " << d.fServer.AsUTF8<
string> () << endl;
91 DoPrintDeviceDescription_ (d.fLocation);
94 searcher->Start (searchFor);
98int main (
int argc,
const char* argv[])
102#if qStroika_Foundation_Common_Platform_POSIX
106 optional<String> searchFor;
110 .fSingleCharName =
'l',
113 .fSingleCharName =
's', .fSupportsArgument =
true, .fHelpArgName =
"SEARCHFOR"sv, .fHelpOptionText =
"Search for the argument UPNP name"sv};
117 listen = cmdLine.Has (kListenO_);
118 searchFor = cmdLine.GetArgument (kSearchO_);
119 if (
auto o = cmdLine.GetArgument (kQuitAfterO_)) {
120 quitAfter =
Time::DurationSeconds{Characters::FloatConversion::ToFloat<Time::DurationSeconds::rep> (*o)};
123 if (not listen and not searchFor.has_value ()) {
124 cerr <<
"Usage: SSDPClient [-l] [-s SEARCHFOR] [--quit-after N]" << endl;
125 cerr <<
" e.g. SSDPClient -l" << endl;
126 cerr <<
" e.g. SSDPClient -s \"upnp:rootdevice\"" << endl;
136 if (searchFor.has_value ()) {
137 DoSearching_ (&s, *searchFor);
139 if (listen or searchFor.has_value ()) {
143 cerr <<
"Specify -l to listen or -s STRING to search" << endl;
148 cerr <<
"Timed out - so - exiting..." << endl;
152 String exceptMsg = Characters::ToString (current_exception ());
153 cerr <<
"Exception - " << exceptMsg.
AsNarrowSDKString () <<
" - 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
nonvirtual string AsNarrowSDKString() const
A generalization of a vector: a container whose elements are keyed by the natural numbers.
nonvirtual void SetSignalHandlers(SignalID signal)
static SignalHandlerRegistry & Get()
static const SignalHandler kIGNORED
nonvirtual void Wait(Time::DurationSeconds timeout=Time::kInfinity)