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,
518 EventContinue = true,
521 ResourceFound?.Invoke(null, e);
522 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.EventContinue : " + e.EventContinue);
523 return e.EventContinue;
527 Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
532 FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(requestId, result);
533 FindingErrorOccurred?.Invoke(null, e);
535 lock (s_resourceFoundCallbacksMap)
537 s_resourceFoundCallbacksMap.Remove(id);
542 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
543 int errorCode = Interop.IoTConnectivity.Client.ResourceFinder.AddResourceFoundCb(hostAddress, (int)connectivityType, queryHandle, s_resourceFoundCallbacksMap[id], id);
544 if (errorCode != (int)IoTConnectivityError.None)
546 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to register resource found event handler");
547 lock (s_resourceFoundCallbacksMap)
549 s_resourceFoundCallbacksMap.Remove(id);
551 throw IoTConnectivityErrorFactory.GetException(errorCode);
557 /// Starts finding the device information of remote server.
559 /// <since_tizen> 3 </since_tizen>
561 /// Requests server for device information.
562 /// If succeeded, <see cref="DeviceInformationFound"/> event handler will be triggered with information of the device.\n
563 /// @a hostAddress could be <see cref="MulticastAddress"/> for the IPv4 multicast.
566 /// http://tizen.org/privilege/internet
568 /// <privlevel>public</privlevel>
569 /// <param name="hostAddress">The host address of the remote server.</param>
570 /// <param name="query">The query specified as a filter for founding resources.</param>
571 /// <returns>RequestId - An identifier for this request.</returns>
572 /// <feature>http://tizen.org/feature/iot.ocf</feature>
573 /// <pre>Initialize() should be called to initialize.</pre>
575 /// <see cref="DeviceInformationFound" /> event handler will be invoked.
577 /// <seealso cref="IoTConnectivityServerManager.SetDeviceName()"/>
578 /// <seealso cref="DeviceInformationFound"/>
579 /// <seealso cref="DeviceInformationFoundEventArgs"/>
580 /// <seealso cref="TimeOut"/>
581 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
582 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
583 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have privilege to access.</exception>
584 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory.</exception>
586 /// EventHandler<DeviceInformationFoundEventArgs> handler = (sender, e) => {
587 /// Console.Log("Device information found, id : " + e.RequestId + ", name : " + e.Name);
589 /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
590 /// Console.Log("Found error :" + e.Error.Message);
592 /// IoTConnectivityClientManager.DeviceInformationFound += handler;
593 /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
594 /// // Do not forget to remove these event handlers when they are not required any more.
595 /// int id = IoTConnectivityClientManager.StartFindingDeviceInformation(IoTConnectivityClientManager.MulticastAddress);
597 public static int StartFindingDeviceInformation(string hostAddress, ResourceQuery query = null)
599 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
601 IntPtr id = IntPtr.Zero;
602 lock (s_deviceInformationCallbacksMap)
604 id = (IntPtr)s_requestId++;
606 s_deviceInformationCallbacksMap[id] = (IntPtr deviceInfoHandle, int result, IntPtr userData) =>
608 if (DeviceInformationFound == null)
611 int requestId = (int)userData;
612 if (result == (int)IoTConnectivityError.None)
614 if (deviceInfoHandle != IntPtr.Zero)
616 DeviceInformationFoundEventArgs e = GetDeviceInformationFoundEventArgs(requestId, deviceInfoHandle);
619 Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't get DeviceInformationFoundEventArgs");
622 DeviceInformationFound?.Invoke(null, e);
623 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.EventContinue : " + e.EventContinue);
624 return e.EventContinue;
628 Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
633 FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(requestId, result);
634 FindingErrorOccurred?.Invoke(null, e);
636 lock (s_deviceInformationCallbacksMap)
638 s_deviceInformationCallbacksMap.Remove(id);
644 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
645 int errorCode = Interop.IoTConnectivity.Client.DeviceInformation.Find(hostAddress, (int)connectivityType, queryHandle, s_deviceInformationCallbacksMap[id], id);
646 if (errorCode != (int)IoTConnectivityError.None)
648 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device information");
649 lock (s_deviceInformationCallbacksMap)
651 s_deviceInformationCallbacksMap.Remove(id);
653 throw IoTConnectivityErrorFactory.GetException(errorCode);
660 /// Starts finding the platform information of remote server.
662 /// <since_tizen> 3 </since_tizen>
664 /// Requests server for platform information.
665 /// If succeeded, <see cref="PlatformInformationFound" /> event handler will be triggered with information of the platform.\n
666 /// @a hostAddress could be <see cref="MulticastAddress"/> for IPv4 multicast.
669 /// http://tizen.org/privilege/internet
671 /// <privlevel>public</privlevel>
672 /// <param name="hostAddress">The host address of remote server.</param>
673 /// <param name="query">The query specified as a filter for founding resources.</param>
674 /// <returns>RequestId - An identifier for this request.</returns>
675 /// <feature>http://tizen.org/feature/iot.ocf</feature>
676 /// <pre>Initialize() should be called to initialize.</pre>
678 /// <see cref="PlatformInformationFound" /> event handler will be invoked.
680 /// <seealso cref="PlatformInformationFound"/>
681 /// <seealso cref="PlatformInformationFoundEventArgs"/>
682 /// <seealso cref="TimeOut"/>
683 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
684 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
685 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have privilege to access.</exception>
686 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory.</exception>
688 /// EventHandler<PlatformInformationFoundEventArgs> handler = (sender, e) => {
689 /// Console.Log("PlatformInformationFound :" + e.RequestId);
691 /// EventHandler<FindingErrorOccurredEventArgs> errorHandler = (sender, e) => {
692 /// Console.Log("Found error :" + e.Error.Message);
694 /// IoTConnectivityClientManager.PlatformInformationFound += handler;
695 /// IoTConnectivityClientManager.FindingErrorOccurred += errorHandler;
696 /// // Do not forget to remove these event handlers when they are not required any more.
697 /// int id = IoTConnectivityClientManager.StartFindingPlatformInformation(IoTConnectivityClientManager.MulticastAddress);
699 public static int StartFindingPlatformInformation(string hostAddress, ResourceQuery query = null)
701 Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType connectivityType = Interop.IoTConnectivity.Client.RemoteResource.ConnectivityType.Ip;
703 IntPtr id = IntPtr.Zero;
704 lock (s_platformInformationCallbacksMap)
706 id = (IntPtr)s_requestId++;
708 s_platformInformationCallbacksMap[id] = (IntPtr platformInfoHandle, int result, IntPtr userData) =>
710 if (PlatformInformationFound == null)
713 int requestId = (int)userData;
714 if (result == (int)IoTConnectivityError.None)
716 if (platformInfoHandle != IntPtr.Zero)
718 PlatformInformationFoundEventArgs e = GetPlatformInformationFoundEventArgs(requestId, platformInfoHandle);
721 Log.Error(IoTConnectivityErrorFactory.LogTag, "Can't get PlatformInformationFoundEventArgs");
724 PlatformInformationFound?.Invoke(null, e);
725 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.EventContinue : " + e.EventContinue);
726 return e.EventContinue;
730 Log.Error(IoTConnectivityErrorFactory.LogTag, "Handle is null");
735 FindingErrorOccurredEventArgs e = GetFindingErrorOccurredEventArgs(requestId, result);
736 FindingErrorOccurred?.Invoke(null, e);
738 lock (s_platformInformationCallbacksMap)
740 s_platformInformationCallbacksMap.Remove(id);
746 IntPtr queryHandle = (query == null) ? IntPtr.Zero : query._resourceQueryHandle;
747 int errorCode = Interop.IoTConnectivity.Client.PlatformInformation.Find(hostAddress, (int)connectivityType, queryHandle, s_platformInformationCallbacksMap[id], id);
748 if (errorCode != (int)IoTConnectivityError.None)
750 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get platform information");
751 lock (s_platformInformationCallbacksMap)
753 s_platformInformationCallbacksMap.Remove(id);
755 throw IoTConnectivityErrorFactory.GetException(errorCode);
762 private static PresenceReceivedEventArgs GetPresenceReceivedEventArgs(int presenceId, IntPtr presenceResponseHandle)
767 int ret = Interop.IoTConnectivity.Client.PresenceResponse.GetHostAddress(presenceResponseHandle, out host);
768 if (ret != (int)IoTConnectivityError.None)
770 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get host address");
774 ret = Interop.IoTConnectivity.Client.PresenceResponse.GetResourceType(presenceResponseHandle, out type);
775 if (ret != (int)IoTConnectivityError.None)
777 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get resource type");
781 ret = Interop.IoTConnectivity.Client.PresenceResponse.GetTrigger(presenceResponseHandle, out trigger);
782 if (ret != (int)IoTConnectivityError.None)
784 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get event type");
788 PresenceReceivedEventArgs e = new PresenceReceivedEventArgs()
790 PresenceId = presenceId,
791 HostAddress = (host != IntPtr.Zero) ? Marshal.PtrToStringAnsi(host) : string.Empty,
792 Type = (type != IntPtr.Zero) ? Marshal.PtrToStringAnsi(type) : string.Empty,
793 EventType = (PresenceEventType)trigger
799 private static DeviceInformationFoundEventArgs GetDeviceInformationFoundEventArgs(int requestId, IntPtr deviceInfoHandle)
801 IntPtr name, specVersion, deviceId, dataModelVersion;
803 int ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.Name, out name);
804 if (ret != (int)IoTConnectivityError.None)
806 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get name");
810 ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.SpecVersion, out specVersion);
811 if (ret != (int)IoTConnectivityError.None)
813 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get spec version");
817 ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.Id, out deviceId);
818 if (ret != (int)IoTConnectivityError.None)
820 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get device id");
824 ret = Interop.IoTConnectivity.Client.DeviceInformation.GetProperty(deviceInfoHandle, (int)Interop.IoTConnectivity.Client.DeviceInformation.Property.DataModelVersion, out dataModelVersion);
825 if (ret != (int)IoTConnectivityError.None)
827 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get data model version");
831 DeviceInformationFoundEventArgs e = new DeviceInformationFoundEventArgs()
833 RequestId = requestId,
834 EventContinue = true,
835 Name = (name != IntPtr.Zero) ? Marshal.PtrToStringAnsi(name) : string.Empty,
836 SpecVersion = (specVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(specVersion) : string.Empty,
837 DeviceId = (deviceId != IntPtr.Zero) ? Marshal.PtrToStringAnsi(deviceId) : string.Empty,
838 DataModelVersion = (dataModelVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(dataModelVersion) : string.Empty
844 private static PlatformInformationFoundEventArgs GetPlatformInformationFoundEventArgs(int requestId, IntPtr platformInfoHandle)
846 IntPtr platformId, manufacturerName, manufacturerUrl, modelNumber, dateOfManufacture, platformVersion, osVersion, hardwareVersion, firmwareVersion, supportUrl, systemTime;
848 int ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.Id, out platformId);
849 if (ret != (int)IoTConnectivityError.None)
851 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get platform id");
855 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.MfgName, out manufacturerName);
856 if (ret != (int)IoTConnectivityError.None)
858 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get manufacturer name");
862 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.MfgUrl, out manufacturerUrl);
863 if (ret != (int)IoTConnectivityError.None)
865 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get manufacturer url");
869 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.ModelNumber, out modelNumber);
870 if (ret != (int)IoTConnectivityError.None)
872 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get model number");
876 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.DateOfMfg, out dateOfManufacture);
877 if (ret != (int)IoTConnectivityError.None)
879 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get date of manufacture");
883 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.PlatformVer, out platformVersion);
884 if (ret != (int)IoTConnectivityError.None)
886 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get platform version");
890 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.OsVer, out osVersion);
891 if (ret != (int)IoTConnectivityError.None)
893 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to os version");
897 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.HardwareVer, out hardwareVersion);
898 if (ret != (int)IoTConnectivityError.None)
900 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to hardware version");
904 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.FirmwareVer, out firmwareVersion);
905 if (ret != (int)IoTConnectivityError.None)
907 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get firmware version");
911 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.SupportUrl, out supportUrl);
912 if (ret != (int)IoTConnectivityError.None)
914 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get support url");
918 ret = Interop.IoTConnectivity.Client.PlatformInformation.GetProperty(platformInfoHandle, (int)Interop.IoTConnectivity.Client.PlatformInformation.Propery.SystemTime, out systemTime);
919 if (ret != (int)IoTConnectivityError.None)
921 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get system time");
925 PlatformInformationFoundEventArgs e = new PlatformInformationFoundEventArgs()
927 RequestId = requestId,
928 EventContinue = true,
929 PlatformId = (platformId != IntPtr.Zero) ? Marshal.PtrToStringAnsi(platformId) : string.Empty,
930 ManufacturerName = (manufacturerName != IntPtr.Zero) ? Marshal.PtrToStringAnsi(manufacturerName) : string.Empty,
931 ManufacturerURL = (manufacturerUrl != IntPtr.Zero) ? Marshal.PtrToStringAnsi(manufacturerUrl) : string.Empty,
932 DateOfManufacture = (dateOfManufacture != IntPtr.Zero) ? Marshal.PtrToStringAnsi(dateOfManufacture) : string.Empty,
933 ModelNumber = (modelNumber != IntPtr.Zero) ? Marshal.PtrToStringAnsi(modelNumber) : string.Empty,
934 PlatformVersion = (platformVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(platformVersion) : string.Empty,
935 OsVersion = (osVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(osVersion) : string.Empty,
936 HardwareVersion = (hardwareVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(hardwareVersion) : string.Empty,
937 FirmwareVersion = (firmwareVersion != IntPtr.Zero) ? Marshal.PtrToStringAnsi(firmwareVersion) : string.Empty,
938 SupportUrl = (supportUrl != IntPtr.Zero) ? Marshal.PtrToStringAnsi(supportUrl) : string.Empty,
939 SystemTime = (systemTime != IntPtr.Zero) ? Marshal.PtrToStringAnsi(systemTime) : string.Empty
942 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.RequestId is " + e.RequestId);
943 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.PlatformId is " + e.PlatformId);
944 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.ManufacturerName is " + e.ManufacturerName);
945 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.ManufacturerURL is " + e.ManufacturerURL);
946 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.DateOfManufacture is " + e.DateOfManufacture);
947 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.ModelNumber is " + e.ModelNumber);
948 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.PlatformVersion is " + e.PlatformVersion);
949 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.OsVersion is " + e.OsVersion);
950 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.HardwareVersion is " + e.HardwareVersion);
951 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.FirmwareVersion is " + e.FirmwareVersion);
952 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.SupportUrl is " + e.SupportUrl);
953 Log.Info(IoTConnectivityErrorFactory.LogTag, "e.SystemTime is " + e.SystemTime);
958 private static FindingErrorOccurredEventArgs GetFindingErrorOccurredEventArgs(int requestId, int err)
960 FindingErrorOccurredEventArgs e = new FindingErrorOccurredEventArgs()
962 RequestId = requestId,
963 Error = IoTConnectivityErrorFactory.GetException(err)