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 /// <since_tizen> 3 </since_tizen>
27 public static class IoTConnectivityClientManager
30 /// The IP Address for multicast.
32 /// <since_tizen> 3 </since_tizen>
33 public const string MulticastAddress = null;
35 private static int s_presenceListenerId = 1;
36 private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.Presence.PresenceCallback> s_presenceCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.Presence.PresenceCallback>();
37 private static Dictionary<IntPtr, IntPtr> s_presenceHandlesMap = new Dictionary<IntPtr, IntPtr>();
39 private static int s_requestId = 1;
40 private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.ResourceFinder.FoundResourceCallback> s_resourceFoundCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.ResourceFinder.FoundResourceCallback>();
41 private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.DeviceInformation.DeviceInformationCallback> s_deviceInformationCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.DeviceInformation.DeviceInformationCallback>();
42 private static Dictionary<IntPtr, Interop.IoTConnectivity.Client.PlatformInformation.PlatformInformationCallback> s_platformInformationCallbacksMap = new Dictionary<IntPtr, Interop.IoTConnectivity.Client.PlatformInformation.PlatformInformationCallback>();
45 /// PresenceReceived event. This event occurs when server starts sending presence of a resource.
47 /// <since_tizen> 3 </since_tizen>
48 public static event EventHandler<PresenceReceivedEventArgs> PresenceReceived;
51 /// ResourceFound event. This event occurs when a resource is found from the remote server
52 /// after sending request using API StartFindingResource().
54 /// <since_tizen> 3 </since_tizen>
55 public static event EventHandler<ResourceFoundEventArgs> ResourceFound;
58 /// PlatformInformationFound event. This event occurs when platform information is found
59 /// after sending request using API StartFindingPlatformInformation().
61 /// <since_tizen> 3 </since_tizen>
62 public static event EventHandler<PlatformInformationFoundEventArgs> PlatformInformationFound;
65 /// DeviceInformationFound event. This event occurs when device information is found
66 /// after sending request using API StartFindingDeviceInformation().
68 /// <since_tizen> 3 </since_tizen>
69 public static event EventHandler<DeviceInformationFoundEventArgs> DeviceInformationFound;
72 /// FindingError event. This event occurs when an error is found.
74 /// <since_tizen> 3 </since_tizen>
75 public static event EventHandler<FindingErrorOccurredEventArgs> FindingErrorOccurred;
78 /// Timeout in seconds.
80 /// <since_tizen> 3 </since_tizen>
82 /// Value to be set must be in range from 1 to 3600. Default timeout interval value is 30.\n
83 /// Sets/gets the timeout of StartFindingResource(), StartFindingDeviceInformation(), StartFindingPlatformInformation(),
84 /// RemoteResource.GetAsync(), RemoteResource.PutAsync(), RemoteResource.PostAsync() and RemoteResource.DeleteAsync() APIs.\n
85 /// Setter can throw exception.
88 /// Initialize() should be called to initialize.
91 /// IoTConnectivityClientManager.Initialize();
92 /// IoTConnectivityClientManager.TimeOut = 120;
94 public static int TimeOut
99 int ret = Interop.IoTConnectivity.Client.IoTCon.GetTimeout(out timeout);
100 if (ret != (int)IoTConnectivityError.None)
102 Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get timeout");
109 int ret = Interop.IoTConnectivity.Client.IoTCon.SetTimeout(value);
110 if (ret != (int)IoTConnectivityError.None)
112 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set timeout");
113 throw IoTConnectivityErrorFactory.GetException(ret);
119 /// Polling interval of IoTConnectivity.
121 /// <since_tizen> 3 </since_tizen>
123 /// Sets/Gets the polling inerval(milliseconds) of IoTCon. Default value is 100 milliseconds.
124 /// Value to be set must be in range from 1 to 999. The closer to 0, the faster it operates.
125 /// Setter is invoked immediately for changing the interval.
126 /// If you want the faster operation, we recommend you set 10 milliseconds for polling interval.
127 /// Setter can throw exception.
130 /// Initialize() should be called to initialize.
133 /// IoTConnectivityClientManager.Initialize();
134 /// IoTConnectivityClientManager.PollingInterval = 100;
136 public static int PollingInterval
141 int ret = Interop.IoTConnectivity.Client.IoTCon.GetPollingInterval(out interval);
142 if (ret != (int)IoTConnectivityError.None)
144 Log.Warn(IoTConnectivityErrorFactory.LogTag, "Failed to get polling interval");
151 int ret = Interop.IoTConnectivity.Client.IoTCon.SetPollingInterval(value);
152 if (ret != (int)IoTConnectivityError.None)
154 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set polling interval");
155 throw IoTConnectivityErrorFactory.GetException(ret);
161 /// Initializes IoTCon.
162 /// Call this function to start IoTCon.
164 /// <since_tizen> 3 </since_tizen>
166 /// @a filePath point to a file for handling secure virtual resources.
167 /// The file that is CBOR(Concise Binary Object Representation)-format must already exist
168 /// in @a filePath. We recommend to use application-local file for @a filePath.
171 /// http://tizen.org/privilege/network.get \n
172 /// http://tizen.org/privilege/internet
174 /// <privlevel>public</privlevel>
175 /// <param name="filePath">The file path to point to storage for handling secure virtual resources.</param>
176 /// <feature>http://tizen.org/feature/iot.ocf</feature>
178 /// You must call Deinitialize() if IoTCon API is no longer needed.
180 /// <seealso cref="Deinitialize()"/>
181 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
182 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter.</exception>
183 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have privilege to access.</exception>
185 /// string filePath = "../../res/iotcon-test-svr-db-client.dat";
186 /// IoTConnectivityClientManager.Initialize(filePath);
188 public static void Initialize(string filePath)
190 int ret = Interop.IoTConnectivity.Client.IoTCon.Initialize(filePath);
191 if (ret != (int)IoTConnectivityError.None)
193 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to initialize");
194 throw IoTConnectivityErrorFactory.GetException(ret);
199 /// Deinitializes IoTCon.
201 /// <since_tizen> 3 </since_tizen>
203 /// This API must be called if IoTCon API is no longer needed.
205 /// <feature>http://tizen.org/feature/iot.ocf</feature>
207 /// Initialize() should be called to initialize.
209 /// <seealso cref="Initialize()"/>
210 /// <seealso cref="SecureInitialize()"/>
212 /// IoTConnectivityClientManager.Deinitialize();
214 public static void Deinitialize()
216 s_presenceListenerId = 1;
217 s_presenceCallbacksMap.Clear();
218 s_presenceHandlesMap.Clear();
221 s_resourceFoundCallbacksMap.Clear();
222 s_deviceInformationCallbacksMap.Clear();
223 s_platformInformationCallbacksMap.Clear();
225 PresenceReceived = delegate{};
226 ResourceFound = delegate{};
227 PlatformInformationFound = delegate{};
228 DeviceInformationFound = delegate{};
229 FindingErrorOccurred = delegate{};
231 Interop.IoTConnectivity.Client.IoTCon.Deinitialize();
235 /// Invokes a next message from a queue for receiving messages from others, immediately.
237 /// <since_tizen> 3 </since_tizen>
239 /// This API invokes a next message from a queue for receiving messages from others, immediately.
240 /// After calling the API, it continues the polling with existing interval.
242 /// <feature>http://tizen.org/feature/iot.ocf</feature>
244 /// Initialize() should be called to initialize.
246 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
248 /// IoTConnectivityClientManager.InvokePolling();
250 public static void InvokePolling()
252 int ret = Interop.IoTConnectivity.Client.IoTCon.InvokePolling();
253 if (ret != (int)IoTConnectivityError.None)
255 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to invoke polling");
256 throw IoTConnectivityErrorFactory.GetException(ret);
261 /// Starts receiving presence events.
263 /// <since_tizen> 3 </since_tizen>
265 /// Sends request to receive presence to an interested server's resource with resourceType.
266 /// If succeeded, <see cref="PresenceReceived"/> event handler will be triggered when the server sends presence.
267 /// A server sends presence events when adds / removes / alters a resource or start / stop presence.\n
268 /// @a hostAddress could be <see cref="MulticastAddress"/> for IPv4 multicast.
269 /// 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
270 /// of lowercase alphabetic, numeric, ".", or "-" characters, and contains no white space.
273 /// http://tizen.org/privilege/internet
275 /// <privlevel>public</privlevel>
276 /// <param name="hostAddress">The address or addressable name of the server.</param>
277 /// <param name="resourceType">A resource type that a client is interested in.</param>
278 /// <returns>PresenceId - An identifier for this request.</returns>
279 /// <feature>http://tizen.org/feature/iot.ocf</feature>
280 /// <pre>Initialize() should be called to initialize.</pre>
282 /// When the resource receive presence, <see cref="PresenceReceived"/> event handler will be invoked.\n
283 /// You must destroy presence by calling StopReceivingPresence() if presence event is no longer needed.
285 /// <seealso cref="IoTConnectivityServerManager.StartSendingPresence()"/>
286 /// <seealso cref="IoTConnectivityServerManager.StopSendingPresence()"/>
287 /// <seealso cref="StopReceivingPresence()"/>
288 /// <seealso cref="PresenceReceived"/>
289 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
290 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter.</exception>
291 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
292 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have privilege to access.</exception>
293 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory.</exception>
295 /// EventHandler<PresenceReceivedEventArgs> handler = (sender, e) => {
296 /// Console.Log("PresenceReceived, presence id :" + e.PresenceId);
298 /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
299 /// Console.Log("Found error :" + e.Error.Message);
301 /// IoTConnectivityClientManager.PresenceReceived += handler;
302 /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
303 /// // Do not forget to remove these event handlers when they are not required any more.
304 /// int id = IoTConnectivityClientManager.StartReceivingPresence(IoTConnectivityClientManager.MulticastAddress, "oic.iot.door");
306 public static int StartReceivingPresence(string hostAddress, string resourceType)
308 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
310 if (resourceType != null && !ResourceTypes.IsValid(resourceType))
312 Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid type");
313 throw new ArgumentException("Invalid type");
316 IntPtr id = IntPtr.Zero;
317 lock (s_presenceCallbacksMap)
319 id = (IntPtr)s_presenceListenerId++;
321 s_presenceCallbacksMap[id] = (IntPtr presence, int result, IntPtr presenceResponseHandle, IntPtr userData) =>
323 int presenceId = (int)userData;
324 if (result == (int)IoTConnectivityError.None)
326 if (presenceResponseHandle != IntPtr.Zero)
328 PresenceReceivedEventArgs e = GetPresenceReceivedEventArgs(presenceId, presenceResponseHandle);
331 Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't get PresenceReceivedEventArgs");
334 PresenceReceived?.Invoke(null, e);
338 Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
344 FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(presenceId, result);
345 FindingErrorOccurred?.Invoke(null, e);
349 IntPtr presenceHandle;
350 int errorCode = Interop.IoTConnectivity.Client.Presence.AddPresenceCb(hostAddress, (int)connectivityType, resourceType, s_presenceCallbacksMap[id], id, out presenceHandle);
351 if (errorCode != (int)IoTConnectivityError.None)
353 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to register presence event handler");
354 lock (s_presenceCallbacksMap)
356 s_presenceCallbacksMap.Remove(id);
358 throw IoTConnectivityErrorFactory.GetException(errorCode);
361 lock (s_presenceHandlesMap)
363 s_presenceHandlesMap[id] = presenceHandle;
369 /// Stops receiving presence events.
371 /// <since_tizen> 3 </since_tizen>
373 /// Sends request to not to receive server's presence any more.
376 /// http://tizen.org/privilege/internet
378 /// <privlevel>public</privlevel>
379 /// <param name="presenceId">The start presence request identifier.</param>
380 /// <feature>http://tizen.org/feature/iot.ocf</feature>
382 /// Initialize() should be called to initialize.
384 /// <seealso cref="IoTConnectivityServerManager.StartSendingPresence()"/>
385 /// <seealso cref="IoTConnectivityServerManager.StopSendingPresence()"/>
386 /// <seealso cref="StartReceivingPresence()"/>
387 /// <seealso cref="PresenceReceived"/>
388 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
389 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter.</exception>
390 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
391 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have privilege to access.</exception>
392 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory.</exception>
394 /// EventHandler<PresenceReceivedEventArgs> handler = (sender, e) => {
395 /// Console.Log("PresenceReceived, presence id :" + e.PresenceId);
397 /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
398 /// Console.Log("Found error :" + e.Error.Message);
400 /// IoTConnectivityClientManager.PresenceReceived += handler;
401 /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
402 /// int id = IoTConnectivityClientManager.StartReceivingPresence(IoTConnectivityClientManager.MulticastAddress, "oic.iot.door");
403 /// await Task.Delay(5000); // Do other things here
404 /// // Call StopReceivingPresence() when receiving presence is not required any more
405 /// IoTConnectivityClientManager.PresenceReceived -= handler;
406 /// IoTConnectivityClientManager.FindingErrorOccurred -= errorHandler;
407 /// IoTConnectivityClientManager.StopReceivingPresence(id);
409 public static void StopReceivingPresence(int presenceId)
411 if (!s_presenceHandlesMap.ContainsKey((IntPtr)presenceId))
413 Log.Error(IoTConnectivityErrorFactory.LogTag, "this presenceId does not exist");
414 throw new ArgumentException("this presenceId does not exist");
417 if (s_presenceHandlesMap.ContainsKey((IntPtr)presenceId))
419 IntPtr presenceHandle = s_presenceHandlesMap[(IntPtr)presenceId];
420 int ret = Interop.IoTConnectivity.Client.Presence.RemovePresenceCb(presenceHandle);
421 if (ret != (int)IoTConnectivityError.None)
423 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to deregister presence event handler");
424 throw IoTConnectivityErrorFactory.GetException(ret);
427 lock (s_presenceHandlesMap)
429 s_presenceHandlesMap.Remove((IntPtr)presenceId);
433 if (s_presenceCallbacksMap.ContainsKey((IntPtr)presenceId))
435 lock (s_presenceCallbacksMap)
437 s_presenceCallbacksMap.Remove((IntPtr)presenceId);
443 /// Starts finding resources.
445 /// <since_tizen> 3 </since_tizen>
447 /// Sends request to find a resource of @a hostAddress server with @a resourceType.
448 /// If succeeded, <see cref="ResourceFound"/> event handler will be triggered with information of the resource.\n
449 /// @a hostAddress could be <see cref="MulticastAddress"/> for the IPv4 multicast.
450 /// 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
451 /// of lowercase alphabetic, numeric, ".", or "-" characters, and contains no white space.
454 /// http://tizen.org/privilege/internet
456 /// <privlevel>public</privlevel>
457 /// <param name="hostAddress">The address or addressable name of the server. The address includes a protocol like coaps://.</param>
458 /// <param name="query">The query specified as a filter for founding resources.</param>
459 /// <returns>RequestId - An identifier for this request.</returns>
460 /// <feature>http://tizen.org/feature/iot.ocf</feature>
461 /// <pre>Initialize() should be called to initialize.</pre>
463 /// When the resource is found, <see cref="ResourceFound"/> event handler will be invoked.
465 /// <seealso cref="ResourceFound"/>
466 /// <seealso cref="ResourceFoundEventArgs"/>
467 /// <seealso cref="TimeOut"/>
468 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
469 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
470 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have privilege to access.</exception>
471 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory.</exception>
473 /// EventHandler<ResourceFoundEventArgs> handler = (sender, e) => {
474 /// Console.Log("Found resource at host address :" + e.Resource.HostAddress + ", uri :" + e.Resource.UriPath);
476 /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
477 /// Console.Log("Found error :" + e.Error.Message);
479 /// IoTConnectivityClientManager.ResourceFound += handler;
480 /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
481 /// ResourceQuery query = new ResourceQuery();
482 /// query.Type = "oic.iot.door";
483 /// // Do not forget to remove these event handlers when they are not required any more.
484 /// int id = IoTConnectivityClientManager.StartFindingResource(null, query);
486 public static int StartFindingResource(string hostAddress, ResourceQuery query = null)
488 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
490 IntPtr id = IntPtr.Zero;
491 lock (s_resourceFoundCallbacksMap)
493 id = (IntPtr)s_requestId++;
495 s_resourceFoundCallbacksMap[id] = (IntPtr remoteResourceHandle, int result, IntPtr userData) =>
497 if (ResourceFound == null)
500 int requestId = (int)userData;
501 if (result == (int)IoTConnectivityError.None)
503 if (remoteResourceHandle != IntPtr.Zero)
505 RemoteResource resource = null;
508 resource = new RemoteResource(remoteResourceHandle);
510 catch (Exception exp)
512 Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't clone RemoteResource's handle: " + exp.Message);
515 ResourceFoundEventArgs e = new ResourceFoundEventArgs()
517 RequestId = requestId,
520 ResourceFound?.Invoke(null, e);
521 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.EventContinue : " + e.EventContinue);
522 return e.EventContinue;
526 Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
531 FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(requestId, result);
532 FindingErrorOccurred?.Invoke(null, e);
534 lock (s_resourceFoundCallbacksMap)
536 s_resourceFoundCallbacksMap.Remove(id);
541 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
542 int errorCode = Interop.IoTConnectivity.Client.ResourceFinder.AddResourceFoundCb(hostAddress, (int)connectivityType, queryHandle, s_resourceFoundCallbacksMap[id], id);
543 if (errorCode != (int)IoTConnectivityError.None)
545 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to register resource found event handler");
546 lock (s_resourceFoundCallbacksMap)
548 s_resourceFoundCallbacksMap.Remove(id);
550 throw IoTConnectivityErrorFactory.GetException(errorCode);
556 /// Starts finding the device information of remote server.
558 /// <since_tizen> 3 </since_tizen>
560 /// Requests server for device information.
561 /// If succeeded, <see cref="DeviceInformationFound"/> event handler will be triggered with information of the device.\n
562 /// @a hostAddress could be <see cref="MulticastAddress"/> for the IPv4 multicast.
565 /// http://tizen.org/privilege/internet
567 /// <privlevel>public</privlevel>
568 /// <param name="hostAddress">The host address of the remote server.</param>
569 /// <param name="query">The query specified as a filter for founding resources.</param>
570 /// <returns>RequestId - An identifier for this request.</returns>
571 /// <feature>http://tizen.org/feature/iot.ocf</feature>
572 /// <pre>Initialize() should be called to initialize.</pre>
574 /// <see cref="DeviceInformationFound" /> event handler will be invoked.
576 /// <seealso cref="IoTConnectivityServerManager.SetDeviceName()"/>
577 /// <seealso cref="DeviceInformationFound"/>
578 /// <seealso cref="DeviceInformationFoundEventArgs"/>
579 /// <seealso cref="TimeOut"/>
580 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
581 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
582 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have privilege to access.</exception>
583 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory.</exception>
585 /// EventHandler<DeviceInformationFoundEventArgs> handler = (sender, e) => {
586 /// Console.Log("Device information found, id : " + e.RequestId + ", name : " + e.Name);
588 /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
589 /// Console.Log("Found error :" + e.Error.Message);
591 /// IoTConnectivityClientManager.DeviceInformationFound += handler;
592 /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
593 /// // Do not forget to remove these event handlers when they are not required any more.
594 /// int id = IoTConnectivityClientManager.StartFindingDeviceInformation(IoTConnectivityClientManager.MulticastAddress);
596 public static int StartFindingDeviceInformation(string hostAddress, ResourceQuery query = null)
598 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
600 IntPtr id = IntPtr.Zero;
601 lock (s_deviceInformationCallbacksMap)
603 id = (IntPtr)s_requestId++;
605 s_deviceInformationCallbacksMap[id] = (IntPtr deviceInfoHandle, int result, IntPtr userData) =>
607 if (DeviceInformationFound == null)
610 int requestId = (int)userData;
611 if (result == (int)IoTConnectivityError.None)
613 if (deviceInfoHandle != IntPtr.Zero)
615 DeviceInformationFoundEventArgs e = GetDeviceInformationFoundEventArgs(requestId, deviceInfoHandle);
618 Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't get DeviceInformationFoundEventArgs");
621 DeviceInformationFound?.Invoke(null, e);
622 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.EventContinue : " + e.EventContinue);
623 return e.EventContinue;
627 Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
632 FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(requestId, result);
633 FindingErrorOccurred?.Invoke(null, e);
635 lock (s_deviceInformationCallbacksMap)
637 s_deviceInformationCallbacksMap.Remove(id);
643 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
644 int errorCode = Interop.IoTConnectivity.Client.DeviceInformation.Find(hostAddress, (int)connectivityType, queryHandle, s_deviceInformationCallbacksMap[id], id);
645 if (errorCode != (int)IoTConnectivityError.None)
647 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device information");
648 lock (s_deviceInformationCallbacksMap)
650 s_deviceInformationCallbacksMap.Remove(id);
652 throw IoTConnectivityErrorFactory.GetException(errorCode);
659 /// Starts finding the platform information of remote server.
661 /// <since_tizen> 3 </since_tizen>
663 /// Requests server for platform information.
664 /// If succeeded, <see cref="PlatformInformationFound" /> event handler will be triggered with information of the platform.\n
665 /// @a hostAddress could be <see cref="MulticastAddress"/> for IPv4 multicast.
668 /// http://tizen.org/privilege/internet
670 /// <privlevel>public</privlevel>
671 /// <param name="hostAddress">The host address of remote server.</param>
672 /// <param name="query">The query specified as a filter for founding resources.</param>
673 /// <returns>RequestId - An identifier for this request.</returns>
674 /// <feature>http://tizen.org/feature/iot.ocf</feature>
675 /// <pre>Initialize() should be called to initialize.</pre>
677 /// <see cref="PlatformInformationFound" /> event handler will be invoked.
679 /// <seealso cref="PlatformInformationFound"/>
680 /// <seealso cref="PlatformInformationFoundEventArgs"/>
681 /// <seealso cref="TimeOut"/>
682 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
683 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
684 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have privilege to access.</exception>
685 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory.</exception>
687 /// EventHandler<PlatformInformationFoundEventArgs> handler = (sender, e) => {
688 /// Console.Log("PlatformInformationFound :" + e.RequestId);
690 /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
691 /// Console.Log("Found error :" + e.Error.Message);
693 /// IoTConnectivityClientManager.PlatformInformationFound += handler;
694 /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
695 /// // Do not forget to remove these event handlers when they are not required any more.
696 /// int id = IoTConnectivityClientManager.StartFindingPlatformInformation(IoTConnectivityClientManager.MulticastAddress);
698 public static int StartFindingPlatformInformation(string hostAddress, ResourceQuery query = null)
700 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
702 IntPtr id = IntPtr.Zero;
703 lock (s_platformInformationCallbacksMap)
705 id = (IntPtr)s_requestId++;
707 s_platformInformationCallbacksMap[id] = (IntPtr platformInfoHandle, int result, IntPtr userData) =>
709 if (PlatformInformationFound == null)
712 int requestId = (int)userData;
713 if (result == (int)IoTConnectivityError.None)
715 if (platformInfoHandle != IntPtr.Zero)
717 PlatformInformationFoundEventArgs e = GetPlatformInformationFoundEventArgs(requestId, platformInfoHandle);
720 Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't get PlatformInformationFoundEventArgs");
723 PlatformInformationFound?.Invoke(null, e);
724 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.EventContinue : " + e.EventContinue);
725 return e.EventContinue;
729 Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
734 FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(requestId, result);
735 FindingErrorOccurred?.Invoke(null, e);
737 lock (s_platformInformationCallbacksMap)
739 s_platformInformationCallbacksMap.Remove(id);
745 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
746 int errorCode = Interop.IoTConnectivity.Client.PlatformInformation.Find(hostAddress, (int)connectivityType, queryHandle, s_platformInformationCallbacksMap[id], id);
747 if (errorCode != (int)IoTConnectivityError.None)
749 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get platform information");
750 lock (s_platformInformationCallbacksMap)
752 s_platformInformationCallbacksMap.Remove(id);
754 throw IoTConnectivityErrorFactory.GetException(errorCode);
761 private static PresenceReceivedEventArgs GetPresenceReceivedEventArgs(int presenceId, IntPtr presenceResponseHandle)
766 int ret = Interop.IoTConnectivity.Client.PresenceResponse.GetHostAddress(presenceResponseHandle, out host);
767 if (ret != (int)IoTConnectivityError.None)
769 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get host address");
773 ret = Interop.IoTConnectivity.Client.PresenceResponse.GetResourceType(presenceResponseHandle, out type);
774 if (ret != (int)IoTConnectivityError.None)
776 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource type");
780 ret = Interop.IoTConnectivity.Client.PresenceResponse.GetTrigger(presenceResponseHandle, out trigger);
781 if (ret != (int)IoTConnectivityError.None)
783 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get event type");
787 PresenceReceivedEventArgs e = new PresenceReceivedEventArgs()
789 PresenceId = presenceId,
790 HostAddress = (host != IntPtr.Zero) ? Marshal.PtrToStringAnsi(host) : string.Empty,
791 Type = (type != IntPtr.Zero) ? Marshal.PtrToStringAnsi(type) : string.Empty,
792 EventType = (PresenceEventType)trigger
798 private static DeviceInformationFoundEventArgs GetDeviceInformationFoundEventArgs(int requestId, IntPtr deviceInfoHandle)
800 IntPtr name, specVersion, deviceId, dataModelVersion;
802 int ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.Name, out name);
803 if (ret != (int)IoTConnectivityError.None)
805 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get name");
809 ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.SpecVersion, out specVersion);
810 if (ret != (int)IoTConnectivityError.None)
812 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get spec version");
816 ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.Id, out deviceId);
817 if (ret != (int)IoTConnectivityError.None)
819 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device id");
823 ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.DataModelVersion, out dataModelVersion);
824 if (ret != (int)IoTConnectivityError.None)
826 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get data model version");
830 DeviceInformationFoundEventArgs e = new DeviceInformationFoundEventArgs()
832 RequestId = requestId,
833 EventContinue = true,
834 Name = (name != IntPtr.Zero) ? Marshal.PtrToStringAnsi(name) : string.Empty,
835 SpecVersion = (specVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(specVersion) : string.Empty,
836 DeviceId = (deviceId != IntPtr.Zero) ? Marshal.PtrToStringAnsi(deviceId) : string.Empty,
837 DataModelVersion = (dataModelVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(dataModelVersion) : string.Empty
843 private static PlatformInformationFoundEventArgs GetPlatformInformationFoundEventArgs(int requestId, IntPtr platformInfoHandle)
845 IntPtr platformId, manufacturerName, manufacturerUrl, modelNumber, dateOfManufacture, platformVersion, osVersion, hardwareVersion, firmwareVersion, supportUrl, systemTime;
847 int ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.Id, out platformId);
848 if (ret != (int)IoTConnectivityError.None)
850 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get platform id");
854 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.MfgName, out manufacturerName);
855 if (ret != (int)IoTConnectivityError.None)
857 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get manufacturer name");
861 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.MfgUrl, out manufacturerUrl);
862 if (ret != (int)IoTConnectivityError.None)
864 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get manufacturer url");
868 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.ModelNumber, out modelNumber);
869 if (ret != (int)IoTConnectivityError.None)
871 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get model number");
875 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.DateOfMfg, out dateOfManufacture);
876 if (ret != (int)IoTConnectivityError.None)
878 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get date of manufacture");
882 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.PlatformVer, out platformVersion);
883 if (ret != (int)IoTConnectivityError.None)
885 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get platform version");
889 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.OsVer, out osVersion);
890 if (ret != (int)IoTConnectivityError.None)
892 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to os version");
896 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.HardwareVer, out hardwareVersion);
897 if (ret != (int)IoTConnectivityError.None)
899 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to hardware version");
903 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.FirmwareVer, out firmwareVersion);
904 if (ret != (int)IoTConnectivityError.None)
906 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get firmware version");
910 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.SupportUrl, out supportUrl);
911 if (ret != (int)IoTConnectivityError.None)
913 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get support url");
917 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.SystemTime, out systemTime);
918 if (ret != (int)IoTConnectivityError.None)
920 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get system time");
924 PlatformInformationFoundEventArgs e = new PlatformInformationFoundEventArgs()
926 RequestId = requestId,
927 PlatformId = (platformId != IntPtr.Zero) ? Marshal.PtrToStringAnsi(platformId) : string.Empty,
928 ManufacturerName = (manufacturerName != IntPtr.Zero) ? Marshal.PtrToStringAnsi(manufacturerName) : string.Empty,
929 ManufacturerURL = (manufacturerUrl != IntPtr.Zero) ? Marshal.PtrToStringAnsi(manufacturerUrl) : string.Empty,
930 DateOfManufacture = (dateOfManufacture != IntPtr.Zero) ? Marshal.PtrToStringAnsi(dateOfManufacture) : string.Empty,
931 ModelNumber = (modelNumber != IntPtr.Zero) ? Marshal.PtrToStringAnsi(modelNumber) : string.Empty,
932 PlatformVersion = (platformVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(platformVersion) : string.Empty,
933 OsVersion = (osVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(osVersion) : string.Empty,
934 HardwareVersion = (hardwareVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(hardwareVersion) : string.Empty,
935 FirmwareVersion = (firmwareVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(firmwareVersion) : string.Empty,
936 SupportUrl = (supportUrl != IntPtr.Zero) ? Marshal.PtrToStringAnsi(supportUrl) : string.Empty,
937 SystemTime = (systemTime != IntPtr.Zero) ? Marshal.PtrToStringAnsi(systemTime) : string.Empty
940 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.RequestId is " + e.RequestId);
941 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.PlatformId is " + e.PlatformId);
942 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.ManufacturerName is " + e.ManufacturerName);
943 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.ManufacturerURL is " + e.ManufacturerURL);
944 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.DateOfManufacture is " + e.DateOfManufacture);
945 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.ModelNumber is " + e.ModelNumber);
946 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.PlatformVersion is " + e.PlatformVersion);
947 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.OsVersion is " + e.OsVersion);
948 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.HardwareVersion is " + e.HardwareVersion);
949 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.FirmwareVersion is " + e.FirmwareVersion);
950 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.SupportUrl is " + e.SupportUrl);
951 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.SystemTime is " + e.SystemTime);
956 private static FindingErrorOccurredEventArgs GetFindingErrorOccurredEventArgs(int requestId, int err)
958 FindingErrorOccurredEventArgs e = new FindingErrorOccurredEventArgs()
960 RequestId = requestId,
961 Error = IoTConnectivityErrorFactory.GetException(err)