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.
18 using System.Collections.Generic;
19 using System.Runtime.InteropServices;
21 namespace Tizen.Network.IoTConnectivity
24 /// IoT connectivity client manager consists of client side APIs.
26 public static class IoTConnectivityClientManager
29 /// The IP Address for multicast
31 public const string MulticastAddress = null;
33 private static int s_presenceListenerId = 1;
34 private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.Presence.PresenceCallback> s_presenceCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.Presence.PresenceCallback>();
35 private static Dictionary<IntPtr, IntPtr> s_presenceHandlesMap = new Dictionary<IntPtr, IntPtr>();
37 private static int s_requestId = 1;
38 private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.ResourceFinder.FoundResourceCallback> s_resourceFoundCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.ResourceFinder.FoundResourceCallback>();
39 private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.DeviceInformation.DeviceInformationCallback> s_deviceInformationCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.DeviceInformation.DeviceInformationCallback>();
40 private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.PlatformInformation.PlatformInformationCallback> s_platformInformationCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.PlatformInformation.PlatformInformationCallback>();
43 /// PresenceReceived event. This event is occurred when server starts sending presence of a resource.
45 public static event EventHandler<PresenceReceivedEventArgs> PresenceReceived;
48 /// ResourceFound event. This event is occurred when a resource is found from the remote server
49 /// after sending request using API StartFindingResource().
51 public static event EventHandler<ResourceFoundEventArgs> ResourceFound;
54 /// PlatformInformationFound event. This event is occurred when platform information is found
55 /// after sending request using API StartFindingPlatformInformation().
57 public static event EventHandler<PlatformInformationFoundEventArgs> PlatformInformationFound;
60 /// DeviceInformationFound event. This event is occurred when device information is found
61 /// after sending request using API StartFindingDeviceInformation().
63 public static event EventHandler<DeviceInformationFoundEventArgs> DeviceInformationFound;
66 /// FindingError event. This event is occurred when an error is found.
68 public static event EventHandler<FindingErrorOccurredEventArgs> FindingErrorOccurred;
71 /// Timeout in seconds
74 /// Value to be set must be in range from 1 to 3600. Default timeout interval value is 30.\n
75 /// Sets/gets the timeout of StartFindingResource(), StartFindingDeviceInformation(), StartFindingPlatformInformation(),
76 /// RemoteResource.GetAsync(), RemoteResource.PutAsync(), RemoteResource.PostAsync() and RemoteResource.DeleteAsync() APIs.\n
77 /// Setter can throw exception.
80 /// Initialize() should be called to initialize
83 /// IoTConnectivityClientManager.Initialize();
84 /// IoTConnectivityClientManager.TimeOut = 120;
86 public static int TimeOut
91 int ret = Interop.IoTConnectivity.Client.IoTCon.GetTimeout(out timeout);
92 if (ret != (int)IoTConnectivityError.None)
94 Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get timeout");
101 int ret = Interop.IoTConnectivity.Client.IoTCon.SetTimeout(value);
102 if (ret != (int)IoTConnectivityError.None)
104 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set timeout");
105 throw IoTConnectivityErrorFactory.GetException(ret);
111 /// Polling interval of IoTConnectivity
114 /// Sets/Gets the polling inerval(milliseconds) of IoTCon. Default value is 100 milliseconds.
115 /// Value to be set must be in range from 1 to 999. The closer to 0, the faster it operates.
116 /// Setter is invoked immediately for changing the interval.
117 /// If you want the faster operation, we recommend you set 10 milliseconds for polling interval.
118 /// Setter can throw exception.
121 /// Initialize() should be called to initialize
124 /// IoTConnectivityClientManager.Initialize();
125 /// IoTConnectivityClientManager.PollingInterval = 100;
127 public static int PollingInterval
132 int ret = Interop.IoTConnectivity.Client.IoTCon.GetPollingInterval(out interval);
133 if (ret != (int)IoTConnectivityError.None)
135 Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get polling interval");
142 int ret = Interop.IoTConnectivity.Client.IoTCon.SetPollingInterval(value);
143 if (ret != (int)IoTConnectivityError.None)
145 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set polling interval");
146 throw IoTConnectivityErrorFactory.GetException(ret);
152 /// Initializes IoTCon.
153 /// Call this function to start IoTCon.
156 /// @a filePath point to a file for handling secure virtual resources.
157 /// The file that is CBOR(Concise Binary Object Representation)-format must already exist
158 /// in @a filePath. We recommend to use application-local file for @a filePath.
161 /// http://tizen.org/privilege/network.get \n
162 /// http://tizen.org/privilege/internet
164 /// <param name="filePath">The file path to point to storage for handling secure virtual resources.</param>
166 /// You must call Deinitialize() if IoTCon API is no longer needed.
168 /// <seealso cref="Deinitialize()"/>
169 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
170 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
171 /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
173 /// string filePath = "../../res/iotcon-test-svr-db-client.dat";
174 /// IoTConnectivityClientManager.Initialize(filePath);
176 public static void Initialize(string filePath)
178 int ret = Interop.IoTConnectivity.Client.IoTCon.Initialize(filePath);
179 if (ret != (int)IoTConnectivityError.None)
181 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to initialize");
182 throw IoTConnectivityErrorFactory.GetException(ret);
187 /// Deinitializes IoTCon.
190 /// This API must be called if IoTCon API is no longer needed.
193 /// Initialize() should be called to initialize.
195 /// <seealso cref="Initialize()"/>
196 /// <seealso cref="SecureInitialize()"/>
198 /// IoTConnectivityClientManager.Deinitialize();
200 public static void Deinitialize()
202 s_presenceListenerId = 1;
203 s_presenceCallbacksMap.Clear();
204 s_presenceHandlesMap.Clear();
207 s_resourceFoundCallbacksMap.Clear();
208 s_deviceInformationCallbacksMap.Clear();
209 s_platformInformationCallbacksMap.Clear();
211 PresenceReceived = delegate{};
212 ResourceFound = delegate{};
213 PlatformInformationFound = delegate{};
214 DeviceInformationFound = delegate{};
215 FindingErrorOccurred = delegate{};
217 Interop.IoTConnectivity.Client.IoTCon.Deinitialize();
221 /// Invokes a next message from a queue for receiving messages from others, immediately.
224 /// This API invokes a next message from a queue for receiving messages from others, immediately.
225 /// After calling the API, it continues the polling with existing interval.
228 /// Initialize() should be called to initialize.
230 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
232 /// IoTConnectivityClientManager.InvokePolling();
234 public static void InvokePolling()
236 int ret = Interop.IoTConnectivity.Client.IoTCon.InvokePolling();
237 if (ret != (int)IoTConnectivityError.None)
239 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to invoke polling");
240 throw IoTConnectivityErrorFactory.GetException(ret);
245 /// Starts receiving presence events
248 /// Sends request to receive presence to an interested server's resource with resourceType.
249 /// If succeeded, <see cref="PresenceReceived"/> event handler will be triggered when the server sends presence.
250 /// A server sends presence events when adds / removes / alters a resource or start / stop presence.\n
251 /// @a hostAddress could be <see cref="MulticastAddress"/> for IPv4 multicast.
252 /// The length of @ resourceType should be less than or equal to 61. The @ resourceType must start with a lowercase alphabetic character, followed by a sequence
253 /// of lowercase alphabetic, numeric, ".", or "-" characters, and contains no white space.
256 /// http://tizen.org/privilege/internet
258 /// <param name="hostAddress">The address or addressable name of the server</param>
259 /// <param name="resourceType">A resource type that a client is interested in</param>
260 /// <returns>PresenceId - An identifier for this request</returns>
261 /// <pre>Initialize() should be called to initialize.</pre>
263 /// When the resource receive presence, <see cref="PresenceReceived"/> event handler will be invoked.\n
264 /// You must destroy presence by calling StopReceivingPresence() if presence event is no longer needed.
266 /// <seealso cref="IoTConnectivityServerManager.StartSendingPresence()"/>
267 /// <seealso cref="IoTConnectivityServerManager.StopSendingPresence()"/>
268 /// <seealso cref="StopReceivingPresence()"/>
269 /// <seealso cref="PresenceReceived"/>
270 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
271 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
272 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
273 /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
274 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
276 /// EventHandler<PresenceReceivedEventArgs> handler = (sender, e) => {
277 /// Console.Log("PresenceReceived, presence id :" + e.PresenceId);
279 /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
280 /// Console.Log("Found error :" + e.Error.Message);
282 /// IoTConnectivityClientManager.PresenceReceived += handler;
283 /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
284 /// // Do not forget to remove these event handlers when they are not required any more.
285 /// int id = IoTConnectivityClientManager.StartReceivingPresence(IoTConnectivityClientManager.MulticastAddress, "oic.iot.door");
287 public static int StartReceivingPresence(string hostAddress, string resourceType)
289 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
291 if (resourceType != null && !ResourceTypes.IsValid(resourceType))
293 Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid type");
294 throw new ArgumentException("Invalid type");
297 IntPtr id = IntPtr.Zero;
298 lock (s_presenceCallbacksMap)
300 id = (IntPtr)s_presenceListenerId++;
302 s_presenceCallbacksMap[id] = (IntPtr presence, int result, IntPtr presenceResponseHandle, IntPtr userData) =>
304 int presenceId = (int)userData;
305 if (result == (int)IoTConnectivityError.None)
307 if (presenceResponseHandle != IntPtr.Zero)
309 PresenceReceivedEventArgs e = GetPresenceReceivedEventArgs(presenceId, presenceResponseHandle);
312 Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't get PresenceReceivedEventArgs");
315 PresenceReceived?.Invoke(null, e);
319 Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
325 FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(presenceId, result);
326 FindingErrorOccurred?.Invoke(null, e);
330 IntPtr presenceHandle;
331 int errorCode = Interop.IoTConnectivity.Client.Presence.AddPresenceCb(hostAddress, (int)connectivityType, resourceType, s_presenceCallbacksMap[id], id, out presenceHandle);
332 if (errorCode != (int)IoTConnectivityError.None)
334 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to register presence event handler");
335 lock (s_presenceCallbacksMap)
337 s_presenceCallbacksMap.Remove(id);
339 throw IoTConnectivityErrorFactory.GetException(errorCode);
342 lock (s_presenceHandlesMap)
344 s_presenceHandlesMap[id] = presenceHandle;
350 /// Stops receiving presence events
353 /// Sends request to not to receive server's presence any more.
356 /// http://tizen.org/privilege/internet
358 /// <param name="presenceId">The start presence request identifier</param>
360 /// Initialize() should be called to initialize.
362 /// <seealso cref="IoTConnectivityServerManager.StartSendingPresence()"/>
363 /// <seealso cref="IoTConnectivityServerManager.StopSendingPresence()"/>
364 /// <seealso cref="StartReceivingPresence()"/>
365 /// <seealso cref="PresenceReceived"/>
366 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
367 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
368 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
369 /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
370 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
372 /// EventHandler<PresenceReceivedEventArgs> handler = (sender, e) => {
373 /// Console.Log("PresenceReceived, presence id :" + e.PresenceId);
375 /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
376 /// Console.Log("Found error :" + e.Error.Message);
378 /// IoTConnectivityClientManager.PresenceReceived += handler;
379 /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
380 /// int id = IoTConnectivityClientManager.StartReceivingPresence(IoTConnectivityClientManager.MulticastAddress, "oic.iot.door");
381 /// await Task.Delay(5000); // Do other things here
382 /// // Call StopReceivingPresence() when receiving presence is not required any more
383 /// IoTConnectivityClientManager.PresenceReceived -= handler;
384 /// IoTConnectivityClientManager.FindingErrorOccurred -= errorHandler;
385 /// IoTConnectivityClientManager.StopReceivingPresence(id);
387 public static void StopReceivingPresence(int presenceId)
389 if (!s_presenceHandlesMap.ContainsKey((IntPtr)presenceId))
391 Log.Error(IoTConnectivityErrorFactory.LogTag, "this presenceId does not exist");
392 throw new ArgumentException("this presenceId does not exist");
395 if (s_presenceHandlesMap.ContainsKey((IntPtr)presenceId))
397 IntPtr presenceHandle = s_presenceHandlesMap[(IntPtr)presenceId];
398 int ret = Interop.IoTConnectivity.Client.Presence.RemovePresenceCb(presenceHandle);
399 if (ret != (int)IoTConnectivityError.None)
401 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to deregister presence event handler");
402 throw IoTConnectivityErrorFactory.GetException(ret);
405 lock (s_presenceHandlesMap)
407 s_presenceHandlesMap.Remove((IntPtr)presenceId);
411 if (s_presenceCallbacksMap.ContainsKey((IntPtr)presenceId))
413 lock (s_presenceCallbacksMap)
415 s_presenceCallbacksMap.Remove((IntPtr)presenceId);
421 /// Starts finding resources.
424 /// Sends request to find a resource of @a hostAddress server with @a resourceType.
425 /// If succeeded, <see cref="ResourceFound"/> event handler will be triggered with information of the resource.\n
426 /// @a hostAddress could be <see cref="MulticastAddress"/> for IPv4 multicast.
427 /// The length of @a resourceType should be less than or equal to 61. The @ resourceType must start with a lowercase alphabetic character, followed by a sequence
428 /// of lowercase alphabetic, numeric, ".", or "-" characters, and contains no white space.
431 /// http://tizen.org/privilege/internet
433 /// <param name="hostAddress">The address or addressable name of the server. The address includes a protocol like coaps://</param>
434 /// <param name="query">The query specified as a filter for founding resources</param>
435 /// <returns>RequestId - An identifier for this request</returns>
436 /// <pre>Initialize() should be called to initialize.</pre>
438 /// When the resource is found, <see cref="ResourceFound"/> event handler will be invoked.
440 /// <seealso cref="ResourceFound"/>
441 /// <seealso cref="ResourceFoundEventArgs"/>
442 /// <seealso cref="TimeOut"/>
443 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
444 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
445 /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
446 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
448 /// EventHandler<ResourceFoundEventArgs> handler = (sender, e) => {
449 /// Console.Log("Found resource at host address :" + e.Resource.HostAddress + ", uri :" + e.Resource.UriPath);
451 /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
452 /// Console.Log("Found error :" + e.Error.Message);
454 /// IoTConnectivityClientManager.ResourceFound += handler;
455 /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
456 /// ResourceQuery query = new ResourceQuery();
457 /// query.Type = "oic.iot.door";
458 /// // Do not forget to remove these event handlers when they are not required any more.
459 /// int id = IoTConnectivityClientManager.StartFindingResource(null, query);
461 public static int StartFindingResource(string hostAddress, ResourceQuery query = null)
463 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
465 IntPtr id = IntPtr.Zero;
466 lock (s_resourceFoundCallbacksMap)
468 id = (IntPtr)s_requestId++;
470 s_resourceFoundCallbacksMap[id] = (IntPtr remoteResourceHandle, int result, IntPtr userData) =>
472 if (ResourceFound == null)
475 int requestId = (int)userData;
476 if (result == (int)IoTConnectivityError.None)
478 if (remoteResourceHandle != IntPtr.Zero)
480 RemoteResource resource = null;
483 resource = new RemoteResource(remoteResourceHandle);
485 catch (Exception exp)
487 Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't clone RemoteResource's handle: " + exp.Message);
490 ResourceFoundEventArgs e = new ResourceFoundEventArgs()
492 RequestId = requestId,
495 ResourceFound?.Invoke(null, e);
496 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.EventContinue : " + e.EventContinue);
497 return e.EventContinue;
501 Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
506 FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(requestId, result);
507 FindingErrorOccurred?.Invoke(null, e);
509 lock (s_resourceFoundCallbacksMap)
511 s_resourceFoundCallbacksMap.Remove(id);
516 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
517 int errorCode = Interop.IoTConnectivity.Client.ResourceFinder.AddResourceFoundCb(hostAddress, (int)connectivityType, queryHandle, s_resourceFoundCallbacksMap[id], id);
518 if (errorCode != (int)IoTConnectivityError.None)
520 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to register resource found event handler");
521 lock (s_resourceFoundCallbacksMap)
523 s_resourceFoundCallbacksMap.Remove(id);
525 throw IoTConnectivityErrorFactory.GetException(errorCode);
531 /// Starts finding the device information of remote server.
534 /// Requests server for device information.
535 /// If succeeded, <see cref="DeviceInformationFound"/> event handler will be triggered with information of the device.\n
536 /// @a hostAddress could be <see cref="MulticastAddress"/> for IPv4 multicast.
539 /// http://tizen.org/privilege/internet
541 /// <param name="hostAddress">The host address of remote server</param>
542 /// <param name="query">The query specified as a filter for founding resources</param>
543 /// <returns>RequestId - An identifier for this request</returns>
544 /// <pre>Initialize() should be called to initialize.</pre>
546 /// <see cref="DeviceInformationFound" /> event handler will be invoked.
548 /// <seealso cref="IoTConnectivityServerManager.SetDeviceName()"/>
549 /// <seealso cref="DeviceInformationFound"/>
550 /// <seealso cref="DeviceInformationFoundEventArgs"/>
551 /// <seealso cref="TimeOut"/>
552 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
553 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
554 /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
555 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
557 /// EventHandler<DeviceInformationFoundEventArgs> handler = (sender, e) => {
558 /// Console.Log("Device information found, id : " + e.RequestId + ", name : " + e.Name);
560 /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
561 /// Console.Log("Found error :" + e.Error.Message);
563 /// IoTConnectivityClientManager.DeviceInformationFound += handler;
564 /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
565 /// // Do not forget to remove these event handlers when they are not required any more.
566 /// int id = IoTConnectivityClientManager.StartFindingDeviceInformation(IoTConnectivityClientManager.MulticastAddress);
568 public static int StartFindingDeviceInformation(string hostAddress, ResourceQuery query = null)
570 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
572 IntPtr id = IntPtr.Zero;
573 lock (s_deviceInformationCallbacksMap)
575 id = (IntPtr)s_requestId++;
577 s_deviceInformationCallbacksMap[id] = (IntPtr deviceInfoHandle, int result, IntPtr userData) =>
579 if (DeviceInformationFound == null)
582 int requestId = (int)userData;
583 if (result == (int)IoTConnectivityError.None)
585 if (deviceInfoHandle != IntPtr.Zero)
587 DeviceInformationFoundEventArgs e = GetDeviceInformationFoundEventArgs(requestId, deviceInfoHandle);
590 Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't get DeviceInformationFoundEventArgs");
593 DeviceInformationFound?.Invoke(null, e);
594 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.EventContinue : " + e.EventContinue);
595 return e.EventContinue;
599 Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
604 FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(requestId, result);
605 FindingErrorOccurred?.Invoke(null, e);
607 lock (s_deviceInformationCallbacksMap)
609 s_deviceInformationCallbacksMap.Remove(id);
615 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
616 int errorCode = Interop.IoTConnectivity.Client.DeviceInformation.Find(hostAddress, (int)connectivityType, queryHandle, s_deviceInformationCallbacksMap[id], id);
617 if (errorCode != (int)IoTConnectivityError.None)
619 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device information");
620 lock (s_deviceInformationCallbacksMap)
622 s_deviceInformationCallbacksMap.Remove(id);
624 throw IoTConnectivityErrorFactory.GetException(errorCode);
631 /// Starts finding the platform information of remote server.
634 /// Requests server for platform information.
635 /// If succeeded, <see cref="PlatformInformationFound" /> event handler will be triggered with information of the platform.\n
636 /// @a hostAddress could be <see cref="MulticastAddress"/> for IPv4 multicast.
639 /// http://tizen.org/privilege/internet
641 /// <param name="hostAddress">The host address of remote server</param>
642 /// <param name="query">The query specified as a filter for founding resources</param>
643 /// <returns>RequestId - An identifier for this request</returns>
644 /// <pre>Initialize() should be called to initialize.</pre>
646 /// <see cref="PlatformInformationFound" /> event handler will be invoked.
648 /// <seealso cref="PlatformInformationFound"/>
649 /// <seealso cref="PlatformInformationFoundEventArgs"/>
650 /// <seealso cref="TimeOut"/>
651 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
652 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
653 /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
654 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
656 /// EventHandler<PlatformInformationFoundEventArgs> handler = (sender, e) => {
657 /// Console.Log("PlatformInformationFound :" + e.RequestId);
659 /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
660 /// Console.Log("Found error :" + e.Error.Message);
662 /// IoTConnectivityClientManager.PlatformInformationFound += handler;
663 /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
664 /// // Do not forget to remove these event handlers when they are not required any more.
665 /// int id = IoTConnectivityClientManager.StartFindingPlatformInformation(IoTConnectivityClientManager.MulticastAddress);
667 public static int StartFindingPlatformInformation(string hostAddress, ResourceQuery query = null)
669 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
671 IntPtr id = IntPtr.Zero;
672 lock (s_platformInformationCallbacksMap)
674 id = (IntPtr)s_requestId++;
676 s_platformInformationCallbacksMap[id] = (IntPtr platformInfoHandle, int result, IntPtr userData) =>
678 if (PlatformInformationFound == null)
681 int requestId = (int)userData;
682 if (result == (int)IoTConnectivityError.None)
684 if (platformInfoHandle != IntPtr.Zero)
686 PlatformInformationFoundEventArgs e = GetPlatformInformationFoundEventArgs(requestId, platformInfoHandle);
689 Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't get PlatformInformationFoundEventArgs");
692 PlatformInformationFound?.Invoke(null, e);
693 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.EventContinue : " + e.EventContinue);
694 return e.EventContinue;
698 Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
703 FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(requestId, result);
704 FindingErrorOccurred?.Invoke(null, e);
706 lock (s_platformInformationCallbacksMap)
708 s_platformInformationCallbacksMap.Remove(id);
714 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
715 int errorCode = Interop.IoTConnectivity.Client.PlatformInformation.Find(hostAddress, (int)connectivityType, queryHandle, s_platformInformationCallbacksMap[id], id);
716 if (errorCode != (int)IoTConnectivityError.None)
718 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get platform information");
719 lock (s_platformInformationCallbacksMap)
721 s_platformInformationCallbacksMap.Remove(id);
723 throw IoTConnectivityErrorFactory.GetException(errorCode);
730 private static PresenceReceivedEventArgs GetPresenceReceivedEventArgs(int presenceId, IntPtr presenceResponseHandle)
735 int ret = Interop.IoTConnectivity.Client.PresenceResponse.GetHostAddress(presenceResponseHandle, out host);
736 if (ret != (int)IoTConnectivityError.None)
738 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get host address");
742 ret = Interop.IoTConnectivity.Client.PresenceResponse.GetResourceType(presenceResponseHandle, out type);
743 if (ret != (int)IoTConnectivityError.None)
745 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource type");
749 ret = Interop.IoTConnectivity.Client.PresenceResponse.GetTrigger(presenceResponseHandle, out trigger);
750 if (ret != (int)IoTConnectivityError.None)
752 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get event type");
756 PresenceReceivedEventArgs e = new PresenceReceivedEventArgs()
758 PresenceId = presenceId,
759 HostAddress = (host != IntPtr.Zero) ? Marshal.PtrToStringAnsi(host) : string.Empty,
760 Type = (type != IntPtr.Zero) ? Marshal.PtrToStringAnsi(type) : string.Empty,
761 EventType = (PresenceEventType)trigger
767 private static DeviceInformationFoundEventArgs GetDeviceInformationFoundEventArgs(int requestId, IntPtr deviceInfoHandle)
769 IntPtr name, specVersion, deviceId, dataModelVersion;
771 int ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.Name, out name);
772 if (ret != (int)IoTConnectivityError.None)
774 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get name");
778 ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.SpecVersion, out specVersion);
779 if (ret != (int)IoTConnectivityError.None)
781 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get spec version");
785 ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.Id, out deviceId);
786 if (ret != (int)IoTConnectivityError.None)
788 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device id");
792 ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.DataModelVersion, out dataModelVersion);
793 if (ret != (int)IoTConnectivityError.None)
795 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get data model version");
799 DeviceInformationFoundEventArgs e = new DeviceInformationFoundEventArgs()
801 RequestId = requestId,
802 EventContinue = true,
803 Name = (name != IntPtr.Zero) ? Marshal.PtrToStringAnsi(name) : string.Empty,
804 SpecVersion = (specVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(specVersion) : string.Empty,
805 DeviceId = (deviceId != IntPtr.Zero) ? Marshal.PtrToStringAnsi(deviceId) : string.Empty,
806 DataModelVersion = (dataModelVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(dataModelVersion) : string.Empty
812 private static PlatformInformationFoundEventArgs GetPlatformInformationFoundEventArgs(int requestId, IntPtr platformInfoHandle)
814 IntPtr platformId, manufacturerName, manufacturerUrl, modelNumber, dateOfManufacture, platformVersion, osVersion, hardwareVersion, firmwareVersion, supportUrl, systemTime;
816 int ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.Id, out platformId);
817 if (ret != (int)IoTConnectivityError.None)
819 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get platform id");
823 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.MfgName, out manufacturerName);
824 if (ret != (int)IoTConnectivityError.None)
826 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get manufacturer name");
830 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.MfgUrl, out manufacturerUrl);
831 if (ret != (int)IoTConnectivityError.None)
833 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get manufacturer url");
837 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.ModelNumber, out modelNumber);
838 if (ret != (int)IoTConnectivityError.None)
840 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get model number");
844 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.DateOfMfg, out dateOfManufacture);
845 if (ret != (int)IoTConnectivityError.None)
847 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get date of manufacture");
851 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.PlatformVer, out platformVersion);
852 if (ret != (int)IoTConnectivityError.None)
854 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get platform version");
858 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.OsVer, out osVersion);
859 if (ret != (int)IoTConnectivityError.None)
861 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to os version");
865 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.HardwareVer, out hardwareVersion);
866 if (ret != (int)IoTConnectivityError.None)
868 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to hardware version");
872 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.FirmwareVer, out firmwareVersion);
873 if (ret != (int)IoTConnectivityError.None)
875 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get firmware version");
879 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.SupportUrl, out supportUrl);
880 if (ret != (int)IoTConnectivityError.None)
882 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get support url");
886 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.SystemTime, out systemTime);
887 if (ret != (int)IoTConnectivityError.None)
889 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get system time");
893 PlatformInformationFoundEventArgs e = new PlatformInformationFoundEventArgs()
895 RequestId = requestId,
896 PlatformId = (platformId != IntPtr.Zero) ? Marshal.PtrToStringAnsi(platformId) : string.Empty,
897 ManufacturerName = (manufacturerName != IntPtr.Zero) ? Marshal.PtrToStringAnsi(manufacturerName) : string.Empty,
898 ManufacturerURL = (manufacturerUrl != IntPtr.Zero) ? Marshal.PtrToStringAnsi(manufacturerUrl) : string.Empty,
899 DateOfManufacture = (dateOfManufacture != IntPtr.Zero) ? Marshal.PtrToStringAnsi(dateOfManufacture) : string.Empty,
900 ModelNumber = (modelNumber != IntPtr.Zero) ? Marshal.PtrToStringAnsi(modelNumber) : string.Empty,
901 PlatformVersion = (platformVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(platformVersion) : string.Empty,
902 OsVersion = (osVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(osVersion) : string.Empty,
903 HardwareVersion = (hardwareVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(hardwareVersion) : string.Empty,
904 FirmwareVersion = (firmwareVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(firmwareVersion) : string.Empty,
905 SupportUrl = (supportUrl != IntPtr.Zero) ? Marshal.PtrToStringAnsi(supportUrl) : string.Empty,
906 SystemTime = (systemTime != IntPtr.Zero) ? Marshal.PtrToStringAnsi(systemTime) : string.Empty
912 private static FindingErrorOccurredEventArgs GetFindingErrorOccurredEventArgs(int requestId, int err)
914 FindingErrorOccurredEventArgs e = new FindingErrorOccurredEventArgs()
916 RequestId = requestId,
917 Error = IoTConnectivityErrorFactory.GetException(err)