--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Cion
+ {
+ internal enum ErrorCode : int
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ InvalidOperation = Tizen.Internals.Errors.ErrorCode.InvalidOperation,
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+
+using ErrorCode = Interop.Cion.ErrorCode;
+
+internal static partial class Interop
+{
+ internal static partial class CionClient
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionClientDiscoveredCb(string serviceName, IntPtr peerInfo, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionClientConnectionResultCb(string serviceName, IntPtr peerInfo, IntPtr result, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionClientPayloadRecievedCb(string serviceName, IntPtr peerInfo, IntPtr payload, int status, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionClientDisconnectedCb(string serviceName, IntPtr peerInfo, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionClientPayloadAsyncResultCb(IntPtr result, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_client_create")]
+ internal static extern ErrorCode CionClientCreate(out ClientSafeHandle client, string serviceName, IntPtr security);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_client_destory")]
+ internal static extern ErrorCode CionClientDestroy(IntPtr client);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_client_try_discovery")]
+ internal static extern ErrorCode CionClientTryDiscovery(ClientSafeHandle client, CionClientDiscoveredCb cb, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_client_stop_discovery")]
+ internal static extern ErrorCode CionClientStopDiscovery(ClientSafeHandle client);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_client_connect")]
+ internal static extern ErrorCode CionClientConnect(ClientSafeHandle client, PeerInfoSafeHandle peerInfo);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_client_disconnect")]
+ internal static extern ErrorCode CionClientDisconnect(ClientSafeHandle client);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_client_send_data")]
+ internal static extern ErrorCode CionClientSendData(ClientSafeHandle client, byte[] data, int dataSize, int timeout, out IntPtr returnData, out int returnDataSize);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_client_send_payload_async")]
+ internal static extern ErrorCode CionClientSendPayloadAsync(ClientSafeHandle client, PayloadSafeHandle payload, CionClientPayloadAsyncResultCb cb, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_client_add_connection_result_cb")]
+ internal static extern ErrorCode CionClientAddConnectionResultCb(ClientSafeHandle client, CionClientConnectionResultCb cb, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_client_add_payload_recieved_cb")]
+ internal static extern ErrorCode CionClientAddPayloadReceivedCb(ClientSafeHandle client, CionClientPayloadRecievedCb cb, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_client_add_disconnected_cb")]
+ internal static extern ErrorCode CionClientAddDisconnectedCb(ClientSafeHandle client, CionClientDisconnectedCb cb, IntPtr userData);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+
+using ErrorCode = Interop.Cion.ErrorCode;
+
+internal static partial class Interop
+{
+ internal static partial class CionConnectionResult
+ {
+ [DllImport(Libraries.Cion, EntryPoint = "cion_connection_result_get_status")]
+ internal static extern ErrorCode CionConnectionResultGetStatus(IntPtr result, out ConnectionStatus status);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_connection_result_get_reason")]
+ internal static extern ErrorCode CionConnectionResultGetReason(IntPtr result, out string reason);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+
+using ErrorCode = Interop.Cion.ErrorCode;
+
+internal static partial class Interop
+{
+ internal static partial class CionGroup
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionGroupPayloadReceivedCb(IntPtr group, IntPtr peerInfo, IntPtr payload, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionGroupJoinedCb(string topicName, IntPtr peerInfo, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionGroupLeftCb(string topicName, IntPtr peerInfo, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_group_create")]
+ internal static extern ErrorCode CionGroupCreate(out GroupSafeHandle group, string topicName, IntPtr security);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_group_destroy")]
+ internal static extern ErrorCode CionGroupDestroy(IntPtr group);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_group_subscribe")]
+ internal static extern ErrorCode CionGroupSubscribe(GroupSafeHandle group);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_group_unsubscribe")]
+ internal static extern ErrorCode CionGroupUnsubscribe(GroupSafeHandle group);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_group_publish")]
+ internal static extern ErrorCode CionGroupPublish(GroupSafeHandle group, PayloadSafeHandle data);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_group_add_payload_received_cb")]
+ internal static extern ErrorCode CionGroupAddPayloadReceivedCb(GroupSafeHandle group, CionGroupPayloadReceivedCb cb, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_group_add_joined_cb")]
+ internal static extern ErrorCode CionGroupAddJoinedCb(GroupSafeHandle group, CionGroupJoinedCb cb, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_group_add_left_cb")]
+ internal static extern ErrorCode CionGroupAddLeftCb(GroupSafeHandle group, CionGroupLeftCb cb, IntPtr userData);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+
+using ErrorCode = Interop.Cion.ErrorCode;
+
+internal static partial class Interop
+{
+ internal static partial class CionPayload
+ {
+ internal enum PayloadType : int
+ {
+ Data,
+ File,
+ }
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_payload_create")]
+ internal static extern ErrorCode CionPayloadCreate(out PayloadSafeHandle payload, PayloadType type);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_payload_destroy")]
+ internal static extern ErrorCode CionPayloadDestroy(IntPtr payload);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_payload_get_type")]
+ internal static extern ErrorCode CionPayloadGetType(IntPtr payload, out PayloadType type);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_payload_get_data")]
+ internal static extern ErrorCode CionPayloadGetData(PayloadSafeHandle payload, out IntPtr data, out int dataSize);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_payload_set_data")]
+ internal static extern ErrorCode CionPayloadSetData(PayloadSafeHandle payload, byte[] data, int dataSize);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_payload_save_as_file")]
+ internal static extern ErrorCode CionPayloadSaveAsFile(PayloadSafeHandle payload, string path);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_payload_get_received_file_name")]
+ internal static extern ErrorCode CionPayloadGetReceivedFileName(PayloadSafeHandle payload, out string path);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_payload_get_received_bytes")]
+ internal static extern ErrorCode CionPayloadGetReceivedBytes(PayloadSafeHandle payload, out UInt64 bytes);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_payload_get_total_bytes")]
+ internal static extern ErrorCode CionPayloadGetTotalBytes(PayloadSafeHandle payload, out UInt64 bytes);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_payload_set_file_path")]
+ internal static extern ErrorCode CionPayloadSetFilePath(PayloadSafeHandle payload, string path);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_payload_get_payload_id")]
+ internal static extern ErrorCode CionPayloadGetPayloadID(PayloadSafeHandle payload, out string id);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+
+using ErrorCode = Interop.Cion.ErrorCode;
+
+internal static partial class Interop
+{
+ internal static partial class CionPayloadAsyncResult
+ {
+ [DllImport(Libraries.Cion, EntryPoint = "cion_payload_async_result_get_result")]
+ internal static extern ErrorCode CionPayloadAsyncResultGetResult(IntPtr result, out int code);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_payload_async_result_get_peer_info")]
+ internal static extern ErrorCode CionPayloadAsyncResultGetPeerInfo(IntPtr result, out IntPtr peerInfo);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_payload_async_result_get_payload_id")]
+ internal static extern ErrorCode CionPayloadAsyncResultGetPayloadID(IntPtr result, out string payloadID);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+
+using ErrorCode = Interop.Cion.ErrorCode;
+
+internal static partial class Interop
+{
+ internal static partial class CionPeerInfo
+ {
+ [DllImport(Libraries.Cion, EntryPoint = "cion_peer_info_clone")]
+ internal static extern ErrorCode CionPeerInfoClone(IntPtr peerInfo, out PeerInfoSafeHandle peerInfoClone);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_peer_info_destroy")]
+ internal static extern ErrorCode CionPeerInfoDestroy(IntPtr peerInfo);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_peer_info_get_device_id")]
+ internal static extern ErrorCode CionPeerInfoGetDeviceId(PeerInfoSafeHandle peerInfo, out string deviceId);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_peer_info_get_device_name")]
+ internal static extern ErrorCode CionPeerInfoGetDeviceName(PeerInfoSafeHandle peerInfo, out string deviceName);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_peer_info_get_device_platform")]
+ internal static extern ErrorCode CionPeerInfoGetDevicePlatform(PeerInfoSafeHandle peerInfo, out string devicePlatform);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_peer_info_get_device_platform_version")]
+ internal static extern ErrorCode CionPeerInfoGetDevicePlatformVersion(PeerInfoSafeHandle peerInfo, out string devicePlatformVersion);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_peer_info_get_device_type")]
+ internal static extern ErrorCode CionPeerInfoGetDeviceType(PeerInfoSafeHandle peerInfo, out string deviceType);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_peer_info_get_app_id")]
+ internal static extern ErrorCode CionPeerInfoGetAppId(PeerInfoSafeHandle peerInfo, out string appId);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_peer_info_get_app_version")]
+ internal static extern ErrorCode CionPeerInfoGetAppVersion(PeerInfoSafeHandle peerInfo, out string appVersion);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_peer_info_get_uuid")]
+ internal static extern ErrorCode CionPeerInfoGetUuid(PeerInfoSafeHandle peerInfo, out string uuid);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications.Cion;
+
+using ErrorCode = Interop.Cion.ErrorCode;
+
+internal static partial class Interop
+{
+ internal static partial class CionSecurity
+ {
+ [DllImport(Libraries.Cion, EntryPoint = "cion_security_create")]
+ internal static extern ErrorCode CionSecurityCreate(out SecuritySafeHandle security);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_security_destroy")]
+ internal static extern ErrorCode CionSecurityDestroy(IntPtr security);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_security_set_ca_path")]
+ internal static extern ErrorCode CionSecuritySetCaPath(SecuritySafeHandle peerInfo, string caPath);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_security_set_cert_path")]
+ internal static extern ErrorCode CionSecuritySetCertPath(SecuritySafeHandle peerInfo, string certPath);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_security_set_private_key_path")]
+ internal static extern ErrorCode CionSecuritySetPrivateKeyPath(SecuritySafeHandle peerInfo, string keyPath);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_security_get_ca_path")]
+ internal static extern ErrorCode CionSecurityGetCaPath(SecuritySafeHandle peerInfo, out string caPath);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_security_get_cert_path")]
+ internal static extern ErrorCode CionSecurityGetCertPath(SecuritySafeHandle peerInfo, out string certPath);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_security_get_private_key_path")]
+ internal static extern ErrorCode CionSecurityGetPrivateKeyPath(SecuritySafeHandle peerInfo, out string keyPath);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+
+using ErrorCode = Interop.Cion.ErrorCode;
+
+internal static partial class Interop
+{
+ internal static partial class CionServer
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionServerPeerInfoIterator(IntPtr peerInfo, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionServerPayloadAsyncResultCb(IntPtr result, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionServerConnectionResultCb(string serviceName, IntPtr peerInfo, IntPtr result, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionServerDataReceivedCb(string serviceName, IntPtr peerInfo, byte[] data, int dataSize, out byte[] returnData, out int returnDataSize, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionServerPayloadRecievedCb(string serviceName, IntPtr peerInfo, IntPtr payload, int status, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionServerConnectionRequestCb(string serviceName, IntPtr peerInfo, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionServerErrorReportedCb(string serviceName, IntPtr peerInfo, int error, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CionServerDisconnectedCb(string serviceName, IntPtr peerInfo, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_server_create")]
+ internal static extern ErrorCode CionServerCreate(out ServerSafeHandle server, string serviceName, string displayName, IntPtr security);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_server_destory")]
+ internal static extern ErrorCode CionServerDestroy(IntPtr server);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_server_listen")]
+ internal static extern ErrorCode CionServerListen(ServerSafeHandle server, CionServerConnectionRequestCb cb, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_server_stop")]
+ internal static extern ErrorCode CionServerStop(ServerSafeHandle server);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_server_accept")]
+ internal static extern ErrorCode CionServerAccept(ServerSafeHandle server, PeerInfoSafeHandle peerInfo);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_server_reject")]
+ internal static extern ErrorCode CionServerReject(ServerSafeHandle server, PeerInfoSafeHandle peerInfo, string reason);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_server_disconnect")]
+ internal static extern ErrorCode CionServerDisconnect(ServerSafeHandle server, PeerInfoSafeHandle peerInfo);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_server_send_payload_async")]
+ internal static extern ErrorCode CionServerSendPayloadAsync(ServerSafeHandle server, PeerInfoSafeHandle peerInfo, PayloadSafeHandle payload,
+ CionServerPayloadAsyncResultCb cb, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_server_foreach_connected_peer_info")]
+ internal static extern ErrorCode CionServerForeachConnectedPeerInfo(ServerSafeHandle server, CionServerPeerInfoIterator cb, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_server_add_connection_result_cb")]
+ internal static extern ErrorCode CionServerAddConnectionResultCb(ServerSafeHandle server, CionServerConnectionResultCb cb, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_server_add_payload_recieved_cb")]
+ internal static extern ErrorCode CionServerAddPayloadReceivedCb(ServerSafeHandle server, CionServerPayloadRecievedCb cb, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_server_add_error_reported_cb")]
+ internal static extern ErrorCode CionServerAddErrorReportedCb(ServerSafeHandle server, CionServerErrorReportedCb cb, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_server_set_data_recieved_cb")]
+ internal static extern ErrorCode CionServerSetDataReceivedCb(ServerSafeHandle server, CionServerDataReceivedCb cb, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_server_add_disconnected_cb")]
+ internal static extern ErrorCode CionServerAddDisconnectedCb(ServerSafeHandle server, CionServerDisconnectedCb cb, IntPtr userData);
+
+ [DllImport(Libraries.Cion, EntryPoint = "cion_server_set_ondemand_launch_enable")]
+ internal static extern ErrorCode CionServerSetOndemandLaunchEnable(ServerSafeHandle server, bool enable);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string Cion = "libcion.so.1";
+ }
+}
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netstandard2.0</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+
+</Project>
--- /dev/null
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31613.86
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Applications.Cion", "Tizen.Applications.Cion.csproj", "{9FDBB6A2-0E97-4B7F-8C71-C09C3C37A44E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen", "..\Tizen\Tizen.csproj", "{DA6CC280-5D47-4A88-A7D0-D96156C03DAA}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Log", "..\Tizen.Log\Tizen.Log.csproj", "{DB0F0139-CDFD-41E6-B8F7-CAE066DDFA6D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9FDBB6A2-0E97-4B7F-8C71-C09C3C37A44E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9FDBB6A2-0E97-4B7F-8C71-C09C3C37A44E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9FDBB6A2-0E97-4B7F-8C71-C09C3C37A44E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9FDBB6A2-0E97-4B7F-8C71-C09C3C37A44E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DA6CC280-5D47-4A88-A7D0-D96156C03DAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DA6CC280-5D47-4A88-A7D0-D96156C03DAA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DA6CC280-5D47-4A88-A7D0-D96156C03DAA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DA6CC280-5D47-4A88-A7D0-D96156C03DAA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DB0F0139-CDFD-41E6-B8F7-CAE066DDFA6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DB0F0139-CDFD-41E6-B8F7-CAE066DDFA6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DB0F0139-CDFD-41E6-B8F7-CAE066DDFA6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DB0F0139-CDFD-41E6-B8F7-CAE066DDFA6D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {0A1F9790-D5BF-4F3F-BAB5-CB9C7B1DA87F}
+ EndGlobalSection
+EndGlobal
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications.Cion
+{
+ /// <summary>
+ /// A class to represent security info.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public class SecurityInfo : IDisposable
+ {
+ private readonly string LogTag = "Tizen.Cion";
+ internal SecuritySafeHandle _handle = null;
+
+ /// <summary>
+ /// The constructor of SecurityInfo class.
+ /// </summary>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public SecurityInfo()
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionSecurity.CionSecurityCreate(out _handle);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to create security info.");
+ }
+ }
+
+ /// <summary>
+ /// Gets the CA cert path.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown when the CA path is invalid.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public string CaPath
+ {
+ get
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionSecurity.CionSecurityGetCaPath(_handle, out string caPath);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get CA path.");
+ return "";
+ }
+ return caPath;
+ }
+
+ set
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionSecurity.CionSecuritySetCaPath(_handle, value);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to set CA path.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the cert path.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown when the cert path is invalid.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public string CertPath
+ {
+ get
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionSecurity.CionSecurityGetCertPath(_handle, out string certPath);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get cert path.");
+ return "";
+ }
+ return certPath;
+ }
+
+ set
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionSecurity.CionSecuritySetCertPath(_handle, value);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to set cert path.");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the private key path.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown when the private key path is invalid.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public string PrivateKeyPath
+ {
+ get
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionSecurity.CionSecurityGetPrivateKeyPath(_handle, out string privateKeyPath);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get private key path.");
+ return "";
+ }
+ return privateKeyPath;
+ }
+
+ set
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionSecurity.CionSecuritySetPrivateKeyPath(_handle, value);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to set private key path.");
+ }
+ }
+ }
+
+ #region IDisposable Support
+ private bool disposedValue = false;
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ _handle.Dispose();
+ }
+ disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the SecurityInfo class.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications.Cion
+{
+ internal sealed class SecuritySafeHandle : SafeHandle
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public SecuritySafeHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool IsInvalid
+ {
+ get { return this.DangerousGetHandle() == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.CionSecurity.CionSecurityDestroy(this.handle);
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ internal static class CionErrorFactory
+ {
+ internal static Exception GetException(Interop.Cion.ErrorCode err, string message)
+ {
+ string errMessage = string.Format("{0} err = {1}", message, err);
+ switch (err)
+ {
+ case Interop.Cion.ErrorCode.InvalidParameter:
+ return new ArgumentException(errMessage);
+ case Interop.Cion.ErrorCode.OutOfMemory:
+ return new InvalidOperationException(errMessage);
+ case Interop.Cion.ErrorCode.IoError:
+ return new global::System.IO.IOException(errMessage);
+ case Interop.Cion.ErrorCode.PermissionDenied:
+ return new UnauthorizedAccessException(errMessage);
+ case Interop.Cion.ErrorCode.InvalidOperation:
+ return new InvalidOperationException(errMessage);
+ case Interop.Cion.ErrorCode.NotSupported:
+ return new NotSupportedException(errMessage);
+ default:
+ return new InvalidOperationException(errMessage);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// An abstract class to represent cion client.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public abstract class ClientBase : IDisposable
+ {
+ private readonly string LogTag = "Tizen.Cion";
+ private readonly ClientSafeHandle _handle;
+
+ private PeerInfo _peer;
+
+ private Interop.CionClient.CionClientDiscoveredCb _discoveredCb;
+ private Interop.CionClient.CionClientConnectionResultCb _connectionResultCb;
+ private Interop.CionClient.CionClientPayloadRecievedCb _payloadRecievedCb;
+ private Interop.CionClient.CionClientDisconnectedCb _disconnectedCb;
+ private Interop.CionClient.CionClientPayloadAsyncResultCb _payloadAsyncResultCb;
+ private Dictionary<string, TaskCompletionSource<PayloadAsyncResult>> _tcsDictionary = new Dictionary<string, TaskCompletionSource<PayloadAsyncResult>>();
+
+ /// <summary>
+ /// Gets the service name of current cion client.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string ServiceName { get; }
+
+ /// <summary>
+ /// Gets peer info of connected cion server.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public PeerInfo PeerInfo
+ {
+ get
+ {
+ return _peer;
+ }
+ }
+
+ /// <summary>
+ /// The constructor of ClientBase class.
+ /// </summary>
+ /// <param name="serviceName">The name of service.</param>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public ClientBase(string serviceName) : this(serviceName, null) { }
+
+ /// <summary>
+ /// The constructor of ClientBase class.
+ /// </summary>
+ /// <param name="serviceName">The name of service.</param>
+ /// <param name="security">The security configuration.</param>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public ClientBase(string serviceName, Cion.SecurityInfo security)
+ {
+ ServiceName = serviceName;
+
+ Cion.SecuritySafeHandle handle = security?._handle;
+ Interop.Cion.ErrorCode ret = Interop.CionClient.CionClientCreate(out _handle, serviceName, handle?.DangerousGetHandle() ?? IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to create client.");
+ }
+
+ _connectionResultCb = new Interop.CionClient.CionClientConnectionResultCb(
+ (string service, IntPtr peerInfo, IntPtr result, IntPtr userData) =>
+ {
+ Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, string.Format("Failed to clone peer info."));
+ return;
+ }
+
+ PeerInfo peer = new PeerInfo(clone);
+ ConnectionResult connectionResult = new ConnectionResult(result);
+ if (connectionResult.Status == ConnectionStatus.OK)
+ {
+ _peer = peer;
+ }
+
+ OnConnectionResult(peer, connectionResult);
+ });
+ ret = Interop.CionClient.CionClientAddConnectionResultCb(_handle, _connectionResultCb, IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw CionErrorFactory.GetException(ret, "Failed to add connection status changed callback.");
+ }
+
+ _payloadRecievedCb = new Interop.CionClient.CionClientPayloadRecievedCb(
+ (string service, IntPtr peerInfo, IntPtr payload, int status, IntPtr userData) =>
+ {
+ Payload receivedPayload;
+ Interop.CionPayload.CionPayloadGetType(payload, out Interop.CionPayload.PayloadType type);
+ switch (type)
+ {
+ case Interop.CionPayload.PayloadType.Data:
+ receivedPayload = new DataPayload(new PayloadSafeHandle(payload, false));
+ break;
+ case Interop.CionPayload.PayloadType.File:
+ receivedPayload = new FilePayload(new PayloadSafeHandle(payload, false));
+ break;
+ default:
+ Log.Error(LogTag, "Invalid payload type received.");
+ return;
+ }
+ OnPayloadReceived(receivedPayload, (PayloadTransferStatus)status);
+ });
+ ret = Interop.CionClient.CionClientAddPayloadReceivedCb(_handle, _payloadRecievedCb, IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw CionErrorFactory.GetException(ret, "Failed to add payload received callback.");
+ }
+
+ _disconnectedCb = new Interop.CionClient.CionClientDisconnectedCb(
+ (string service, IntPtr peerInfo, IntPtr userData) =>
+ {
+ Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, string.Format("Failed to clone peer info."));
+ return;
+ }
+ OnDisconnected(new PeerInfo(clone));
+ });
+ ret = Interop.CionClient.CionClientAddDisconnectedCb(_handle, _disconnectedCb, IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw CionErrorFactory.GetException(ret, "Failed to add disconnected callback.");
+ }
+ }
+
+ /// <summary>
+ /// Starts discovering cion servers.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown when the discovery operation is already in progress.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public void TryDiscovery()
+ {
+ Log.Error(LogTag, string.Format("Try discovery start"));
+
+ if (_discoveredCb == null)
+ {
+ Interop.CionClient.CionClientDiscoveredCb cb = new Interop.CionClient.CionClientDiscoveredCb(
+ (string serviceName, IntPtr peerInfo, IntPtr userData) =>
+ {
+ Log.Error(LogTag, string.Format("callback called !!"));
+
+ Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to clone peer info.");
+ return;
+ }
+ OnDiscovered(new PeerInfo(clone));
+ });
+ _discoveredCb = cb;
+ }
+
+ Interop.Cion.ErrorCode ret = Interop.CionClient.CionClientTryDiscovery(_handle, _discoveredCb, IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to try discovery.");
+ }
+ }
+
+ /// <summary>
+ /// Stops discovering.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown when the client is not discovering.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public void StopDiscovery()
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionClient.CionClientStopDiscovery(_handle);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to stop discovery.");
+ }
+ }
+
+ /// <summary>
+ /// Connects with the cion server.
+ /// </summary>
+ /// <param name="peer">The peer to connect.</param>
+ /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege>
+ /// <since_tizen> 9 </since_tizen>
+ public void Connect(PeerInfo peer)
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionClient.CionClientConnect(_handle, peer?._handle);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to connect.");
+ }
+ }
+
+ /// <summary>
+ /// Disconnects from the cion server.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public void Disconnect()
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionClient.CionClientDisconnect(_handle);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to disconnect.");
+ }
+ _peer = null;
+ }
+
+ /// <summary>
+ /// Sends data synchronously to the connected cion server.
+ /// </summary>
+ /// <param name="data">The data to send.</param>
+ /// <param name="timeout">The timeout of sending operation.</param>
+ /// <exception cref="ArgumentException">Thrown when the given data is invalid.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when there is no connected cion server.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public byte[] SendData(byte[] data, int timeout)
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionClient.CionClientSendData(_handle, data, data?.Length ?? -1, timeout, out IntPtr returnDataPtr, out int returnDataSize);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to send data.");
+ }
+ byte[] returnData = new byte[returnDataSize];
+ Marshal.Copy(returnDataPtr, returnData, 0, returnDataSize);
+ Log.Info(LogTag, string.Format("Returned data size: {0}", returnDataSize));
+
+ return returnData;
+ }
+
+ /// <summary>
+ /// Sends payload asynchronously to the connected cion server.
+ /// </summary>
+ /// <param name="payload">The payload to send.</param>
+ /// <exception cref="ArgumentException">Thrown when the payload is not valid.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when there is no connected cion server.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public Task<PayloadAsyncResult> SendPayloadAsync(Payload payload)
+ {
+ if (payload?.Id.Length == 0)
+ {
+ throw new ArgumentException("Payload is invalid.");
+ }
+
+ TaskCompletionSource<PayloadAsyncResult> tcs = new TaskCompletionSource<PayloadAsyncResult>();
+ _tcsDictionary[payload.Id] = tcs;
+
+ if (_payloadAsyncResultCb == null)
+ {
+ Interop.CionClient.CionClientPayloadAsyncResultCb cb = new Interop.CionClient.CionClientPayloadAsyncResultCb(
+ (IntPtr result, IntPtr userData) =>
+ {
+ TaskCompletionSource<PayloadAsyncResult> tcsToReturn = _tcsDictionary[payload.Id];
+ PayloadAsyncResult resultPayload = null;
+ try
+ {
+ resultPayload = PayloadAsyncResult.CreateFromHandle(result);
+ }
+ catch (Exception e)
+ {
+ Log.Error(LogTag, string.Format("Failed to create PayloadAsyncResult from result handle: {0}.", e.Message));
+ tcsToReturn.SetException(e);
+ return;
+ }
+ tcsToReturn.SetResult(resultPayload);
+ _tcsDictionary.Remove(resultPayload.PayloadId);
+ });
+ _payloadAsyncResultCb = cb;
+ }
+
+ Interop.Cion.ErrorCode ret = Interop.CionClient.CionClientSendPayloadAsync(_handle, payload?._handle, _payloadAsyncResultCb, IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to send payload.");
+ }
+
+ return tcs.Task;
+ }
+
+ /// <summary>
+ /// The result callback of connection request.
+ /// </summary>
+ /// <param name="peerInfo">The peer info of the cion server.</param>
+ /// <param name="result">The result of the connection.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected abstract void OnConnectionResult(PeerInfo peerInfo, ConnectionResult result);
+
+ /// <summary>
+ /// The callback invoked when received payload.
+ /// </summary>
+ /// <param name="payload">The received payload.</param>
+ /// <param name="status">The status of sent payload.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected abstract void OnPayloadReceived(Payload payload, PayloadTransferStatus status);
+
+ /// <summary>
+ /// The callback invoked when the cion server discovered.
+ /// </summary>
+ /// <param name="peerInfo">The peer info of discovered cion server.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected abstract void OnDiscovered(PeerInfo peerInfo);
+
+ /// <summary>
+ /// The callback invoked when disconnected with cion client.
+ /// </summary>
+ /// <param name="peerInfo">The peer info of the cion server.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected abstract void OnDisconnected(PeerInfo peerInfo);
+
+ #region IDisposable Support
+ private bool disposedValue = false;
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ _handle.Dispose();
+ }
+ disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the ClientBase class.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ internal sealed class ClientSafeHandle : SafeHandle
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public ClientSafeHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool IsInvalid
+ {
+ get { return this.DangerousGetHandle() == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.CionClient.CionClientDestroy(this.handle);
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// A class to represent result of connection.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public class ConnectionResult
+ {
+ private readonly string _reason;
+ private readonly ConnectionStatus _status;
+
+ internal ConnectionResult(IntPtr handle)
+ {
+ Interop.CionConnectionResult.CionConnectionResultGetReason(handle, out _reason);
+ Interop.CionConnectionResult.CionConnectionResultGetStatus(handle, out _status);
+ }
+
+ /// <summary>
+ /// Gets the connection status.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public ConnectionStatus Status
+ {
+ get
+ {
+ return _status;
+ }
+ }
+
+ /// <summary>
+ /// Gets the reason of the connection result.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string Reason
+ {
+ get
+ {
+ return _reason;
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for connection status.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public enum ConnectionStatus
+ {
+ /// <summary>
+ /// The connection request is accepted.
+ /// </summary>
+ OK,
+ /// <summary>
+ /// The connection request is rejected.
+ /// </summary>
+ Rejected,
+ /// <summary>
+ /// The error occurred while the connection request is in-progress.
+ /// </summary>
+ Error,
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// A class to represent data type payload.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public class DataPayload : Payload
+ {
+ internal DataPayload(PayloadSafeHandle handle)
+ {
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// The constructor of DataPayload class.
+ /// </summary>
+ /// <param name="data">The data of payload.</param>
+ /// <exception cref="ArgumentException">Thrown when the input data is invalid.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public DataPayload(byte[] data)
+ {
+ Interop.CionPayload.CionPayloadCreate(out _handle, Interop.CionPayload.PayloadType.Data);
+ Interop.CionPayload.CionPayloadSetData(_handle, data, data?.Length ?? -1);
+ }
+
+ /// <summary>
+ /// Gets type of the payload.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public override PayloadType PayloadType
+ {
+ get
+ {
+ return PayloadType.DataPayload;
+ }
+ }
+
+ /// <summary>
+ /// Gets data of the payload.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public byte[] Data
+ {
+ get
+ {
+ Interop.CionPayload.CionPayloadGetData(_handle, out IntPtr byteArrPtr, out int size);
+ byte[] byteArr = new byte[size];
+ Marshal.Copy(byteArrPtr, byteArr, 0, size);
+ return byteArr;
+ }
+ set
+ {
+ Interop.CionPayload.CionPayloadSetData(_handle, value, value?.Length ?? 0);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// A class to represent file type payload.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public class FilePayload : Payload
+ {
+ private readonly string LogTag = "Tizen.Cion";
+
+ internal FilePayload(PayloadSafeHandle handle)
+ {
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// The constructor of FilePayload class.
+ /// </summary>
+ /// <param name="path">The path of file for the FilePayload.</param>
+ /// <exception cref="ArgumentException">Thrown when the input file path is invalid.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public FilePayload(string path)
+ {
+ Interop.CionPayload.CionPayloadCreate(out _handle, Interop.CionPayload.PayloadType.File);
+ Interop.CionPayload.CionPayloadSetFilePath(_handle, path);
+ }
+
+ /// <summary>
+ /// Gets the name of received file.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string ReceivedFileName
+ {
+ get
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionPayload.CionPayloadGetReceivedFileName(_handle, out string path);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ // property should not throw exception.
+ return "";
+ }
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// Gets size of received file.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public UInt64 ReceivedBytes
+ {
+ get
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionPayload.CionPayloadGetReceivedBytes(_handle, out UInt64 bytes);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get received bytes.");
+ return Byte.MinValue;
+ }
+ return bytes;
+ }
+ }
+
+ /// <summary>
+ /// Gets total size of the file.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public UInt64 TotalBytes
+ {
+ get
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionPayload.CionPayloadGetTotalBytes(_handle, out UInt64 bytes);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get total bytes.");
+ return Byte.MinValue;
+ }
+ return bytes;
+ }
+ }
+
+ /// <summary>
+ /// Gets type of the payload.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public override PayloadType PayloadType
+ {
+ get
+ {
+ return PayloadType.FilePayload;
+ }
+ }
+
+ /// <summary>
+ /// Saves file of payload to speicific path.
+ /// </summary>
+ /// <param name="path">The path of file to save.</param>
+ /// <since_tizen> 9 </since_tizen>
+ public void SaveAsFile(string path)
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionPayload.CionPayloadSaveAsFile(_handle, path);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to save as file.");
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// An abstract class to represent cion group.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public abstract class GroupBase : IDisposable
+ {
+ private readonly GroupSafeHandle _handle;
+
+ private Interop.CionGroup.CionGroupPayloadReceivedCb _payloadReceivedCb;
+ private Interop.CionGroup.CionGroupLeftCb _leftCb;
+ private Interop.CionGroup.CionGroupJoinedCb _joinedCb;
+
+ /// <summary>
+ /// Gets the topic of current cion group.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string Topic { get; }
+
+ /// <summary>
+ /// The constructor of GroupBase class.
+ /// </summary>
+ /// <param name="topicName">The topic of group.</param>
+ /// <since_tizen> 9 </since_tizen>
+ public GroupBase(string topicName) : this(topicName, null) { }
+
+ /// <summary>
+ /// The constructor of GroupBase class.
+ /// </summary>
+ /// <param name="topicName">The topic of group.</param>
+ /// <param name="security">The security configuration.</param>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public GroupBase(string topicName, Cion.SecurityInfo security)
+ {
+ Topic = topicName;
+
+ Cion.SecuritySafeHandle handle = security?._handle;
+ Interop.Cion.ErrorCode ret = Interop.CionGroup.CionGroupCreate(out _handle, topicName, handle?.DangerousGetHandle() ?? IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to create group.");
+ }
+
+ _payloadReceivedCb = new Interop.CionGroup.CionGroupPayloadReceivedCb(
+ (IntPtr group, IntPtr peerInfo, IntPtr payload, IntPtr userData) =>
+ {
+ Payload receivedPayload;
+ Interop.CionPayload.CionPayloadGetType(payload, out Interop.CionPayload.PayloadType type);
+ switch (type)
+ {
+ case Interop.CionPayload.PayloadType.Data:
+ receivedPayload = new DataPayload(new PayloadSafeHandle(payload, false));
+ break;
+ case Interop.CionPayload.PayloadType.File:
+ receivedPayload = new FilePayload(new PayloadSafeHandle(payload, false));
+ break;
+ default:
+ throw new ArgumentException("Invalid payload type received.");
+ }
+ OnPayloadReceived(receivedPayload, new PeerInfo(new PeerInfoSafeHandle(peerInfo, false)));
+ });
+ ret = Interop.CionGroup.CionGroupAddPayloadReceivedCb(_handle, _payloadReceivedCb, IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw CionErrorFactory.GetException(ret, "Failed to add payload received callback.");
+ }
+
+ _joinedCb = new Interop.CionGroup.CionGroupJoinedCb(
+ (string name, IntPtr peerInfo, IntPtr userData) =>
+ {
+ Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.Cion.ErrorCode.None)
+ {
+ return;
+ }
+ OnJoined(new PeerInfo(clone));
+ });
+ ret = Interop.CionGroup.CionGroupAddJoinedCb(_handle, _joinedCb, IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw CionErrorFactory.GetException(ret, "Failed to add joined callback.");
+ }
+
+ _leftCb = new Interop.CionGroup.CionGroupLeftCb(
+ (string name, IntPtr peerInfo, IntPtr userData) =>
+ {
+ Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.Cion.ErrorCode.None)
+ {
+ return;
+ }
+ OnLeft(new PeerInfo(clone));
+ });
+ ret = Interop.CionGroup.CionGroupAddLeftCb(_handle, _leftCb, IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw CionErrorFactory.GetException(ret, "Failed to add joined callback.");
+ }
+ }
+
+ /// <summary>
+ /// Subscribes the topic.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege>
+ /// <since_tizen> 9 </since_tizen>
+ public void Subscribe()
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionGroup.CionGroupSubscribe(_handle);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to subscribe.");
+ }
+ }
+
+ /// <summary>
+ /// Unsubscribes the topic.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public void Unsubscribe()
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionGroup.CionGroupUnsubscribe(_handle);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to unsubscribe.");
+ }
+ }
+
+ /// <summary>
+ /// Publishes payload to current group.
+ /// </summary>
+ /// <param name="payload">The payload to publish.</param>
+ /// <exception cref="ArgumentException">Thrown when the payload is invalid.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public void Publish(Payload payload)
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionGroup.CionGroupPublish(_handle, payload?._handle);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to publish payload.");
+ }
+ }
+
+ /// <summary>
+ /// The callback invoked when payload received.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ protected abstract void OnPayloadReceived(Payload payload, PeerInfo peer);
+
+ /// <summary>
+ /// The callback invoked when another peer joined in the current group.
+ /// </summary>
+ /// <param name="peerInfo">The peer info of joined in the current group.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected abstract void OnJoined(PeerInfo peerInfo);
+
+ /// <summary>
+ /// The callback invoked when another peer left from the current group.
+ /// </summary>
+ /// <param name="peerInfo">The peer info of left from the current group.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected abstract void OnLeft(PeerInfo peerInfo);
+
+ #region IDisposable Support
+ private bool disposedValue = false;
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ _handle.Dispose();
+ }
+ disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the GroupBase class.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ internal sealed class GroupSafeHandle : SafeHandle
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public GroupSafeHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool IsInvalid
+ {
+ get { return this.DangerousGetHandle() == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.CionGroup.CionGroupDestroy(this.handle);
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// An abstract class to represent payload.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public abstract class Payload
+ {
+ private readonly string LogTag = "Tizen.Cion";
+ internal PayloadSafeHandle _handle;
+
+ /// <summary>
+ /// Gets type of the payload.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public abstract PayloadType PayloadType { get; }
+
+ /// <summary>
+ /// Gets Id of the payload.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string Id
+ {
+ get
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionPayload.CionPayloadGetPayloadID(_handle, out string id);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get id of payload.");
+ return "";
+ }
+ return id;
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// A class to represent result of payload.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public class PayloadAsyncResult : IDisposable
+ {
+ private PayloadAsyncResult(PayloadAsyncResultCode result, PeerInfo peer, string payloadId)
+ {
+ Result = result;
+ PeerInfo = peer;
+ PayloadId = payloadId;
+ }
+
+ internal static PayloadAsyncResult CreateFromHandle(IntPtr handle)
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionPayloadAsyncResult.CionPayloadAsyncResultGetResult(handle, out int code);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Fail to get result code from the AsyncResult");
+ }
+
+ ret = Interop.CionPayloadAsyncResult.CionPayloadAsyncResultGetPayloadID(handle, out string payloadId);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Fail to get payload id from the AsyncResult");
+ }
+
+ ret = Interop.CionPayloadAsyncResult.CionPayloadAsyncResultGetPeerInfo(handle, out IntPtr peer);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Fail to get peerinfo from the AsyncResult");
+ }
+ ret = Interop.CionPeerInfo.CionPeerInfoClone(peer, out PeerInfoSafeHandle clone);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to clone peer info.");
+ }
+
+ return new PayloadAsyncResult((PayloadAsyncResultCode)code, new PeerInfo(clone), payloadId);
+ }
+
+ /// <summary>
+ /// Gets the result of payload.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public PayloadAsyncResultCode Result { get; }
+
+ /// <summary>
+ /// Gets the peer info of payload.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public PeerInfo PeerInfo { get; }
+
+ /// <summary>
+ /// Gets the payload id.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string PayloadId { get; }
+
+ #region IDisposable Support
+ private bool disposedValue = false;
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ PeerInfo?.Dispose();
+ }
+ disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the PayloadAsyncResult class.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for payload result code.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public enum PayloadAsyncResultCode
+ {
+ /// <summary>
+ /// Fail to get the result code.
+ /// </summary>
+ Error = -1,
+ /// <summary>
+ /// The async request result is not yet received.
+ /// </summary>
+ Pending = 0,
+ /// <summary>
+ /// The async request result is success.
+ /// </summary>
+ Success,
+ /// <summary>
+ /// The async request result is fail.
+ /// </summary>
+ Fail,
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ internal sealed class PayloadSafeHandle : SafeHandle
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public PayloadSafeHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ internal PayloadSafeHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool IsInvalid
+ {
+ get { return this.DangerousGetHandle() == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.CionPayload.CionPayloadDestroy(this.handle);
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for payload transfer status.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public enum PayloadTransferStatus
+ {
+ /// <summary>
+ /// Success.
+ /// </summary>
+ Success,
+ /// <summary>
+ /// Failure.
+ /// </summary>
+ Failure,
+ /// <summary>
+ /// In Progress.
+ /// </summary>
+ InProgress,
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for payload type.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public enum PayloadType
+ {
+ /// <summary>
+ /// Data payload.
+ /// </summary>
+ DataPayload,
+ /// <summary>
+ /// File payload.
+ /// </summary>
+ FilePayload,
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// A class to represent peer info.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public class PeerInfo : IDisposable
+ {
+ private readonly string LogTag = "Tizen.Cion";
+ internal PeerInfoSafeHandle _handle;
+
+ internal PeerInfo(PeerInfoSafeHandle handle)
+ {
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// Gets the device id.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string DeviceId
+ {
+ get
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionPeerInfo.CionPeerInfoGetDeviceId(_handle, out string deviceId);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get device id.");
+ return "";
+ }
+ return deviceId;
+ }
+ }
+
+ /// <summary>
+ /// Gets the device name.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string DeviceName
+ {
+ get
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionPeerInfo.CionPeerInfoGetDeviceName(_handle, out string deviceName);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get device name.");
+ return "";
+ }
+ return deviceName;
+ }
+ }
+
+ /// <summary>
+ /// Gets the device platform.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string DevicePlatform
+ {
+ get
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionPeerInfo.CionPeerInfoGetDevicePlatform(_handle, out string devicePlatform);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get device platform.");
+ return "";
+ }
+ return devicePlatform;
+ }
+ }
+
+ /// <summary>
+ /// Gets the device platform version.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string DevicePlatformVersion
+ {
+ get
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionPeerInfo.CionPeerInfoGetDevicePlatformVersion(_handle, out string devicePlatformVersion);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get device platform version.");
+ return "";
+ }
+ return devicePlatformVersion;
+ }
+ }
+
+ /// <summary>
+ /// Gets the device type.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string DeviceType
+ {
+ get
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionPeerInfo.CionPeerInfoGetDeviceType(_handle, out string deviceType);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get device platform type.");
+ return "";
+ }
+ return deviceType;
+ }
+ }
+
+ /// <summary>
+ /// Gets the application id.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string AppId
+ {
+ get
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionPeerInfo.CionPeerInfoGetAppId(_handle, out string AppId);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get application id.");
+ return "";
+ }
+ return AppId;
+ }
+ }
+
+ /// <summary>
+ /// Gets the application version.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string AppVersion
+ {
+ get
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionPeerInfo.CionPeerInfoGetAppVersion(_handle, out string AppVersion);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get application version.");
+ return "";
+ }
+ return AppVersion;
+ }
+ }
+
+ /// <summary>
+ /// Gets the UUID.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string UUID
+ {
+ get
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionPeerInfo.CionPeerInfoGetUuid(_handle, out string uuid);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get UUID.");
+ return "";
+ }
+ return uuid;
+ }
+ }
+
+ #region IDisposable Support
+ private bool disposedValue = false;
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ _handle.Dispose();
+ }
+ disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the PeerInfo class.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ internal sealed class PeerInfoSafeHandle : SafeHandle
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public PeerInfoSafeHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ internal PeerInfoSafeHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool IsInvalid
+ {
+ get { return this.DangerousGetHandle() == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.CionPeerInfo.CionPeerInfoDestroy(this.handle);
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// An abstract class to represent cion server.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public abstract class ServerBase : IDisposable
+ {
+ private const string LogTag = "Tizen.Cion";
+
+ private readonly ServerSafeHandle _handle;
+ private Interop.CionServer.CionServerConnectionRequestCb _connectionRequestCb;
+ private Interop.CionServer.CionServerConnectionResultCb _connectionResultCb;
+ private Interop.CionServer.CionServerDataReceivedCb _dataReceivedCb;
+ private Interop.CionServer.CionServerPayloadRecievedCb _payloadRecievedCb;
+ private Interop.CionServer.CionServerDisconnectedCb _disconnectedCb;
+ private Interop.CionServer.CionServerPayloadAsyncResultCb _payloadAsyncResultCb;
+ private Dictionary<Tuple<string, string>, TaskCompletionSource<PayloadAsyncResult>> _tcsDictionary = new Dictionary<Tuple<string, string>, TaskCompletionSource<PayloadAsyncResult>>();
+
+ /// <summary>
+ /// Gets the service name of current cion server.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string ServiceName { get; }
+
+ /// <summary>
+ /// Gets the display name of current cion server.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string DisplayName { get; }
+
+ /// <summary>
+ /// The constructor of ServerBase class.
+ /// </summary>
+ /// <param name="serviceName">The name of service.</param>
+ /// <param name="displayName">The display name of service.</param>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public ServerBase(string serviceName, string displayName) : this(serviceName, displayName, null) { }
+
+ /// <summary>
+ /// The constructor of ServerBase class.
+ /// </summary>
+ /// <param name="serviceName">The name of service.</param>
+ /// <param name="displayName">The display name of service.</param>
+ /// <param name="security">The security configuration.</param>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public ServerBase(string serviceName, string displayName, Cion.SecurityInfo security)
+ {
+ ServiceName = serviceName;
+ DisplayName = displayName;
+
+ Cion.SecuritySafeHandle handle = security?._handle;
+ Interop.Cion.ErrorCode ret = Interop.CionServer.CionServerCreate(out _handle, serviceName, displayName, handle?.DangerousGetHandle() ?? IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to create server handle.");
+ }
+
+ _connectionResultCb = new Interop.CionServer.CionServerConnectionResultCb(
+ (string service, IntPtr peerInfo, IntPtr result, IntPtr userData) =>
+ {
+ Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to clone peer info.");
+ return;
+ }
+ OnConnectionResult(new PeerInfo(clone), new ConnectionResult(result));
+ });
+ ret = Interop.CionServer.CionServerAddConnectionResultCb(_handle, _connectionResultCb, IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw CionErrorFactory.GetException(ret, "Failed to add connection status changed callback.");
+ }
+
+ _dataReceivedCb = new Interop.CionServer.CionServerDataReceivedCb(
+ (string service, IntPtr peerInfo, byte[] data, int dataSize, out byte[] returnData, out int returnDataSize, IntPtr userData) =>
+ {
+ returnData = OnDataReceived(data, new PeerInfo(new PeerInfoSafeHandle(peerInfo, false)));
+ returnDataSize = returnData.Length;
+ });
+ ret = Interop.CionServer.CionServerSetDataReceivedCb(_handle, _dataReceivedCb, IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw CionErrorFactory.GetException(ret, "Failed to set data received callback.");
+ }
+
+ _payloadRecievedCb = new Interop.CionServer.CionServerPayloadRecievedCb(
+ (string service, IntPtr peerInfo, IntPtr payload, int status, IntPtr userData) =>
+ {
+ Payload receivedPayload;
+ Interop.CionPayload.CionPayloadGetType(payload, out Interop.CionPayload.PayloadType type);
+ switch (type)
+ {
+ case Interop.CionPayload.PayloadType.Data:
+ receivedPayload = new DataPayload(new PayloadSafeHandle(payload, false));
+ break;
+ case Interop.CionPayload.PayloadType.File:
+ receivedPayload = new FilePayload(new PayloadSafeHandle(payload, false));
+ break;
+ default:
+ Log.Error(LogTag, "Invalid payload type received.");
+ return;
+ }
+ OnPayloadReceived(receivedPayload, new PeerInfo(new PeerInfoSafeHandle(peerInfo, false)), (PayloadTransferStatus)status);
+ });
+ ret = Interop.CionServer.CionServerAddPayloadReceivedCb(_handle, _payloadRecievedCb, IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw CionErrorFactory.GetException(ret, "Failed to add payload received callback.");
+ }
+
+ _disconnectedCb = new Interop.CionServer.CionServerDisconnectedCb(
+ (string service, IntPtr peerInfo, IntPtr userData) =>
+ {
+ Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, string.Format("Failed to clone peer info."));
+ return;
+ }
+ OnDisconnected(new PeerInfo(clone));
+ });
+ ret = Interop.CionServer.CionServerAddDisconnectedCb(_handle, _disconnectedCb, IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw CionErrorFactory.GetException(ret, "Failed to add disconnected callback.");
+ }
+ }
+
+ /// <summary>
+ /// Starts server and listens for requests from cion clients.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown when the listen operation is already in progress.</exception>
+ /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege>
+ /// <since_tizen> 9 </since_tizen>
+ public void Listen()
+ {
+ if (_connectionRequestCb == null)
+ {
+ Interop.CionServer.CionServerConnectionRequestCb cb = new Interop.CionServer.CionServerConnectionRequestCb(
+ (serviceName, peerInfo, userData) =>
+ {
+ Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.Cion.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to clone peer info");
+ return;
+ }
+ OnConnentionRequest(new PeerInfo(clone));
+ });
+ _connectionRequestCb = cb;
+ }
+
+ Interop.Cion.ErrorCode ret = Interop.CionServer.CionServerListen(_handle, _connectionRequestCb, IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to listen server.");
+ }
+ }
+
+ /// <summary>
+ /// Stops the listen operation.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown when the server is not listening.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public void Stop()
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionServer.CionServerStop(_handle);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to stop server.");
+ }
+ }
+
+ /// <summary>
+ /// Disconnects with the peer.
+ /// </summary>
+ /// <param name="peerInfo">The peer to disconnect.</param>
+ /// <exception cref="ArgumentException">Thrown when the given peer info is invalid.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public void Disconnect(PeerInfo peerInfo)
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionServer.CionServerDisconnect(_handle, peerInfo?._handle);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to stop server.");
+ }
+ }
+
+ /// <summary>
+ /// Sends the payload to a peer asynchronously.
+ /// </summary>
+ /// <param name="payload">The payload to send.</param>
+ /// <param name="peerInfo">The peer to send payload.</param>
+ /// <exception cref="ArgumentException">Thrown when the payload is not valid.</exception>
+ /// <exception cref="InvalidOperationException">Thrown when there is no such connected cion client.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public Task<PayloadAsyncResult> SendPayloadAsync(Payload payload, PeerInfo peerInfo)
+ {
+ if (payload?.Id.Length == 0 || peerInfo?.UUID.Length == 0)
+ {
+ throw new ArgumentException("Payload or peerinfo is invalid.");
+ }
+
+ TaskCompletionSource<PayloadAsyncResult> tcs = new TaskCompletionSource<PayloadAsyncResult>();
+ _tcsDictionary[Tuple.Create(payload.Id, peerInfo.UUID)] = tcs;
+
+ if (_payloadAsyncResultCb == null)
+ {
+ Interop.CionServer.CionServerPayloadAsyncResultCb cb = new Interop.CionServer.CionServerPayloadAsyncResultCb(
+ (IntPtr result, IntPtr userData) =>
+ {
+ PayloadAsyncResult resultPayload = null;
+ try
+ {
+ resultPayload = PayloadAsyncResult.CreateFromHandle(result);
+ }
+ catch (Exception e)
+ {
+ Log.Error(LogTag, string.Format("Failed to create PayloadAsyncResult from result handle: {0}.", e.Message));
+ return;
+ }
+ TaskCompletionSource<PayloadAsyncResult> tcsToReturn = _tcsDictionary[Tuple.Create(resultPayload.PayloadId, resultPayload.PeerInfo.UUID)];
+ tcsToReturn.SetResult(resultPayload);
+ _tcsDictionary.Remove(Tuple.Create(resultPayload.PayloadId, resultPayload.PeerInfo.UUID));
+ });
+ _payloadAsyncResultCb = cb;
+ }
+
+ Interop.Cion.ErrorCode ret = Interop.CionServer.CionServerSendPayloadAsync(_handle, peerInfo?._handle, payload?._handle, _payloadAsyncResultCb, IntPtr.Zero);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to send payload.");
+ }
+
+ return tcs.Task;
+ }
+
+ /// <summary>
+ /// Sends the payload to all of connected peer asynchronously.
+ /// </summary>
+ /// <param name="payload">The payload to send.</param>
+ /// <since_tizen> 9 </since_tizen>
+ public void SendPayloadAsync(Payload payload)
+ {
+ var peerList = GetConnectedPeerList();
+ foreach (var peer in peerList)
+ {
+ SendPayloadAsync(payload, peer);
+ }
+ }
+
+ /// <summary>
+ /// Accepts the connection request from the peer.
+ /// </summary>
+ /// <param name="peerInfo">The peer to accept the connection request.</param>
+ /// <since_tizen> 9 </since_tizen>
+ public void Accept(PeerInfo peerInfo)
+ {
+ Interop.CionServer.CionServerAccept(_handle, peerInfo?._handle);
+ }
+
+ /// <summary>
+ /// Rejects the connection request from the peer.
+ /// </summary>
+ /// <param name="peerInfo">The peer to reject the connection request.</param>
+ /// <param name="reason">The reason why reject the connection request.</param>
+ /// <since_tizen> 9 </since_tizen>
+ public void Reject(PeerInfo peerInfo, string reason)
+ {
+ Interop.CionServer.CionServerReject(_handle, peerInfo?._handle, reason);
+ }
+
+ /// <summary>
+ /// Gets connected peers.
+ /// </summary>
+ /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
+ /// <since_tizen> 9 </since_tizen>
+ public IEnumerable<PeerInfo> GetConnectedPeerList()
+ {
+ List<PeerInfo> peerInfoList = new List<PeerInfo>();
+ Interop.Cion.ErrorCode ret = Interop.CionServer.CionServerForeachConnectedPeerInfo(_handle, (peer, userData) =>
+ {
+ Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peer, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(clone_ret, "Failed to clone peer info.");
+ }
+ peerInfoList.Add(new PeerInfo(clone));
+ }, IntPtr.Zero);
+ return peerInfoList;
+ }
+
+ /// <summary>
+ /// Sets ondemand launch enabled flag.
+ /// </summary>
+ /// <param name="enable">Whether ondemand launch is enabled or not.</param>
+ /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
+ /// <privilege>http://tizen.org/privilege/d2d.remotelaunch</privilege>
+ /// <since_tizen> 9 </since_tizen>
+ public void SetOndemandLaunchEnabled(bool enable)
+ {
+ Interop.Cion.ErrorCode ret = Interop.CionServer.CionServerSetOndemandLaunchEnable(_handle, enable);
+ if (ret != Interop.Cion.ErrorCode.None)
+ {
+ throw CionErrorFactory.GetException(ret, "Failed to set ondemand launch enable");
+ }
+ }
+
+ /// <summary>
+ /// The result callback of connection request.
+ /// </summary>
+ /// <param name="peerInfo">The peer info of the cion client.</param>
+ /// <param name="result">The result of the connection.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected abstract void OnConnectionResult(PeerInfo peerInfo, ConnectionResult result);
+
+ /// <summary>
+ /// The callback invoked when received data.
+ /// </summary>
+ /// <param name="data">The received data.</param>
+ /// <param name="peerInfo">The peer info of the cion client.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected abstract byte[] OnDataReceived(byte[] data, PeerInfo peerInfo);
+
+ /// <summary>
+ /// The callback invoked when received payload.
+ /// </summary>
+ /// <param name="data">The received data.</param>
+ /// <param name="peerInfo">The peer info of the cion client.</param>
+ /// <param name="status">The status of payload transfer.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected abstract void OnPayloadReceived(Payload data, PeerInfo peerInfo, PayloadTransferStatus status);
+
+ /// <summary>
+ /// The callback invoked when connection requested from the cion client.
+ /// </summary>
+ /// <param name="peerInfo">The peer info of the cion client.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected abstract void OnConnentionRequest(PeerInfo peerInfo);
+
+ /// <summary>
+ /// The callback invoked when disconnected with cion client.
+ /// </summary>
+ /// <param name="peerInfo">The peer info of the cion client.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected abstract void OnDisconnected(PeerInfo peerInfo);
+
+ #region IDisposable Support
+ private bool disposedValue = false;
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ _handle.Dispose();
+ }
+ disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Releases all resources used by the ServerBase class.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ internal sealed class ServerSafeHandle : SafeHandle
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public ServerSafeHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool IsInvalid
+ {
+ get { return this.DangerousGetHandle() == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.CionServer.CionServerDestroy(this.handle);
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+}