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 /// <since_tizen> 3 </since_tizen>
31 public class RemoteResource : IDisposable
33 internal const int TimeOutMax = 3600;
34 internal IntPtr _remoteResourceHandle = IntPtr.Zero;
36 private bool _disposed = false;
37 private bool _cacheEnabled = false;
38 private ResourceOptions _options;
40 private int _responseCallbackId = 1;
41 private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.RemoteResource.ResponseCallback> _responseCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.RemoteResource.ResponseCallback>();
43 private Interop.IoTConnectivity.Client.RemoteResource.CachedRepresentationChangedCallback _cacheUpdatedCallback;
44 private Interop.IoTConnectivity.Client.RemoteResource.StateChangedCallback _stateChangedCallback;
45 private Interop.IoTConnectivity.Client.RemoteResource.ObserveCallback _observeCallback;
47 private EventHandler<StateChangedEventArgs> _stateChangedEventHandler;
50 /// Creates a remote resource instance.
52 /// <since_tizen> 3 </since_tizen>
54 /// To use this API, you should provide all the details required to correctly contact and
55 /// observe the object.\n
56 /// If not, you should discover the resource object manually.\n
57 /// The @a policy can contain multiple policies like ResourcePolicy.Discoverable | ResourcePolicy.Observable.
59 /// <param name="hostAddress">The host address of the resource.</param>
60 /// <param name="uriPath">The URI path of the resource.</param>
61 /// <param name="policy">The policies of the resource.</param>
62 /// <param name="resourceTypes">The resource types of the resource.</param>
63 /// <param name="resourceInterfaces">The resource interfaces of the resource.</param>
64 /// <feature>http://tizen.org/feature/iot.ocf</feature>
65 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
66 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory.</exception>
67 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter.</exception>
68 public RemoteResource(string hostAddress, string uriPath, ResourcePolicy policy, ResourceTypes resourceTypes, ResourceInterfaces resourceInterfaces)
70 if (hostAddress == null || uriPath == null || resourceTypes == null || resourceInterfaces == null)
72 Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid parameters");
73 throw new ArgumentException("Invalid parameter");
76 HostAddress = hostAddress;
79 Types = new List<string>(resourceTypes);
80 Interfaces = new List<string>(resourceInterfaces);
83 CreateRemoteResource(resourceTypes._resourceTypeHandle, resourceInterfaces.ResourceInterfacesHandle);
86 internal RemoteResource(IntPtr handleToClone)
88 int ret = Interop.IoTConnectivity.Client.RemoteResource.Clone(handleToClone, out _remoteResourceHandle);
89 if (ret != (int)IoTConnectivityError.None)
91 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to clone");
92 throw IoTConnectivityErrorFactory.GetException(ret);
98 /// Destructor of the RemoteResource class.
106 /// The event is invoked with cached resource attributes.
108 /// <since_tizen> 3 </since_tizen>
109 public event EventHandler<CacheUpdatedEventArgs> CacheUpdated;
112 /// Observe an event on the resource sent by the server.
114 /// <since_tizen> 3 </since_tizen>
115 public event EventHandler<ObserverNotifiedEventArgs> ObserverNotified;
118 /// The event is called when remote resource's state are changed.
120 /// <since_tizen> 3 </since_tizen>
121 public event EventHandler<StateChangedEventArgs> StateChanged
125 if (_stateChangedEventHandler == null)
127 RegisterStateChangedEvent();
129 _stateChangedEventHandler += value;
133 _stateChangedEventHandler -= value;
134 if (_stateChangedEventHandler == null)
136 UnregisterStateChangedEvent();
142 /// The host address of the resource.
144 /// <since_tizen> 3 </since_tizen>
145 /// <value>The host address of the resource.</value>
146 public string HostAddress { get; private set; }
149 /// The URI path of the resource.
151 /// <since_tizen> 3 </since_tizen>
152 /// <value>The URI path of the resource.</value>
153 public string UriPath { get; private set; }
156 /// The resource types of the remote resource.
158 /// <since_tizen> 3 </since_tizen>
159 /// <value>The resource types of the remote resource.</value>
160 public IEnumerable<string> Types { get; private set; }
163 /// The interfaces of the resource.
165 /// <since_tizen> 3 </since_tizen>
166 /// <value>The interfaces of the resource.</value>
167 public IEnumerable<string> Interfaces { get; private set; }
170 /// The policy of the resource.
172 /// <since_tizen> 3 </since_tizen>
173 /// <value>The policy of the resource.</value>
174 public ResourcePolicy Policy { get; private set; }
177 /// The header options of the resource.
179 /// <since_tizen> 3 </since_tizen>
180 /// <value>The header options of the resource.</value>
181 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
182 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter.</exception>
183 public ResourceOptions Options
194 int ret = Interop.IoTConnectivity.Client.RemoteResource.SetOptions(_remoteResourceHandle, value._resourceOptionsHandle);
195 if (ret != (int)IoTConnectivityError.None)
197 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set options");
198 throw IoTConnectivityErrorFactory.GetException(ret);
205 /// Indicates the CacheEnabled status of the remote resource.
207 /// <since_tizen> 3 </since_tizen>
209 /// Client can start caching only when this is set true. Set it to false to stop caching the resource attributes.
211 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
212 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter.</exception>
213 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
214 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have privilege to access.</exception>
215 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory.</exception>
216 public bool CacheEnabled
220 return _cacheEnabled;
224 if (_cacheEnabled != value)
226 _cacheEnabled = value;
227 HandleCachePolicyChanged();
233 /// Time interval of monitoring and caching API.
235 /// <since_tizen> 3 </since_tizen>
237 /// Default time interval is 10 seconds.
238 /// Seconds for time interval (must be in range from 1 to 3600).
240 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
241 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter.</exception>
242 public int TimeInterval
247 int ret = Interop.IoTConnectivity.Client.RemoteResource.GetTimeInterval(_remoteResourceHandle, out interval);
248 if (ret != (int)IoTConnectivityError.None)
250 Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get time interval");
257 int ret = (int)IoTConnectivityError.InvalidParameter;
258 if (value <= TimeOutMax && value > 0)
260 ret = Interop.IoTConnectivity.Client.RemoteResource.SetTimeInterval(_remoteResourceHandle, value);
262 if (ret != (int)IoTConnectivityError.None)
264 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set time interval");
265 throw IoTConnectivityErrorFactory.GetException(ret);
271 /// The device ID of the resource.
273 /// <since_tizen> 3 </since_tizen>
274 /// <value>The device ID of the resource.</value>
275 public string DeviceId { get; private set; }
278 /// Gets cached representation from the remote resource.
280 /// <since_tizen> 3 </since_tizen>
281 /// <returns>cached representation from the remote resource.</returns>
282 /// <feature>http://tizen.org/feature/iot.ocf</feature>
283 public Representation CachedRepresentation()
286 int ret = Interop.IoTConnectivity.Client.RemoteResource.GetCachedRepresentation(_remoteResourceHandle, out handle);
287 if (ret != (int)IoTConnectivityError.None)
289 Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get CachedRepresentation");
293 Representation representation = new Representation(handle);
294 return representation;
298 /// Starts observing on the resource.
300 /// <since_tizen> 3 </since_tizen>
302 /// When server sends notification message, <see cref="ObserverNotified"/> will be called.
305 /// http://tizen.org/privilege/internet
307 /// <privlevel>public</privlevel>
308 /// <param name="policy">The type to specify how client wants to observe.</param>
309 /// <param name="query">The query to send to server.</param>
310 /// <feature>http://tizen.org/feature/iot.ocf</feature>
311 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
312 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
313 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have privilege to access.</exception>
314 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory.</exception>
315 public void StartObserving(ObservePolicy policy, ResourceQuery query = null)
317 _observeCallback = (IntPtr resource, int err, int sequenceNumber, IntPtr response, IntPtr userData) =>
320 IntPtr representationHandle;
321 int ret = Interop.IoTConnectivity.Server.Response.GetResult(response, out result);
322 if (ret != (int)IoTConnectivityError.None)
324 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get result");
328 ret = Interop.IoTConnectivity.Server.Response.GetRepresentation(response, out representationHandle);
329 if (ret != (int)IoTConnectivityError.None)
331 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get representation");
335 Representation repr = null;
338 repr = new Representation(representationHandle);
340 catch (Exception exp)
342 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new representation: " + exp.Message);
346 ObserverNotifiedEventArgs e = new ObserverNotifiedEventArgs()
348 Representation = repr,
349 Result = (ResponseCode)result
351 ObserverNotified?.Invoke(this, e);
354 IntPtr queryHandle = IntPtr.Zero;
357 queryHandle = query._resourceQueryHandle;
360 int errCode = Interop.IoTConnectivity.Client.RemoteResource.RegisterObserve(_remoteResourceHandle, (int)policy, queryHandle, _observeCallback, IntPtr.Zero);
361 if (errCode != (int)IoTConnectivityError.None)
363 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to register observe callbacks");
364 throw IoTConnectivityErrorFactory.GetException(errCode);
369 /// Stops observing on the resource.
371 /// <since_tizen> 3 </since_tizen>
373 /// http://tizen.org/privilege/internet
375 /// <privlevel>public</privlevel>
376 /// <feature>http://tizen.org/feature/iot.ocf</feature>
377 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
378 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
379 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have privilege to access.</exception>
380 public void StopObserving()
382 int ret = Interop.IoTConnectivity.Client.RemoteResource.DeregisterObserve(_remoteResourceHandle);
383 if (ret != (int)IoTConnectivityError.None)
385 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to deregister observe callbacks");
386 throw IoTConnectivityErrorFactory.GetException(ret);
391 /// Gets the attributes of a resource asynchronously.
393 /// <since_tizen> 3 </since_tizen>
395 /// http://tizen.org/privilege/internet
397 /// <privlevel>public</privlevel>
398 /// <param name="query">The ResourceQuery to send to server.</param>
399 /// <returns>Remote response with result and representation.</returns>
400 /// <feature>http://tizen.org/feature/iot.ocf</feature>
401 public async Task<RemoteResponse> GetAsync(ResourceQuery query = null)
403 TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
405 IntPtr id = IntPtr.Zero;
406 lock (_responseCallbacksMap)
408 id = (IntPtr)_responseCallbackId++;
410 _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
412 IntPtr responseCallbackId = userData;
413 lock(_responseCallbacksMap)
415 _responseCallbacksMap.Remove(responseCallbackId);
418 if (responseHandle != IntPtr.Zero)
422 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
426 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
427 tcsRemoteResponse.TrySetException(exp);
432 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
436 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
437 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Get(_remoteResourceHandle, queryHandle, _responseCallbacksMap[id], id);
438 if (errCode != (int)IoTConnectivityError.None)
440 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource attributes");
441 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
443 return await tcsRemoteResponse.Task;
447 /// Puts the representation of a resource asynchronously.
449 /// <since_tizen> 3 </since_tizen>
451 /// http://tizen.org/privilege/internet
453 /// <privlevel>public</privlevel>
454 /// <param name="representation">Resource representation to put.</param>
455 /// <param name="query">The ResourceQuery to send to server.</param>
456 /// <returns>Remote response with result and representation.</returns>
457 /// <feature>http://tizen.org/feature/iot.ocf</feature>
458 public async Task<RemoteResponse> PutAsync(Representation representation, ResourceQuery query = null)
460 TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
462 IntPtr id = IntPtr.Zero;
463 lock (_responseCallbacksMap)
465 id = (IntPtr)_responseCallbackId++;
467 _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
469 IntPtr responseCallbackId = userData;
470 lock (_responseCallbacksMap)
472 _responseCallbacksMap.Remove(responseCallbackId);
474 if (err == (int)(IoTConnectivityError.Iotivity))
476 RemoteResponse response = new RemoteResponse();
477 response.Result = ResponseCode.Forbidden;
478 response.Representation = null;
479 tcsRemoteResponse.TrySetResult(response);
481 else if (responseHandle != IntPtr.Zero)
485 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
487 catch (Exception exp)
489 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
490 tcsRemoteResponse.TrySetException(exp);
495 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
498 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
499 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Put(_remoteResourceHandle, representation._representationHandle, queryHandle, _responseCallbacksMap[id], id);
500 if (errCode != (int)IoTConnectivityError.None)
502 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to put resource representation");
503 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
505 return await tcsRemoteResponse.Task;
509 /// Posts request on a resource asynchronously.
511 /// <since_tizen> 3 </since_tizen>
513 /// http://tizen.org/privilege/internet
515 /// <privlevel>public</privlevel>
516 /// <param name="representation">Resource representation of request.</param>
517 /// <param name="query">The ResourceQuery to send to server.</param>
518 /// <returns>Remote response with result and representation.</returns>
519 /// <feature>http://tizen.org/feature/iot.ocf</feature>
520 public async Task<RemoteResponse> PostAsync(Representation representation, ResourceQuery query = null)
522 TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
524 IntPtr id = IntPtr.Zero;
525 lock (_responseCallbacksMap)
527 id = (IntPtr)_responseCallbackId++;
529 _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
531 IntPtr responseCallbackId = userData;
532 lock (_responseCallbacksMap)
534 _responseCallbacksMap.Remove(responseCallbackId);
536 if (responseHandle != IntPtr.Zero)
540 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
542 catch (Exception exp)
544 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
545 tcsRemoteResponse.TrySetException(exp);
550 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
553 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
554 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Post(_remoteResourceHandle, representation._representationHandle, queryHandle, _responseCallbacksMap[id], id);
555 if (errCode != (int)IoTConnectivityError.None)
557 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to post request");
558 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
560 return await tcsRemoteResponse.Task;
564 /// Deletes the resource asynchronously.
566 /// <since_tizen> 3 </since_tizen>
568 /// http://tizen.org/privilege/internet
570 /// <privlevel>public</privlevel>
571 /// <returns>Remote response with result and representation.</returns>
572 /// <feature>http://tizen.org/feature/iot.ocf</feature>
573 public async Task<RemoteResponse> DeleteAsync()
575 TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
577 IntPtr id = IntPtr.Zero;
578 lock (_responseCallbacksMap)
580 id = (IntPtr)_responseCallbackId++;
582 _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
584 IntPtr responseCallbackId = userData;
585 lock (_responseCallbacksMap)
587 _responseCallbacksMap.Remove(responseCallbackId);
589 if (err == (int)(IoTConnectivityError.Iotivity))
591 RemoteResponse response = new RemoteResponse();
592 response.Result = ResponseCode.Forbidden;
593 response.Representation = null;
594 tcsRemoteResponse.TrySetResult(response);
596 else if (responseHandle != IntPtr.Zero)
600 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
602 catch (Exception exp)
604 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
605 tcsRemoteResponse.TrySetException(exp);
610 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
614 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Delete(_remoteResourceHandle, _responseCallbacksMap[id], id);
615 if (errCode != (int)IoTConnectivityError.None)
617 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to delete");
618 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
620 return await tcsRemoteResponse.Task;
624 /// Releases any unmanaged resources used by this object.
626 /// <since_tizen> 3 </since_tizen>
627 /// <feature>http://tizen.org/feature/iot.ocf</feature>
628 public void Dispose()
631 GC.SuppressFinalize(this);
634 internal static Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType GetConnectivityType(string hostAddress)
636 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.None;
638 Log.Info(IoTConnectivityErrorFactory.LogTag, hostAddress);
640 if (hostAddress == IoTConnectivityClientManager.MulticastAddress)
642 type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv4;
647 string hostName = hostAddress;
648 if (hostAddress.Contains(":"))
650 string[] hostParts = hostAddress.Split(':');
651 if (hostParts.Length == 2)
653 hostName = hostParts[0];
656 if (hostAddress.Contains("%"))
658 string[] hostParts = hostAddress.Split('%');
659 if (hostParts.Length == 2)
661 hostName = hostParts[0];
664 if (hostName.Contains("["))
666 string[] hostParts = hostName.Split('[');
667 if (hostParts.Length == 2)
669 hostName = hostParts[1];
672 Log.Info(IoTConnectivityErrorFactory.LogTag, hostName);
673 if (IPAddress.TryParse(hostName, out address))
675 switch (address.AddressFamily)
677 case System.Net.Sockets.AddressFamily.InterNetwork:
678 type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv4;
680 case System.Net.Sockets.AddressFamily.InterNetworkV6:
681 type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv6;
684 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to parse for Ipv4 or Ipv6");
690 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to parse hostname " + hostName);
697 /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
699 /// <since_tizen> 3 </since_tizen>
700 /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
701 /// <feature>http://tizen.org/feature/iot.ocf</feature>
702 protected virtual void Dispose(bool disposing)
709 // Free managed objects
712 Interop.IoTConnectivity.Client.RemoteResource.Destroy(_remoteResourceHandle);
716 private void HandleCachePolicyChanged()
720 _cacheUpdatedCallback = (IntPtr resource, IntPtr representation, IntPtr userData) =>
724 Representation repr = null;
727 repr = new Representation(representation);
729 catch (Exception exp)
731 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new Representation: " + exp.Message);
735 CacheUpdatedEventArgs e = new CacheUpdatedEventArgs()
737 Representation = repr
739 CacheUpdated?.Invoke(this, e);
743 int ret = Interop.IoTConnectivity.Client.RemoteResource.StartCaching(_remoteResourceHandle, _cacheUpdatedCallback, IntPtr.Zero);
744 if (ret != (int)IoTConnectivityError.None)
746 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add cache updated event handler");
747 throw IoTConnectivityErrorFactory.GetException(ret);
752 int ret = Interop.IoTConnectivity.Client.RemoteResource.StopCaching(_remoteResourceHandle);
753 if (ret != (int)IoTConnectivityError.None)
755 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove cache updated event handler");
756 throw IoTConnectivityErrorFactory.GetException(ret);
761 private void RegisterStateChangedEvent()
763 _stateChangedCallback = (IntPtr resource, int state, IntPtr userData) =>
765 StateChangedEventArgs e = new StateChangedEventArgs()
767 State = (ResourceState)state
769 _stateChangedEventHandler?.Invoke(null, e);
772 int ret = Interop.IoTConnectivity.Client.RemoteResource.StartMonitoring(_remoteResourceHandle, _stateChangedCallback, IntPtr.Zero);
773 if (ret != (int)IoTConnectivityError.None)
775 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add state changed event handler");
776 throw IoTConnectivityErrorFactory.GetException(ret);
780 private void UnregisterStateChangedEvent()
782 int ret = Interop.IoTConnectivity.Client.RemoteResource.StopMonitoring(_remoteResourceHandle);
783 if (ret != (int)IoTConnectivityError.None)
785 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove state changed event handler");
786 throw IoTConnectivityErrorFactory.GetException(ret);
790 private void CreateRemoteResource(IntPtr resourceTypeHandle, IntPtr resourceInterfaceHandle)
792 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = GetConnectivityType(HostAddress);
793 if (connectivityType == Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.None)
795 Log.Error(IoTConnectivityErrorFactory.LogTag, "Unable to parse host address");
796 throw new ArgumentException("Unable to parse host address");
798 int ret = Interop.IoTConnectivity.Client.RemoteResource.Create(HostAddress, (int)connectivityType, UriPath, (int)Policy, resourceTypeHandle, resourceInterfaceHandle, out _remoteResourceHandle);
799 if (ret != (int)IoTConnectivityError.None)
801 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get remote resource");
802 throw IoTConnectivityErrorFactory.GetException(ret);
806 private void SetRemoteResource()
808 IntPtr hostAddressPtr, uriPathPtr;
809 int ret = Interop.IoTConnectivity.Client.RemoteResource.GetHostAddress(_remoteResourceHandle, out hostAddressPtr);
810 if (ret != (int)IoTConnectivityError.None)
812 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get host address");
813 throw IoTConnectivityErrorFactory.GetException(ret);
816 ret = Interop.IoTConnectivity.Client.RemoteResource.GetUriPath(_remoteResourceHandle, out uriPathPtr);
817 if (ret != (int)IoTConnectivityError.None)
819 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get uri path");
820 throw IoTConnectivityErrorFactory.GetException(ret);
823 int policy = (int)ResourcePolicy.NoProperty;
824 ret = Interop.IoTConnectivity.Client.RemoteResource.GetPolicies(_remoteResourceHandle, out policy);
825 if (ret != (int)IoTConnectivityError.None)
827 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get uri path");
828 throw IoTConnectivityErrorFactory.GetException(ret);
831 IntPtr typesHandle, interfacesHandle;
832 ret = Interop.IoTConnectivity.Client.RemoteResource.GetTypes(_remoteResourceHandle, out typesHandle);
833 if (ret != (int)IoTConnectivityError.None)
835 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource types");
836 throw IoTConnectivityErrorFactory.GetException(ret);
839 ret = Interop.IoTConnectivity.Client.RemoteResource.GetInterfaces(_remoteResourceHandle, out interfacesHandle);
840 if (ret != (int)IoTConnectivityError.None)
842 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource interfaces");
843 throw IoTConnectivityErrorFactory.GetException(ret);
847 ret = Interop.IoTConnectivity.Client.RemoteResource.GetDeviceId(_remoteResourceHandle, out deviceIdPtr);
848 if (ret != (int)IoTConnectivityError.None)
850 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device id");
851 throw IoTConnectivityErrorFactory.GetException(ret);
853 DeviceId = (deviceIdPtr != IntPtr.Zero) ? Marshal.PtrToStringAnsi(deviceIdPtr) : string.Empty;
854 HostAddress = (hostAddressPtr != IntPtr.Zero) ? Marshal.PtrToStringAnsi(hostAddressPtr) : string.Empty;
855 UriPath = (uriPathPtr != IntPtr.Zero) ? Marshal.PtrToStringAnsi(uriPathPtr) : string.Empty;
856 Types = new ResourceTypes(typesHandle);
857 Interfaces = new ResourceInterfaces(interfacesHandle);
858 Policy = (ResourcePolicy)policy;
861 private RemoteResponse GetRemoteResponse(IntPtr response)
864 IntPtr representationHandle, optionsHandle;
865 int ret = Interop.IoTConnectivity.Server.Response.GetResult(response, out result);
866 if (ret != (int)IoTConnectivityError.None)
868 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get result");
869 throw IoTConnectivityErrorFactory.GetException(ret);
872 ret = Interop.IoTConnectivity.Server.Response.GetRepresentation(response, out representationHandle);
873 if (ret != (int)IoTConnectivityError.None)
875 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get representation");
876 throw IoTConnectivityErrorFactory.GetException(ret);
879 ret = Interop.IoTConnectivity.Server.Response.GetOptions(response, out optionsHandle);
880 if (ret != (int)IoTConnectivityError.None)
882 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get options");
883 throw IoTConnectivityErrorFactory.GetException(ret);
885 return new RemoteResponse()
887 Result = (ResponseCode)result,
888 Representation = new Representation(representationHandle),
889 Options = (optionsHandle == IntPtr.Zero)? null : new ResourceOptions(optionsHandle)