Merge "Added iotcon test cases" into devel
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.IoTConnectivity / Tizen.Network.IoTConnectivity / RemoteResource.cs
1 /// Copyright 2016 by Samsung Electronics, Inc.,
2 ///
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.
8
9 using System;
10 using System.Collections.Generic;
11 using System.Net;
12 using System.Threading.Tasks;
13
14 namespace Tizen.Network.IoTConnectivity
15 {
16     /// <summary>
17     /// RemoteResource class
18     /// </summary>
19     public class RemoteResource : IDisposable
20     {
21         internal const int TimeOutMax = 3600;
22         internal IntPtr _remoteResourceHandle = IntPtr.Zero;
23
24         private bool _disposed = false;
25         private bool _cacheEnabled = false;
26         private ResourceOptions _options;
27
28         private int _responseCallbackId = 1;
29         private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.RemoteResource.ResponseCallback> _responseCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.RemoteResource.ResponseCallback>();
30
31         private Interop.IoTConnectivity.Client.RemoteResource.CachedRepresentationChangedCallback _cacheUpdatedCallback;
32         private Interop.IoTConnectivity.Client.RemoteResource.StateChangedCallback _stateChangedCallback;
33         private Interop.IoTConnectivity.Client.RemoteResource.ObserveCallback _observeCallback;
34
35         private EventHandler<StateChangedEventArgs> _stateChangedEventHandler;
36
37         /// <summary>
38         /// Constructor
39         /// </summary>
40         public RemoteResource(string hostAddress, string uriPath, ResourcePolicy policy, ResourceTypes resourceTypes, ResourceInterfaces resourceInterfaces)
41         {
42             if (hostAddress == null || uriPath == null || resourceTypes == null || resourceInterfaces == null)
43             {
44                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid parameters");
45                 throw new ArgumentException("Invalid parameter");
46             }
47
48             HostAddress = hostAddress;
49             UriPath = uriPath;
50             Policy = policy;
51             Types = new List<string>(resourceTypes);
52             Interfaces = new List<string>(resourceInterfaces);
53             DeviceId = null;
54
55             CreateRemoteResource(resourceTypes._resourceTypeHandle, resourceInterfaces.ResourceInterfacesHandle);
56         }
57
58         internal RemoteResource(IntPtr handleToClone)
59         {
60             int ret = Interop.IoTConnectivity.Client.RemoteResource.Clone(handleToClone, out _remoteResourceHandle);
61             if (ret != (int)IoTConnectivityError.None)
62             {
63                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to clone");
64                 throw IoTConnectivityErrorFactory.GetException(ret);
65             }
66             SetRemoteResource();
67         }
68
69         ~RemoteResource()
70         {
71             Dispose(false);
72         }
73
74         /// <summary>
75         /// Event that is called to cache resource attribute's
76         /// </summary>
77         public event EventHandler<CacheUpdatedEventArgs> CacheUpdated;
78
79         /// <summary>
80         /// Observe event on the resource
81         /// </summary>
82         public event EventHandler<ObserverNotifiedEventArgs> ObserverNotified;
83
84         /// <summary>
85         /// Event that is called when remote resource's state are changed
86         /// </summary>
87         public event EventHandler<StateChangedEventArgs> StateChanged
88         {
89             add
90             {
91                 if (_stateChangedEventHandler == null)
92                 {
93                     RegisterStateChangedEvent();
94                 }
95                 _stateChangedEventHandler += value;
96             }
97             remove
98             {
99                 _stateChangedEventHandler -= value;
100                 if (_stateChangedEventHandler == null)
101                 {
102                     UnregisterStateChangedEvent();
103                 }
104             }
105         }
106
107         /// <summary>
108         /// The host address of the resource
109         /// </summary>
110         public string HostAddress { get; private set; }
111
112         /// <summary>
113         /// The URI path of the resource
114         /// </summary>
115         public string UriPath { get; private set; }
116
117         /// <summary>
118         /// The resource types of the remote resource
119         /// </summary>
120         public IEnumerable<string> Types { get; private set; }
121
122         /// <summary>
123         /// The interfaces of the resource
124         /// </summary>
125         public IEnumerable<string> Interfaces { get; private set; }
126
127         /// <summary>
128         /// The policy of the resource
129         /// </summary>
130         public ResourcePolicy Policy { get; private set; }
131
132         /// <summary>
133         /// The header options of the resource
134         /// </summary>
135         public ResourceOptions Options
136         {
137             get
138             {
139                 return _options;
140             }
141             set
142             {
143                 _options = value;
144                 if (value != null)
145                 {
146                     int ret = Interop.IoTConnectivity.Client.RemoteResource.SetOptions(_remoteResourceHandle, value._resourceOptionsHandle);
147                     if (ret != (int)IoTConnectivityError.None)
148                     {
149                         Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set options");
150                         throw IoTConnectivityErrorFactory.GetException(ret);
151                     }
152                 }
153             }
154         }
155
156         /// <summary>
157         /// Cache enabled property
158         /// </summary>
159         public bool CacheEnabled
160         {
161             get
162             {
163                 return _cacheEnabled;
164             }
165             set
166             {
167                 if (_cacheEnabled != value)
168                 {
169                     _cacheEnabled = value;
170                     HandleCachePolicyChanged();
171                 }
172             }
173         }
174
175         /// <summary>
176         /// Time interval of monitoring and caching API
177         /// </summary>
178         public int TimeInterval
179         {
180             get
181             {
182                 int interval;
183                 int ret = Interop.IoTConnectivity.Client.RemoteResource.GetTimeInterval(_remoteResourceHandle, out interval);
184                 if (ret != (int)IoTConnectivityError.None)
185                 {
186                     Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get time interval");
187                     return 0;
188                 }
189                 return interval;
190             }
191             set
192             {
193                 int ret = (int)IoTConnectivityError.InvalidParameter;
194                 if (value < TimeOutMax && value > 0)
195                 {
196                     ret = Interop.IoTConnectivity.Client.RemoteResource.SetTimeInterval(_remoteResourceHandle, value);
197                 }
198                 if (ret != (int)IoTConnectivityError.None)
199                 {
200                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set time interval");
201                     throw IoTConnectivityErrorFactory.GetException(ret);
202                 }
203             }
204         }
205
206         /// <summary>
207         /// The device id of the resource
208         /// </summary>
209         public string DeviceId { get; private set; }
210
211         /// <summary>
212         /// Gets cached representation of the remote resource
213         /// </summary>
214         public Representation CachedRepresentation()
215         {
216             IntPtr handle;
217             int ret = Interop.IoTConnectivity.Client.RemoteResource.GetCachedRepresentation(_remoteResourceHandle, out handle);
218             if (ret != (int)IoTConnectivityError.None)
219             {
220                 Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get CachedRepresentation");
221                 return null;
222             }
223
224             Representation representation = new Representation(handle);
225             return representation;
226         }
227
228         /// <summary>
229         /// Registers the observe callback on the resource
230         /// </summary>
231         /// <param name="policy">The type to specify how client wants to observe</param>
232         /// <param name="query">The ResourceQuery to send to server</param>
233         public void StartObserving(ObservePolicy policy, ResourceQuery query = null)
234         {
235             _observeCallback = (IntPtr resource, int err, int sequenceNumber, IntPtr response, IntPtr userData) =>
236             {
237                 int result;
238                 IntPtr representationHandle;
239                 int ret = Interop.IoTConnectivity.Server.Response.GetResult(response, out result);
240                 if (ret != (int)IoTConnectivityError.None)
241                 {
242                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get result");
243                     return;
244                 }
245
246                 ret = Interop.IoTConnectivity.Server.Response.GetRepresentation(response, out representationHandle);
247                 if (ret != (int)IoTConnectivityError.None)
248                 {
249                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get representation");
250                     return;
251                 }
252
253                 Representation repr = null;
254                 try
255                 {
256                     repr = new Representation(representationHandle);
257                 }
258                 catch (Exception exp)
259                 {
260                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new representation: " + exp.Message);
261                     return;
262                 }
263
264                 ObserverNotifiedEventArgs e = new ObserverNotifiedEventArgs()
265                 {
266                     Representation = repr,
267                     Result = (ResponseCode)result
268                 };
269                 ObserverNotified?.Invoke(null, e);
270             };
271
272             IntPtr queryHandle = IntPtr.Zero;
273             if (query != null)
274             {
275                 queryHandle = query._resourceQueryHandle;
276             }
277
278             int errCode = Interop.IoTConnectivity.Client.RemoteResource.RegisterObserve(_remoteResourceHandle, (int)policy, queryHandle, _observeCallback, IntPtr.Zero);
279             if (errCode != (int)IoTConnectivityError.None)
280             {
281                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to register observe callbacks");
282                 throw IoTConnectivityErrorFactory.GetException(errCode);
283             }
284         }
285
286         /// <summary>
287         /// Deregisters the observe callback on the resource
288         /// </summary>
289         public void StopObserving()
290         {
291             int ret = Interop.IoTConnectivity.Client.RemoteResource.DeregisterObserve(_remoteResourceHandle);
292             if (ret != (int)IoTConnectivityError.None)
293             {
294                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to deregister observe callbacks");
295                 throw IoTConnectivityErrorFactory.GetException(ret);
296             }
297         }
298
299         /// <summary>
300         /// Gets the attributes of a resource
301         /// </summary>
302         /// <param name="query">The ResourceQuery to send to server</param>
303         /// <returns></returns>
304         public async Task<RemoteResponse> GetAsync(ResourceQuery query = null)
305         {
306             TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
307
308             IntPtr id = IntPtr.Zero;
309             lock (_responseCallbacksMap)
310             {
311                 id = (IntPtr)_responseCallbackId++;
312             }
313             _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
314             {
315                 IntPtr responseCallbackId = userData;
316                 lock(_responseCallbacksMap)
317                 {
318                     _responseCallbacksMap.Remove(responseCallbackId);
319                 }
320
321                 if (responseHandle != IntPtr.Zero)
322                 {
323                     try
324                     {
325                         tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
326                     }
327                     catch(Exception exp)
328                     {
329                         Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
330                         tcsRemoteResponse.TrySetException(exp);
331                     }
332                 }
333                 else
334                 {
335                     tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
336                 }
337             };
338
339             IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
340             int errCode = Interop.IoTConnectivity.Client.RemoteResource.Get(_remoteResourceHandle, queryHandle, _responseCallbacksMap[id], id);
341             if (errCode != (int)IoTConnectivityError.None)
342             {
343                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource attributes");
344                 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
345             }
346             return await tcsRemoteResponse.Task;
347         }
348
349         /// <summary>
350         /// Puts the representation of a resource, asynchronously.
351         /// </summary>
352         /// <param name="representation">Resource representation</param>
353         /// <param name="query">The ResourceQuery to send to server</param>
354         /// <returns></returns>
355         public async Task<RemoteResponse> PutAsync(Representation representation, ResourceQuery query = null)
356         {
357             TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
358
359             IntPtr id = IntPtr.Zero;
360             lock (_responseCallbacksMap)
361             {
362                 id = (IntPtr)_responseCallbackId++;
363             }
364             _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
365             {
366                 IntPtr responseCallbackId = userData;
367                 lock (_responseCallbacksMap)
368                 {
369                     _responseCallbacksMap.Remove(responseCallbackId);
370                 }
371
372                 if (responseHandle != IntPtr.Zero)
373                 {
374                     try
375                     {
376                         tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
377                     }
378                     catch (Exception exp)
379                     {
380                         Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
381                         tcsRemoteResponse.TrySetException(exp);
382                     }
383                 }
384                 else
385                 {
386                     tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
387                 }
388             };
389
390             IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
391             int errCode = Interop.IoTConnectivity.Client.RemoteResource.Put(_remoteResourceHandle, representation._representationHandle, queryHandle, _responseCallbacksMap[id], id);
392             if (errCode != (int)IoTConnectivityError.None)
393             {
394                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to put resource representation");
395                 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
396             }
397             return await tcsRemoteResponse.Task;
398         }
399
400         /// <summary>
401         /// Post request on a resource
402         /// </summary>
403         /// <param name="representation">Resource representation</param>
404         /// <param name="query">The ResourceQuery to send to server</param>
405         /// <returns></returns>
406         public async Task<RemoteResponse> PostAsync(Representation representation, ResourceQuery query = null)
407         {
408             TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
409
410             IntPtr id = IntPtr.Zero;
411             lock (_responseCallbacksMap)
412             {
413                 id = (IntPtr)_responseCallbackId++;
414             }
415             _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
416             {
417                 IntPtr responseCallbackId = userData;
418                 lock (_responseCallbacksMap)
419                 {
420                     _responseCallbacksMap.Remove(responseCallbackId);
421                 }
422
423                 if (responseHandle != IntPtr.Zero)
424                 {
425                     try
426                     {
427                         tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
428                     }
429                     catch (Exception exp)
430                     {
431                         Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
432                         tcsRemoteResponse.TrySetException(exp);
433                     }
434                 }
435                 else
436                 {
437                     tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
438                 }
439             };
440
441             IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
442             int errCode = Interop.IoTConnectivity.Client.RemoteResource.Post(_remoteResourceHandle, representation._representationHandle, queryHandle, _responseCallbacksMap[id], id);
443             if (errCode != (int)IoTConnectivityError.None)
444             {
445                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to post request");
446                 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
447             }
448             return await tcsRemoteResponse.Task;
449         }
450
451         /// <summary>
452         /// Delete the resource
453         /// </summary>
454         /// <returns></returns>
455         public async Task<RemoteResponse> DeleteAsync()
456         {
457             TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
458
459             IntPtr id = IntPtr.Zero;
460             lock (_responseCallbacksMap)
461             {
462                 id = (IntPtr)_responseCallbackId++;
463             }
464             _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
465             {
466                 IntPtr responseCallbackId = userData;
467                 lock (_responseCallbacksMap)
468                 {
469                     _responseCallbacksMap.Remove(responseCallbackId);
470                 }
471
472                 if (responseHandle != IntPtr.Zero)
473                 {
474                     try
475                     {
476                         tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
477                     }
478                     catch (Exception exp)
479                     {
480                         Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
481                         tcsRemoteResponse.TrySetException(exp);
482                     }
483                 }
484                 else
485                 {
486                     tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
487                 }
488             };
489
490             int errCode = Interop.IoTConnectivity.Client.RemoteResource.Delete(_remoteResourceHandle, _responseCallbacksMap[id], id);
491             if (errCode != (int)IoTConnectivityError.None)
492             {
493                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to delete");
494                 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
495             }
496             return await tcsRemoteResponse.Task;
497         }
498
499         public void Dispose()
500         {
501             Dispose(true);
502             GC.SuppressFinalize(this);
503         }
504
505         internal static Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType GetConnectivityType(string hostAddress)
506         {
507             Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.None;
508
509             if (hostAddress == IoTConnectivityClientManager.MulticastAddress)
510             {
511                 type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv4;
512             }
513             else
514             {
515                 IPAddress address;
516                 if (IPAddress.TryParse(hostAddress, out address))
517                 {
518                     switch (address.AddressFamily)
519                     {
520                         case System.Net.Sockets.AddressFamily.InterNetwork:
521                             type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv4;
522                             break;
523                         case System.Net.Sockets.AddressFamily.InterNetworkV6:
524                             type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv6;
525                             break;
526                         default:
527                             Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to parse for Ipv4 or Ipv6");
528                             break;
529                     }
530                 }
531             }
532             return type;
533         }
534
535         protected virtual void Dispose(bool disposing)
536         {
537             if (_disposed)
538                 return;
539
540             if (disposing)
541             {
542                 // Free managed objects
543             }
544
545             Interop.IoTConnectivity.Client.RemoteResource.Destroy(_remoteResourceHandle);
546             _disposed = true;
547         }
548
549         private void HandleCachePolicyChanged()
550         {
551             if (_cacheEnabled)
552             {
553                 _cacheUpdatedCallback = (IntPtr resource, IntPtr representation, IntPtr userData) =>
554                 {
555                     if (CacheEnabled)
556                     {
557                         Representation repr = null;
558                         try
559                         {
560                             repr = new Representation(representation);
561                         }
562                         catch (Exception exp)
563                         {
564                             Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new Representation: " + exp.Message);
565                             return;
566                         }
567
568                         CacheUpdatedEventArgs e = new CacheUpdatedEventArgs()
569                         {
570                             Representation = repr
571                         };
572                         CacheUpdated?.Invoke(null, e);
573                     }
574                 };
575
576                 int ret = Interop.IoTConnectivity.Client.RemoteResource.StartCaching(_remoteResourceHandle, _cacheUpdatedCallback, IntPtr.Zero);
577                 if (ret != (int)IoTConnectivityError.None)
578                 {
579                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add cache updated event handler");
580                     throw IoTConnectivityErrorFactory.GetException(ret);
581                 }
582             }
583             else
584             {
585                 int ret = Interop.IoTConnectivity.Client.RemoteResource.StopCaching(_remoteResourceHandle);
586                 if (ret != (int)IoTConnectivityError.None)
587                 {
588                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove cache updated event handler");
589                     throw IoTConnectivityErrorFactory.GetException(ret);
590                 }
591             }
592         }
593
594         private void RegisterStateChangedEvent()
595         {
596             _stateChangedCallback = (IntPtr resource, int state, IntPtr userData) =>
597             {
598                 StateChangedEventArgs e = new StateChangedEventArgs()
599                 {
600                     State = (ResourceState)state
601                 };
602                 _stateChangedEventHandler?.Invoke(null, e);
603             };
604
605             int ret = Interop.IoTConnectivity.Client.RemoteResource.StartMonitoring(_remoteResourceHandle, _stateChangedCallback, IntPtr.Zero);
606             if (ret != (int)IoTConnectivityError.None)
607             {
608                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add state changed event handler");
609                 throw IoTConnectivityErrorFactory.GetException(ret);
610             }
611         }
612
613         private void UnregisterStateChangedEvent()
614         {
615             int ret = Interop.IoTConnectivity.Client.RemoteResource.StopMonitoring(_remoteResourceHandle);
616             if (ret != (int)IoTConnectivityError.None)
617             {
618                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove state changed event handler");
619                 throw IoTConnectivityErrorFactory.GetException(ret);
620             }
621         }
622
623         private void CreateRemoteResource(IntPtr resourceTypeHandle, IntPtr resourceInterfaceHandle)
624         {
625             Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = GetConnectivityType(HostAddress);
626             if (connectivityType == Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.None)
627             {
628                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Unable to parse host address");
629                 throw new ArgumentException("Unable to parse host address");
630             }
631             int ret = Interop.IoTConnectivity.Client.RemoteResource.Create(HostAddress, (int)connectivityType, UriPath, (int)Policy, resourceTypeHandle, resourceInterfaceHandle, out _remoteResourceHandle);
632             if (ret != (int)IoTConnectivityError.None)
633             {
634                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get remote resource");
635                 throw IoTConnectivityErrorFactory.GetException(ret);
636             }
637         }
638
639         private void SetRemoteResource()
640         {
641             string hostAddress, uriPath;
642             int ret = Interop.IoTConnectivity.Client.RemoteResource.GetHostAddress(_remoteResourceHandle, out hostAddress);
643             if (ret != (int)IoTConnectivityError.None)
644             {
645                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get host address");
646                 throw IoTConnectivityErrorFactory.GetException(ret);
647             }
648
649             ret = Interop.IoTConnectivity.Client.RemoteResource.GetUriPath(_remoteResourceHandle, out uriPath);
650             if (ret != (int)IoTConnectivityError.None)
651             {
652                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get uri path");
653                 throw IoTConnectivityErrorFactory.GetException(ret);
654             }
655
656             int policy = (int)ResourcePolicy.NoProperty;
657             ret = Interop.IoTConnectivity.Client.RemoteResource.GetProperties(_remoteResourceHandle, out policy);
658             if (ret != (int)IoTConnectivityError.None)
659             {
660                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get uri path");
661                 throw IoTConnectivityErrorFactory.GetException(ret);
662             }
663
664             IntPtr typesHandle, interfacesHandle;
665             ret = Interop.IoTConnectivity.Client.RemoteResource.GetTypes(_remoteResourceHandle, out typesHandle);
666             if (ret != (int)IoTConnectivityError.None)
667             {
668                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource types");
669                 throw IoTConnectivityErrorFactory.GetException(ret);
670             }
671
672             ret = Interop.IoTConnectivity.Client.RemoteResource.GetInterfaces(_remoteResourceHandle, out interfacesHandle);
673             if (ret != (int)IoTConnectivityError.None)
674             {
675                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource interfaces");
676                 throw IoTConnectivityErrorFactory.GetException(ret);
677             }
678
679             string deviceId;
680             ret = Interop.IoTConnectivity.Client.RemoteResource.GetDeviceId(_remoteResourceHandle, out deviceId);
681             if (ret != (int)IoTConnectivityError.None)
682             {
683                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device id");
684                 throw IoTConnectivityErrorFactory.GetException(ret);
685             }
686
687             DeviceId = deviceId;
688             HostAddress = hostAddress;
689             UriPath = uriPath;
690             Types = new ResourceTypes(typesHandle);
691             Interfaces = new ResourceInterfaces(interfacesHandle);
692             Policy = (ResourcePolicy)policy;
693         }
694
695         private RemoteResponse GetRemoteResponse(IntPtr response)
696         {
697             int result;
698             IntPtr representationHandle, optionsHandle;
699             int ret = Interop.IoTConnectivity.Server.Response.GetResult(response, out result);
700             if (ret != (int)IoTConnectivityError.None)
701             {
702                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get result");
703                 throw IoTConnectivityErrorFactory.GetException(ret);
704             }
705
706             ret = Interop.IoTConnectivity.Server.Response.GetRepresentation(response, out representationHandle);
707             if (ret != (int)IoTConnectivityError.None)
708             {
709                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get representation");
710                 throw IoTConnectivityErrorFactory.GetException(ret);
711             }
712
713             ret = Interop.IoTConnectivity.Server.Response.GetOptions(response, out optionsHandle);
714             if (ret != (int)IoTConnectivityError.None)
715             {
716                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get options");
717                 throw IoTConnectivityErrorFactory.GetException(ret);
718             }
719
720             return new RemoteResponse()
721             {
722                 Result = (ResponseCode)result,
723                 Representation = new Representation(representationHandle),
724                 Options = new ResourceOptions(optionsHandle)
725             };
726         }
727     }
728 }