Stroika Library 3.0d25
 
Loading...
Searching...
No Matches
Search.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4#ifndef _Stroika_Frameworks_UPnP_SSDP_Client_Search_h_
5#define _Stroika_Frameworks_UPnP_SSDP_Client_Search_h_ 1
6
7#include "Stroika/Frameworks/StroikaPreComp.h"
8
9#include <functional>
10
12#include "Stroika/Foundation/IO/Network/InternetProtocol/IP.h"
13
14#include "Stroika/Frameworks/UPnP/Device.h"
17
18/**
19 * \file
20 *
21 * \note Code-Status: <a href="Code-Status.md#Beta">Beta</a>
22 */
23
24namespace Stroika::Frameworks::UPnP::SSDP::Client {
25
26 /**
27 */
28 class Search {
29 public:
30 /**
31 * \par Example Usage
32 * \code
33 * Search search{callOnFinds, Search::kRootDevice, Search::Options{.fIPVersion = IPVersionSupport::eIPV4Only}};
34 * \endcode
35 */
36 struct Options {
37 /**
38 * Which SSDP channels to search on: IPv4 (239.255.255.250) and/or IPv6 (ff02::c).
39 */
40 IO::Network::InternetProtocol::IP::IPVersionSupport fIPVersion{IO::Network::InternetProtocol::IP::IPVersionSupport::eDEFAULT};
41
42 /**
43 * The TTL (IPv6: hop limit) of each M-SEARCH: how many routers it may cross (@see kDefaultMulticastTTL).
44 */
46
47 /**
48 * Which network interfaces to search on - asked of each one, for each send (@see SSDP::InterfaceFilter).
49 */
51
52 /**
53 * When a network appears, search there right away, rather than at the next retry (it starts the search over).
54 * It costs a LinkMonitor (all share one thread, waiting on the OS's address-change notifications) - and, only while
55 * a burst of changes settles and is acted on, a thread of its own. Where the OS cannot tell (e.g. some containers),
56 * it is just not done.
57 */
59 };
60 static const Options kDefaultOptions;
61
62 public:
63 /**
64 * Search for SSDP devices, calling callOnFinds - and any callback added with AddOnFoundCallback - with each answer. The
65 * search starts given initialSearch, else with Start (); @see Start () for possible values for initialSearch and
66 * autoRetryInterval.
67 *
68 * \note THREADS: callOnFinds is called on the searcher's own thread, not the caller's - so it must be thread-safe, and
69 * whatever it shares with other threads needs synchronizing (e.g. Execution::Synchronized). An exception from it
70 * is logged (DbgTrace) and ignored: the other callbacks still get the answer.
71 *
72 * \note Keep callOnFinds quick: Stop () and destruction wait for one running. (Searching a network that appears does
73 * not - given Options::fFollowNetworkChanges, the search starts over once it returns.)
74 * Hand slow work - fetching the device description, say - to another thread, or give it a timeout: an HTTP fetch
75 * from a device that has just gone can take minutes (IO::Network::Transfer::Connection has no timeout of its own).
76 *
77 * \note NETWORKS: each M-SEARCH goes out of every network interface options.fInterfaces accepts (by default, every one
78 * running and not loopback) - listed afresh for each send, so networks that come and go are picked up (a new
79 * one right away, given Options::fFollowNetworkChanges). If it accepts none (or there is no network yet),
80 * nothing is sent until there is one.
81 */
82 Search (const Options& options = kDefaultOptions);
83 Search (const function<void (const SSDP::Advertisement& d)>& callOnFinds, const Options& options = kDefaultOptions); ///< \brief callOnFinds: called on the searcher's own thread
84 Search (const function<void (const SSDP::Advertisement& d)>& callOnFinds, const String& initialSearch,
85 const Options& options = kDefaultOptions); ///< \brief ... and Start (initialSearch); callOnFinds: called on the searcher's own thread
86 Search (const function<void (const SSDP::Advertisement& d)>& callOnFinds, const String& initialSearch,
87 const optional<Time::Duration>& autoRetryInterval,
88 const Options& options = kDefaultOptions); ///< \brief ... and Start (initialSearch, autoRetryInterval); callOnFinds: called on the searcher's own thread
89 Search (Search&&) = default;
90 Search (const Search&) = delete;
91
92 public:
93 /**
94 * Its OK to destroy a searcher while running. It will silently stop the running searcher thread.
95 */
96 ~Search ();
97
98 public:
99 nonvirtual const Search& operator= (const Search&) = delete;
100
101 public:
102 /**
103 * \brief Names a callback AddOnFoundCallback added, for RemoveOnFoundCallback.
104 */
105 using CallbackID = Execution::CallbackRegistry<void (const SSDP::Advertisement&)>::ID;
106
107 public:
108 /**
109 * \brief Call callOnFinds too, with each answer from now on. From any thread, also once the search has started - and
110 * from within a callback; it never waits for a running one.
111 *
112 * \note THREADS: callOnFinds is called on the searcher's own thread, not the caller's - so it must be thread-safe.
113 */
114 nonvirtual CallbackID AddOnFoundCallback (const function<void (const SSDP::Advertisement& d)>& callOnFinds);
115
116 public:
117 /**
118 * \brief Once this returns, that callback is not running, and is never called again - except that, called from within it,
119 * the call already under way finishes. So it waits for that callback, running on the searcher's thread: do not
120 * call it holding a lock that callback takes. Removing one not added (or already removed) does nothing.
121 */
122 nonvirtual void RemoveOnFoundCallback (CallbackID callOnFinds);
123
124 public:
125 /**
126 * \brief The network interfaces its last M-SEARCH went out of - as they were then (so with the addresses they had then).
127 * Safe to call from any thread.
128 */
129 nonvirtual IO::Network::InterfacesByID GetNetworkInterfaces () const;
130
131 public:
132 /**
133 * ssdp:all - possible argument for search string
134 */
135 static const String kSSDPAny;
136
137 public:
138 /**
139 * upnp:rootdevice - possible argument for search string
140 */
141 static const String kRootDevice;
142
143 public:
144 /**
145 * Starts searcher (probably starts a thread).
146 * args - ST, strings, uuid etc.
147 *
148 * If already running, this automatically stops an existing search, and restarts it with
149 * the given serviceType parameters.
150 *
151 * ssdp:all: Search for all devices and services.
152 * \par Example Usage
153 * \code
154 * Start ("ssdp:all"); // Search for all devices and services
155 * Start (kSSDPAny); // ...
156 * \endcode
157 *
158 * \par Example Usage
159 * \code
160 * Start ("upnp:rootdevice"); // Search for all root devices
161 * Start (kRootDevice); // ...
162 * \endcode
163 *
164 * \par Example Usage
165 * \code
166 * Start ("urn:schemas-wifialliance-org:service:WFAWLANConfig:1"); // Search for all devices of this type
167 * \endcode
168 *
169 *
170 * \par Example Usage
171 * \code
172 * Start ("uuid:9cd09dd4-fd8d-5737-abc3-2faa8c11cbdb"); // Search specific device
173 * \endcode
174 *
175 */
176 nonvirtual void Start (const String& serviceType, const optional<Time::Duration>& autoRetryInterval = nullopt);
177
178 public:
179 /**
180 * Stop an already running search. Not an error to call if not already started (just does nothing).
181 * This will block until the searcher has stopped (typically milliseconds).
182 */
183 nonvirtual void Stop ();
184
185 private:
186 class Rep_;
187 shared_ptr<Rep_> fRep_;
188 };
189
190}
191
192/*
193 ********************************************************************************
194 ***************************** Implementation Details ***************************
195 ********************************************************************************
196 */
197#include "Search.inl"
198
199#endif /*_Stroika_Frameworks_UPnP_SSDP_Client_Search_h_*/
bool DefaultInterfaceFilter(const Foundation::IO::Network::Interface &i)
SSDP's default InterfaceFilter: an interface that is running, and not loopback (whose multicast suppo...
constexpr uint8_t kDefaultMulticastTTL
The TTL (IPv6: hop limit) multicast SSDP packets - NOTIFYs and M-SEARCHes - go out with,...
function< bool(const Foundation::IO::Network::Interface &i)> InterfaceFilter
Which network interfaces SSDP is to talk on - asked of each interface every time SSDP lists them,...
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
a cross between Mapping<KEY, T> and Collection<T> and Set<T>
The callbacks an object calls when something happens - each added, and removed by the ID Add gave it ...
IO::Network::InternetProtocol::IP::IPVersionSupport fIPVersion
Definition Search.h:40