[Nsd]Fixed ArgumentException and implemented IDisposable in INsdService
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.Nsd / Tizen.Network.Nsd / SsdpService.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Threading;
19
20 namespace Tizen.Network.Nsd
21 {
22     internal class SsdpInitializer
23     {
24         internal SsdpInitializer()
25         {
26             Globals.SsdpInitialize();
27         }
28
29         ~SsdpInitializer()
30         {
31             int ret = Interop.Nsd.Ssdp.Deinitialize();
32             if (ret != (int)SsdpError.None)
33             {
34                 Log.Error(Globals.LogTag, "Failed to deinitialize Ssdp, Error - " + (SsdpError)ret);
35             }
36         }
37     }
38
39     /// <summary>
40     /// This class is used for managing local service registration and its properties using SSDP.
41     /// </summary>
42     /// <since_tizen> 4 </since_tizen>
43     public class SsdpService : INsdService
44     {
45         private uint _serviceHandle;
46         private string _target;
47         private Interop.Nsd.Ssdp.ServiceRegisteredCallback _serviceRegisteredCallback;
48
49         /// <summary>
50         /// Constructor to create SsdpService instance that sets the target to a given value.
51         /// </summary>
52         /// <since_tizen> 4 </since_tizen>
53         /// <param name="target">The SSDP local service's target. It may be a device type or a service type.</param>
54         /// <feature>http://tizen.org/feature/network.ssdp</feature>
55         public SsdpService(string target)
56         {
57             _target = target;
58             SsdpInitializeCreateService();
59         }
60
61         internal SsdpService(uint service)
62         {
63             _serviceHandle = service;
64         }
65
66         internal void SsdpInitializeCreateService()
67         {
68             SsdpInitializer ssdpInit = Globals.s_threadSsd.Value;
69             Log.Info(Globals.LogTag, "Initialize ThreadLocal<SsdpInitializer> instance = " + ssdpInit);
70             int ret = Interop.Nsd.Ssdp.CreateService(_target, out _serviceHandle);
71             if (ret != (int)SsdpError.None)
72             {
73                 Log.Error(Globals.LogTag, "Failed to create a local Ssdp service handle, Error - " + (SsdpError)ret);
74                 NsdErrorFactory.ThrowSsdpException(ret);
75             }
76         }
77
78         /// <summary>
79         /// Unique Service Name of SSDP service.
80         /// </summary>
81         /// <remarks>
82         /// Set Usn for only unregistered service created locally. If service is already registered, Usn will not be set.
83         /// In case of error, null will be returned during get and exception will be thrown during set.
84         /// </remarks>
85         /// <since_tizen> 4 </since_tizen>
86         /// <feature>http://tizen.org/feature/network.ssdp</feature>
87         /// <exception cref="NotSupportedException">Thrown while setting this property when SSDP is not supported.</exception>
88         /// <exception cref="ArgumentException">Thrown when Usn value is set to null.</exception>
89         /// <exception cref="InvalidOperationException">Thrown while setting this property when any other error occurred.</exception>
90         public string Usn
91         {
92             get
93             {
94                 string usn;
95                 int ret = Interop.Nsd.Ssdp.GetUsn(_serviceHandle, out usn);
96                 if (ret != (int)SsdpError.None)
97                 {
98                     Log.Error(Globals.LogTag, "Failed to get usn of service, Error: " + (SsdpError)ret);
99                     return null;
100                 }
101
102                 return usn;
103             }
104
105             set
106             {
107                 if (!Globals.s_threadSsd.IsValueCreated)
108                 {
109                     SsdpInitializeCreateService();
110                 }
111
112                 int ret = Interop.Nsd.Ssdp.SetUsn(_serviceHandle, value);
113                 if (ret != (int)SsdpError.None)
114                 {
115                     Log.Error(Globals.LogTag, "Failed to set usn of service, Error: " + (SsdpError)ret);
116                     NsdErrorFactory.ThrowSsdpException(ret);
117                 }
118             }
119         }
120
121         /// <summary>
122         /// Target of SSDP service.
123         /// </summary>
124         /// <remarks>
125         /// It may be a device type or a service type specified in UPnP forum (http://upnp.org).
126         /// In case of error, null will be returned.
127         /// </remarks>
128         /// <since_tizen> 4 </since_tizen>
129         public string Target
130         {
131             get
132             {
133                 string target;
134                 int ret = Interop.Nsd.Ssdp.GetTarget(_serviceHandle, out target);
135                 if (ret != (int)SsdpError.None)
136                 {
137                     Log.Error(Globals.LogTag, "Failed to get target of service, Error: " + (SsdpError)ret);
138                     return null;
139                 }
140
141                 return target;
142             }
143         }
144
145         /// <summary>
146         /// URL of SSDP service.
147         /// </summary>
148         /// <remarks>
149         /// Set Url for only unregistered service created locally. If service is already registered, Url will not be set.
150         /// In case of error, null will be returned during get and exception will be thrown during set.
151         /// </remarks>
152         /// <since_tizen> 4 </since_tizen>
153         /// <feature>http://tizen.org/feature/network.ssdp</feature>
154         /// <exception cref="NotSupportedException">Thrown while setting this property when SSDP is not supported.</exception>
155         /// <exception cref="ArgumentException">Thrown when Url value is set to null.</exception>
156         /// <exception cref="InvalidOperationException">Thrown while setting this property when any other error occurred.</exception>
157         public string Url
158         {
159             get
160             {
161                 string url;
162                 int ret = Interop.Nsd.Ssdp.GetUrl(_serviceHandle, out url);
163                 if (ret != (int)SsdpError.None)
164                 {
165                     Log.Error(Globals.LogTag, "Failed to get url of Ssdp service, Error: " + (SsdpError)ret);
166                     return null;
167                 }
168
169                 return url;
170             }
171
172             set
173             {
174                 if (!Globals.s_threadSsd.IsValueCreated)
175                 {
176                     SsdpInitializeCreateService();
177                 }
178
179                 int ret = Interop.Nsd.Ssdp.SetUrl(_serviceHandle, value);
180                 if (ret != (int)SsdpError.None)
181                 {
182                     Log.Error(Globals.LogTag, "Failed to set url of Ssdp service, Error: " + (SsdpError)ret);
183                     NsdErrorFactory.ThrowSsdpException(ret);
184                 }
185             }
186         }
187
188         /// <summary>
189         /// Registers the SSDP local service for publishing.
190         /// </summary>
191         /// <remarks>
192         /// A service created locally must be passed.
193         /// Url and Usn of the service must be set before RegisterService is called.
194         /// </remarks>
195         /// <since_tizen> 4 </since_tizen>
196         /// <privilege>http://tizen.org/privilege/internet</privilege>
197         /// <feature>http://tizen.org/feature/network.ssdp</feature>
198         /// <exception cref="InvalidOperationException">Thrown when any other error occurred.</exception>
199         /// <exception cref="NotSupportedException">Thrown when SSDP is not supported.</exception>
200         /// <exception cref="UnauthorizedAccessException">Thrown when permission is denied.</exception>
201         public void RegisterService()
202         {
203             if (!Globals.s_threadSsd.IsValueCreated)
204             {
205                 SsdpInitializeCreateService();
206             }
207
208             _serviceRegisteredCallback = (SsdpError result, uint service, IntPtr userData) =>
209             {
210             };
211
212             int ret = Interop.Nsd.Ssdp.RegisterService(_serviceHandle, _serviceRegisteredCallback, IntPtr.Zero);
213             if (ret != (int)SsdpError.None)
214             {
215                 Log.Error(Globals.LogTag, "Failed to register the Ssdp local service, Error: " + (SsdpError)ret);
216                 NsdErrorFactory.ThrowSsdpException(ret);
217             }
218         }
219
220         /// <summary>
221         /// Deregisters the SSDP local service.
222         /// </summary>
223         /// <remarks>
224         /// A local service registered using RegisterService() must be passed.
225         /// </remarks>
226         /// <since_tizen> 4 </since_tizen>
227         /// <feature>http://tizen.org/feature/network.ssdp</feature>
228         /// <exception cref="InvalidOperationException">Thrown when any other error occurred.</exception>
229         /// <exception cref="NotSupportedException">Thrown when SSDP is not supported.</exception>
230         public void DeregisterService()
231         {
232             int ret = Interop.Nsd.Ssdp.DeregisterService(_serviceHandle);
233             if (ret != (int)SsdpError.None)
234             {
235                 Log.Error(Globals.LogTag, "Failed to deregister the Ssdp local service, Error: " + (SsdpError)ret);
236                 NsdErrorFactory.ThrowSsdpException(ret);
237             }
238         }
239
240         #region IDisposable Support
241         private bool _disposedValue = false; // To detect redundant calls
242
243         protected virtual void Dispose(bool disposing)
244         {
245             if (!_disposedValue)
246             {
247                 if (disposing)
248                 {
249                     if (_serviceHandle != 0)
250                     {
251                         int ret = Interop.Nsd.Ssdp.DestroyService(_serviceHandle);
252                         if (ret != (int)SsdpError.None)
253                         {
254                             Log.Error(Globals.LogTag, "Failed to destroy the local Ssdp service handle, Error - " + (SsdpError)ret);
255                         }
256                     }
257                 }
258
259                 _disposedValue = true;
260             }
261         }
262
263         ~SsdpService()
264         {
265             Dispose(false);
266         }
267
268         /// <summary>
269         /// Disposes the memory allocated to unmanaged resources.
270         /// </summary>
271         /// <since_tizen> 4 </since_tizen>
272         public void Dispose()
273         {
274             Dispose(true);
275             GC.SuppressFinalize(this);
276         }
277         #endregion
278     }
279 }