Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
BasicServer.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include "Stroika/Frameworks/StroikaPreComp.h"
5
7#include "Stroika/Foundation/Containers/Sequence.h"
13#include "Stroika/Foundation/Streams/MemoryStream.h"
14
17
18#include "BasicServer.h"
19
20using namespace Stroika::Foundation;
23using namespace Stroika::Foundation::Execution;
24using namespace Stroika::Foundation::IO;
26
27using namespace Stroika::Frameworks;
28using namespace Stroika::Frameworks::UPnP;
29using namespace Stroika::Frameworks::UPnP::SSDP;
30using namespace Stroika::Frameworks::UPnP::SSDP::Server;
31
32/*
33********************************************************************************
34******************************* BasicServer::Rep_ ******************************
35********************************************************************************
36*/
37class BasicServer::Rep_ {
38public:
39 Sequence<Advertisement> fAdvertisements;
40 FrequencyInfo fFrequencyInfo;
41 URI fLocation;
42 Rep_ (const Device& d, const DeviceDescription& dd, const FrequencyInfo& fi, IO::Network::InternetProtocol::IP::IPVersionSupport ipVersion)
43 : fFrequencyInfo{fi}
44 , fLocation{d.fLocation}
45 {
46 {
47 SSDP::Advertisement dan;
48 // dan.fLocation set in GetAdjustedAdvertisements_...
49 dan.fServer = d.fServer;
50 {
51 dan.fTarget = kTarget_UPNPRootDevice;
52 dan.fUSN = Format ("uuid:{}::{}"_f, d.fDeviceID, kTarget_UPNPRootDevice);
53 fAdvertisements.Append (dan);
54 }
55 {
56 dan.fUSN = Format ("uuid:{}"_f, d.fDeviceID);
57 dan.fTarget = dan.fUSN;
58 fAdvertisements.Append (dan);
59 }
60 if (not dd.fDeviceType.empty ()) {
61 dan.fUSN = Format ("uuid:{}::{}"_f, d.fDeviceID, dd.fDeviceType);
62 dan.fTarget = dd.fDeviceType;
63 fAdvertisements.Append (dan);
64 }
65 }
66
67 // SEE http://stroika-bugs.sophists.com/browse/STK-962 - make resilient to failures setting up watchers, to retry
68
69 fNotifier_ = make_unique<PeriodicNotifier> (GetAdjustedAdvertisements_ (), fi, ipVersion);
70 fSearchResponder_ = make_unique<SearchResponder> (GetAdjustedAdvertisements_ (), ipVersion);
71
73 LinkMonitor lm;
74 lm.AddCallback ([this] (LinkMonitor::LinkChange lc, String netName, String ipNum) {
75 Debug::TraceContextBumper ctx{"Basic SSDP server - LinkMonitor callback", "lc = {}, netName={}, ipNum={}"_f, lc, netName, ipNum};
76 if (lc == LinkMonitor::LinkChange::eAdded) {
77 this->Restart_ ();
78 }
79 });
80 fLinkMonitor_ = optional<LinkMonitor>{move (lm)};
81 }
82 Sequence<Advertisement> GetAdjustedAdvertisements_ () const
83 {
84 /*
85 * As a convenience, automatically set the LOCATION advertised to be that of the primary IP address of this
86 * host.
87 */
88 if (fLocation.GetAuthority () and fLocation.GetAuthority ()->GetHost ()) {
89 return fAdvertisements;
90 }
91 else {
92 Sequence<Advertisement> revisedAdvertisements;
93 URI useBaseURL = fLocation;
94 URI::Authority useAuthority = useBaseURL.GetAuthority ().value_or (URI::Authority{});
95 useAuthority.SetHost (IO::Network::GetPrimaryInternetAddress ());
96 useBaseURL.SetAuthority (useAuthority);
97 for (auto ai : fAdvertisements) {
98 ai.fLocation = useBaseURL.Combine (ai.fLocation);
99 revisedAdvertisements.Append (ai);
100 }
101 return revisedAdvertisements;
102 }
103 }
104 void Restart_ ()
105 {
106 Debug::TraceContextBumper ctx{"Restarting Basic SSDP server threads"};
107 fNotifier_.reset ();
108 fSearchResponder_.reset ();
109 fNotifier_ = make_unique<PeriodicNotifier> (GetAdjustedAdvertisements_ (), PeriodicNotifier::FrequencyInfo{});
110 fSearchResponder_ = make_unique<SearchResponder> (GetAdjustedAdvertisements_ ());
111 }
112 unique_ptr<PeriodicNotifier> fNotifier_;
113 unique_ptr<SearchResponder> fSearchResponder_;
114 optional<IO::Network::LinkMonitor> fLinkMonitor_; // optional so we can delete it first on shutdown (so no restart while stopping stuff)
115};
116
117/*
118********************************************************************************
119********************************** BasicServer *********************************
120********************************************************************************
121*/
122BasicServer::BasicServer (const Device& d, const DeviceDescription& dd, const FrequencyInfo& fi, IO::Network::InternetProtocol::IP::IPVersionSupport ipVersion)
123 : fRep_{make_shared<Rep_> (d, dd, fi, ipVersion)}
124{
125}
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
A generalization of a vector: a container whose elements are keyed by the natural numbers.
Definition Sequence.h:187
nonvirtual void Append(ArgByValueType< value_type > item)
Definition Sequence.inl:330
nonvirtual URI Combine(const URI &overridingURI) const
Combine overridingURI possibly relative url with this base url, to produce a new URI.
Definition URI.cpp:316
nonvirtual optional< Authority > GetAuthority() const
Definition URI.inl:55
Authority is roughly the part of a URL where you say the hostname (and portnumber etc) - part just af...
InternetAddress GetPrimaryInternetAddress()