2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 using System.Collections.Generic;
21 using System.Runtime.InteropServices;
22 using System.Threading.Tasks;
24 namespace Tizen.Network.IoTConnectivity
27 /// This class represents a remote resource.
28 /// It provides APIs to manage remote resource.
30 public class RemoteResource : IDisposable
32 internal const int TimeOutMax = 3600;
33 internal IntPtr _remoteResourceHandle = IntPtr.Zero;
35 private bool _disposed = false;
36 private bool _cacheEnabled = false;
37 private ResourceOptions _options;
39 private int _responseCallbackId = 1;
40 private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.RemoteResource.ResponseCallback> _responseCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.RemoteResource.ResponseCallback>();
42 private Interop.IoTConnectivity.Client.RemoteResource.CachedRepresentationChangedCallback _cacheUpdatedCallback;
43 private Interop.IoTConnectivity.Client.RemoteResource.StateChangedCallback _stateChangedCallback;
44 private Interop.IoTConnectivity.Client.RemoteResource.ObserveCallback _observeCallback;
46 private EventHandler<StateChangedEventArgs> _stateChangedEventHandler;
49 /// Creates a remote resource instance
52 /// To use this API, you should provide all of the details required to correctly contact and
53 /// observe the object.\n
54 /// If not, you should discover the resource object manually.\n
55 /// The @a policy can contain multiple policies like ResourcePolicy.Discoverable | ResourcePolicy.Observable.
57 /// <param name="hostAddress">The host address of the resource</param>
58 /// <param name="uriPath">The URI path of the resource</param>
59 /// <param name="policy">The policies of the resource</param>
60 /// <param name="resourceTypes">The resource types of the resource</param>
61 /// <param name="resourceInterfaces">The resource interfaces of the resource</param>
62 public RemoteResource(string hostAddress, string uriPath, ResourcePolicy policy, ResourceTypes resourceTypes, ResourceInterfaces resourceInterfaces)
64 if (hostAddress == null || uriPath == null || resourceTypes == null || resourceInterfaces == null)
66 Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid parameters");
67 throw new ArgumentException("Invalid parameter");
70 HostAddress = hostAddress;
73 Types = new List<string>(resourceTypes);
74 Interfaces = new List<string>(resourceInterfaces);
77 CreateRemoteResource(resourceTypes._resourceTypeHandle, resourceInterfaces.ResourceInterfacesHandle);
80 internal RemoteResource(IntPtr handleToClone)
82 int ret = Interop.IoTConnectivity.Client.RemoteResource.Clone(handleToClone, out _remoteResourceHandle);
83 if (ret != (int)IoTConnectivityError.None)
85 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to clone");
86 throw IoTConnectivityErrorFactory.GetException(ret);
92 /// Destructor of the RemoteResource class.
100 /// Event that is invoked with cached resource attributes
102 public event EventHandler<CacheUpdatedEventArgs> CacheUpdated;
105 /// Observe event on the resource sent by the server
107 public event EventHandler<ObserverNotifiedEventArgs> ObserverNotified;
110 /// Event that is called when remote resource's state are changed
112 public event EventHandler<StateChangedEventArgs> StateChanged
116 if (_stateChangedEventHandler == null)
118 RegisterStateChangedEvent();
120 _stateChangedEventHandler += value;
124 _stateChangedEventHandler -= value;
125 if (_stateChangedEventHandler == null)
127 UnregisterStateChangedEvent();
133 /// The host address of the resource
135 public string HostAddress { get; private set; }
138 /// The URI path of the resource
140 public string UriPath { get; private set; }
143 /// The resource types of the remote resource
145 public IEnumerable<string> Types { get; private set; }
148 /// The interfaces of the resource
150 public IEnumerable<string> Interfaces { get; private set; }
153 /// The policy of the resource
155 public ResourcePolicy Policy { get; private set; }
158 /// The device name of the remote resource
160 public string DeviceName { get; private set; }
163 /// The header options of the resource
165 public ResourceOptions Options
176 int ret = Interop.IoTConnectivity.Client.RemoteResource.SetOptions(_remoteResourceHandle, value._resourceOptionsHandle);
177 if (ret != (int)IoTConnectivityError.None)
179 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set options");
180 throw IoTConnectivityErrorFactory.GetException(ret);
187 /// Indicates the CacheEnabled status of the remote resource.
190 /// Client can start caching only when this is set true. Set it to false to stop caching the resource attributes.
192 public bool CacheEnabled
196 return _cacheEnabled;
200 if (_cacheEnabled != value)
202 _cacheEnabled = value;
203 HandleCachePolicyChanged();
209 /// Time interval of monitoring and caching API
212 /// Default time interval is 10 seconds.\n
213 /// Seconds for time interval (must be in range from 1 to 3600)
215 public int TimeInterval
220 int ret = Interop.IoTConnectivity.Client.RemoteResource.GetTimeInterval(_remoteResourceHandle, out interval);
221 if (ret != (int)IoTConnectivityError.None)
223 Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get time interval");
230 int ret = (int)IoTConnectivityError.InvalidParameter;
231 if (value <= TimeOutMax && value > 0)
233 ret = Interop.IoTConnectivity.Client.RemoteResource.SetTimeInterval(_remoteResourceHandle, value);
235 if (ret != (int)IoTConnectivityError.None)
237 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set time interval");
238 throw IoTConnectivityErrorFactory.GetException(ret);
244 /// The device id of the resource
246 public string DeviceId { get; private set; }
249 /// Gets cached representation from the remote resource
251 public Representation CachedRepresentation()
254 int ret = Interop.IoTConnectivity.Client.RemoteResource.GetCachedRepresentation(_remoteResourceHandle, out handle);
255 if (ret != (int)IoTConnectivityError.None)
257 Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get CachedRepresentation");
261 Representation representation = new Representation(handle);
262 return representation;
266 /// Starts observing on the resource
269 /// When server sends notification message, <see cref="ObserverNotified"/> will be called.
272 /// http://tizen.org/privilege/internet
274 /// <param name="policy">The type to specify how client wants to observe</param>
275 /// <param name="query">The query to send to server</param>
276 public void StartObserving(ObservePolicy policy, ResourceQuery query = null)
278 _observeCallback = (IntPtr resource, int err, int sequenceNumber, IntPtr response, IntPtr userData) =>
281 IntPtr representationHandle;
282 int ret = Interop.IoTConnectivity.Server.Response.GetResult(response, out result);
283 if (ret != (int)IoTConnectivityError.None)
285 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get result");
289 ret = Interop.IoTConnectivity.Server.Response.GetRepresentation(response, out representationHandle);
290 if (ret != (int)IoTConnectivityError.None)
292 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get representation");
296 Representation repr = null;
299 repr = new Representation(representationHandle);
301 catch (Exception exp)
303 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new representation: " + exp.Message);
307 ObserverNotifiedEventArgs e = new ObserverNotifiedEventArgs()
309 Representation = repr,
310 Result = (ResponseCode)result
312 ObserverNotified?.Invoke(null, e);
315 IntPtr queryHandle = IntPtr.Zero;
318 queryHandle = query._resourceQueryHandle;
321 int errCode = Interop.IoTConnectivity.Client.RemoteResource.RegisterObserve(_remoteResourceHandle, (int)policy, queryHandle, _observeCallback, IntPtr.Zero);
322 if (errCode != (int)IoTConnectivityError.None)
324 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to register observe callbacks");
325 throw IoTConnectivityErrorFactory.GetException(errCode);
330 /// Stops observing on the resource
333 /// http://tizen.org/privilege/internet
335 public void StopObserving()
337 int ret = Interop.IoTConnectivity.Client.RemoteResource.DeregisterObserve(_remoteResourceHandle);
338 if (ret != (int)IoTConnectivityError.None)
340 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to deregister observe callbacks");
341 throw IoTConnectivityErrorFactory.GetException(ret);
346 /// Gets the attributes of a resource, asynchronously
349 /// http://tizen.org/privilege/internet
351 /// <param name="query">The ResourceQuery to send to server</param>
352 /// <returns>Remote response with result and representation</returns>
353 public async Task<RemoteResponse> GetAsync(ResourceQuery query = null)
355 TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
357 IntPtr id = IntPtr.Zero;
358 lock (_responseCallbacksMap)
360 id = (IntPtr)_responseCallbackId++;
362 _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
364 IntPtr responseCallbackId = userData;
365 lock(_responseCallbacksMap)
367 _responseCallbacksMap.Remove(responseCallbackId);
370 if (responseHandle != IntPtr.Zero)
374 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
378 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
379 tcsRemoteResponse.TrySetException(exp);
384 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
388 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
389 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Get(_remoteResourceHandle, queryHandle, _responseCallbacksMap[id], id);
390 if (errCode != (int)IoTConnectivityError.None)
392 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource attributes");
393 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
395 return await tcsRemoteResponse.Task;
399 /// Puts the representation of a resource, asynchronously.
402 /// http://tizen.org/privilege/internet
404 /// <param name="representation">Resource representation to put</param>
405 /// <param name="query">The ResourceQuery to send to server</param>
406 /// <returns>Remote response with result and representation</returns>
407 public async Task<RemoteResponse> PutAsync(Representation representation, ResourceQuery query = null)
409 TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
411 IntPtr id = IntPtr.Zero;
412 lock (_responseCallbacksMap)
414 id = (IntPtr)_responseCallbackId++;
416 _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
418 IntPtr responseCallbackId = userData;
419 lock (_responseCallbacksMap)
421 _responseCallbacksMap.Remove(responseCallbackId);
423 if (err == (int)(IoTConnectivityError.Iotivity))
425 RemoteResponse response = new RemoteResponse();
426 response.Result = ResponseCode.Forbidden;
427 response.Representation = null;
428 tcsRemoteResponse.TrySetResult(response);
430 else if (responseHandle != IntPtr.Zero)
434 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
436 catch (Exception exp)
438 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
439 tcsRemoteResponse.TrySetException(exp);
444 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
447 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
448 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Put(_remoteResourceHandle, representation._representationHandle, queryHandle, _responseCallbacksMap[id], id);
449 if (errCode != (int)IoTConnectivityError.None)
451 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to put resource representation");
452 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
454 return await tcsRemoteResponse.Task;
458 /// Post request on a resource, asynchronously
461 /// http://tizen.org/privilege/internet
463 /// <param name="representation">Resource representation of request</param>
464 /// <param name="query">The ResourceQuery to send to server</param>
465 /// <returns>Remote response with result and representation</returns>
466 public async Task<RemoteResponse> PostAsync(Representation representation, ResourceQuery query = null)
468 TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
470 IntPtr id = IntPtr.Zero;
471 lock (_responseCallbacksMap)
473 id = (IntPtr)_responseCallbackId++;
475 _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
477 IntPtr responseCallbackId = userData;
478 lock (_responseCallbacksMap)
480 _responseCallbacksMap.Remove(responseCallbackId);
482 if (responseHandle != IntPtr.Zero)
486 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
488 catch (Exception exp)
490 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
491 tcsRemoteResponse.TrySetException(exp);
496 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
499 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
500 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Post(_remoteResourceHandle, representation._representationHandle, queryHandle, _responseCallbacksMap[id], id);
501 if (errCode != (int)IoTConnectivityError.None)
503 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to post request");
504 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
506 return await tcsRemoteResponse.Task;
510 /// Deletes the resource, asynchronously
513 /// http://tizen.org/privilege/internet
515 /// <returns>Remote response with result and representation</returns>
516 public async Task<RemoteResponse> DeleteAsync()
518 TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
520 IntPtr id = IntPtr.Zero;
521 lock (_responseCallbacksMap)
523 id = (IntPtr)_responseCallbackId++;
525 _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
527 IntPtr responseCallbackId = userData;
528 lock (_responseCallbacksMap)
530 _responseCallbacksMap.Remove(responseCallbackId);
532 if (err == (int)(IoTConnectivityError.Iotivity))
534 RemoteResponse response = new RemoteResponse();
535 response.Result = ResponseCode.Forbidden;
536 response.Representation = null;
537 tcsRemoteResponse.TrySetResult(response);
539 else if (responseHandle != IntPtr.Zero)
543 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
545 catch (Exception exp)
547 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
548 tcsRemoteResponse.TrySetException(exp);
553 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
557 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Delete(_remoteResourceHandle, _responseCallbacksMap[id], id);
558 if (errCode != (int)IoTConnectivityError.None)
560 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to delete");
561 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
563 return await tcsRemoteResponse.Task;
567 /// Releases any unmanaged resources used by this object.
569 public void Dispose()
572 GC.SuppressFinalize(this);
575 internal static Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType GetConnectivityType(string hostAddress)
577 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.None;
579 if (hostAddress == IoTConnectivityClientManager.MulticastAddress)
581 type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv4;
586 string hostName = hostAddress;
587 if (hostAddress.Contains(":"))
589 string[] hostParts = hostAddress.Split(':');
590 if (hostParts.Length == 2)
592 hostName = hostParts[0];
595 if (IPAddress.TryParse(hostName, out address))
597 switch (address.AddressFamily)
599 case System.Net.Sockets.AddressFamily.InterNetwork:
600 type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv4;
602 case System.Net.Sockets.AddressFamily.InterNetworkV6:
603 type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv6;
606 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to parse for Ipv4 or Ipv6");
615 /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
617 /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
618 protected virtual void Dispose(bool disposing)
625 // Free managed objects
628 Interop.IoTConnectivity.Client.RemoteResource.Destroy(_remoteResourceHandle);
632 private void HandleCachePolicyChanged()
636 _cacheUpdatedCallback = (IntPtr resource, IntPtr representation, IntPtr userData) =>
640 Representation repr = null;
643 repr = new Representation(representation);
645 catch (Exception exp)
647 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new Representation: " + exp.Message);
651 CacheUpdatedEventArgs e = new CacheUpdatedEventArgs()
653 Representation = repr
655 CacheUpdated?.Invoke(null, e);
659 int ret = Interop.IoTConnectivity.Client.RemoteResource.StartCaching(_remoteResourceHandle, _cacheUpdatedCallback, IntPtr.Zero);
660 if (ret != (int)IoTConnectivityError.None)
662 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add cache updated event handler");
663 throw IoTConnectivityErrorFactory.GetException(ret);
668 int ret = Interop.IoTConnectivity.Client.RemoteResource.StopCaching(_remoteResourceHandle);
669 if (ret != (int)IoTConnectivityError.None)
671 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove cache updated event handler");
672 throw IoTConnectivityErrorFactory.GetException(ret);
677 private void RegisterStateChangedEvent()
679 _stateChangedCallback = (IntPtr resource, int state, IntPtr userData) =>
681 StateChangedEventArgs e = new StateChangedEventArgs()
683 State = (ResourceState)state
685 _stateChangedEventHandler?.Invoke(null, e);
688 int ret = Interop.IoTConnectivity.Client.RemoteResource.StartMonitoring(_remoteResourceHandle, _stateChangedCallback, IntPtr.Zero);
689 if (ret != (int)IoTConnectivityError.None)
691 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add state changed event handler");
692 throw IoTConnectivityErrorFactory.GetException(ret);
696 private void UnregisterStateChangedEvent()
698 int ret = Interop.IoTConnectivity.Client.RemoteResource.StopMonitoring(_remoteResourceHandle);
699 if (ret != (int)IoTConnectivityError.None)
701 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove state changed event handler");
702 throw IoTConnectivityErrorFactory.GetException(ret);
706 private void CreateRemoteResource(IntPtr resourceTypeHandle, IntPtr resourceInterfaceHandle)
708 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = GetConnectivityType(HostAddress);
709 if (connectivityType == Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.None)
711 Log.Error(IoTConnectivityErrorFactory.LogTag, "Unable to parse host address");
712 throw new ArgumentException("Unable to parse host address");
714 int ret = Interop.IoTConnectivity.Client.RemoteResource.Create(HostAddress, (int)connectivityType, UriPath, (int)Policy, resourceTypeHandle, resourceInterfaceHandle, out _remoteResourceHandle);
715 if (ret != (int)IoTConnectivityError.None)
717 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get remote resource");
718 throw IoTConnectivityErrorFactory.GetException(ret);
722 ret = Interop.IoTConnectivity.Client.RemoteResource.GetDeviceName(_remoteResourceHandle, out deviceName);
723 if (ret != (int)IoTConnectivityError.None)
725 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device name of remote resource");
726 throw IoTConnectivityErrorFactory.GetException(ret);
728 DeviceName = Marshal.PtrToStringAnsi(deviceName);*/
731 private void SetRemoteResource()
733 IntPtr hostAddressPtr, uriPathPtr;
734 int ret = Interop.IoTConnectivity.Client.RemoteResource.GetHostAddress(_remoteResourceHandle, out hostAddressPtr);
735 if (ret != (int)IoTConnectivityError.None)
737 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get host address");
738 throw IoTConnectivityErrorFactory.GetException(ret);
741 ret = Interop.IoTConnectivity.Client.RemoteResource.GetUriPath(_remoteResourceHandle, out uriPathPtr);
742 if (ret != (int)IoTConnectivityError.None)
744 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get uri path");
745 throw IoTConnectivityErrorFactory.GetException(ret);
748 int policy = (int)ResourcePolicy.NoProperty;
749 ret = Interop.IoTConnectivity.Client.RemoteResource.GetPolicies(_remoteResourceHandle, out policy);
750 if (ret != (int)IoTConnectivityError.None)
752 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get uri path");
753 throw IoTConnectivityErrorFactory.GetException(ret);
756 IntPtr typesHandle, interfacesHandle;
757 ret = Interop.IoTConnectivity.Client.RemoteResource.GetTypes(_remoteResourceHandle, out typesHandle);
758 if (ret != (int)IoTConnectivityError.None)
760 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource types");
761 throw IoTConnectivityErrorFactory.GetException(ret);
764 ret = Interop.IoTConnectivity.Client.RemoteResource.GetInterfaces(_remoteResourceHandle, out interfacesHandle);
765 if (ret != (int)IoTConnectivityError.None)
767 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource interfaces");
768 throw IoTConnectivityErrorFactory.GetException(ret);
772 ret = Interop.IoTConnectivity.Client.RemoteResource.GetDeviceId(_remoteResourceHandle, out deviceIdPtr);
773 if (ret != (int)IoTConnectivityError.None)
775 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device id");
776 throw IoTConnectivityErrorFactory.GetException(ret);
779 ret = Interop.IoTConnectivity.Client.RemoteResource.GetDeviceName(_remoteResourceHandle, out deviceName);
780 if (ret != (int)IoTConnectivityError.None)
782 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device name of remote resource");
783 throw IoTConnectivityErrorFactory.GetException(ret);
785 DeviceName = Marshal.PtrToStringAnsi(deviceName);
786 DeviceId = Marshal.PtrToStringAnsi(deviceIdPtr);
787 HostAddress = Marshal.PtrToStringAnsi(hostAddressPtr);
788 UriPath = Marshal.PtrToStringAnsi(uriPathPtr);
789 Types = new ResourceTypes(typesHandle);
790 Interfaces = new ResourceInterfaces(interfacesHandle);
791 Policy = (ResourcePolicy)policy;
794 private RemoteResponse GetRemoteResponse(IntPtr response)
797 IntPtr representationHandle, optionsHandle;
798 int ret = Interop.IoTConnectivity.Server.Response.GetResult(response, out result);
799 if (ret != (int)IoTConnectivityError.None)
801 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get result");
802 throw IoTConnectivityErrorFactory.GetException(ret);
805 ret = Interop.IoTConnectivity.Server.Response.GetRepresentation(response, out representationHandle);
806 if (ret != (int)IoTConnectivityError.None)
808 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get representation");
809 throw IoTConnectivityErrorFactory.GetException(ret);
812 ret = Interop.IoTConnectivity.Server.Response.GetOptions(response, out optionsHandle);
813 if (ret != (int)IoTConnectivityError.None)
815 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get options");
816 throw IoTConnectivityErrorFactory.GetException(ret);
818 return new RemoteResponse()
820 Result = (ResponseCode)result,
821 Representation = new Representation(representationHandle),
822 Options = (optionsHandle == IntPtr.Zero)? null : new ResourceOptions(optionsHandle)