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 IntPtr presenceHandle = s_presenceHandlesMap[(IntPtr)presenceId];
392 int ret = Interop.IoTConnectivity.Client.Presence.RemovePresenceCb(presenceHandle);
393 if (ret != (int)IoTConnectivityError.None)
395 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to deregister presence event handler");
396 throw IoTConnectivityErrorFactory.GetException(ret);
399 lock (s_presenceHandlesMap)
401 s_presenceHandlesMap.Remove((IntPtr)presenceId);
405 if (s_presenceCallbacksMap.ContainsKey((IntPtr)presenceId))
407 lock (s_presenceCallbacksMap)
409 s_presenceCallbacksMap.Remove((IntPtr)presenceId);
415 /// Starts finding resources.
418 /// Sends request to find a resource of @a hostAddress server with @a resourceType.
419 /// If succeeded, <see cref="ResourceFound"/> event handler will be triggered with information of the resource.\n
420 /// @a hostAddress could be <see cref="MulticastAddress"/> for IPv4 multicast.
421 /// 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
422 /// of lowercase alphabetic, numeric, ".", or "-" characters, and contains no white space.
425 /// http://tizen.org/privilege/internet
427 /// <param name="hostAddress">The address or addressable name of the server. The address includes a protocol like coaps://</param>
428 /// <param name="query">The query specified as a filter for founding resources</param>
429 /// <returns>RequestId - An identifier for this request</returns>
430 /// <pre>Initialize() should be called to initialize.</pre>
432 /// When the resource is found, <see cref="ResourceFound"/> event handler will be invoked.
434 /// <seealso cref="ResourceFound"/>
435 /// <seealso cref="ResourceFoundEventArgs"/>
436 /// <seealso cref="TimeOut"/>
437 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
438 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
439 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
440 /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
441 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
443 /// EventHandler<ResourceFoundEventArgs> handler = (sender, e) => {
444 /// Console.Log("Found resource at host address :" + e.Resource.HostAddress + ", uri :" + e.Resource.UriPath);
446 /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
447 /// Console.Log("Found error :" + e.Error.Message);
449 /// IoTConnectivityClientManager.ResourceFound += handler;
450 /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
451 /// ResourceQuery query = new ResourceQuery();
452 /// query.Type = "oic.iot.door";
453 /// // Do not forget to remove these event handlers when they are not required any more.
454 /// int id = IoTConnectivityClientManager.StartFindingResource(null, query);
456 public static int StartFindingResource(string hostAddress, ResourceQuery query = null)
458 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
460 IntPtr id = IntPtr.Zero;
461 lock (s_resourceFoundCallbacksMap)
463 id = (IntPtr)s_requestId++;
465 s_resourceFoundCallbacksMap[id] = (IntPtr remoteResourceHandle, int result, IntPtr userData) =>
467 if (ResourceFound == null)
470 int requestId = (int)userData;
471 if (result == (int)IoTConnectivityError.None)
473 if (remoteResourceHandle != IntPtr.Zero)
475 RemoteResource resource = null;
478 resource = new RemoteResource(remoteResourceHandle);
480 catch (Exception exp)
482 Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't clone RemoteResource's handle: " + exp.Message);
485 ResourceFoundEventArgs e = new ResourceFoundEventArgs()
487 RequestId = requestId,
490 ResourceFound?.Invoke(null, e);
494 Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
499 FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(requestId, result);
500 FindingErrorOccurred?.Invoke(null, e);
502 lock (s_resourceFoundCallbacksMap)
504 s_resourceFoundCallbacksMap.Remove(id);
509 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
510 int errorCode = Interop.IoTConnectivity.Client.ResourceFinder.AddResourceFoundCb(hostAddress, (int)connectivityType, queryHandle, s_resourceFoundCallbacksMap[id], id);
511 if (errorCode != (int)IoTConnectivityError.None)
513 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to register resource found event handler");
514 lock (s_resourceFoundCallbacksMap)
516 s_resourceFoundCallbacksMap.Remove(id);
518 throw IoTConnectivityErrorFactory.GetException(errorCode);
524 /// Starts finding the device information of remote server.
527 /// Requests server for device information.
528 /// If succeeded, <see cref="DeviceInformationFound"/> event handler will be triggered with information of the device.\n
529 /// @a hostAddress could be <see cref="MulticastAddress"/> for IPv4 multicast.
532 /// http://tizen.org/privilege/internet
534 /// <param name="hostAddress">The host address of remote server</param>
535 /// <param name="query">The query specified as a filter for founding resources</param>
536 /// <returns>RequestId - An identifier for this request</returns>
537 /// <pre>Initialize() should be called to initialize.</pre>
539 /// <see cref="DeviceInformationFound" /> event handler will be invoked.
541 /// <seealso cref="IoTConnectivityServerManager.SetDeviceName()"/>
542 /// <seealso cref="DeviceInformationFound"/>
543 /// <seealso cref="DeviceInformationFoundEventArgs"/>
544 /// <seealso cref="TimeOut"/>
545 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
546 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
547 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
548 /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
549 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
551 /// EventHandler<DeviceInformationFoundEventArgs> handler = (sender, e) => {
552 /// Console.Log("Device information found, id : " + e.RequestId + ", name : " + e.Name);
554 /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
555 /// Console.Log("Found error :" + e.Error.Message);
557 /// IoTConnectivityClientManager.DeviceInformationFound += handler;
558 /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
559 /// // Do not forget to remove these event handlers when they are not required any more.
560 /// int id = IoTConnectivityClientManager.StartFindingDeviceInformation(IoTConnectivityClientManager.MulticastAddress);
562 public static int StartFindingDeviceInformation(string hostAddress, ResourceQuery query = null)
564 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
566 IntPtr id = IntPtr.Zero;
567 lock (s_deviceInformationCallbacksMap)
569 id = (IntPtr)s_requestId++;
571 s_deviceInformationCallbacksMap[id] = (IntPtr deviceInfoHandle, int result, IntPtr userData) =>
573 if (DeviceInformationFound == null)
576 int requestId = (int)userData;
577 if (result == (int)IoTConnectivityError.None)
579 if (deviceInfoHandle != IntPtr.Zero)
581 DeviceInformationFoundEventArgs e = GetDeviceInformationFoundEventArgs(requestId, deviceInfoHandle);
584 Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't get DeviceInformationFoundEventArgs");
587 DeviceInformationFound?.Invoke(null, e);
591 Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
596 FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(requestId, result);
597 FindingErrorOccurred?.Invoke(null, e);
599 lock (s_deviceInformationCallbacksMap)
601 s_deviceInformationCallbacksMap.Remove(id);
607 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
608 int errorCode = Interop.IoTConnectivity.Client.DeviceInformation.Find(hostAddress, (int)connectivityType, queryHandle, s_deviceInformationCallbacksMap[id], id);
609 if (errorCode != (int)IoTConnectivityError.None)
611 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device information");
612 lock (s_deviceInformationCallbacksMap)
614 s_deviceInformationCallbacksMap.Remove(id);
616 throw IoTConnectivityErrorFactory.GetException(errorCode);
623 /// Starts finding the platform information of remote server.
626 /// Requests server for platform information.
627 /// If succeeded, <see cref="PlatformInformationFound" /> event handler will be triggered with information of the platform.\n
628 /// @a hostAddress could be <see cref="MulticastAddress"/> for IPv4 multicast.
631 /// http://tizen.org/privilege/internet
633 /// <param name="hostAddress">The host address of remote server</param>
634 /// <param name="query">The query specified as a filter for founding resources</param>
635 /// <returns>RequestId - An identifier for this request</returns>
636 /// <pre>Initialize() should be called to initialize.</pre>
638 /// <see cref="PlatformInformationFound" /> event handler will be invoked.
640 /// <seealso cref="PlatformInformationFound"/>
641 /// <seealso cref="PlatformInformationFoundEventArgs"/>
642 /// <seealso cref="TimeOut"/>
643 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
644 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
645 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
646 /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access</exception>
647 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
649 /// EventHandler<PlatformInformationFoundEventArgs> handler = (sender, e) => {
650 /// Console.Log("PlatformInformationFound :" + e.RequestId);
652 /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
653 /// Console.Log("Found error :" + e.Error.Message);
655 /// IoTConnectivityClientManager.PlatformInformationFound += handler;
656 /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
657 /// // Do not forget to remove these event handlers when they are not required any more.
658 /// int id = IoTConnectivityClientManager.StartFindingPlatformInformation(IoTConnectivityClientManager.MulticastAddress);
660 public static int StartFindingPlatformInformation(string hostAddress, ResourceQuery query = null)
662 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
664 IntPtr id = IntPtr.Zero;
665 lock (s_platformInformationCallbacksMap)
667 id = (IntPtr)s_requestId++;
669 s_platformInformationCallbacksMap[id] = (IntPtr platformInfoHandle, int result, IntPtr userData) =>
671 if (PlatformInformationFound == null)
674 int requestId = (int)userData;
675 if (result == (int)IoTConnectivityError.None)
677 if (platformInfoHandle != IntPtr.Zero)
679 PlatformInformationFoundEventArgs e = GetPlatformInformationFoundEventArgs(requestId, platformInfoHandle);
682 Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't get PlatformInformationFoundEventArgs");
685 PlatformInformationFound?.Invoke(null, e);
689 Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
694 FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(requestId, result);
695 FindingErrorOccurred?.Invoke(null, e);
697 lock (s_platformInformationCallbacksMap)
699 s_platformInformationCallbacksMap.Remove(id);
705 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
706 int errorCode = Interop.IoTConnectivity.Client.PlatformInformation.Find(hostAddress, (int)connectivityType, queryHandle, s_platformInformationCallbacksMap[id], id);
707 if (errorCode != (int)IoTConnectivityError.None)
709 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get platform information");
710 lock (s_platformInformationCallbacksMap)
712 s_platformInformationCallbacksMap.Remove(id);
714 throw IoTConnectivityErrorFactory.GetException(errorCode);
721 private static PresenceReceivedEventArgs GetPresenceReceivedEventArgs(int presenceId, IntPtr presenceResponseHandle)
726 int ret = Interop.IoTConnectivity.Client.PresenceResponse.GetHostAddress(presenceResponseHandle, out host);
727 if (ret != (int)IoTConnectivityError.None)
729 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get host address");
733 ret = Interop.IoTConnectivity.Client.PresenceResponse.GetResourceType(presenceResponseHandle, out type);
734 if (ret != (int)IoTConnectivityError.None)
736 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource type");
740 ret = Interop.IoTConnectivity.Client.PresenceResponse.GetTrigger(presenceResponseHandle, out trigger);
741 if (ret != (int)IoTConnectivityError.None)
743 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get event type");
747 PresenceReceivedEventArgs e = new PresenceReceivedEventArgs()
749 PresenceId = presenceId,
750 HostAddress = Marshal.PtrToStringAnsi(host),
751 Type = Marshal.PtrToStringAnsi(type),
752 EventType = (PresenceEventType)trigger
758 private static DeviceInformationFoundEventArgs GetDeviceInformationFoundEventArgs(int requestId, IntPtr deviceInfoHandle)
760 IntPtr name, specVersion, deviceId, dataModelVersion;
762 int ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.Name, out name);
763 if (ret != (int)IoTConnectivityError.None)
765 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get name");
769 ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.SpecVersion, out specVersion);
770 if (ret != (int)IoTConnectivityError.None)
772 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get spec version");
776 ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.Id, out deviceId);
777 if (ret != (int)IoTConnectivityError.None)
779 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device id");
783 ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.DataModelVersion, out dataModelVersion);
784 if (ret != (int)IoTConnectivityError.None)
786 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get data model version");
790 DeviceInformationFoundEventArgs e = new DeviceInformationFoundEventArgs()
792 RequestId = requestId,
793 Name = Marshal.PtrToStringAnsi(name),
794 SpecVersion = Marshal.PtrToStringAnsi(specVersion),
795 DeviceId = Marshal.PtrToStringAnsi(deviceId),
796 DataModelVersion = Marshal.PtrToStringAnsi(dataModelVersion)
802 private static PlatformInformationFoundEventArgs GetPlatformInformationFoundEventArgs(int requestId, IntPtr platformInfoHandle)
804 IntPtr platformId, manufacturerName, manufacturerUrl, modelNumber, dateOfManufacture, platformVersion, osVersion, hardwareVersion, firmwareVersion, supportUrl, systemTime;
806 int ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.Id, out platformId);
807 if (ret != (int)IoTConnectivityError.None)
809 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get platform id");
813 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.MfgName, out manufacturerName);
814 if (ret != (int)IoTConnectivityError.None)
816 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get manufacturer name");
820 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.MfgUrl, out manufacturerUrl);
821 if (ret != (int)IoTConnectivityError.None)
823 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get manufacturer url");
827 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.ModelNumber, out modelNumber);
828 if (ret != (int)IoTConnectivityError.None)
830 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get model number");
834 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.DateOfMfg, out dateOfManufacture);
835 if (ret != (int)IoTConnectivityError.None)
837 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get date of manufacture");
841 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.PlatformVer, out platformVersion);
842 if (ret != (int)IoTConnectivityError.None)
844 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get platform version");
848 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.OsVer, out osVersion);
849 if (ret != (int)IoTConnectivityError.None)
851 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to os version");
855 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.HardwareVer, out hardwareVersion);
856 if (ret != (int)IoTConnectivityError.None)
858 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to hardware version");
862 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.FirmwareVer, out firmwareVersion);
863 if (ret != (int)IoTConnectivityError.None)
865 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get firmware version");
869 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.SupportUrl, out supportUrl);
870 if (ret != (int)IoTConnectivityError.None)
872 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get support url");
876 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.SystemTime, out systemTime);
877 if (ret != (int)IoTConnectivityError.None)
879 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get system time");
883 PlatformInformationFoundEventArgs e = new PlatformInformationFoundEventArgs()
885 RequestId = requestId,
886 PlatformId = (platformId != IntPtr.Zero) ? Marshal.PtrToStringAnsi(platformId) : string.Empty,
887 ManufacturerName = (manufacturerName != IntPtr.Zero) ? Marshal.PtrToStringAnsi(manufacturerName) : string.Empty,
888 ManufacturerURL = (manufacturerUrl != IntPtr.Zero) ? Marshal.PtrToStringAnsi(manufacturerUrl) : string.Empty,
889 DateOfManufacture = (dateOfManufacture != IntPtr.Zero) ? Marshal.PtrToStringAnsi(dateOfManufacture) : string.Empty,
890 ModelNumber = (modelNumber != IntPtr.Zero) ? Marshal.PtrToStringAnsi(modelNumber) : string.Empty,
891 PlatformVersion = (platformVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(platformVersion) : string.Empty,
892 OsVersion = (osVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(osVersion) : string.Empty,
893 HardwareVersion = (hardwareVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(hardwareVersion) : string.Empty,
894 FirmwareVersion = (firmwareVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(firmwareVersion) : string.Empty,
895 SupportUrl = (supportUrl != IntPtr.Zero) ? Marshal.PtrToStringAnsi(supportUrl) : string.Empty,
896 SystemTime = (systemTime != IntPtr.Zero) ? Marshal.PtrToStringAnsi(systemTime) : string.Empty
902 private static FindingErrorOccurredEventArgs GetFindingErrorOccurredEventArgs(int requestId, int err)
904 FindingErrorOccurredEventArgs e = new FindingErrorOccurredEventArgs()
906 RequestId = requestId,
907 Error = IoTConnectivityErrorFactory.GetException(err)