Stroika Library 3.0d21
 
Loading...
Searching...
No Matches
SSDPServer.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include "Stroika/Frameworks/StroikaPreComp.h"
5
6#include <iostream>
7
12#include "Stroika/Foundation/Execution/CommandLine.h"
13#include "Stroika/Foundation/Execution/SignalHandlers.h"
14#include "Stroika/Foundation/Execution/TimeOutException.h"
15#include "Stroika/Foundation/Execution/WaitableEvent.h"
16#include "Stroika/Foundation/IO/Network/HTTP/Headers.h"
17#include "Stroika/Foundation/IO/Network/Listener.h"
19#include "Stroika/Frameworks/UPnP/SSDP/Server/BasicServer.h"
20#include "Stroika/Frameworks/WebServer/ConnectionManager.h"
21
22using namespace std;
23
24using namespace Stroika::Foundation;
26using namespace Stroika::Foundation::Execution;
27using namespace Stroika::Foundation::IO;
29using namespace Stroika::Frameworks;
30using namespace Stroika::Frameworks::UPnP;
31using namespace Stroika::Frameworks::UPnP::SSDP;
32using namespace Stroika::Frameworks::WebServer;
33
36
37namespace {
38 struct WebServerForDeviceDescription_ : WebServer::ConnectionManager {
39 static inline const HTTP::Headers kDefaultResponseHeaders_{[] () {
41 h.server = "stroika-ssdp-server-demo"sv;
42 return h;
43 }()};
44 WebServerForDeviceDescription_ (uint16_t webServerPortNumber, const DeviceDescription& dd)
47 Route{""_RegEx,
48 [dd] (Message& m) {
49 Response& response = m.rwResponse ();
50 response.contentType = DataExchange::InternetMediaTypes::kXML;
51 response.write (Stroika::Frameworks::UPnP::Serialize (dd));
52 }},
53 },
54 Options{.fMaxConnections = 3, .fDefaultResponseHeaders = kDefaultResponseHeaders_}}
55 {
56 }
57 };
58}
59
60int main ([[maybe_unused]] int argc, [[maybe_unused]] const char* argv[])
61{
62 CommandLine cmdLine{argc, argv};
63
65
66#if qStroika_Foundation_Common_Platform_POSIX
68#endif
69
70 Time::DurationSeconds quitAfter = Time::kInfinity;
71 uint16_t portForOurWS = 8080;
72
73 const CommandLine::Option kQuitAfterO_{.fLongName = "quit-after"sv, .fSupportsArgument = true};
74 const Sequence<CommandLine::Option> kAllOptions_{StandardCommandLineOptions::kHelp, kQuitAfterO_};
75
76 if (auto o = cmdLine.GetArgument (kQuitAfterO_)) {
77 quitAfter = Time::DurationSeconds{Characters::FloatConversion::ToFloat<Time::DurationSeconds::rep> (*o)};
78 }
79
80 if (cmdLine.Has (StandardCommandLineOptions::kHelp)) {
81 cerr << cmdLine.GenerateUsage (kAllOptions_) << endl;
82 return EXIT_SUCCESS;
83 }
84
85 IntervalTimer::Manager::Activator intervalTimerMgrActivator; // required by UPnP::BasicServer
86
87 try {
88 Device d;
89 d.fLocation.SetScheme (URI::SchemeType{"http"sv});
90 d.fLocation.SetAuthority (URI::Authority{nullopt, portForOurWS});
91 d.fServer = UPnP::SSDP::MakeServerHeaderValue ("MyStroikaBasedSampleProduct/1.0"sv);
92 d.fDeviceID = UPnP::MungePrimaryMacAddrIntoBaseDeviceID ("315CAAE0-1335-57BF-A178-24C9EE756627"sv);
93
94 DeviceDescription deviceInfo;
95 deviceInfo.fPresentationURL = URI{"http://www.sophists.com/"sv};
96 deviceInfo.fDeviceType = "urn:sophists.com:device:deviceType:1.0"sv;
97 deviceInfo.fManufactureName = "Sophist Solutions, Inc."sv;
98 deviceInfo.fFriendlyName = "Sophist Solutions fake device"sv;
99 deviceInfo.fManufacturingURL = URI{"http://www.sophists.com/"sv};
100 deviceInfo.fModelDescription = "long user-friendly title"sv;
101 deviceInfo.fModelName = "model name"sv;
102 deviceInfo.fModelNumber = "model number"sv;
103 deviceInfo.fModelURL = URI{"http://www.sophists.com/"sv};
104 deviceInfo.fSerialNumber = "manufacturer's serial number"sv;
105 deviceInfo.fUDN = "uuid:" + d.fDeviceID;
106
107 WebServerForDeviceDescription_ deviceWS{portForOurWS, deviceInfo};
108 BasicServer b{d, deviceInfo};
109 WaitableEvent{}.Wait (quitAfter); // wait quitAfter seconds, or til user hits ctrl-c
110 }
111 catch (const TimeOutException&) {
112 cerr << "Timed out - so - exiting..." << endl;
113 return EXIT_SUCCESS;
114 }
115 catch (...) {
116 cerr << "Exception - " << Characters::ToString (current_exception ()) << " - terminating..." << endl;
117 return EXIT_FAILURE;
118 }
119 return EXIT_SUCCESS;
120}
chrono::duration< double > DurationSeconds
chrono::duration<double> - a time span (length of time) measured in seconds, but high precision.
Definition Realtime.h:57
#define Stroika_Foundation_Debug_OptionalizeTraceArgs(...)
Definition Trace.h:270
A generalization of a vector: a container whose elements are keyed by the natural numbers.
nonvirtual void Wait(Time::DurationSeconds timeout=Time::kInfinity)
roughly equivalent to Association<String,String>, except that the class is smart about certain keys a...
Definition Headers.h:129
Common::Property< optional< String > > server
Definition Headers.h:404
nonvirtual void SetScheme(const optional< SchemeType > &scheme)
Definition URI.inl:41
Authority is roughly the part of a URL where you say the hostname (and portnumber etc) - part just af...
handle the multicast part of UPnP SSDP - listening for searches and sending periodic notifications
Definition BasicServer.h:42
Traversal::Iterable< SocketAddress > SocketAddresses(const Traversal::Iterable< InternetAddress > &internetAddresses, PortType portNumber)
Traversal::Iterable< InternetAddress > InternetAddresses_Any(InternetProtocol::IP::IPVersionSupport ipSupport=InternetProtocol::IP::IPVersionSupport::eDEFAULT)
STL namespace.
Having explicit activator object allows for users to control the starting/stopping of facility in a m...