1 /// Copyright 2016 by Samsung Electronics, Inc.,
3 /// This software is the confidential and proprietary information
4 /// of Samsung Electronics, Inc. ("Confidential Information"). You
5 /// shall not disclose such Confidential Information and shall use
6 /// it only in accordance with the terms of the license agreement
7 /// you entered into with Samsung.
10 using System.Collections.Generic;
11 using System.Collections.ObjectModel;
12 using System.Runtime.InteropServices;
14 namespace Tizen.Network.IoTConnectivity
17 /// Abstract class respresenting a resource.
18 /// All resources need to inherit from this class.
20 public abstract class Resource : IDisposable
22 private IntPtr _resourceHandle = IntPtr.Zero;
23 private bool _disposed = false;
24 private ObservableCollection<Resource> _children = new ObservableCollection<Resource>();
25 private IntPtr _observerHandle = IntPtr.Zero;
31 /// @a uri format would be relative URI path like '/a/light'
32 /// and its length must be less than 128.
35 /// http://tizen.org/privilege/internet
37 /// <param name="uri">The URI path of the resource</param>
38 /// <param name="types">Resource types</param>
39 /// <param name="interfaces">Resource interfaces</param>
40 /// <param name="policy">The policies of the resoruce</param>
42 /// IoTConnectivityServerManager.Initialize() should be called to initialize
44 /// <seealso cref="ResourceTypes"/>
45 /// <seealso cref="ResourceInterfaces"/>
46 /// <seealso cref="ResourcePolicy"/>
48 /// // Create a class which inherits from Resource
49 /// public class DoorResource : Resource
51 /// public DoorResource(string uri, ResourceTypes types, ResourceInterfaces interfaces, ResourcePolicy policy)
52 /// : base(uri, types, interfaces, policy) {
54 /// protected override Response OnDelete(Request request) {
57 /// protected override Response OnGet(Request request) {
60 /// // Override other abstract methods of Resource class
63 /// // Use it like below
64 /// ResourceInterfaces ifaces = new ResourceInterfaces(new List<string>(){ ResourceInterfaces.DefaultInterface });
65 /// ResourceTypes types = new ResourceTypes(new List<string>(){ "oic.iot.door.new" });
66 /// Resource resource = new DoorResource("/door/uri1", types, ifaces, ResourcePolicy.Discoverable | ResourcePolicy.Observable);
68 protected Resource(string uri, ResourceTypes types, ResourceInterfaces interfaces, ResourcePolicy policy)
72 Interfaces = interfaces;
75 _children.CollectionChanged += ChildrenCollectionChanged;
77 int ret = Interop.IoTConnectivity.Server.Observers.Create(out _observerHandle);
78 if (ret != (int)IoTConnectivityError.None)
80 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create obsever handle");
81 throw IoTConnectivityErrorFactory.GetException(ret);
86 /// Destructor of the Resource class.
94 /// Type details of the resource
96 public ResourceTypes Types { get; internal set; }
99 /// Interface details of the resource
101 public ResourceInterfaces Interfaces { get; internal set; }
104 /// The policies of the resource
106 public ResourcePolicy Policy { get; internal set; }
109 /// URI path of the resource
111 public string UriPath { get; internal set; }
114 /// List of Child resources
116 public ICollection<Resource> Children
124 internal IntPtr ResourceHandle
128 return _resourceHandle;
132 _resourceHandle = value;
137 /// Notify the specified representation and qos.
140 /// http://tizen.org/privilege/internet
142 /// <param name="representation">Representation.</param>
143 /// <param name="qos">The quality of service for message transfer.</param>
145 /// IoTConnectivityServerManager.Initialize() should be called to initialize
147 /// <seealso cref="Representation"/>
148 /// <seealso cref="QualityOfService"/>
150 /// ResourceInterfaces ifaces = new ResourceInterfaces(new List<string>(){ ResourceInterfaces.DefaultInterface });
151 /// ResourceTypes types = new ResourceTypes(new List<string>(){ "oic.iot.door.new.notify" });
152 /// Resource resource = new DoorResource("/door/uri/new/notify", types, ifaces, ResourcePolicy.Discoverable | ResourcePolicy.Observable);
153 /// IoTConnectivityServerManager.RegisterResource(resource);
155 /// Representation repr = new Representation();
156 /// repr.UriPath = "/door/uri/new/notify";
157 /// repr.Type = new ResourceTypes(new List<string>(){ "oic.iot.door.new.notify" });
158 /// repr.Attributes = new Attributes() {
161 /// resource.Notify(repr, QualityOfService.High);
163 public void Notify(Representation representation, QualityOfService qos)
165 int ret = (int)IoTConnectivityError.None;
166 ret = Interop.IoTConnectivity.Server.Resource.Notify(_resourceHandle, representation._representationHandle, _observerHandle, (int)qos);
167 if (ret != (int)IoTConnectivityError.None)
169 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to send notification");
170 throw IoTConnectivityErrorFactory.GetException(ret);
175 /// This is Called when the client performs get operation on this resource.
177 /// <param name="request">A request from client</param>
178 /// <returns>A response having the representation and the result</returns>
179 protected abstract Response OnGet(Request request);
182 /// This is Called when the client performs put operation on this resource.
184 /// <param name="request">A request from client</param>
185 /// <returns>A response</returns>
186 protected abstract Response OnPut(Request request);
189 /// This is Called when the client performs post operation on this resource.
191 /// <param name="request">A request from client</param>
192 /// <returns>A response having the representation and the result</returns>
193 protected abstract Response OnPost(Request request);
196 /// This is Called when the client performs delete operation on this resource.
198 /// <param name="request">A request from client</param>
199 /// <returns>A response</returns>
200 protected abstract Response OnDelete(Request request);
203 /// Called on the observing event.
205 /// <param name="request">A request from client</param>
206 /// <param name="type">Observer type</param>
207 /// <param name="observeId">Observe identifier.</param>
208 /// <returns>Returns true if it wants to be observed, else false.</returns>
209 protected abstract bool OnObserving(Request request, ObserveType type, int observeId);
212 /// Releases any unmanaged resources used by this object.
214 public void Dispose()
217 GC.SuppressFinalize(this);
221 /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
223 /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
224 protected virtual void Dispose(bool disposing)
232 Interfaces?.Dispose();
235 if (_resourceHandle != IntPtr.Zero)
236 Interop.IoTConnectivity.Server.Resource.Destroy(_resourceHandle);
237 if (_observerHandle != IntPtr.Zero)
238 Interop.IoTConnectivity.Server.Observers.Destroy(_observerHandle);
242 // This method is used as callback for Resource
243 internal void OnRequest(IntPtr resourceHandle, IntPtr requestHandle, IntPtr userData)
245 Request request = GetRequest(requestHandle);
246 Response response = null;
250 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get Request");
257 int ret = Interop.IoTConnectivity.Server.Request.GetObserveType(requestHandle, out observeType);
258 if (ret != (int)IoTConnectivityError.None)
260 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get observe type");
263 if ((ObserveType)observeType != ObserveType.NoType)
266 ret = Interop.IoTConnectivity.Server.Request.GetObserveId(requestHandle, out observeId);
267 if (ret != (int)IoTConnectivityError.None)
269 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get observe id");
272 switch ((ObserveType)observeType)
274 case ObserveType.Register:
276 if (OnObserving(request, ObserveType.Register, observeId))
278 ret = Interop.IoTConnectivity.Server.Observers.Add(_observerHandle, observeId);
279 if (ret != (int)IoTConnectivityError.None)
281 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add observer id");
288 // If OnObserving for ObserveType.Register returns false, do not operate for Get operation after Observe operation.
292 case ObserveType.Deregister:
294 if (OnObserving(request, ObserveType.Deregister, observeId))
296 ret = Interop.IoTConnectivity.Server.Observers.Remove(_observerHandle, observeId);
297 if (ret != (int)IoTConnectivityError.None)
299 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove observer id");
306 // If OnObserving for ObserveType.Deregister returns false, do not operate for Get operation after Observe operation.
313 ret = Interop.IoTConnectivity.Server.Request.GetRequestType(requestHandle, out requestType);
314 if (ret != (int)IoTConnectivityError.None)
316 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get request type");
319 switch ((Interop.IoTConnectivity.Server.RequestType)requestType)
321 case Interop.IoTConnectivity.Server.RequestType.Put:
323 response = OnPut(request);
326 case Interop.IoTConnectivity.Server.RequestType.Get:
328 response = OnGet(request);
331 case Interop.IoTConnectivity.Server.RequestType.Post:
333 response = OnPost(request);
336 case Interop.IoTConnectivity.Server.RequestType.Delete:
338 response = OnDelete(request);
344 if (response == null)
346 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to send Response");
350 if (!response.Send(requestHandle))
352 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to send Response");
363 private Request GetRequest(IntPtr requestHandle)
365 IntPtr hostAddressPtr;
366 int ret = Interop.IoTConnectivity.Server.Request.GetHostAddress(requestHandle, out hostAddressPtr);
367 if (ret != (int)IoTConnectivityError.None)
369 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get host address");
373 IntPtr optionsHandle = IntPtr.Zero;
374 ret = Interop.IoTConnectivity.Server.Request.GetOptions(requestHandle, out optionsHandle);
375 if (ret != (int)IoTConnectivityError.None)
377 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get options");
381 IntPtr queryHandle = IntPtr.Zero;
382 ret = Interop.IoTConnectivity.Server.Request.GetQuery(requestHandle, out queryHandle);
383 if (ret != (int)IoTConnectivityError.None)
385 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get Query");
389 IntPtr representationHandle = IntPtr.Zero;
390 ret = Interop.IoTConnectivity.Server.Request.GetRepresentation(requestHandle, out representationHandle);
391 if (ret != (int)IoTConnectivityError.None)
393 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get representation");
397 ResourceOptions opts = null;
398 ResourceQuery query = null;
399 Representation representation = null;
402 opts = (optionsHandle == IntPtr.Zero) ? null : new ResourceOptions(optionsHandle);
404 catch (Exception exp)
406 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new ResourceOptions: " + exp.Message);
412 query = (queryHandle == IntPtr.Zero) ? null : new ResourceQuery(queryHandle);
414 catch (Exception exp)
416 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new ResourceQuery: " + exp.Message);
422 representation = (representationHandle == IntPtr.Zero) ? null : new Representation(representationHandle); ;
424 catch (Exception exp)
426 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new Representation: " + exp.Message);
432 HostAddress = Marshal.PtrToStringAnsi(hostAddressPtr),
435 Representation = representation
439 private void ChildrenCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs eventArgs)
441 if (eventArgs.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
443 foreach (Resource r in eventArgs.NewItems)
445 int ret = Interop.IoTConnectivity.Server.Resource.BindChildResource(_resourceHandle, r._resourceHandle);
446 if (ret != (int)IoTConnectivityError.None)
448 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to bind resource ");
449 throw IoTConnectivityErrorFactory.GetException(ret);
453 else if (eventArgs.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
455 foreach (Resource r in eventArgs.NewItems)
457 int ret = Interop.IoTConnectivity.Server.Resource.UnbindChildResource(_resourceHandle, r._resourceHandle);
458 if (ret != (int)IoTConnectivityError.None)
460 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to unbind resource");
461 throw IoTConnectivityErrorFactory.GetException(ret);