Stroika Library 3.0d25
 
Loading...
Searching...
No Matches
BasicServer.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. 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 Memory::MakeSharedPtr;
28
29using namespace Stroika::Frameworks;
30using namespace Stroika::Frameworks::UPnP;
31using namespace Stroika::Frameworks::UPnP::SSDP;
32using namespace Stroika::Frameworks::UPnP::SSDP::Server;
33
34/*
35 ********************************************************************************
36 ******************************* BasicServer::Rep_ ******************************
37 ********************************************************************************
38 */
39class BasicServer::Rep_ final {
40public:
41 Sequence<Advertisement> fAdvertisements; // without fLocation: the notifier and responder fill that in
42 LocationProvider fLocation;
43 Options fOptions;
44 Rep_ (const Device& d, const DeviceDescription& dd, const LocationProvider& location, const Options& options)
45 : fLocation{location}
46 , fOptions{options}
47 {
48 {
49 SSDP::Advertisement dan;
50 dan.fServer = d.fServer;
51 dan.fMaxAge = options.fFrequencyInfo.fMaxAge; // so answers to searches say what the NOTIFYs do
52 {
53 dan.fTarget = kTarget_UPNPRootDevice;
54 dan.fUSN = Format ("uuid:{}::{}"_f, d.fDeviceID, kTarget_UPNPRootDevice);
55 fAdvertisements.Append (dan);
56 }
57 {
58 dan.fUSN = Format ("uuid:{}"_f, d.fDeviceID);
59 dan.fTarget = dan.fUSN;
60 fAdvertisements.Append (dan);
61 }
62 if (not dd.fDeviceType.empty ()) {
63 dan.fUSN = Format ("uuid:{}::{}"_f, d.fDeviceID, dd.fDeviceType);
64 dan.fTarget = dd.fDeviceType;
65 fAdvertisements.Append (dan);
66 }
67 // and each of its service types - once, however many of its services are of it (UPnP Device Architecture 1.1, section 1.1.2)
68 if (dd.fServices) {
69 for (const DeviceDescription::Service& s : *dd.fServices) {
70 if (not s.fServiceType.empty () and
71 not fAdvertisements.Any ([&] (const Advertisement& a) { return a.fTarget == s.fServiceType; })) {
72 dan.fUSN = Format ("uuid:{}::{}"_f, d.fDeviceID, s.fServiceType);
73 dan.fTarget = s.fServiceType;
74 fAdvertisements.Append (dan);
75 }
76 }
77 }
78 }
79
80 // the notifier and responder each follow network changes themselves (Options::fFollowNetworkChanges)
81 fNotifier_ = make_unique<PeriodicNotifier> (fAdvertisements, fLocation,
82 PeriodicNotifier::Options{.fFrequencyInfo = fOptions.fFrequencyInfo,
83 .fIPVersion = fOptions.fIPVersion,
84 .fMulticastTTL = fOptions.fMulticastTTL,
85 .fInterfaces = fOptions.fInterfaces,
86 .fFollowNetworkChanges = fOptions.fFollowNetworkChanges});
87 fSearchResponder_ = make_unique<SearchResponder> (fAdvertisements, fLocation,
88 SearchResponder::Options{.fIPVersion = fOptions.fIPVersion,
89 .fInterfaces = fOptions.fInterfaces,
90 .fFollowNetworkChanges = fOptions.fFollowNetworkChanges});
91 }
92 unique_ptr<PeriodicNotifier> fNotifier_;
93 unique_ptr<SearchResponder> fSearchResponder_; // last, so destroyed first: no search is answered after the notifier says ssdp:byebye
94};
95
96/*
97********************************************************************************
98********************************** BasicServer *********************************
99********************************************************************************
100*/
101BasicServer::BasicServer (const Device& d, const DeviceDescription& dd, const LocationProvider& location, const Options& options)
102 : fRep_{MakeSharedPtr<Rep_> (d, dd, location, options)}
103{
104}
105
107{
108 InterfacesByID result = fRep_->fNotifier_->GetNetworkInterfaces ();
109 result += fRep_->fSearchResponder_->GetNetworkInterfaces (); // one on both is there once: they are keyed by fInterfaceID
110 return result;
111}
a cross between Mapping<KEY, T> and Collection<T> and Set<T>
A generalization of a vector: a container whose elements are keyed by the natural numbers.
nonvirtual void Append(ArgByValueType< value_type > item)
Definition Sequence.inl:615
nonvirtual bool Any() const
Any() same as not empty (); Any (includeIfTrue) returns true iff includeIfTrue returns true on any va...
nonvirtual IO::Network::InterfacesByID GetNetworkInterfaces() const
The network interfaces it is advertising on now: those its NOTIFYs last went out of,...