/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Net;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace Tizen.Network.IoTConnectivity
{
///
/// This class represents a remote resource.
/// It provides APIs to manage remote resource.
///
/// 3
public class RemoteResource : IDisposable
{
internal const int TimeOutMax = 3600;
internal IntPtr _remoteResourceHandle = IntPtr.Zero;
private bool _disposed = false;
private bool _cacheEnabled = false;
private ResourceOptions _options;
private static int _responseCallbackId = 1;
private static IDictionary _responseCallbacksMap = new ConcurrentDictionary();
private Interop.IoTConnectivity.Client.RemoteResource.CachedRepresentationChangedCallback _cacheUpdatedCallback;
private Interop.IoTConnectivity.Client.RemoteResource.StateChangedCallback _stateChangedCallback;
private Interop.IoTConnectivity.Client.RemoteResource.ObserveCallback _observeCallback;
private EventHandler _stateChangedEventHandler;
///
/// Creates a remote resource instance.
///
/// 3
///
/// To use this API, you should provide all the details required to correctly contact and
/// observe the object.
/// If not, you should discover the resource object manually.
/// The can contain multiple policies like ResourcePolicy.Discoverable | ResourcePolicy.Observable.
///
/// The host address of the resource.
/// The URI path of the resource.
/// The policies of the resource.
/// The resource types of the resource.
/// The resource interfaces of the resource.
/// http://tizen.org/feature/iot.ocf
/// Thrown when the iotcon is not supported.
/// Thrown when there is not enough memory.
/// Thrown when there is an invalid parameter.
public RemoteResource(string hostAddress, string uriPath, ResourcePolicy policy, ResourceTypes resourceTypes, ResourceInterfaces resourceInterfaces)
{
if (hostAddress == null || uriPath == null || resourceTypes == null || resourceInterfaces == null)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid parameters");
throw new ArgumentException("Invalid parameter");
}
HostAddress = hostAddress;
UriPath = uriPath;
Policy = policy;
Types = new List(resourceTypes);
Interfaces = new List(resourceInterfaces);
DeviceId = null;
CreateRemoteResource(resourceTypes._resourceTypeHandle, resourceInterfaces.ResourceInterfacesHandle);
}
internal RemoteResource(IntPtr handleToClone)
{
int ret = Interop.IoTConnectivity.Client.RemoteResource.Clone(handleToClone, out _remoteResourceHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to clone");
throw IoTConnectivityErrorFactory.GetException(ret);
}
SetRemoteResource();
}
///
/// Destructor of the RemoteResource class.
///
~RemoteResource()
{
Dispose(false);
}
///
/// The event is invoked with cached resource attributes.
///
/// 3
public event EventHandler CacheUpdated;
///
/// Observe an event on the resource sent by the server.
///
/// 3
public event EventHandler ObserverNotified;
///
/// The event is called when remote resource's state are changed.
///
/// 3
public event EventHandler StateChanged
{
add
{
if (_stateChangedEventHandler == null)
{
RegisterStateChangedEvent();
}
_stateChangedEventHandler += value;
}
remove
{
_stateChangedEventHandler -= value;
if (_stateChangedEventHandler == null)
{
UnregisterStateChangedEvent();
}
}
}
///
/// The host address of the resource.
///
/// 3
/// The host address of the resource.
public string HostAddress { get; private set; }
///
/// The URI path of the resource.
///
/// 3
/// The URI path of the resource.
public string UriPath { get; private set; }
///
/// The resource types of the remote resource.
///
/// 3
/// The resource types of the remote resource.
public IEnumerable Types { get; private set; }
///
/// The interfaces of the resource.
///
/// 3
/// The interfaces of the resource.
public IEnumerable Interfaces { get; private set; }
///
/// The policy of the resource.
///
/// 3
/// The policy of the resource.
public ResourcePolicy Policy { get; private set; }
///
/// The header options of the resource.
///
/// 3
/// The header options of the resource.
/// Thrown when the iotcon is not supported.
/// Thrown when there is an invalid parameter.
public ResourceOptions Options
{
get
{
return _options;
}
set
{
_options = value;
if (value != null)
{
int ret = Interop.IoTConnectivity.Client.RemoteResource.SetOptions(_remoteResourceHandle, value._resourceOptionsHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set options");
throw IoTConnectivityErrorFactory.GetException(ret);
}
}
}
}
///
/// Indicates the CacheEnabled status of the remote resource.
///
/// 3
///
/// Client can start caching only when this is set true. Set it to false to stop caching the resource attributes.
///
/// Thrown when the iotcon is not supported.
/// Thrown when there is an invalid parameter.
/// Thrown when the operation is invalid.
/// Thrown when an application does not have privilege to access.
/// Thrown when there is not enough memory.
public bool CacheEnabled
{
get
{
return _cacheEnabled;
}
set
{
if (_cacheEnabled != value)
{
_cacheEnabled = value;
HandleCachePolicyChanged();
}
}
}
///
/// Time interval of monitoring and caching API.
///
/// 3
///
/// Default time interval is 10 seconds.
/// Seconds for time interval (must be in range from 1 to 3600).
///
/// Thrown when the iotcon is not supported.
/// Thrown when there is an invalid parameter.
public int TimeInterval
{
get
{
int interval;
int ret = Interop.IoTConnectivity.Client.RemoteResource.GetTimeInterval(_remoteResourceHandle, out interval);
if (ret != (int)IoTConnectivityError.None)
{
Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get time interval");
return 0;
}
return interval;
}
set
{
int ret = (int)IoTConnectivityError.InvalidParameter;
if (value <= TimeOutMax && value > 0)
{
ret = Interop.IoTConnectivity.Client.RemoteResource.SetTimeInterval(_remoteResourceHandle, value);
}
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set time interval");
throw IoTConnectivityErrorFactory.GetException(ret);
}
}
}
///
/// The device ID of the resource.
///
/// 3
/// The device ID of the resource.
public string DeviceId { get; private set; }
///
/// Gets cached representation from the remote resource.
///
/// 3
/// cached representation from the remote resource.
/// http://tizen.org/feature/iot.ocf
public Representation CachedRepresentation()
{
IntPtr handle;
int ret = Interop.IoTConnectivity.Client.RemoteResource.GetCachedRepresentation(_remoteResourceHandle, out handle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get CachedRepresentation");
return null;
}
Representation representation = new Representation(handle);
return representation;
}
///
/// Starts observing on the resource.
///
/// 3
///
/// When server sends notification message, will be called.
///
/// http://tizen.org/privilege/internet
/// public
/// The type to specify how client wants to observe.
/// The query to send to server.
/// http://tizen.org/feature/iot.ocf
/// Thrown when the iotcon is not supported.
/// Thrown when the operation is invalid.
/// Thrown when an application does not have privilege to access.
/// Thrown when there is not enough memory.
public void StartObserving(ObservePolicy policy, ResourceQuery query = null)
{
_observeCallback = (IntPtr resource, int err, int sequenceNumber, IntPtr response, IntPtr userData) =>
{
int result;
IntPtr representationHandle;
int ret = Interop.IoTConnectivity.Server.Response.GetResult(response, out result);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get result");
return;
}
ret = Interop.IoTConnectivity.Server.Response.GetRepresentation(response, out representationHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get representation");
return;
}
Representation repr = null;
try
{
repr = new Representation(representationHandle);
}
catch (Exception exp)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new representation: " + exp.Message);
return;
}
ObserverNotifiedEventArgs e = new ObserverNotifiedEventArgs()
{
Representation = repr,
Result = (ResponseCode)result
};
ObserverNotified?.Invoke(this, e);
};
IntPtr queryHandle = IntPtr.Zero;
if (query != null)
{
queryHandle = query._resourceQueryHandle;
}
int errCode = Interop.IoTConnectivity.Client.RemoteResource.RegisterObserve(_remoteResourceHandle, (int)policy, queryHandle, _observeCallback, IntPtr.Zero);
if (errCode != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to register observe callbacks");
throw IoTConnectivityErrorFactory.GetException(errCode);
}
}
///
/// Stops observing on the resource.
///
/// 3
/// http://tizen.org/privilege/internet
/// public
/// http://tizen.org/feature/iot.ocf
/// Thrown when the iotcon is not supported.
/// Thrown when the operation is invalid.
/// Thrown when an application does not have privilege to access.
public void StopObserving()
{
int ret = Interop.IoTConnectivity.Client.RemoteResource.DeregisterObserve(_remoteResourceHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to deregister observe callbacks");
throw IoTConnectivityErrorFactory.GetException(ret);
}
}
///
/// Gets the attributes of a resource asynchronously.
///
/// 3
/// http://tizen.org/privilege/internet
/// public
/// The ResourceQuery to send to server.
/// Remote response with result and representation.
/// http://tizen.org/feature/iot.ocf
public async Task GetAsync(ResourceQuery query = null)
{
TaskCompletionSource tcsRemoteResponse = new TaskCompletionSource();
IntPtr id = IntPtr.Zero;
lock (_responseCallbacksMap)
{
id = (IntPtr)_responseCallbackId++;
}
_responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
{
IntPtr responseCallbackId = userData;
_responseCallbacksMap.Remove(responseCallbackId);
if (responseHandle != IntPtr.Zero)
{
try
{
tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
}
catch(Exception exp)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
tcsRemoteResponse.TrySetException(exp);
}
}
else
{
tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
}
};
IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
int errCode = Interop.IoTConnectivity.Client.RemoteResource.Get(_remoteResourceHandle, queryHandle, _responseCallbacksMap[id], id);
if (errCode != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource attributes");
tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
}
return await tcsRemoteResponse.Task;
}
///
/// Puts the representation of a resource asynchronously.
///
/// 3
/// http://tizen.org/privilege/internet
/// public
/// Resource representation to put.
/// The ResourceQuery to send to server.
/// Remote response with result and representation.
/// http://tizen.org/feature/iot.ocf
public async Task PutAsync(Representation representation, ResourceQuery query = null)
{
TaskCompletionSource tcsRemoteResponse = new TaskCompletionSource();
IntPtr id = IntPtr.Zero;
lock (_responseCallbacksMap)
{
id = (IntPtr)_responseCallbackId++;
}
_responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
{
IntPtr responseCallbackId = userData;
_responseCallbacksMap.Remove(responseCallbackId);
if (err == (int)(IoTConnectivityError.Iotivity))
{
RemoteResponse response = new RemoteResponse();
response.Result = ResponseCode.Forbidden;
response.Representation = null;
tcsRemoteResponse.TrySetResult(response);
}
else if (responseHandle != IntPtr.Zero)
{
try
{
tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
}
catch (Exception exp)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
tcsRemoteResponse.TrySetException(exp);
}
}
else
{
tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
}
};
IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
int errCode = Interop.IoTConnectivity.Client.RemoteResource.Put(_remoteResourceHandle, representation._representationHandle, queryHandle, _responseCallbacksMap[id], id);
if (errCode != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to put resource representation");
tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
}
return await tcsRemoteResponse.Task;
}
///
/// Posts request on a resource asynchronously.
///
/// 3
/// http://tizen.org/privilege/internet
/// public
/// Resource representation of request.
/// The ResourceQuery to send to server.
/// Remote response with result and representation.
/// http://tizen.org/feature/iot.ocf
public async Task PostAsync(Representation representation, ResourceQuery query = null)
{
TaskCompletionSource tcsRemoteResponse = new TaskCompletionSource();
IntPtr id = IntPtr.Zero;
lock (_responseCallbacksMap)
{
id = (IntPtr)_responseCallbackId++;
}
_responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
{
IntPtr responseCallbackId = userData;
_responseCallbacksMap.Remove(responseCallbackId);
if (responseHandle != IntPtr.Zero)
{
try
{
tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
}
catch (Exception exp)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
tcsRemoteResponse.TrySetException(exp);
}
}
else
{
tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
}
};
IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
int errCode = Interop.IoTConnectivity.Client.RemoteResource.Post(_remoteResourceHandle, representation._representationHandle, queryHandle, _responseCallbacksMap[id], id);
if (errCode != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to post request");
tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
}
return await tcsRemoteResponse.Task;
}
///
/// Deletes the resource asynchronously.
///
/// 3
/// http://tizen.org/privilege/internet
/// public
/// Remote response with result and representation.
/// http://tizen.org/feature/iot.ocf
public async Task DeleteAsync()
{
TaskCompletionSource tcsRemoteResponse = new TaskCompletionSource();
IntPtr id = IntPtr.Zero;
lock (_responseCallbacksMap)
{
id = (IntPtr)_responseCallbackId++;
}
_responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
{
IntPtr responseCallbackId = userData;
_responseCallbacksMap.Remove(responseCallbackId);
if (err == (int)(IoTConnectivityError.Iotivity))
{
RemoteResponse response = new RemoteResponse();
response.Result = ResponseCode.Forbidden;
response.Representation = null;
tcsRemoteResponse.TrySetResult(response);
}
else if (responseHandle != IntPtr.Zero)
{
try
{
tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
}
catch (Exception exp)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
tcsRemoteResponse.TrySetException(exp);
}
}
else
{
tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
}
};
int errCode = Interop.IoTConnectivity.Client.RemoteResource.Delete(_remoteResourceHandle, _responseCallbacksMap[id], id);
if (errCode != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to delete");
tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
}
return await tcsRemoteResponse.Task;
}
///
/// Releases any unmanaged resources used by this object.
///
/// 3
/// http://tizen.org/feature/iot.ocf
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
internal static Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType GetConnectivityType(string hostAddress)
{
Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.None;
Log.Info(IoTConnectivityErrorFactory.LogTag, hostAddress);
if (hostAddress == IoTConnectivityClientManager.MulticastAddress)
{
type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv4;
}
else
{
IPAddress address;
string hostName = hostAddress;
if (hostAddress.Contains(":"))
{
string[] hostParts = hostAddress.Split(':');
if (hostParts.Length == 2)
{
hostName = hostParts[0];
}
}
if (hostAddress.Contains("%"))
{
string[] hostParts = hostAddress.Split('%');
if (hostParts.Length == 2)
{
hostName = hostParts[0];
}
}
if (hostName.Contains("["))
{
string[] hostParts = hostName.Split('[');
if (hostParts.Length == 2)
{
hostName = hostParts[1];
}
}
Log.Info(IoTConnectivityErrorFactory.LogTag, hostName);
if (IPAddress.TryParse(hostName, out address))
{
switch (address.AddressFamily)
{
case System.Net.Sockets.AddressFamily.InterNetwork:
type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv4;
break;
case System.Net.Sockets.AddressFamily.InterNetworkV6:
type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv6;
break;
default:
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to parse for Ipv4 or Ipv6");
break;
}
}
else
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to parse hostname " + hostName);
}
}
return type;
}
///
/// 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)
{
// Free managed objects
}
Interop.IoTConnectivity.Client.RemoteResource.Destroy(_remoteResourceHandle);
_disposed = true;
}
private void HandleCachePolicyChanged()
{
if (_cacheEnabled)
{
_cacheUpdatedCallback = (IntPtr resource, IntPtr representation, IntPtr userData) =>
{
if (CacheEnabled)
{
Representation repr = null;
try
{
repr = new Representation(representation);
}
catch (Exception exp)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new Representation: " + exp.Message);
return;
}
CacheUpdatedEventArgs e = new CacheUpdatedEventArgs()
{
Representation = repr
};
CacheUpdated?.Invoke(this, e);
}
};
int ret = Interop.IoTConnectivity.Client.RemoteResource.StartCaching(_remoteResourceHandle, _cacheUpdatedCallback, IntPtr.Zero);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add cache updated event handler");
throw IoTConnectivityErrorFactory.GetException(ret);
}
}
else
{
int ret = Interop.IoTConnectivity.Client.RemoteResource.StopCaching(_remoteResourceHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove cache updated event handler");
throw IoTConnectivityErrorFactory.GetException(ret);
}
}
}
private void RegisterStateChangedEvent()
{
_stateChangedCallback = (IntPtr resource, int state, IntPtr userData) =>
{
StateChangedEventArgs e = new StateChangedEventArgs()
{
State = (ResourceState)state
};
_stateChangedEventHandler?.Invoke(null, e);
};
int ret = Interop.IoTConnectivity.Client.RemoteResource.StartMonitoring(_remoteResourceHandle, _stateChangedCallback, IntPtr.Zero);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add state changed event handler");
throw IoTConnectivityErrorFactory.GetException(ret);
}
}
private void UnregisterStateChangedEvent()
{
int ret = Interop.IoTConnectivity.Client.RemoteResource.StopMonitoring(_remoteResourceHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove state changed event handler");
throw IoTConnectivityErrorFactory.GetException(ret);
}
}
private void CreateRemoteResource(IntPtr resourceTypeHandle, IntPtr resourceInterfaceHandle)
{
Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = GetConnectivityType(HostAddress);
if (connectivityType == Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Unable to parse host address");
throw new ArgumentException("Unable to parse host address");
}
int ret = Interop.IoTConnectivity.Client.RemoteResource.Create(HostAddress, (int)connectivityType, UriPath, (int)Policy, resourceTypeHandle, resourceInterfaceHandle, out _remoteResourceHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get remote resource");
throw IoTConnectivityErrorFactory.GetException(ret);
}
}
private void SetRemoteResource()
{
IntPtr hostAddressPtr, uriPathPtr;
int ret = Interop.IoTConnectivity.Client.RemoteResource.GetHostAddress(_remoteResourceHandle, out hostAddressPtr);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get host address");
throw IoTConnectivityErrorFactory.GetException(ret);
}
ret = Interop.IoTConnectivity.Client.RemoteResource.GetUriPath(_remoteResourceHandle, out uriPathPtr);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get uri path");
throw IoTConnectivityErrorFactory.GetException(ret);
}
int policy = (int)ResourcePolicy.NoProperty;
ret = Interop.IoTConnectivity.Client.RemoteResource.GetPolicies(_remoteResourceHandle, out policy);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get uri path");
throw IoTConnectivityErrorFactory.GetException(ret);
}
IntPtr typesHandle, interfacesHandle;
ret = Interop.IoTConnectivity.Client.RemoteResource.GetTypes(_remoteResourceHandle, out typesHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource types");
throw IoTConnectivityErrorFactory.GetException(ret);
}
ret = Interop.IoTConnectivity.Client.RemoteResource.GetInterfaces(_remoteResourceHandle, out interfacesHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource interfaces");
throw IoTConnectivityErrorFactory.GetException(ret);
}
IntPtr deviceIdPtr;
ret = Interop.IoTConnectivity.Client.RemoteResource.GetDeviceId(_remoteResourceHandle, out deviceIdPtr);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device id");
throw IoTConnectivityErrorFactory.GetException(ret);
}
DeviceId = (deviceIdPtr != IntPtr.Zero) ? Marshal.PtrToStringAnsi(deviceIdPtr) : string.Empty;
HostAddress = (hostAddressPtr != IntPtr.Zero) ? Marshal.PtrToStringAnsi(hostAddressPtr) : string.Empty;
UriPath = (uriPathPtr != IntPtr.Zero) ? Marshal.PtrToStringAnsi(uriPathPtr) : string.Empty;
Types = new ResourceTypes(typesHandle);
Interfaces = new ResourceInterfaces(interfacesHandle);
Policy = (ResourcePolicy)policy;
}
private RemoteResponse GetRemoteResponse(IntPtr response)
{
int result;
IntPtr representationHandle, optionsHandle;
int ret = Interop.IoTConnectivity.Server.Response.GetResult(response, out result);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get result");
throw IoTConnectivityErrorFactory.GetException(ret);
}
ret = Interop.IoTConnectivity.Server.Response.GetRepresentation(response, out representationHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get representation");
throw IoTConnectivityErrorFactory.GetException(ret);
}
ret = Interop.IoTConnectivity.Server.Response.GetOptions(response, out optionsHandle);
if (ret != (int)IoTConnectivityError.None)
{
Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get options");
throw IoTConnectivityErrorFactory.GetException(ret);
}
return new RemoteResponse()
{
Result = (ResponseCode)result,
Representation = new Representation(representationHandle),
Options = (optionsHandle == IntPtr.Zero)? null : new ResourceOptions(optionsHandle)
};
}
}
}