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.
20 public class RemoteResource : IDisposable
22 internal const int TimeOutMax = 3600;
23 internal IntPtr _remoteResourceHandle = IntPtr.Zero;
25 private bool _disposed = false;
26 private bool _cacheEnabled = false;
27 private ResourceOptions _options;
29 private int _responseCallbackId = 1;
30 private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.RemoteResource.ResponseCallback> _responseCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.RemoteResource.ResponseCallback>();
32 private Interop.IoTConnectivity.Client.RemoteResource.CachedRepresentationChangedCallback _cacheUpdatedCallback;
33 private Interop.IoTConnectivity.Client.RemoteResource.StateChangedCallback _stateChangedCallback;
34 private Interop.IoTConnectivity.Client.RemoteResource.ObserveCallback _observeCallback;
36 private EventHandler<StateChangedEventArgs> _stateChangedEventHandler;
41 public RemoteResource(string hostAddress, string uriPath, ResourcePolicy policy, ResourceTypes resourceTypes, ResourceInterfaces resourceInterfaces)
43 if (hostAddress == null || uriPath == null || resourceTypes == null || resourceInterfaces == null)
45 Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid parameters");
46 throw new ArgumentException("Invalid parameter");
49 HostAddress = hostAddress;
52 Types = new List<string>(resourceTypes);
53 Interfaces = new List<string>(resourceInterfaces);
56 CreateRemoteResource(resourceTypes._resourceTypeHandle, resourceInterfaces.ResourceInterfacesHandle);
59 internal RemoteResource(IntPtr handleToClone)
61 int ret = Interop.IoTConnectivity.Client.RemoteResource.Clone(handleToClone, out _remoteResourceHandle);
62 if (ret != (int)IoTConnectivityError.None)
64 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to clone");
65 throw IoTConnectivityErrorFactory.GetException(ret);
76 /// Event that is called to cache resource attribute's
78 public event EventHandler<CacheUpdatedEventArgs> CacheUpdated;
81 /// Observe event on the resource
83 public event EventHandler<ObserverNotifiedEventArgs> ObserverNotified;
86 /// Event that is called when remote resource's state are changed
88 public event EventHandler<StateChangedEventArgs> StateChanged
92 if (_stateChangedEventHandler == null)
94 RegisterStateChangedEvent();
96 _stateChangedEventHandler += value;
100 _stateChangedEventHandler -= value;
101 if (_stateChangedEventHandler == null)
103 UnregisterStateChangedEvent();
109 /// The host address of the resource
111 public string HostAddress { get; private set; }
114 /// The URI path of the resource
116 public string UriPath { get; private set; }
119 /// The resource types of the remote resource
121 public IEnumerable<string> Types { get; private set; }
124 /// The interfaces of the resource
126 public IEnumerable<string> Interfaces { get; private set; }
129 /// The policy of the resource
131 public ResourcePolicy Policy { get; private set; }
134 /// The device name of the remote resource
136 public string DeviceName { get; private set; }
139 /// The header options of the resource
141 public ResourceOptions Options
152 int ret = Interop.IoTConnectivity.Client.RemoteResource.SetOptions(_remoteResourceHandle, value._resourceOptionsHandle);
153 if (ret != (int)IoTConnectivityError.None)
155 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set options");
156 throw IoTConnectivityErrorFactory.GetException(ret);
163 /// Cache enabled property
165 public bool CacheEnabled
169 return _cacheEnabled;
173 if (_cacheEnabled != value)
175 _cacheEnabled = value;
176 HandleCachePolicyChanged();
182 /// Time interval of monitoring and caching API
184 public int TimeInterval
189 int ret = Interop.IoTConnectivity.Client.RemoteResource.GetTimeInterval(out interval);
190 if (ret != (int)IoTConnectivityError.None)
192 Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get time interval");
199 int ret = (int)IoTConnectivityError.InvalidParameter;
200 if (value < TimeOutMax && value > 0)
202 ret = Interop.IoTConnectivity.Client.RemoteResource.SetTimeInterval(value);
204 if (ret != (int)IoTConnectivityError.None)
206 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set time interval");
207 throw IoTConnectivityErrorFactory.GetException(ret);
213 /// The device id of the resource
215 public string DeviceId { get; private set; }
218 /// Gets cached representation of the remote resource
220 public Representation CachedRepresentation()
223 int ret = Interop.IoTConnectivity.Client.RemoteResource.GetCachedRepresentation(_remoteResourceHandle, out handle);
224 if (ret != (int)IoTConnectivityError.None)
226 Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get CachedRepresentation");
230 Representation representation = new Representation(handle);
231 return representation;
235 /// Registers the observe callback on the resource
237 /// <param name="policy">The type to specify how client wants to observe</param>
238 /// <param name="query">The ResourceQuery to send to server</param>
239 public void StartObserving(ObservePolicy policy, ResourceQuery query = null)
241 _observeCallback = (IntPtr resource, int err, int sequenceNumber, IntPtr response, IntPtr userData) =>
244 IntPtr representationHandle;
245 int ret = Interop.IoTConnectivity.Server.Response.GetResult(response, out result);
246 if (ret != (int)IoTConnectivityError.None)
248 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get result");
252 ret = Interop.IoTConnectivity.Server.Response.GetRepresentation(response, out representationHandle);
253 if (ret != (int)IoTConnectivityError.None)
255 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get representation");
259 Representation repr = null;
262 repr = new Representation(representationHandle);
264 catch (Exception exp)
266 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new representation: " + exp.Message);
270 ObserverNotifiedEventArgs e = new ObserverNotifiedEventArgs()
272 Representation = repr,
273 Result = (ResponseCode)result
275 ObserverNotified?.Invoke(null, e);
278 IntPtr queryHandle = IntPtr.Zero;
281 queryHandle = query._resourceQueryHandle;
284 int errCode = Interop.IoTConnectivity.Client.RemoteResource.RegisterObserve(_remoteResourceHandle, (int)policy, queryHandle, _observeCallback, IntPtr.Zero);
285 if (errCode != (int)IoTConnectivityError.None)
287 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to register observe callbacks");
288 throw IoTConnectivityErrorFactory.GetException(errCode);
293 /// Deregisters the observe callback on the resource
295 public void StopObserving()
297 int ret = Interop.IoTConnectivity.Client.RemoteResource.DeregisterObserve(_remoteResourceHandle);
298 if (ret != (int)IoTConnectivityError.None)
300 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to deregister observe callbacks");
301 throw IoTConnectivityErrorFactory.GetException(ret);
306 /// Gets the attributes of a resource
308 /// <param name="query">The ResourceQuery to send to server</param>
309 /// <returns></returns>
310 public async Task<RemoteResponse> GetAsync(ResourceQuery query = null)
312 TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
314 IntPtr id = IntPtr.Zero;
315 lock (_responseCallbacksMap)
317 id = (IntPtr)_responseCallbackId++;
319 _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
321 IntPtr responseCallbackId = userData;
322 lock(_responseCallbacksMap)
324 _responseCallbacksMap.Remove(responseCallbackId);
327 if (responseHandle != IntPtr.Zero)
331 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
335 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
336 tcsRemoteResponse.TrySetException(exp);
341 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
345 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
346 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Get(_remoteResourceHandle, queryHandle, _responseCallbacksMap[id], id);
347 if (errCode != (int)IoTConnectivityError.None)
349 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource attributes");
350 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
352 return await tcsRemoteResponse.Task;
356 /// Puts the representation of a resource, asynchronously.
358 /// <param name="representation">Resource representation</param>
359 /// <param name="query">The ResourceQuery to send to server</param>
360 /// <returns></returns>
361 public async Task<RemoteResponse> PutAsync(Representation representation, ResourceQuery query = null)
363 TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
365 IntPtr id = IntPtr.Zero;
366 lock (_responseCallbacksMap)
368 id = (IntPtr)_responseCallbackId++;
370 _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
372 IntPtr responseCallbackId = userData;
373 lock (_responseCallbacksMap)
375 _responseCallbacksMap.Remove(responseCallbackId);
377 if (err == (int)(IoTConnectivityError.Iotivity))
379 RemoteResponse response = new RemoteResponse();
380 response.Result = ResponseCode.Forbidden;
381 response.Representation = null;
382 tcsRemoteResponse.TrySetResult(response);
384 else if (responseHandle != IntPtr.Zero)
388 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
390 catch (Exception exp)
392 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
393 tcsRemoteResponse.TrySetException(exp);
398 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
401 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
402 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Put(_remoteResourceHandle, representation._representationHandle, queryHandle, _responseCallbacksMap[id], id);
403 if (errCode != (int)IoTConnectivityError.None)
405 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to put resource representation");
406 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
408 return await tcsRemoteResponse.Task;
412 /// Post request on a resource
414 /// <param name="representation">Resource representation</param>
415 /// <param name="query">The ResourceQuery to send to server</param>
416 /// <returns></returns>
417 public async Task<RemoteResponse> PostAsync(Representation representation, ResourceQuery query = null)
419 TaskCompletionSource<RemoteResponse> tcsRemoteResponse = new TaskCompletionSource<RemoteResponse>();
421 IntPtr id = IntPtr.Zero;
422 lock (_responseCallbacksMap)
424 id = (IntPtr)_responseCallbackId++;
426 _responseCallbacksMap[id] = (IntPtr resource, int err, int requestType, IntPtr responseHandle, IntPtr userData) =>
428 IntPtr responseCallbackId = userData;
429 lock (_responseCallbacksMap)
431 _responseCallbacksMap.Remove(responseCallbackId);
434 if (responseHandle != IntPtr.Zero)
438 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
440 catch (Exception exp)
442 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
443 tcsRemoteResponse.TrySetException(exp);
448 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
452 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
453 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Post(_remoteResourceHandle, representation._representationHandle, queryHandle, _responseCallbacksMap[id], id);
454 if (errCode != (int)IoTConnectivityError.None)
456 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to post request");
457 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
459 return await tcsRemoteResponse.Task;
463 /// Delete the resource
465 /// <returns></returns>
466 public async Task<RemoteResponse> DeleteAsync()
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 (err == (int)(IoTConnectivityError.Iotivity))
484 RemoteResponse response = new RemoteResponse();
485 response.Result = ResponseCode.Forbidden;
486 response.Representation = null;
487 tcsRemoteResponse.TrySetResult(response);
489 else if (responseHandle != IntPtr.Zero)
493 tcsRemoteResponse.TrySetResult(GetRemoteResponse(responseHandle));
495 catch (Exception exp)
497 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get RemoteResponse: ", exp.Message);
498 tcsRemoteResponse.TrySetException(exp);
503 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.System));
507 int errCode = Interop.IoTConnectivity.Client.RemoteResource.Delete(_remoteResourceHandle, _responseCallbacksMap[id], id);
508 if (errCode != (int)IoTConnectivityError.None)
510 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to delete");
511 tcsRemoteResponse.TrySetException(IoTConnectivityErrorFactory.GetException(errCode));
513 return await tcsRemoteResponse.Task;
516 public void Dispose()
519 GC.SuppressFinalize(this);
522 internal static Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType GetConnectivityType(string hostAddress)
524 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.None;
526 if (hostAddress == IoTConnectivityClientManager.MulticastAddress)
528 type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv4;
533 string hostName = hostAddress;
534 if (hostAddress.Contains(":"))
536 string[] hostParts = hostAddress.Split(':');
537 if (hostParts.Length == 2)
539 hostName = hostParts[0];
542 if (IPAddress.TryParse(hostName, out address))
544 switch (address.AddressFamily)
546 case System.Net.Sockets.AddressFamily.InterNetwork:
547 type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv4;
549 case System.Net.Sockets.AddressFamily.InterNetworkV6:
550 type = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ipv6;
553 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to parse for Ipv4 or Ipv6");
561 protected virtual void Dispose(bool disposing)
568 // Free managed objects
571 Interop.IoTConnectivity.Client.RemoteResource.Destroy(_remoteResourceHandle);
575 private void HandleCachePolicyChanged()
579 _cacheUpdatedCallback = (IntPtr resource, IntPtr representation, IntPtr userData) =>
583 Representation repr = null;
586 repr = new Representation(representation);
588 catch (Exception exp)
590 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to new Representation: " + exp.Message);
594 CacheUpdatedEventArgs e = new CacheUpdatedEventArgs()
596 Representation = repr
598 CacheUpdated?.Invoke(null, e);
602 int ret = Interop.IoTConnectivity.Client.RemoteResource.StartCaching(_remoteResourceHandle, _cacheUpdatedCallback, IntPtr.Zero);
603 if (ret != (int)IoTConnectivityError.None)
605 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add cache updated event handler");
606 throw IoTConnectivityErrorFactory.GetException(ret);
611 int ret = Interop.IoTConnectivity.Client.RemoteResource.StopCaching(_remoteResourceHandle);
612 if (ret != (int)IoTConnectivityError.None)
614 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove cache updated event handler");
615 throw IoTConnectivityErrorFactory.GetException(ret);
620 private void RegisterStateChangedEvent()
622 _stateChangedCallback = (IntPtr resource, int state, IntPtr userData) =>
624 StateChangedEventArgs e = new StateChangedEventArgs()
626 State = (ResourceState)state
628 _stateChangedEventHandler?.Invoke(null, e);
631 int ret = Interop.IoTConnectivity.Client.RemoteResource.StartMonitoring(_remoteResourceHandle, _stateChangedCallback, IntPtr.Zero);
632 if (ret != (int)IoTConnectivityError.None)
634 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add state changed event handler");
635 throw IoTConnectivityErrorFactory.GetException(ret);
639 private void UnregisterStateChangedEvent()
641 int ret = Interop.IoTConnectivity.Client.RemoteResource.StopMonitoring(_remoteResourceHandle);
642 if (ret != (int)IoTConnectivityError.None)
644 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove state changed event handler");
645 throw IoTConnectivityErrorFactory.GetException(ret);
649 private void CreateRemoteResource(IntPtr resourceTypeHandle, IntPtr resourceInterfaceHandle)
651 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = GetConnectivityType(HostAddress);
652 if (connectivityType == Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.None)
654 Log.Error(IoTConnectivityErrorFactory.LogTag, "Unable to parse host address");
655 throw new ArgumentException("Unable to parse host address");
657 int ret = Interop.IoTConnectivity.Client.RemoteResource.Create(HostAddress, (int)connectivityType, UriPath, (int)Policy, resourceTypeHandle, resourceInterfaceHandle, out _remoteResourceHandle);
658 if (ret != (int)IoTConnectivityError.None)
660 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get remote resource");
661 throw IoTConnectivityErrorFactory.GetException(ret);
665 ret = Interop.IoTConnectivity.Client.RemoteResource.GetDeviceName(_remoteResourceHandle, out deviceName);
666 if (ret != (int)IoTConnectivityError.None)
668 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device name of remote resource");
669 throw IoTConnectivityErrorFactory.GetException(ret);
671 DeviceName = Marshal.PtrToStringAuto(deviceName);*/
674 private void SetRemoteResource()
676 IntPtr hostAddressPtr, uriPathPtr;
677 int ret = Interop.IoTConnectivity.Client.RemoteResource.GetHostAddress(_remoteResourceHandle, out hostAddressPtr);
678 if (ret != (int)IoTConnectivityError.None)
680 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get host address");
681 throw IoTConnectivityErrorFactory.GetException(ret);
684 ret = Interop.IoTConnectivity.Client.RemoteResource.GetUriPath(_remoteResourceHandle, out uriPathPtr);
685 if (ret != (int)IoTConnectivityError.None)
687 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get uri path");
688 throw IoTConnectivityErrorFactory.GetException(ret);
691 int policy = (int)ResourcePolicy.NoProperty;
692 ret = Interop.IoTConnectivity.Client.RemoteResource.GetPolicies(_remoteResourceHandle, out policy);
693 if (ret != (int)IoTConnectivityError.None)
695 Log.Error(IoTConnectivityErrorFactory.LogTag, "Faled to get uri path");
696 throw IoTConnectivityErrorFactory.GetException(ret);
699 IntPtr typesHandle, interfacesHandle;
700 ret = Interop.IoTConnectivity.Client.RemoteResource.GetTypes(_remoteResourceHandle, out typesHandle);
701 if (ret != (int)IoTConnectivityError.None)
703 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource types");
704 throw IoTConnectivityErrorFactory.GetException(ret);
707 ret = Interop.IoTConnectivity.Client.RemoteResource.GetInterfaces(_remoteResourceHandle, out interfacesHandle);
708 if (ret != (int)IoTConnectivityError.None)
710 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource interfaces");
711 throw IoTConnectivityErrorFactory.GetException(ret);
715 ret = Interop.IoTConnectivity.Client.RemoteResource.GetDeviceId(_remoteResourceHandle, out deviceIdPtr);
716 if (ret != (int)IoTConnectivityError.None)
718 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device id");
719 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.PtrToStringAuto(deviceName);
729 DeviceId = Marshal.PtrToStringAuto(deviceIdPtr);
730 HostAddress = Marshal.PtrToStringAuto(hostAddressPtr);
731 UriPath = Marshal.PtrToStringAuto(uriPathPtr);
732 Types = new ResourceTypes(typesHandle);
733 Interfaces = new ResourceInterfaces(interfacesHandle);
734 Policy = (ResourcePolicy)policy;
737 private RemoteResponse GetRemoteResponse(IntPtr response)
740 IntPtr representationHandle, optionsHandle;
741 int ret = Interop.IoTConnectivity.Server.Response.GetResult(response, out result);
742 if (ret != (int)IoTConnectivityError.None)
744 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get result");
745 throw IoTConnectivityErrorFactory.GetException(ret);
748 ret = Interop.IoTConnectivity.Server.Response.GetRepresentation(response, out representationHandle);
749 if (ret != (int)IoTConnectivityError.None)
751 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get representation");
752 throw IoTConnectivityErrorFactory.GetException(ret);
755 ret = Interop.IoTConnectivity.Server.Response.GetOptions(response, out optionsHandle);
756 if (ret != (int)IoTConnectivityError.None)
758 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get options");
759 throw IoTConnectivityErrorFactory.GetException(ret);
761 return new RemoteResponse()
763 Result = (ResponseCode)result,
764 Representation = new Representation(representationHandle),
765 Options = (optionsHandle == IntPtr.Zero)? null : new ResourceOptions(optionsHandle)