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;
12 using System.Runtime.InteropServices;
13 using System.Threading.Tasks;
15 namespace Tizen.Network.IoTConnectivity
18 /// This class represents a remote resource.
19 /// It provides APIs to manage remote resource.
21 public class RemoteResource : IDisposable
23 internal const int TimeOutMax = 3600;
24 internal IntPtr _remoteResourceHandle = IntPtr.Zero;
26 private bool _disposed = false;
27 private bool _cacheEnabled = false;
28 private ResourceOptions _options;
30 private int _responseCallbackId = 1;
31 private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.RemoteResource.ResponseCallback> _responseCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.RemoteResource.ResponseCallback>();
33 private Interop.IoTConnectivity.Client.RemoteResource.CachedRepresentationChangedCallback _cacheUpdatedCallback;
34 private Interop.IoTConnectivity.Client.RemoteResource.StateChangedCallback _stateChangedCallback;
35 private Interop.IoTConnectivity.Client.RemoteResource.ObserveCallback _observeCallback;
37 private EventHandler<StateChangedEventArgs> _stateChangedEventHandler;
40 /// Creates a remote resource instance
43 /// To use this API, you should provide all of the details required to correctly contact and
44 /// observe the object.\n
45 /// If not, you should discover the resource object manually.\n
46 /// The @a policy can contain multiple policies like ResourcePolicy.Discoverable | ResourcePolicy.Observable.
48 /// <param name="hostAddress">The host address of the resource</param>
49 /// <param name="uriPath">The URI path of the resource</param>
50 /// <param name="policy">The policies of the resource</param>
51 /// <param name="resourceTypes">The resource types of the resource</param>
52 /// <param name="resourceInterfaces">The resource interfaces of the resource</param>
53 public RemoteResource(string hostAddress, string uriPath, ResourcePolicy policy, ResourceTypes resourceTypes, ResourceInterfaces resourceInterfaces)
55 if (hostAddress == null || uriPath == null || resourceTypes == null || resourceInterfaces == null)
57 Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid parameters");
58 throw new ArgumentException("Invalid parameter");
61 HostAddress = hostAddress;
64 Types = new List<string>(resourceTypes);
65 Interfaces = new List<string>(resourceInterfaces);
68 CreateRemoteResource(resourceTypes._resourceTypeHandle, resourceInterfaces.ResourceInterfacesHandle);
71 internal RemoteResource(IntPtr handleToClone)
73 int ret = Interop.IoTConnectivity.Client.RemoteResource.Clone(handleToClone, out _remoteResourceHandle);
74 if (ret != (int)IoTConnectivityError.None)
76 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to clone");
77 throw IoTConnectivityErrorFactory.GetException(ret);
83 /// Destructor of the RemoteResource class.
91 /// Event that is invoked with cached resource attributes
93 public event EventHandler<CacheUpdatedEventArgs> CacheUpdated;
96 /// Observe event on the resource sent by the server
98 public event EventHandler<ObserverNotifiedEventArgs> ObserverNotified;
101 /// Event that is called when remote resource's state are changed
103 public event EventHandler<StateChangedEventArgs> StateChanged
107 if (_stateChangedEventHandler == null)
109 RegisterStateChangedEvent();
111 _stateChangedEventHandler += value;
115 _stateChangedEventHandler -= value;
116 if (_stateChangedEventHandler == null)
118 UnregisterStateChangedEvent();
124 /// The host address of the resource
126 public string HostAddress { get; private set; }
129 /// The URI path of the resource
131 public string UriPath { get; private set; }
134 /// The resource types of the remote resource
136 public IEnumerable<string> Types { get; private set; }
139 /// The interfaces of the resource
141 public IEnumerable<string> Interfaces { get; private set; }
144 /// The policy of the resource
146 public ResourcePolicy Policy { get; private set; }
149 /// The device name of the remote resource
151 public string DeviceName { get; private set; }
154 /// The header options of the resource
156 public ResourceOptions Options
167 int ret = Interop.IoTConnectivity.Client.RemoteResource.SetOptions(_remoteResourceHandle, value._resourceOptionsHandle);
168 if (ret != (int)IoTConnectivityError.None)
170 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set options");
171 throw IoTConnectivityErrorFactory.GetException(ret);
178 /// Indicates the CacheEnabled status of the remote resource.
181 /// Client can start caching only when this is set true. Set it to false to stop caching the resource attributes.
183 public bool CacheEnabled
187 return _cacheEnabled;
191 if (_cacheEnabled != value)
193 _cacheEnabled = value;
194 HandleCachePolicyChanged();
200 /// Time interval of monitoring and caching API
203 /// Default time interval is 10 seconds.\n
204 /// Seconds for time interval (must be in range from 1 to 3600)
206 public int TimeInterval
211 int ret = Interop.IoTConnectivity.Client.RemoteResource.GetTimeInterval(out interval);
212 if (ret != (int)IoTConnectivityError.None)
214 Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get time interval");
221 int ret = (int)IoTConnectivityError.InvalidParameter;
222 if (value <= TimeOutMax && value > 0)
224 ret = Interop.IoTConnectivity.Client.RemoteResource.SetTimeInterval(value);
226 if (ret != (int)IoTConnectivityError.None)
228 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set time interval");
229 throw IoTConnectivityErrorFactory.GetException(ret);
235 /// The device id of the resource
237 public string DeviceId { get; private set; }
240 /// Gets cached representation from the remote resource
242 public Representation CachedRepresentation()
245 int ret = Interop.IoTConnectivity.Client.RemoteResource.GetCachedRepresentation(_remoteResourceHandle, out handle);
246 if (ret != (int)IoTConnectivityError.None)
248 Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get CachedRepresentation");
252 Representation representation = new Representation(handle);
253 return representation;
257 /// Starts observing on the resource
260 /// When server sends notification message, <see cref="ObserverNotified"/> will be called.
263 /// http://tizen.org/privilege/internet
265 /// <param name="policy">The type to specify how client wants to observe</param>
266 /// <param name="query">The query to send to server</param>
267 public void StartObserving(ObservePolicy policy, ResourceQuery query = null)
269 _observeCallback = (IntPtr resource, int err, int sequenceNumber, IntPtr response, IntPtr userData) =>
272 IntPtr representationHandle;
273 int ret = Interop.IoTConnectivity.Server.Response.GetResult(response, out result);
274 if (ret != (int)IoTConnectivityError.None)
276 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get result");
280 ret = Interop.IoTConnectivity.Server.Response.GetRepresentation(response, out representationHandle);
281 if (ret != (int)IoTConnectivityError.None)
283 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get representation");
287 Representation repr = null;
290 repr = new Representation(representationHandle);
292 catch (Exception exp)
294 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new representation: " + exp.Message);
298 ObserverNotifiedEventArgs e = new ObserverNotifiedEventArgs()
300 Representation = repr,
301 Result = (ResponseCode)result
303 ObserverNotified?.Invoke(null, e);
306 IntPtr queryHandle = IntPtr.Zero;
309 queryHandle = query._resourceQueryHandle;
312 int errCode = Interop.IoTConnectivity.Client.RemoteResource.RegisterObserve(_remoteResourceHandle, (int)policy, queryHandle, _observeCallback, IntPtr.Zero);
313 if (errCode != (int)IoTConnectivityError.None)
315 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to register observe callbacks");
316 throw IoTConnectivityErrorFactory.GetException(errCode);
321 /// Stops observing on the resource
324 /// http://tizen.org/privilege/internet
326 public void StopObserving()
328 int ret = Interop.IoTConnectivity.Client.RemoteResource.DeregisterObserve(_remoteResourceHandle);
329 if (ret != (int)IoTConnectivityError.None)
331 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to deregister observe callbacks");
332 throw IoTConnectivityErrorFactory.GetException(ret);
337 /// Gets the attributes of a resource, asynchronously
340 /// http://tizen.org/privilege/internet
342 /// <param name="query">The ResourceQuery to send to server</param>
343 /// <returns>Remote response with result and representation</returns>
344 public async Task<RemoteResponse> GetAsync(ResourceQuery query = null)
346 TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
348 IntPtr id = IntPtr.Zero;
349 lock (_responseCallbacksMap)
351 id = (IntPtr)_responseCallbackId++;
353 _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
355 IntPtr responseCallbackId = userData;
356 lock(_responseCallbacksMap)
358 _responseCallbacksMap.Remove(responseCallbackId);
361 if (responseHandle != IntPtr.Zero)
365 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
369 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
370 tcsRemoteResponse.TrySetException(exp);
375 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
379 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
380 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Get(_remoteResourceHandle, queryHandle, _responseCallbacksMap[id], id);
381 if (errCode != (int)IoTConnectivityError.None)
383 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource attributes");
384 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
386 return await tcsRemoteResponse.Task;
390 /// Puts the representation of a resource, asynchronously.
393 /// http://tizen.org/privilege/internet
395 /// <param name="representation">Resource representation to put</param>
396 /// <param name="query">The ResourceQuery to send to server</param>
397 /// <returns>Remote response with result and representation</returns>
398 public async Task<RemoteResponse> PutAsync(Representation representation, ResourceQuery query = null)
400 TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
402 IntPtr id = IntPtr.Zero;
403 lock (_responseCallbacksMap)
405 id = (IntPtr)_responseCallbackId++;
407 _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
409 IntPtr responseCallbackId = userData;
410 lock (_responseCallbacksMap)
412 _responseCallbacksMap.Remove(responseCallbackId);
414 if (err == (int)(IoTConnectivityError.Iotivity))
416 RemoteResponse response = new RemoteResponse();
417 response.Result = ResponseCode.Forbidden;
418 response.Representation = null;
419 tcsRemoteResponse.TrySetResult(response);
421 else if (responseHandle != IntPtr.Zero)
425 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
427 catch (Exception exp)
429 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
430 tcsRemoteResponse.TrySetException(exp);
435 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
438 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
439 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Put(_remoteResourceHandle, representation._representationHandle, queryHandle, _responseCallbacksMap[id], id);
440 if (errCode != (int)IoTConnectivityError.None)
442 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to put resource representation");
443 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
445 return await tcsRemoteResponse.Task;
449 /// Post request on a resource, asynchronously
452 /// http://tizen.org/privilege/internet
454 /// <param name="representation">Resource representation of request</param>
455 /// <param name="query">The ResourceQuery to send to server</param>
456 /// <returns>Remote response with result and representation</returns>
457 public async Task<RemoteResponse> PostAsync(Representation representation, ResourceQuery query = null)
459 TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
461 IntPtr id = IntPtr.Zero;
462 lock (_responseCallbacksMap)
464 id = (IntPtr)_responseCallbackId++;
466 _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
468 IntPtr responseCallbackId = userData;
469 lock (_responseCallbacksMap)
471 _responseCallbacksMap.Remove(responseCallbackId);
473 if (responseHandle != IntPtr.Zero)
477 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
479 catch (Exception exp)
481 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
482 tcsRemoteResponse.TrySetException(exp);
487 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
490 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
491 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Post(_remoteResourceHandle, representation._representationHandle, queryHandle, _responseCallbacksMap[id], id);
492 if (errCode != (int)IoTConnectivityError.None)
494 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to post request");
495 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
497 return await tcsRemoteResponse.Task;
501 /// Deletes the resource, asynchronously
504 /// http://tizen.org/privilege/internet
506 /// <returns>Remote response with result and representation</returns>
507 public async Task<RemoteResponse> DeleteAsync()
509 TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
511 IntPtr id = IntPtr.Zero;
512 lock (_responseCallbacksMap)
514 id = (IntPtr)_responseCallbackId++;
516 _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
518 IntPtr responseCallbackId = userData;
519 lock (_responseCallbacksMap)
521 _responseCallbacksMap.Remove(responseCallbackId);
523 if (err == (int)(IoTConnectivityError.Iotivity))
525 RemoteResponse response = new RemoteResponse();
526 response.Result = ResponseCode.Forbidden;
527 response.Representation = null;
528 tcsRemoteResponse.TrySetResult(response);
530 else if (responseHandle != IntPtr.Zero)
534 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
536 catch (Exception exp)
538 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
539 tcsRemoteResponse.TrySetException(exp);
544 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
548 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Delete(_remoteResourceHandle, _responseCallbacksMap[id], id);
549 if (errCode != (int)IoTConnectivityError.None)
551 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to delete");
552 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
554 return await tcsRemoteResponse.Task;
558 /// Releases any unmanaged resources used by this object.
560 public void Dispose()
563 GC.SuppressFinalize(this);
566 internal static Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType GetConnectivityType(string hostAddress)
568 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.None;
570 if (hostAddress == IoTConnectivityClientManager.MulticastAddress)
572 type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv4;
577 string hostName = hostAddress;
578 if (hostAddress.Contains(":"))
580 string[] hostParts = hostAddress.Split(':');
581 if (hostParts.Length == 2)
583 hostName = hostParts[0];
586 if (IPAddress.TryParse(hostName, out address))
588 switch (address.AddressFamily)
590 case System.Net.Sockets.AddressFamily.InterNetwork:
591 type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv4;
593 case System.Net.Sockets.AddressFamily.InterNetworkV6:
594 type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv6;
597 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to parse for Ipv4 or Ipv6");
606 /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
608 /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
609 protected virtual void Dispose(bool disposing)
616 // Free managed objects
619 Interop.IoTConnectivity.Client.RemoteResource.Destroy(_remoteResourceHandle);
623 private void HandleCachePolicyChanged()
627 _cacheUpdatedCallback = (IntPtr resource, IntPtr representation, IntPtr userData) =>
631 Representation repr = null;
634 repr = new Representation(representation);
636 catch (Exception exp)
638 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new Representation: " + exp.Message);
642 CacheUpdatedEventArgs e = new CacheUpdatedEventArgs()
644 Representation = repr
646 CacheUpdated?.Invoke(null, e);
650 int ret = Interop.IoTConnectivity.Client.RemoteResource.StartCaching(_remoteResourceHandle, _cacheUpdatedCallback, IntPtr.Zero);
651 if (ret != (int)IoTConnectivityError.None)
653 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add cache updated event handler");
654 throw IoTConnectivityErrorFactory.GetException(ret);
659 int ret = Interop.IoTConnectivity.Client.RemoteResource.StopCaching(_remoteResourceHandle);
660 if (ret != (int)IoTConnectivityError.None)
662 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove cache updated event handler");
663 throw IoTConnectivityErrorFactory.GetException(ret);
668 private void RegisterStateChangedEvent()
670 _stateChangedCallback = (IntPtr resource, int state, IntPtr userData) =>
672 StateChangedEventArgs e = new StateChangedEventArgs()
674 State = (ResourceState)state
676 _stateChangedEventHandler?.Invoke(null, e);
679 int ret = Interop.IoTConnectivity.Client.RemoteResource.StartMonitoring(_remoteResourceHandle, _stateChangedCallback, IntPtr.Zero);
680 if (ret != (int)IoTConnectivityError.None)
682 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add state changed event handler");
683 throw IoTConnectivityErrorFactory.GetException(ret);
687 private void UnregisterStateChangedEvent()
689 int ret = Interop.IoTConnectivity.Client.RemoteResource.StopMonitoring(_remoteResourceHandle);
690 if (ret != (int)IoTConnectivityError.None)
692 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove state changed event handler");
693 throw IoTConnectivityErrorFactory.GetException(ret);
697 private void CreateRemoteResource(IntPtr resourceTypeHandle, IntPtr resourceInterfaceHandle)
699 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = GetConnectivityType(HostAddress);
700 if (connectivityType == Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.None)
702 Log.Error(IoTConnectivityErrorFactory.LogTag, "Unable to parse host address");
703 throw new ArgumentException("Unable to parse host address");
705 int ret = Interop.IoTConnectivity.Client.RemoteResource.Create(HostAddress, (int)connectivityType, UriPath, (int)Policy, resourceTypeHandle, resourceInterfaceHandle, out _remoteResourceHandle);
706 if (ret != (int)IoTConnectivityError.None)
708 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get remote resource");
709 throw IoTConnectivityErrorFactory.GetException(ret);
713 ret = Interop.IoTConnectivity.Client.RemoteResource.GetDeviceName(_remoteResourceHandle, out deviceName);
714 if (ret != (int)IoTConnectivityError.None)
716 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device name of remote resource");
717 throw IoTConnectivityErrorFactory.GetException(ret);
719 DeviceName = Marshal.PtrToStringAuto(deviceName);*/
722 private void SetRemoteResource()
724 IntPtr hostAddressPtr, uriPathPtr;
725 int ret = Interop.IoTConnectivity.Client.RemoteResource.GetHostAddress(_remoteResourceHandle, out hostAddressPtr);
726 if (ret != (int)IoTConnectivityError.None)
728 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get host address");
729 throw IoTConnectivityErrorFactory.GetException(ret);
732 ret = Interop.IoTConnectivity.Client.RemoteResource.GetUriPath(_remoteResourceHandle, out uriPathPtr);
733 if (ret != (int)IoTConnectivityError.None)
735 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get uri path");
736 throw IoTConnectivityErrorFactory.GetException(ret);
739 int policy = (int)ResourcePolicy.NoProperty;
740 ret = Interop.IoTConnectivity.Client.RemoteResource.GetPolicies(_remoteResourceHandle, out policy);
741 if (ret != (int)IoTConnectivityError.None)
743 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get uri path");
744 throw IoTConnectivityErrorFactory.GetException(ret);
747 IntPtr typesHandle, interfacesHandle;
748 ret = Interop.IoTConnectivity.Client.RemoteResource.GetTypes(_remoteResourceHandle, out typesHandle);
749 if (ret != (int)IoTConnectivityError.None)
751 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource types");
752 throw IoTConnectivityErrorFactory.GetException(ret);
755 ret = Interop.IoTConnectivity.Client.RemoteResource.GetInterfaces(_remoteResourceHandle, out interfacesHandle);
756 if (ret != (int)IoTConnectivityError.None)
758 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource interfaces");
759 throw IoTConnectivityErrorFactory.GetException(ret);
763 ret = Interop.IoTConnectivity.Client.RemoteResource.GetDeviceId(_remoteResourceHandle, out deviceIdPtr);
764 if (ret != (int)IoTConnectivityError.None)
766 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device id");
767 throw IoTConnectivityErrorFactory.GetException(ret);
770 ret = Interop.IoTConnectivity.Client.RemoteResource.GetDeviceName(_remoteResourceHandle, out deviceName);
771 if (ret != (int)IoTConnectivityError.None)
773 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device name of remote resource");
774 throw IoTConnectivityErrorFactory.GetException(ret);
776 DeviceName = Marshal.PtrToStringAuto(deviceName);
777 DeviceId = Marshal.PtrToStringAuto(deviceIdPtr);
778 HostAddress = Marshal.PtrToStringAuto(hostAddressPtr);
779 UriPath = Marshal.PtrToStringAuto(uriPathPtr);
780 Types = new ResourceTypes(typesHandle);
781 Interfaces = new ResourceInterfaces(interfacesHandle);
782 Policy = (ResourcePolicy)policy;
785 private RemoteResponse GetRemoteResponse(IntPtr response)
788 IntPtr representationHandle, optionsHandle;
789 int ret = Interop.IoTConnectivity.Server.Response.GetResult(response, out result);
790 if (ret != (int)IoTConnectivityError.None)
792 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get result");
793 throw IoTConnectivityErrorFactory.GetException(ret);
796 ret = Interop.IoTConnectivity.Server.Response.GetRepresentation(response, out representationHandle);
797 if (ret != (int)IoTConnectivityError.None)
799 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get representation");
800 throw IoTConnectivityErrorFactory.GetException(ret);
803 ret = Interop.IoTConnectivity.Server.Response.GetOptions(response, out optionsHandle);
804 if (ret != (int)IoTConnectivityError.None)
806 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get options");
807 throw IoTConnectivityErrorFactory.GetException(ret);
809 return new RemoteResponse()
811 Result = (ResponseCode)result,
812 Representation = new Representation(representationHandle),
813 Options = (optionsHandle == IntPtr.Zero)? null : new ResourceOptions(optionsHandle)