();
private IntPtr _observerHandle = IntPtr.Zero;
///
/// The constructor.
///
/// 3
///
/// @a uri format would be relative URI path like '/a/light'
/// and its length must be less than 128.
///
///
/// http://tizen.org/privilege/internet
///
/// public
/// The URI path of the resource.
/// Resource types.
/// Resource interfaces.
/// The policies of the resoruce.
/// http://tizen.org/feature/iot.ocf
///
/// IoTConnectivityServerManager.Initialize() should be called to initialize.
///
///
///
///
/// Thrown when the iotcon is not supported.
/// Thrown when there is not enough memory.
///
/// // Create a class which inherits from Resource
/// public class DoorResource : Resource
/// {
/// public DoorResource(string uri, ResourceTypes types, ResourceInterfaces interfaces, ResourcePolicy policy)
/// : base(uri, types, interfaces, policy) {
/// }
/// protected override Response OnDelete(Request request) {
/// // Do something
/// }
/// protected override Response OnGet(Request request) {
/// // Do something
/// }
/// // Override other abstract methods of Resource class
/// }
///
/// // Use it like below
/// ResourceInterfaces ifaces = new ResourceInterfaces(new List(){ ResourceInterfaces.DefaultInterface });
/// ResourceTypes types = new ResourceTypes(new List(){ "oic.iot.door.new" });
/// Resource resource = new DoorResource("/door/uri1", types, ifaces, ResourcePolicy.Discoverable | ResourcePolicy.Observable);
///
protected Resource(string uri, ResourceTypes types, ResourceInterfaces interfaces, ResourcePolicy policy)
{
UriPath = uri;
Types = types;
Interfaces = interfaces;
Policy = policy;
_children.CollectionChanged += ChildrenCollectionChanged;
int ret = Interop.IoTConnectivity.Server.Observers.Create(out _observerHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create obsever handle");
throw IoTConnectivityErrorFactory.GetException(ret);
}
}
///
/// Destructor of the Resource class.
///
~Resource()
{
Dispose(false);
}
///
/// Type details of the resource.
///
/// 3
/// Type details of the resource.
public ResourceTypes Types { get; internal set; }
///
/// Interface details of the resource.
///
/// 3
/// Interface details of the resource.
public ResourceInterfaces Interfaces { get; internal set; }
///
/// The policies of the resource.
///
/// 3
/// The policies of the resource.
public ResourcePolicy Policy { get; internal set; }
///
/// URI path of the resource.
///
/// 3
/// URI path of the resource.
public string UriPath { get; internal set; }
///
/// List of Child resources.
///
/// 3
/// List of Child resources.
public ICollection Children
{
get
{
return _children;
}
}
internal IntPtr ResourceHandle
{
get
{
return _resourceHandle;
}
set
{
_resourceHandle = value;
}
}
///
/// Notify the specified representation and qos.
///
/// 3
///
/// http://tizen.org/privilege/internet
///
/// public
/// Representation.
/// The quality of service for message transfer.
/// http://tizen.org/feature/iot.ocf
///
/// IoTConnectivityServerManager.Initialize() should be called to initialize.
///
///
///
/// Thrown when the iotcon is not supported.
/// Thrown when an application does not have privilege to access.
/// Thrown when the operation is invalid.
///
/// ResourceInterfaces ifaces = new ResourceInterfaces(new List(){ ResourceInterfaces.DefaultInterface });
/// ResourceTypes types = new ResourceTypes(new List(){ "oic.iot.door.new.notify" });
/// Resource resource = new DoorResource("/door/uri/new/notify", types, ifaces, ResourcePolicy.Discoverable | ResourcePolicy.Observable);
/// IoTConnectivityServerManager.RegisterResource(resource);
///
/// Representation repr = new Representation();
/// repr.UriPath = "/door/uri/new/notify";
/// repr.Type = new ResourceTypes(new List(){ "oic.iot.door.new.notify" });
/// repr.Attributes = new Attributes() {
/// _attribute, 1 }
/// };
/// resource.Notify(repr, QualityOfService.High);
///
public void Notify(Representation representation, QualityOfService qos)
{
int ret = (int)IoTConnectivityError.None;
ret = Interop.IoTConnectivity.Server.Resource.Notify(_resourceHandle, representation._representationHandle, _observerHandle, (int)qos);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to send notification");
throw IoTConnectivityErrorFactory.GetException(ret);
}
}
///
/// This is called when the client performs get operation on this resource.
///
/// 3
/// A request from client.
/// A response having the representation and the result.
protected abstract Response OnGet(Request request);
///
/// This is called when the client performs put operation on this resource.
///
/// 3
/// A request from client.
/// A response.
protected abstract Response OnPut(Request request);
///
/// This is called when the client performs post operation on this resource.
///
/// 3
/// A request from client.
/// A response having the representation and the result.
protected abstract Response OnPost(Request request);
///
/// This is called when the client performs delete operation on this resource.
///
/// 3
/// A request from client.
/// A response.
protected abstract Response OnDelete(Request request);
///
/// Called on the observing event.
///
/// 3
/// A request from client.
/// Observer type.
/// Observe identifier.
/// Returns true if it wants to be observed, else false.
protected abstract bool OnObserving(Request request, ObserveType type, int observeId);
///
/// Releases any unmanaged resources used by this object.
///
/// 3
/// http://tizen.org/feature/iot.ocf
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
///
/// 3
/// If true, disposes any disposable objects. If false, does not dispose disposable objects.
/// http://tizen.org/feature/iot.ocf
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
Types?.Dispose();
Interfaces?.Dispose();
}
if (_resourceHandle != IntPtr.Zero)
Interop.IoTConnectivity.Server.Resource.Destroy(_resourceHandle);
if (_observerHandle != IntPtr.Zero)
Interop.IoTConnectivity.Server.Observers.Destroy(_observerHandle);
_disposed = true;
}
// This method is used as callback for Resource
internal void OnRequest(IntPtr resourceHandle, IntPtr requestHandle, IntPtr userData)
{
Request request = GetRequest(requestHandle);
Response response = null;
if (request == null)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get Request");
return;
}
try
{
int observeType;
int ret = Interop.IoTConnectivity.Server.Request.GetObserveType(requestHandle, out observeType);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get observe type");
return;
}
if ((ObserveType)observeType != ObserveType.NoType)
{
int observeId;
ret = Interop.IoTConnectivity.Server.Request.GetObserveId(requestHandle, out observeId);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get observe id");
return;
}
switch ((ObserveType)observeType)
{
case ObserveType.Register:
{
if (OnObserving(request, ObserveType.Register, observeId))
{
ret = Interop.IoTConnectivity.Server.Observers.Add(_observerHandle, observeId);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add observer id");
return;
}
break;
}
else
{
// If OnObserving for ObserveType.Register returns false, do not operate for Get operation after Observe operation.
return;
}
}
case ObserveType.Deregister:
{
if (OnObserving(request, ObserveType.Deregister, observeId))
{
ret = Interop.IoTConnectivity.Server.Observers.Remove(_observerHandle, observeId);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove observer id");
return;
}
break;
}
else
{
// If OnObserving for ObserveType.Deregister returns false, do not operate for Get operation after Observe operation.
return;
}
}
}
}
int requestType;
ret = Interop.IoTConnectivity.Server.Request.GetRequestType(requestHandle, out requestType);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get request type");
return;
}
switch ((Interop.IoTConnectivity.Server.RequestType)requestType)
{
case Interop.IoTConnectivity.Server.RequestType.Put:
{
response = OnPut(request);
break;
}
case Interop.IoTConnectivity.Server.RequestType.Get:
{
response = OnGet(request);
break;
}
case Interop.IoTConnectivity.Server.RequestType.Post:
{
response = OnPost(request);
break;
}
case Interop.IoTConnectivity.Server.RequestType.Delete:
{
response = OnDelete(request);
break;
}
default:
break;
}
if (response == null)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to send Response");
return;
}
if (!response.Send(requestHandle))
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to send Response");
return;
}
}
finally
{
request?.Dispose();
response?.Dispose();
}
}
private Request GetRequest(IntPtr requestHandle)
{
IntPtr hostAddressPtr;
int ret = Interop.IoTConnectivity.Server.Request.GetHostAddress(requestHandle, out hostAddressPtr);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get host address");
return null;
}
IntPtr optionsHandle = IntPtr.Zero;
ret = Interop.IoTConnectivity.Server.Request.GetOptions(requestHandle, out optionsHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get options");
return null;
}
IntPtr queryHandle = IntPtr.Zero;
ret = Interop.IoTConnectivity.Server.Request.GetQuery(requestHandle, out queryHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get Query");
return null;
}
IntPtr representationHandle = IntPtr.Zero;
ret = Interop.IoTConnectivity.Server.Request.GetRepresentation(requestHandle, out representationHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Get representation");
return null;
}
ResourceOptions opts = null;
ResourceQuery query = null;
Representation representation = null;
try
{
opts = (optionsHandle == IntPtr.Zero) ? null : new ResourceOptions(optionsHandle);
}
catch (Exception exp)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new ResourceOptions: " + exp.Message);
return null;
}
try
{
query = (queryHandle == IntPtr.Zero) ? null : new ResourceQuery(queryHandle);
}
catch (Exception exp)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new ResourceQuery: " + exp.Message);
opts?.Dispose();
return null;
}
try
{
representation = (representationHandle == IntPtr.Zero) ? null : new Representation(representationHandle);
}
catch (Exception exp)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new Representation: " + exp.Message);
opts?.Dispose();
query?.Dispose();
return null;
}
return new Request()
{
HostAddress = (hostAddressPtr != IntPtr.Zero) ? Marshal.PtrToStringAnsi(hostAddressPtr) : string.Empty,
Options = opts,
Query = query,
Representation = representation
};
}
private void ChildrenCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs eventArgs)
{
if (eventArgs.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
foreach (Resource r in eventArgs.NewItems)
{
int ret = Interop.IoTConnectivity.Server.Resource.BindChildResource(_resourceHandle, r._resourceHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to bind resource ");
throw IoTConnectivityErrorFactory.GetException(ret);
}
}
}
else if (eventArgs.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
{
foreach (Resource r in eventArgs.NewItems)
{
int ret = Interop.IoTConnectivity.Server.Resource.UnbindChildResource(_resourceHandle, r._resourceHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to unbind resource");
throw IoTConnectivityErrorFactory.GetException(ret);
}
}
}
}
}
}