[Tizen.Applications.ComponentBased][TCSACR-398] Add ComponentPort class (#2548)
authorhjhun <36876573+hjhun@users.noreply.github.com>
Tue, 26 Jan 2021 23:37:43 +0000 (08:37 +0900)
committerGitHub <noreply@github.com>
Tue, 26 Jan 2021 23:37:43 +0000 (08:37 +0900)
* Devel Component Port

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Change parameter name to endpoint

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Use Serializable instead of Parcelable

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Remove Marker interface

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Check result object

The result has to be a serializble object.

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Fix wrong description

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Remove SafePortHandle

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Modify using directives

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Fix typo

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
Co-authored-by: pjh9216 <jh9216.park@samsung.com>
src/Tizen.Applications.ComponentBased.Port/Interop/Interop.ComponentPort.cs [new file with mode: 0755]
src/Tizen.Applications.ComponentBased.Port/Interop/Interop.Libraries.cs [new file with mode: 0755]
src/Tizen.Applications.ComponentBased.Port/Interop/Interop.Parcel.cs [new file with mode: 0755]
src/Tizen.Applications.ComponentBased.Port/Tizen.Applications.ComponentBased.Port.csproj [new file with mode: 0644]
src/Tizen.Applications.ComponentBased.Port/Tizen.Applications.ComponentBased.Port.sln [new file with mode: 0755]
src/Tizen.Applications.ComponentBased.Port/Tizen.Applications.ComponentBased.Port/ComponentPort.cs [new file with mode: 0755]
src/Tizen.Applications.ComponentBased.Port/Tizen.Applications.ComponentBased.Port/Parcel.cs [new file with mode: 0755]
src/Tizen.Applications.ComponentBased.Port/Tizen.Applications.ComponentBased.Port/SafeParcelHandle.cs [new file with mode: 0755]

diff --git a/src/Tizen.Applications.ComponentBased.Port/Interop/Interop.ComponentPort.cs b/src/Tizen.Applications.ComponentBased.Port/Interop/Interop.ComponentPort.cs
new file mode 100755 (executable)
index 0000000..8dc3b3d
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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 Tizen.Applications.ComponentBased;
+
+internal static partial class Interop
+{
+    internal static partial class ComponentPort
+    {
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void ComponentPortRequestCallback(string sender, IntPtr request, IntPtr userData);
+        // typedef void (*component_port_request_cb)(const char *sender, parcel_h request, IntPtr user_data);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void ComponentPortSyncRequestCallback(string sender, IntPtr request, IntPtr response, IntPtr userData);
+        // typedef void (*component_port_request_cb)(const char *sender, parcel_h request, parcel_h response IntPtr user_data);
+
+        internal enum ErrorCode
+        {
+            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,
+        }
+
+        [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_create")]
+        internal static extern ErrorCode Create(string portName, out IntPtr handle);
+        // int component_port_create(const char *port_name, component_port_h *port);
+
+        [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_destroy")]
+        internal static extern ErrorCode Destroy(IntPtr handle);
+        // int component_port_destroy(component_port_h port);
+
+        [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_set_request_cb")]
+        internal static extern ErrorCode SetRequestCb(IntPtr handle, ComponentPortRequestCallback callback, IntPtr userData);
+        // int component_port_set_request_cb(component_port_h port, component_port_request_cb callback, void *user_data);
+
+        [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_set_sync_request_cb")]
+        internal static extern ErrorCode SetSyncRequestCb(IntPtr handle, ComponentPortSyncRequestCallback callback, IntPtr userData);
+        // int component_port_set_sync_request_cb(component_port_h port, component_port_sync_request_cb callback, void *user_data);
+
+        [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_add_privilege")]
+        internal static extern ErrorCode AddPrivilege(IntPtr handle, string privilege);
+        // int component_port_add_privilege(component_port_h port, const char *privilege);
+
+        [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_wait_for_event")]
+        internal static extern void WaitForEvent(IntPtr handle);
+        // void component_port_wait_for_event(component_port_h port);
+
+        [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_cancel")]
+        internal static extern void Cancel(IntPtr handle);
+        // void component_port_cancel(component_port_h port);
+
+        [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_send")]
+        internal static extern ErrorCode Send(IntPtr handle, string endpoint, Int32 timeout, SafeParcelHandle request);
+        // int component_port_send(component_port_h port, const char *endpoint, int timeout, parcel_h request);
+
+        [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_send_sync")]
+        internal static extern ErrorCode SendSync(IntPtr handle, string endpoint, Int32 timeout, SafeParcelHandle request, out SafeParcelHandle response);
+        // int component_port_send(component_port_h port, const char *endpoint, int timeout, parcel_h request, parcel_h *response);
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Applications.ComponentBased.Port/Interop/Interop.Libraries.cs b/src/Tizen.Applications.ComponentBased.Port/Interop/Interop.Libraries.cs
new file mode 100755 (executable)
index 0000000..e7d08de
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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 ComponentPort = "libcomponent-based-port.so.1";
+        public const string Parcel = "libparcel.so.0";
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Applications.ComponentBased.Port/Interop/Interop.Parcel.cs b/src/Tizen.Applications.ComponentBased.Port/Interop/Interop.Parcel.cs
new file mode 100755 (executable)
index 0000000..a45bbd9
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * 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.Internals;
+using Tizen.Applications;
+
+internal static partial class Interop
+{
+    internal static partial class Parcel
+    {
+        internal enum ErrorCode
+        {
+            None = Tizen.Internals.Errors.ErrorCode.None,
+            InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+            IllegalByteSeq = Tizen.Internals.Errors.ErrorCode.IllegalByteSeq,
+            NoData = Tizen.Internals.Errors.ErrorCode.NoData,
+            OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+        }
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_create")]
+        internal static extern ErrorCode Create(out SafeParcelHandle handle);
+        // int parcel_create(parcel_h *parcel);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_destroy")]
+        internal static extern ErrorCode DangerousDestroy(IntPtr handle);
+        // int parcel_destroy(parcel_h parcel);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_clone")]
+        internal static extern ErrorCode DangerousClone(IntPtr handle, out SafeParcelHandle clone);
+        // int parcel_clone(parcel_h parcel, parcel_h *clone);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_burst_write")]
+        internal static extern ErrorCode BurstWrite(SafeParcelHandle handle, byte[] buf, UInt32 size);
+        // int parcel_burst_write(parcel_h parcel, cont void *buf, uint32_t size);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_burst_read")]
+        internal static extern ErrorCode BurstRead(SafeParcelHandle handle, [In, Out] byte[] buf, UInt32 size);
+        // int parcel_burst_read(parcel_h parcel, void *buf, uint32_t size);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_bool")]
+        internal static extern ErrorCode WriteBool(SafeParcelHandle handle, bool val);
+        // int parcel_write_bool(parcel_h parcel, bool val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_byte")]
+        internal static extern ErrorCode WriteByte(SafeParcelHandle handle, byte val);
+        // int parcel_write_byte(parcel_h parcel, char val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_uint16")]
+        internal static extern ErrorCode WriteUInt16(SafeParcelHandle handle, UInt16 val);
+        // int parcel_write_uint16(parcel_h parcel, uint16_t val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_uint32")]
+        internal static extern ErrorCode WriteUInt32(SafeParcelHandle handle, UInt32 val);
+        // int parcel_write_uint32(parcel_h parcel, uint32_t val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_uint64")]
+        internal static extern ErrorCode WriteUInt64(SafeParcelHandle handle, UInt64 val);
+        // int parcel_write_uint64(parcel_h parcel, uint64_t val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_int16")]
+        internal static extern ErrorCode WriteInt16(SafeParcelHandle handle, Int16 val);
+        // int parcel_write_int16(parcel_h parcel, int16_t val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_int32")]
+        internal static extern ErrorCode WriteInt32(SafeParcelHandle handle, Int32 val);
+        // int parcel_write_int32(parcel_h parcel, int32_t val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_int64")]
+        internal static extern ErrorCode WriteInt64(SafeParcelHandle handle, Int64 val);
+        // int parcel_write_int64(parcel_h parcel, int64_t val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_float")]
+        internal static extern ErrorCode WriteFloat(SafeParcelHandle handle, float val);
+        // int parcel_write_float(parcel_h parcel, float val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_double")]
+        internal static extern ErrorCode WriteDouble(SafeParcelHandle handle, double val);
+        // int parcel_write_double(parcel_h parcel, double val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_string")]
+        internal static extern ErrorCode WriteString(SafeParcelHandle handle, string str);
+        // int parcel_write_string(parcel_h parcel, const char *str);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_bundle")]
+        internal static extern ErrorCode WriteBundle(SafeParcelHandle handle, IntPtr b);
+        // int parcel_write_bundle(parcel_h parcel, bundle *b);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_bool")]
+        internal static extern ErrorCode ReadBool(SafeParcelHandle handle, out bool val);
+        // int parcel_read_bool(parcel_h parcel, bool *val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_byte")]
+        internal static extern ErrorCode ReadByte(SafeParcelHandle handle, out byte val);
+        // int parcel_read_byte(parcel_h parcel, char *val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_uint16")]
+        internal static extern ErrorCode ReadUInt16(SafeParcelHandle handle, out UInt16 val);
+        // int parcel_read_uint16(parcel_h parcel, uint16_t *val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_uint32")]
+        internal static extern ErrorCode ReadUInt32(SafeParcelHandle handle, out UInt32 val);
+        // int parcel_read_uint32(parcel_h parcel, uint32_t *val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_uint64")]
+        internal static extern ErrorCode ReadUInt64(SafeParcelHandle handle, out UInt64 val);
+        // int parcel_read_uint64(parcel_h parcel, uint64_t *val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_int16")]
+        internal static extern ErrorCode ReadInt16(SafeParcelHandle handle, out Int16 val);
+        // int parcel_read_int16(parcel_h parcel, int16_t *val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_int32")]
+        internal static extern ErrorCode ReadInt32(SafeParcelHandle handle, out Int32 val);
+        // int parcel_read_int32(parcel_h parcel, int32_t *val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_int64")]
+        internal static extern ErrorCode ReadInt64(SafeParcelHandle handle, out Int64 val);
+        // int parcel_read_int64(parcel_h parcel, int64_t *val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_float")]
+        internal static extern ErrorCode ReadFloat(SafeParcelHandle handle, out float val);
+        // int parcel_read_float(parcel_h parcel, float *val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_double")]
+        internal static extern ErrorCode ReadDouble(SafeParcelHandle handle, out double val);
+        // int parcel_read_double(parcel_h parcel, double *val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_string")]
+        internal static extern ErrorCode ReadString(SafeParcelHandle handle, out string val);
+        // int parcel_read_string(parcel_h parcel, char **val);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_bundle")]
+        internal static extern ErrorCode ReadBundle(SafeParcelHandle handle, out IntPtr b);
+        // int parcel_read_bundle(parcel_h parcel, bundle **b);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_get_raw")]
+        internal static extern ErrorCode GetRaw(SafeParcelHandle handle, out IntPtr raw, out UInt32 size);
+        // int parcel_get_raw(parcel_h parcel, void **raw, uint32_t *size);
+
+        [DllImport(Libraries.Parcel, EntryPoint = "parcel_reset")]
+        internal static extern ErrorCode Reset(SafeParcelHandle handle, byte[] buf, UInt32 size);
+        // int parcel_reset(parcel_h parcel, const void *buf, uint32_t size);
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Applications.ComponentBased.Port/Tizen.Applications.ComponentBased.Port.csproj b/src/Tizen.Applications.ComponentBased.Port/Tizen.Applications.ComponentBased.Port.csproj
new file mode 100644 (file)
index 0000000..4c51c41
--- /dev/null
@@ -0,0 +1,12 @@
+<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>
\ No newline at end of file
diff --git a/src/Tizen.Applications.ComponentBased.Port/Tizen.Applications.ComponentBased.Port.sln b/src/Tizen.Applications.ComponentBased.Port/Tizen.Applications.ComponentBased.Port.sln
new file mode 100755 (executable)
index 0000000..ee842a1
--- /dev/null
@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30517.126
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Applications.ComponentBased.Port", "Tizen.Applications.ComponentBased.Port.csproj", "{FF190549-DDD6-47ED-ABA3-717B0C130C3D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen", "..\Tizen\Tizen.csproj", "{2E04FB0F-03F4-40B0-BB25-5ADFB08C8DF3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Log", "..\Tizen.Log\Tizen.Log.csproj", "{8DA5B43B-63E9-460C-B64F-0B691539DC5D}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Any CPU = Debug|Any CPU
+               Release|Any CPU = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {FF190549-DDD6-47ED-ABA3-717B0C130C3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {FF190549-DDD6-47ED-ABA3-717B0C130C3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {FF190549-DDD6-47ED-ABA3-717B0C130C3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {FF190549-DDD6-47ED-ABA3-717B0C130C3D}.Release|Any CPU.Build.0 = Release|Any CPU
+               {2E04FB0F-03F4-40B0-BB25-5ADFB08C8DF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {2E04FB0F-03F4-40B0-BB25-5ADFB08C8DF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {2E04FB0F-03F4-40B0-BB25-5ADFB08C8DF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {2E04FB0F-03F4-40B0-BB25-5ADFB08C8DF3}.Release|Any CPU.Build.0 = Release|Any CPU
+               {8DA5B43B-63E9-460C-B64F-0B691539DC5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {8DA5B43B-63E9-460C-B64F-0B691539DC5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {8DA5B43B-63E9-460C-B64F-0B691539DC5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {8DA5B43B-63E9-460C-B64F-0B691539DC5D}.Release|Any CPU.Build.0 = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+       GlobalSection(ExtensibilityGlobals) = postSolution
+               SolutionGuid = {0335C3BF-98CA-4337-96E5-088E9CEFDFFC}
+       EndGlobalSection
+EndGlobal
diff --git a/src/Tizen.Applications.ComponentBased.Port/Tizen.Applications.ComponentBased.Port/ComponentPort.cs b/src/Tizen.Applications.ComponentBased.Port/Tizen.Applications.ComponentBased.Port/ComponentPort.cs
new file mode 100755 (executable)
index 0000000..c7d68e4
--- /dev/null
@@ -0,0 +1,391 @@
+/*
+ * 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.IO;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Security;
+using System.Xml.Serialization;
+
+namespace Tizen.Applications.ComponentBased
+{
+    /// <summary>
+    /// Abstract class for creating a component port class.
+    /// </summary>
+    /// <since_tizen> 9 </since_tizen>
+    public abstract class ComponentPort : IDisposable
+    {
+        private static string LogTag = "ComponentPort";
+        private readonly string _portName;
+        private IntPtr _port = IntPtr.Zero;
+        private Interop.ComponentPort.ComponentPortRequestCallback _requestEventCallback;
+        private Interop.ComponentPort.ComponentPortSyncRequestCallback _syncRequestEventCallback;
+
+        /// <summary>
+        /// Constructor for this class.
+        /// </summary>
+        /// <exception cref="ArgumentException">Thrown when the argument is invalid.</exception>
+        /// <exception cref="OutOfMemoryException">Thrown when the memory is insufficient.</exception>
+        /// <exception cref="global::System.IO.IOException">Thrown when because of I/O error.</exception>
+        /// <param name="portName">The name of the port.</param>
+        /// <since_tizen> 9 </since_tizen>
+        public ComponentPort(string portName)
+        {
+            var ret = Interop.ComponentPort.Create(portName, out _port);
+            if (ret != Interop.ComponentPort.ErrorCode.None)
+                throw ComponentPortErrorFactory.GetException(ret, "ComponentPort(" + portName + ").");
+
+            _portName = portName;
+            _requestEventCallback = new Interop.ComponentPort.ComponentPortRequestCallback(OnRequestEvent);
+            _syncRequestEventCallback = new Interop.ComponentPort.ComponentPortSyncRequestCallback(OnSyncRequestEvent);
+            Interop.ComponentPort.SetRequestCb(_port, _requestEventCallback, IntPtr.Zero);
+            Interop.ComponentPort.SetSyncRequestCb(_port, _syncRequestEventCallback, IntPtr.Zero);
+        }
+
+        /// <summary>
+        /// Gets the port name.
+        /// </summary>
+        /// <since_tizen> 9 </since_tizen>
+        public string PortName
+        {
+            get
+            {
+                return _portName;
+            }
+        }
+
+        /// <summary>
+        /// Adds a privilege to the port object.
+        /// </summary>
+        /// <exception cref="ArgumentException">Thrown when the argument is invalid.</exception>
+        /// <param name="privilege">privilege data</param>
+        /// <since_tizen> 9 </since_tizen>
+        public void AddPrivilege(string privilege)
+        {
+            Interop.ComponentPort.AddPrivilege(_port, privilege);
+        }
+
+        /// <summary>
+        /// Waits for events.
+        /// </summary>
+        /// <since_tizen> 9 </since_tizen>
+        public void WaitForEvent()
+        {
+            Interop.ComponentPort.WaitForEvent(_port);
+        }
+
+        /// <summary>
+        /// Cancels waiting for events.
+        /// </summary>
+        /// <since_tizen> 9 </since_tizen>
+        public void Cancel()
+        {
+            Interop.ComponentPort.Cancel(_port);
+        }
+
+        /// <summary>
+        /// Sends the request data.
+        /// </summary>
+        /// <exception cref="ArgumentException">Thrown when the argument is invalid.</exception>
+        /// <exception cref="OutOfMemoryException">Thrown when the memory is insufficient.</exception>
+        /// <exception cref="UnauthorizedAccessException">Thrown when because of permission denied.</exception>
+        /// <exception cref="global::System.IO.IOException">Thrown when because of I/O error.</exception>
+        /// <param name="endpoint">The name of the endpoint</param>
+        /// <param name="timeout">The interval of timeout</param>
+        /// <param name="request">The serializable data to send</param>
+        /// <since_tizen> 9 </since_tizen>
+        public void Send(string endpoint, int timeout, object request)
+        {
+            if (request == null)
+            {
+                throw new ArgumentException("request is null");
+            }
+
+            if (!request.GetType().IsSerializable)
+            {
+                throw new ArgumentException("request is not serializable");
+            }
+
+            Interop.ComponentPort.ErrorCode err;
+            using (Parcel reqParcel = ToParcel(request))
+            {
+                err = Interop.ComponentPort.Send(_port, endpoint, timeout, reqParcel.SafeParcelHandle);
+            }
+            if (err != Interop.ComponentPort.ErrorCode.None)
+            {
+                throw ComponentPortErrorFactory.GetException(err, "Failed to send the request.");
+            }
+        }
+
+        /// <summary>
+        /// Sends the request data synchronously.
+        /// </summary>
+        /// <exception cref="ArgumentException">Thrown when the argument is invalid.</exception>
+        /// <exception cref="OutOfMemoryException">Thrown when the memory is insufficient.</exception>
+        /// <exception cref="UnauthorizedAccessException">Thrown when because of permission denied.</exception>
+        /// <exception cref="global::System.IO.IOException">Thrown when because of I/O error.</exception>
+        /// <param name="endpoint">The name of the endpoint</param>
+        /// <param name="timeout">The interval of timeout</param>
+        /// <param name="request">The serializable data to send</param>
+        /// <returns>The received serializable data</returns>
+        /// /// <since_tizen> 9 </since_tizen>
+        public object SendSync(string endpoint, int timeout, object request)
+        {
+            if (request == null)
+            {
+                throw new ArgumentException("request is null");
+            }
+
+            if (!request.GetType().IsSerializable)
+            {
+                throw new ArgumentException("request is not serializable");
+            }
+
+            SafeParcelHandle resSafeHandle = null;
+            Interop.ComponentPort.ErrorCode err;
+            using (Parcel reqParcel = ToParcel(request))
+            {             
+                err = Interop.ComponentPort.SendSync(_port, endpoint, timeout, reqParcel.SafeParcelHandle, out resSafeHandle);
+            }
+            if (err != Interop.ComponentPort.ErrorCode.None)
+            {
+                throw ComponentPortErrorFactory.GetException(err, "Failed to send the request.");
+            }
+
+            using (Parcel resParcel = new Parcel(resSafeHandle))
+            {
+                object response = FromParcel(resParcel);
+                return response;
+            }            
+        }
+
+        /// <summary>
+        /// Abstract method for receiving a request event.
+        /// </summary>
+        /// <param name="sender">The name of the sender</param>
+        /// <param name="request">The serializable data</param>
+        /// <since_tizen> 9 </since_tizen>
+        protected abstract void OnRequestEvent(string sender, object request);
+
+        /// <summary>
+        /// Abstract method for receiving a synchronous request event.
+        /// </summary>
+        /// <param name="sender">The name of the sender</param>
+        /// <param name="request">The serializable data</param>
+        /// <returns>The serializable data</returns>
+        /// <since_tizen> 9 </since_tizen>
+        protected abstract object OnSyncRequestEvent(string sender, object request);
+
+
+        private void OnRequestEvent(string sender, IntPtr request, IntPtr data)
+        {
+            SafeParcelHandle reqSafeHandle = new SafeParcelHandle(request, false);
+            using (var reqParcel = new Parcel(reqSafeHandle))
+            {
+                object req = FromParcel(reqParcel);
+                OnRequestEvent(sender, req);
+            }
+        }
+
+        private void OnSyncRequestEvent(string sender, IntPtr request, IntPtr response, IntPtr data)
+        {
+            SafeParcelHandle reqSafeHandle = new SafeParcelHandle(request, false);
+
+            object req = null;
+            using (Parcel reqParcel = new Parcel(reqSafeHandle))
+            {
+                req = FromParcel(reqParcel);
+            }
+
+            object result = OnSyncRequestEvent(sender, req);
+            if (!result.GetType().IsSerializable)
+            {
+                Log.Error(LogTag, "result is not serializable");
+            }
+            else
+            {
+               SafeParcelHandle resSafeHandle = new SafeParcelHandle(response, false);
+               using (Parcel resParcel = new Parcel(resSafeHandle))
+                {
+                    using (Parcel resultParcel = ToParcel(result))
+                    {
+                        resParcel.UnMarshall(resultParcel.Marshall());
+                    }
+                }
+            }
+        }
+
+        private Parcel ToParcel(object envelope)
+        {
+            if (envelope == null)
+                return null;
+
+            BinaryFormatter formatter = new BinaryFormatter
+            {
+                Binder = new PortBinder(),
+                AssemblyFormat = FormatterAssemblyStyle.Full
+            };
+
+            using (MemoryStream stream = new MemoryStream())
+            {
+                formatter.Serialize(stream, envelope);
+                Parcel parcel = new Parcel();
+                parcel.UnMarshall(stream.ToArray());
+                return parcel;
+            }
+        }
+
+        private object FromParcel(Parcel parcel)
+        {
+            if (parcel == null)
+                return null;
+
+            BinaryFormatter formatter = new BinaryFormatter
+            {
+                Binder = new PortBinder(),
+                AssemblyFormat = FormatterAssemblyStyle.Full,
+            };
+
+            object envelope = null;
+            using (MemoryStream stream = new MemoryStream(parcel.Marshall()))
+            {
+                try
+                {
+                    envelope = (object)formatter.Deserialize(stream);
+                }
+                catch (ArgumentException e)
+                {
+                    Log.Error(LogTag, "ArgumentException occurs: " + e.Message);
+                }
+                catch (SerializationException e)
+                {
+                    Log.Error(LogTag, "SerializationException occurs: " + e.Message);
+                }
+                catch (SecurityException e)
+                {
+                    Log.Error(LogTag, "SecurityException occurs: " + e.Message);
+                }
+            }
+
+            return envelope;
+        }
+
+
+        #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, or false not to dispose disposable objects.</param>
+        /// <since_tizen> 9 </since_tizen>
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!disposedValue)
+            {
+                if (disposing)
+                {
+                    if (_port != IntPtr.Zero)
+                        Interop.ComponentPort.Destroy(_port);
+                    _port = IntPtr.Zero;
+                }
+
+                disposedValue = true;
+            }
+        }
+
+        /// <summary>
+        /// Finalizer of the class ComponentPort.
+        /// </summary>
+        /// <since_tizen> 9 </since_tizen>
+        ~ComponentPort()
+        {
+            Dispose(disposing: false);
+        }
+
+        /// <summary>
+        /// Releases all the resources used by the class ComponentPort.
+        /// </summary>
+        /// <since_tizen> 9 </since_tizen>>
+        public void Dispose()
+        {
+            Dispose(disposing: true);
+            GC.SuppressFinalize(this);
+        }
+        #endregion
+
+        internal sealed class PortBinder : SerializationBinder
+        {
+            private static string LogTag = "PortBinder";
+
+            private string GetAssemblyName(string typeName)
+            {
+                foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
+                {
+                    foreach (Type t in a.GetTypes())
+                    {
+                        if (t.FullName == typeName)
+                        {
+                            Log.Warn(LogTag, "Found! AssemblyName: " + a.FullName);
+                            return a.FullName;
+                        }
+                    }
+                }
+
+                return string.Empty;
+            }
+
+            public override Type BindToType(string assemblyName, string typeName)
+            {
+                Type returntype = null;
+                Log.Warn(LogTag, "AssemblyName: " + assemblyName);
+                Log.Warn(LogTag, "TypeName: " + typeName);
+                string foundAssemblyName = GetAssemblyName(typeName);
+                if (foundAssemblyName.Length != 0)
+                {
+                    returntype = Type.GetType(String.Format("{0}, {1}", typeName, foundAssemblyName));
+                }
+                else
+                {
+                    returntype = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName));
+                }
+                return returntype;
+            }
+        }
+
+        internal static class ComponentPortErrorFactory
+        {
+            internal static Exception GetException(Interop.ComponentPort.ErrorCode err, string message)
+            {
+                string errMessage = string.Format("{0} err = {1}", message, err);
+                switch (err)
+                {
+                    case Interop.ComponentPort.ErrorCode.InvalidParameter:
+                        return new ArgumentException(errMessage);
+                    case Interop.ComponentPort.ErrorCode.PermissionDenied:
+                        return new UnauthorizedAccessException(errMessage);
+                    case Interop.ComponentPort.ErrorCode.OutOfMemory:
+                        return new OutOfMemoryException(errMessage);
+                    default:
+                        return new global::System.IO.IOException(errMessage);
+                }
+            }
+        }
+    }
+}
diff --git a/src/Tizen.Applications.ComponentBased.Port/Tizen.Applications.ComponentBased.Port/Parcel.cs b/src/Tizen.Applications.ComponentBased.Port/Tizen.Applications.ComponentBased.Port/Parcel.cs
new file mode 100755 (executable)
index 0000000..4f2db8a
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * 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;
+
+namespace Tizen.Applications.ComponentBased
+{
+    internal class Parcel : IDisposable
+    {
+        private readonly SafeParcelHandle _handle;
+
+        public Parcel()
+        {
+            var ret = Interop.Parcel.Create(out _handle);
+            if (ret != Interop.Parcel.ErrorCode.None)
+            {
+                throw ParcelErrorFactory.GetException(ret, "Parcel() is failed.");
+            }
+        }
+
+        public Parcel(SafeParcelHandle handle)
+        {
+            if (handle == null)
+            {
+                throw new ArgumentException("handle is null");
+            }
+
+            _handle = handle;
+        }
+
+        public SafeParcelHandle SafeParcelHandle
+        {
+            get
+            {
+                return _handle;
+            }
+        }
+
+        public byte[] Marshall()
+        {
+            Interop.Parcel.GetRaw(_handle, out IntPtr raw, out UInt32 size);
+            byte[] ret = new byte[size];
+            Marshal.Copy((IntPtr)raw, (byte[])ret, 0, (int)size);
+            return ret;
+        }
+
+        public void UnMarshall(byte[] bytes)
+        {
+            Interop.Parcel.Reset(_handle, bytes, (UInt32)bytes.Length);
+        }
+
+        #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 object.</param>
+        /// <since_tizen> 9 </since_tizen>
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!disposedValue)
+            {
+                if (disposing)
+                {
+                    if (_handle != null && !_handle.IsInvalid)
+                        _handle.Dispose();
+                }
+
+                disposedValue = true;
+            }
+        }
+
+        /// <summary>
+        /// Finalizer of the class Parcel.
+        /// </summary>
+        /// <since_tizen> 9 </since_tizen>
+        ~Parcel()
+        {
+            Dispose(disposing: false);
+        }
+
+        /// <summary>
+        /// Releases all the resources used by the class parcel.
+        /// </summary>
+        /// <since_tizen> 9 </since_tizen>>
+        public void Dispose()
+        {
+            Dispose(disposing: true);
+            GC.SuppressFinalize(this);
+        }
+        #endregion
+
+        internal static class ParcelErrorFactory
+        {
+            internal static Exception GetException(Interop.Parcel.ErrorCode err, string message)
+            {
+                string errMessage = string.Format("{0} err = {1}", message, err);
+                switch (err)
+                {
+                    case Interop.Parcel.ErrorCode.NoData:
+                    case Interop.Parcel.ErrorCode.IllegalByteSeq:
+                        return new InvalidOperationException(errMessage);
+                    case Interop.Parcel.ErrorCode.InvalidParameter:
+                        return new ArgumentException(errMessage);
+                    default:
+                        return new OutOfMemoryException(errMessage);
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Applications.ComponentBased.Port/Tizen.Applications.ComponentBased.Port/SafeParcelHandle.cs b/src/Tizen.Applications.ComponentBased.Port/Tizen.Applications.ComponentBased.Port/SafeParcelHandle.cs
new file mode 100755 (executable)
index 0000000..0a3396a
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+namespace Tizen.Applications
+{
+    internal sealed class SafeParcelHandle : SafeHandle
+    {
+        public SafeParcelHandle() : base(IntPtr.Zero, true)
+        {
+
+        }
+
+        public SafeParcelHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+        {
+            SetHandle(existingHandle);
+        }
+
+        public override bool IsInvalid
+        {
+            get { return this.handle == IntPtr.Zero;  }
+        }
+
+        protected override bool ReleaseHandle()
+        {
+            Interop.Parcel.DangerousDestroy(this.handle);
+            this.SetHandle(IntPtr.Zero);
+            return true;
+        }
+    }
+}
\ No newline at end of file