1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_dom_presentation_provider_MulticastDNSDeviceProvider_h
8 #define mozilla_dom_presentation_provider_MulticastDNSDeviceProvider_h
9 
10 #include "mozilla/RefPtr.h"
11 #include "nsCOMPtr.h"
12 #include "nsICancelable.h"
13 #include "nsIDNSServiceDiscovery.h"
14 #include "nsIObserver.h"
15 #include "nsIPresentationDevice.h"
16 #include "nsIPresentationDeviceProvider.h"
17 #include "nsIPresentationControlService.h"
18 #include "nsITimer.h"
19 #include "nsString.h"
20 #include "nsTArray.h"
21 #include "nsWeakPtr.h"
22 
23 class nsITCPDeviceInfo;
24 
25 namespace mozilla {
26 namespace dom {
27 namespace presentation {
28 
29 class DNSServiceWrappedListener;
30 class MulticastDNSService;
31 
32 class MulticastDNSDeviceProvider final
33     : public nsIPresentationDeviceProvider,
34       public nsIDNSServiceDiscoveryListener,
35       public nsIDNSRegistrationListener,
36       public nsIDNSServiceResolveListener,
37       public nsIPresentationControlServerListener,
38       public nsIObserver {
39  public:
40   NS_DECL_ISUPPORTS
41   NS_DECL_NSIPRESENTATIONDEVICEPROVIDER
42   NS_DECL_NSIDNSSERVICEDISCOVERYLISTENER
43   NS_DECL_NSIDNSREGISTRATIONLISTENER
44   NS_DECL_NSIDNSSERVICERESOLVELISTENER
45   NS_DECL_NSIPRESENTATIONCONTROLSERVERLISTENER
46   NS_DECL_NSIOBSERVER
47 
48   explicit MulticastDNSDeviceProvider() = default;
49   nsresult Init();
50   nsresult Uninit();
51 
52  private:
53   enum class DeviceState : uint32_t { eUnknown, eActive };
54 
55   class Device final : public nsIPresentationDevice {
56    public:
57     NS_DECL_ISUPPORTS
58     NS_DECL_NSIPRESENTATIONDEVICE
59 
Device(const nsACString & aId,const nsACString & aName,const nsACString & aType,const nsACString & aAddress,const uint16_t aPort,const nsACString & aCertFingerprint,DeviceState aState,MulticastDNSDeviceProvider * aProvider)60     explicit Device(const nsACString& aId, const nsACString& aName,
61                     const nsACString& aType, const nsACString& aAddress,
62                     const uint16_t aPort, const nsACString& aCertFingerprint,
63                     DeviceState aState, MulticastDNSDeviceProvider* aProvider)
64         : mId(aId),
65           mName(aName),
66           mType(aType),
67           mAddress(aAddress),
68           mPort(aPort),
69           mCertFingerprint(aCertFingerprint),
70           mState(aState),
71           mProvider(aProvider) {}
72 
Id()73     const nsCString& Id() const { return mId; }
74 
Address()75     const nsCString& Address() const { return mAddress; }
76 
Port()77     uint16_t Port() const { return mPort; }
78 
CertFingerprint()79     const nsCString& CertFingerprint() const { return mCertFingerprint; }
80 
State()81     DeviceState State() const { return mState; }
82 
ChangeState(DeviceState aState)83     void ChangeState(DeviceState aState) { mState = aState; }
84 
Update(const nsACString & aName,const nsACString & aType,const nsACString & aAddress,const uint16_t aPort,const nsACString & aCertFingerprint)85     void Update(const nsACString& aName, const nsACString& aType,
86                 const nsACString& aAddress, const uint16_t aPort,
87                 const nsACString& aCertFingerprint) {
88       mName = aName;
89       mType = aType;
90       mAddress = aAddress;
91       mPort = aPort;
92       mCertFingerprint = aCertFingerprint;
93     }
94 
95    private:
96     virtual ~Device() = default;
97 
98     nsCString mId;
99     nsCString mName;
100     nsCString mType;
101     nsCString mAddress;
102     uint16_t mPort;
103     nsCString mCertFingerprint;
104     DeviceState mState;
105     MulticastDNSDeviceProvider* mProvider;
106   };
107 
108   struct DeviceIdComparator {
EqualsDeviceIdComparator109     bool Equals(const RefPtr<Device>& aA, const RefPtr<Device>& aB) const {
110       return aA->Id() == aB->Id();
111     }
112   };
113 
114   struct DeviceAddressComparator {
EqualsDeviceAddressComparator115     bool Equals(const RefPtr<Device>& aA, const RefPtr<Device>& aB) const {
116       return aA->Address() == aB->Address();
117     }
118   };
119 
120   virtual ~MulticastDNSDeviceProvider();
121   nsresult StartServer();
122   nsresult StopServer();
123   void AbortServerRetry();
124   nsresult RegisterMDNSService();
125   nsresult UnregisterMDNSService(nsresult aReason);
126   nsresult StopDiscovery(nsresult aReason);
127   nsresult Connect(Device* aDevice, nsIPresentationControlChannel** aRetVal);
128   bool IsCompatibleServer(nsIDNSServiceInfo* aServiceInfo);
129 
130   // device manipulation
131   nsresult AddDevice(const nsACString& aId, const nsACString& aServiceName,
132                      const nsACString& aServiceType, const nsACString& aAddress,
133                      const uint16_t aPort, const nsACString& aCertFingerprint);
134   nsresult UpdateDevice(const uint32_t aIndex, const nsACString& aServiceName,
135                         const nsACString& aServiceType,
136                         const nsACString& aAddress, const uint16_t aPort,
137                         const nsACString& aCertFingerprint);
138   nsresult RemoveDevice(const uint32_t aIndex);
139   bool FindDeviceById(const nsACString& aId, uint32_t& aIndex);
140 
141   bool FindDeviceByAddress(const nsACString& aAddress, uint32_t& aIndex);
142 
143   already_AddRefed<Device> GetOrCreateDevice(nsITCPDeviceInfo* aDeviceInfo);
144 
145   void MarkAllDevicesUnknown();
146   void ClearUnknownDevices();
147   void ClearDevices();
148 
149   // preferences
150   nsresult OnDiscoveryChanged(bool aEnabled);
151   nsresult OnDiscoveryTimeoutChanged(uint32_t aTimeoutMs);
152   nsresult OnDiscoverableChanged(bool aEnabled);
153   nsresult OnServiceNameChanged(const nsACString& aServiceName);
154 
155   bool mInitialized = false;
156   nsWeakPtr mDeviceListener;
157   nsCOMPtr<nsIPresentationControlService> mPresentationService;
158   nsCOMPtr<nsIDNSServiceDiscovery> mMulticastDNS;
159   RefPtr<DNSServiceWrappedListener> mWrappedListener;
160 
161   nsCOMPtr<nsICancelable> mDiscoveryRequest;
162   nsCOMPtr<nsICancelable> mRegisterRequest;
163 
164   nsTArray<RefPtr<Device>> mDevices;
165 
166   bool mDiscoveryEnabled = false;
167   bool mIsDiscovering = false;
168   uint32_t mDiscoveryTimeoutMs;
169   nsCOMPtr<nsITimer> mDiscoveryTimer;
170 
171   bool mDiscoverable = false;
172   bool mDiscoverableEncrypted = false;
173   bool mIsServerRetrying = false;
174   uint32_t mServerRetryMs;
175   nsCOMPtr<nsITimer> mServerRetryTimer;
176 
177   nsCString mServiceName;
178   nsCString mRegisteredName;
179 };
180 
181 }  // namespace presentation
182 }  // namespace dom
183 }  // namespace mozilla
184 
185 #endif  // mozilla_dom_presentation_provider_MulticastDNSDeviceProvider_h
186