From d66fc52a5b15261c0e8a0c3082e3cb493579f216 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Wed, 20 Jul 2022 15:46:45 +0900 Subject: [PATCH] [aitt] Implement CS generator Change-Id: I1133a468213f3fa864b644b7fca4a6dbd9a85be3 Signed-off-by: Sangyoon Jang --- Makefile.dibs | 3 + idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen.cc | 78 ++ idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen.h | 42 + idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen_cb.h | 1310 ++++++++++++++++++++ idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen.cc | 80 ++ idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen.h | 45 + .../aitt_plugin_cs_interop_gen_cb.h | 374 ++++++ .../aitt_plugin_cs_transportable.cc | 152 +++ .../gen_aitt_plugin/aitt_plugin_cs_transportable.h | 50 + idlc/gen_aitt_plugin/aitt_plugin_loader.cc | 3 +- idlc/gen_cion/cs_cion_group_gen.cc | 43 +- idlc/gen_cion/cs_cion_group_gen_cb.h | 15 - idlc/gen_cion/cs_cion_proxy_gen.cc | 34 +- idlc/gen_cion/cs_cion_stub_gen.cc | 33 +- idlc/gen_cion/cs_transportable.h | 5 + idlc/gen_cion/default_cs_transportable.cc | 89 +- idlc/gen_cion/default_cs_transportable.h | 12 + idlc/main.cc | 35 +- 18 files changed, 2276 insertions(+), 127 deletions(-) create mode 100644 idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen.cc create mode 100644 idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen.h create mode 100644 idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen_cb.h create mode 100644 idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen.cc create mode 100644 idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen.h create mode 100644 idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen_cb.h create mode 100644 idlc/gen_aitt_plugin/aitt_plugin_cs_transportable.cc create mode 100644 idlc/gen_aitt_plugin/aitt_plugin_cs_transportable.h diff --git a/Makefile.dibs b/Makefile.dibs index 141b42b..6c0bb38 100644 --- a/Makefile.dibs +++ b/Makefile.dibs @@ -63,6 +63,9 @@ SRC_FILES := \ idlc/gen_cion/java_cion_stub_repo_gen.cc \ idlc/gen_cion/java_cion_utility_gen.cc \ idlc/gen_aitt_plugin/aitt_plugin_c_transportable.cc \ + idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen.cc \ + idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen.cc \ + idlc/gen_aitt_plugin/aitt_plugin_cs_transportable.cc \ idlc/gen_aitt_plugin/aitt_plugin_internal_body_gen.cc \ idlc/gen_aitt_plugin/aitt_plugin_internal_header_gen.cc \ idlc/gen_aitt_plugin/aitt_plugin_loader.cc \ diff --git a/idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen.cc b/idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen.cc new file mode 100644 index 0000000..e8e8ce0 --- /dev/null +++ b/idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen.cc @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#include "idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen.h" + +#include "idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen_cb.h" + +namespace tidl { + +AittPluginCsBaseGen::AittPluginCsBaseGen(std::shared_ptr doc, + std::shared_ptr trans) : CionPluginBase(doc, trans) { +} + +void AittPluginCsBaseGen::OnInitGen(std::ofstream& stream) { + GenUsing(stream); + stream << "namespace Tizen.Applications.AittPlugin\n"; + stream << "{\n"; + GenBase(stream); + stream << "}\n"; +} + +void AittPluginCsBaseGen::OnFiniGen(std::ofstream& stream) { +} + +void AittPluginCsBaseGen::GenUsing(std::ofstream& stream) { + stream << CB_BASE_USING; +} + +void AittPluginCsBaseGen::GenBase(std::ofstream& stream) { + stream << CB_ERROR_FACTORY; + stream << CB_DATA_PAYLOAD; + stream << CB_FILE_PAYLOAD; + stream << CB_PEER_INFO; + stream << CB_PEER_INFO_SAFE_HANDLE; + stream << CB_PAYLOAD; + stream << CB_PAYLOAD_ASYNC_RESULT; + stream << CB_PAYLOAD_ASYNC_RESULT_CODE; + stream << CB_PAYLOAD_SAFE_HANDLE; + stream << CB_PAYLOAD_TRANSFER_STATUS; + stream << CB_PAYLOAD_TYPE; + stream << CB_CONNECTION_RESULT; + stream << CB_CONNECTION_STATUS; + + switch (GetType()) { + // client + case 1: + stream << CB_CLIENT_SAFE_HANDLE; + stream << CB_CLIENT_BASE; + break; + // server + case 2: + stream << CB_SERVER_SAFE_HANDLE; + stream << CB_SERVER_BASE; + break; + // group + case 3: + stream << CB_GROUP_SAFE_HANDLE; + stream << CB_GROUP_BASE; + break; + default: + break; + } +} + +} // namespace tidl diff --git a/idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen.h b/idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen.h new file mode 100644 index 0000000..153cc48 --- /dev/null +++ b/idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#ifndef IDLC_GEN_AITT_PLUGIN_AITT_PLUGIN_CS_BASE_GEN_H_ +#define IDLC_GEN_AITT_PLUGIN_AITT_PLUGIN_CS_BASE_GEN_H_ + +#include + +#include "idlc/gen_cion/cion_plugin_base.h" + +namespace tidl { + +class AittPluginCsBaseGen : public CionPluginBase { + public: + explicit AittPluginCsBaseGen(std::shared_ptr doc, + std::shared_ptr trans); + virtual ~AittPluginCsBaseGen() = default; + + void OnInitGen(std::ofstream& stream) override; + void OnFiniGen(std::ofstream& stream) override; + + private: + void GenUsing(std::ofstream& stream); + void GenBase(std::ofstream& stream); +}; + +} // namespace tidl + +#endif // IDLC_GEN_AITT_PLUGIN_AITT_PLUGIN_CS_BASE_GEN_H_ diff --git a/idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen_cb.h b/idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen_cb.h new file mode 100644 index 0000000..95ddc9d --- /dev/null +++ b/idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen_cb.h @@ -0,0 +1,1310 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#ifndef IDLC_GEN_AITT_PLUGIN_AITT_PLUGIN_CS_BASE_GEN_CB_H_ +#define IDLC_GEN_AITT_PLUGIN_AITT_PLUGIN_CS_BASE_GEN_CB_H_ + +constexpr char CB_BASE_USING[] = +R"__cs_cb( +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +)__cs_cb"; + +constexpr char CB_ERROR_FACTORY[] = +R"__cs_cb( + internal static class AittPluginErrorFactory + { + internal static Exception GetException(Interop.AittPlugin.ErrorCode err, string message) + { + string errMessage = string.Format("{0} err = {1}", message, err); + switch (err) + { + case Interop.AittPlugin.ErrorCode.IoError: + return new InvalidOperationException(errMessage); + case Interop.AittPlugin.ErrorCode.OutOfMemory: + return new InvalidOperationException(errMessage); + case Interop.AittPlugin.ErrorCode.PermissionDenied: + return new UnauthorizedAccessException(errMessage); + case Interop.AittPlugin.ErrorCode.InvalidParameter: + return new ArgumentException(errMessage); + case Interop.AittPlugin.ErrorCode.InvalidOperation: + return new InvalidOperationException(errMessage); + case Interop.AittPlugin.ErrorCode.AlreadyInProgress: + return new InvalidOperationException(errMessage); + case Interop.AittPlugin.ErrorCode.NotSupported: + return new NotSupportedException(errMessage); + case Interop.AittPlugin.ErrorCode.TimedOut: + return new TimeoutException(errMessage); + case Interop.AittPlugin.ErrorCode.OperationFailed: + return new InvalidOperationException(errMessage); + default: + return new InvalidOperationException(errMessage); + } + } + } +)__cs_cb"; + +constexpr char CB_CLIENT_BASE[] = +R"__cs_cb( + public abstract class ClientBase : IDisposable + { + private readonly string LogTag = "Tizen.Applications.AittPlugin"; + private readonly ClientSafeHandle _handle; + + private PeerInfo _peer; + + private Interop.AittPluginClient.AittPluginClientServerDiscoveredCb _discoveredCb; + private Interop.AittPluginClient.AittPluginClientConnectionResultCb _connectionResultCb; + private Interop.AittPluginClient.AittPluginClientPayloadReceivedCb _payloadRecievedCb; + private Interop.AittPluginClient.AittPluginClientDisconnectedCb _disconnectedCb; + private Dictionary> _tcsDictionary = new Dictionary>(); + private Dictionary _payloadAsyncCbDictionary = new Dictionary(); + + public string ServiceName { get; } + + public PeerInfo PeerInfo + { + get + { + return _peer; + } + } + + public ClientBase(string serviceName, string brokerIp, int brokerPort, string userName, string password, string myIp, int protocol) + { + ServiceName = serviceName; + + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginClient.AittPluginClientCreate(out _handle, serviceName, brokerIp, brokerPort, userName, password, myIp, protocol); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to create client."); + } + + _connectionResultCb = new Interop.AittPluginClient.AittPluginClientConnectionResultCb( + (string service, IntPtr peerInfo, IntPtr result, IntPtr userData) => + { + Interop.AittPlugin.ErrorCode clone_ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); + if (clone_ret != Interop.AittPlugin.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.AittPluginClient.AittPluginClientAddConnectionResultCb(_handle, _connectionResultCb, IntPtr.Zero); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + _handle.Dispose(); + throw AittPluginErrorFactory.GetException(ret, "Failed to add connection status changed callback."); + } + + _payloadRecievedCb = new Interop.AittPluginClient.AittPluginClientPayloadReceivedCb( + (string service, IntPtr peerInfo, IntPtr payload, int status, IntPtr userData) => + { + Payload receivedPayload; + Interop.AittPluginPayload.AittPluginPayloadGetType(payload, out Interop.AittPluginPayload.PayloadType type); + switch (type) + { + case Interop.AittPluginPayload.PayloadType.Data: + receivedPayload = new DataPayload(new PayloadSafeHandle(payload, false)); + break; + case Interop.AittPluginPayload.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.AittPluginClient.AittPluginClientAddPayloadReceivedCb(_handle, _payloadRecievedCb, IntPtr.Zero); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + _handle.Dispose(); + throw AittPluginErrorFactory.GetException(ret, "Failed to add payload received callback."); + } + + _disconnectedCb = new Interop.AittPluginClient.AittPluginClientDisconnectedCb( + (string service, IntPtr peerInfo, IntPtr userData) => + { + Interop.AittPlugin.ErrorCode clone_ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); + if (clone_ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, string.Format("Failed to clone peer info.")); + return; + } + OnDisconnected(new PeerInfo(clone)); + }); + ret = Interop.AittPluginClient.AittPluginClientAddDisconnectedCb(_handle, _disconnectedCb, IntPtr.Zero); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + _handle.Dispose(); + throw AittPluginErrorFactory.GetException(ret, "Failed to add disconnected callback."); + } + } + + public void TryDiscovery() + { + if (_discoveredCb == null) + { + Interop.AittPluginClient.AittPluginClientServerDiscoveredCb cb = new Interop.AittPluginClient.AittPluginClientServerDiscoveredCb( + (string serviceName, IntPtr peerInfo, IntPtr userData) => + { + Interop.AittPlugin.ErrorCode clone_ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); + if (clone_ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to clone peer info."); + return; + } + OnDiscovered(new PeerInfo(clone)); + }); + _discoveredCb = cb; + } + + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginClient.AittPluginClientTryDiscovery(_handle, _discoveredCb, IntPtr.Zero); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to try discovery."); + } + } + + public void StopDiscovery() + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginClient.AittPluginClientStopDiscovery(_handle); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to stop discovery."); + } + } + + public void Connect(PeerInfo peer) + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginClient.AittPluginClientConnect(_handle, peer?._handle); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to connect."); + } + } + + public void Disconnect() + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginClient.AittPluginClientDisconnect(_handle); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, string.Format("Failed to disconnect: {0}", ret)); + } + _peer = null; + } + + public byte[] SendData(byte[] data, int timeout) + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginClient.AittPluginClientSendData(_handle, data, data?.Length ?? -1, timeout, out IntPtr returnDataPtr, out int returnDataSize); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.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; + } + + public Task SendPayloadAsync(Payload payload) + { + if (payload == null || payload.Id.Length == 0) + { + throw new ArgumentException("Payload is invalid."); + } + + if (_tcsDictionary.ContainsKey(payload.Id)) + { + throw new InvalidOperationException("Payload is already sent."); + } + + TaskCompletionSource tcs = new TaskCompletionSource(); + _tcsDictionary[payload.Id] = tcs; + + Interop.AittPluginClient.AittPluginClientPayloadAsyncResultCb cb = new Interop.AittPluginClient.AittPluginClientPayloadAsyncResultCb( + (IntPtr result, IntPtr userData) => + { + TaskCompletionSource 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); + _payloadAsyncCbDictionary.Remove(resultPayload.PayloadId); + _tcsDictionary.Remove(resultPayload.PayloadId); + }); + + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginClient.AittPluginClientSendPayloadAsync(_handle, payload?._handle, cb, IntPtr.Zero); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to send payload."); + } + + _payloadAsyncCbDictionary[payload?.Id] = cb; + + return tcs.Task; + } + + protected abstract void OnConnectionResult(PeerInfo peerInfo, ConnectionResult result); + protected abstract void OnPayloadReceived(Payload payload, PayloadTransferStatus status); + protected abstract void OnDiscovered(PeerInfo peerInfo); + protected abstract void OnDisconnected(PeerInfo peerInfo); + + private bool disposedValue = false; + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + _handle.Dispose(); + } + disposedValue = true; + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +)__cs_cb"; + +constexpr char CB_CLIENT_SAFE_HANDLE[] = +R"__cs_cb( + 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.AittPluginClient.AittPluginClientDestroy(this.handle); + SetHandle(IntPtr.Zero); + return true; + } + } +)__cs_cb"; + +constexpr char CB_CONNECTION_RESULT[] = +R"__cs_cb( + public class ConnectionResult + { + private readonly string _reason; + private readonly ConnectionStatus _status; + + internal ConnectionResult(IntPtr handle) + { + Interop.AittPluginConnectionResult.AittPluginConnectionResultGetReason(handle, out _reason); + Interop.AittPluginConnectionResult.AittPluginConnectionResultGetStatus(handle, out _status); + } + + public ConnectionStatus Status + { + get + { + return _status; + } + } + + public string Reason + { + get + { + return _reason; + } + } + } +)__cs_cb"; + +constexpr char CB_CONNECTION_STATUS[] = +R"__cs_cb( + public enum ConnectionStatus + { + OK, + Rejected, + Error, + } +)__cs_cb"; + +constexpr char CB_DATA_PAYLOAD[] = +R"__cs_cb( + public class DataPayload : Payload + { + internal DataPayload(PayloadSafeHandle handle) + { + _handle = handle; + } + + public DataPayload(byte[] data) + { + Interop.AittPluginPayload.AittPluginPayloadCreate(out _handle, Interop.AittPluginPayload.PayloadType.Data); + Interop.AittPluginPayload.AittPluginPayloadSetData(_handle, data, data?.Length ?? -1); + } + + public override PayloadType PayloadType + { + get + { + return PayloadType.DataPayload; + } + } + + public byte[] Data + { + get + { + Interop.AittPluginPayload.AittPluginPayloadGetData(_handle, out IntPtr byteArrPtr, out int size); + byte[] byteArr = new byte[size]; + Marshal.Copy(byteArrPtr, byteArr, 0, size); + return byteArr; + } + set + { + Interop.AittPluginPayload.AittPluginPayloadSetData(_handle, value, value?.Length ?? 0); + } + } + } +)__cs_cb"; + +constexpr char CB_FILE_PAYLOAD[] = +R"__cs_cb( + public class FilePayload : Payload + { + private readonly string LogTag = "Tizen.Applications.AittPlugin"; + + internal FilePayload(PayloadSafeHandle handle) + { + _handle = handle; + } + + public FilePayload(string path) + { + Interop.AittPluginPayload.AittPluginPayloadCreate(out _handle, Interop.AittPluginPayload.PayloadType.File); + Interop.AittPluginPayload.AittPluginPayloadSetFilePath(_handle, path); + } + + public string ReceivedFileName + { + get + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginPayload.AittPluginPayloadGetReceivedFileName(_handle, out string path); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + // property should not throw exception. + return ""; + } + return path; + } + } + + public UInt64 ReceivedBytes + { + get + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginPayload.AittPluginPayloadGetReceivedBytes(_handle, out UInt64 bytes); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to get received bytes."); + return Byte.MinValue; + } + return bytes; + } + } + + public UInt64 TotalBytes + { + get + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginPayload.AittPluginPayloadGetTotalBytes(_handle, out UInt64 bytes); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to get total bytes."); + return Byte.MinValue; + } + return bytes; + } + } + + public override PayloadType PayloadType + { + get + { + return PayloadType.FilePayload; + } + } + + public void SaveAsFile(string path) + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginPayload.AittPluginPayloadSaveAsFile(_handle, path); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to save as file."); + } + } + } +)__cs_cb"; + +constexpr char CB_GROUP_BASE[] = +R"__cs_cb( + public abstract class GroupBase : IDisposable + { + private readonly string LogTag = "Tizen.Applications.AittPlugin"; + private readonly GroupSafeHandle _handle; + + private Interop.AittPluginGroup.AittPluginGroupPayloadReceivedCb _payloadReceivedCb; + private Interop.AittPluginGroup.AittPluginGroupLeftCb _leftCb; + private Interop.AittPluginGroup.AittPluginGroupJoinedCb _joinedCb; + + public string Topic { get; } + + public GroupBase(string topicName, string brokerIp, int brokerPort, string userName, string password, string myIp, int protocol) + { + Topic = topicName; + + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginGroup.AittPluginGroupCreate(out _handle, topicName, brokerIp, brokerPort, userName, password, myIp, protocol); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to create group."); + } + + _payloadReceivedCb = new Interop.AittPluginGroup.AittPluginGroupPayloadReceivedCb( + (IntPtr group, IntPtr peerInfo, IntPtr payload, IntPtr userData) => + { + Payload receivedPayload; + Interop.AittPluginPayload.AittPluginPayloadGetType(payload, out Interop.AittPluginPayload.PayloadType type); + switch (type) + { + case Interop.AittPluginPayload.PayloadType.Data: + receivedPayload = new DataPayload(new PayloadSafeHandle(payload, false)); + break; + case Interop.AittPluginPayload.PayloadType.File: + receivedPayload = new FilePayload(new PayloadSafeHandle(payload, false)); + break; + default: + Log.Error(LogTag, "Invalid payload type received."); + return; + } + Interop.AittPlugin.ErrorCode clone_ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); + if (clone_ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to clone peer info."); + return; + } + OnPayloadReceived(receivedPayload, new PeerInfo(clone)); + }); + ret = Interop.AittPluginGroup.AittPluginGroupAddPayloadReceivedCb(_handle, _payloadReceivedCb, IntPtr.Zero); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + _handle.Dispose(); + throw AittPluginErrorFactory.GetException(ret, "Failed to add payload received callback."); + } + + _joinedCb = new Interop.AittPluginGroup.AittPluginGroupJoinedCb( + (string name, IntPtr peerInfo, IntPtr userData) => + { + Interop.AittPlugin.ErrorCode clone_ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); + if (clone_ret != Interop.AittPlugin.ErrorCode.None) + { + return; + } + OnJoined(new PeerInfo(clone)); + }); + ret = Interop.AittPluginGroup.AittPluginGroupAddJoinedCb(_handle, _joinedCb, IntPtr.Zero); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + _handle.Dispose(); + throw AittPluginErrorFactory.GetException(ret, "Failed to add joined callback."); + } + + _leftCb = new Interop.AittPluginGroup.AittPluginGroupLeftCb( + (string name, IntPtr peerInfo, IntPtr userData) => + { + Interop.AittPlugin.ErrorCode clone_ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); + if (clone_ret != Interop.AittPlugin.ErrorCode.None) + { + return; + } + OnLeft(new PeerInfo(clone)); + }); + ret = Interop.AittPluginGroup.AittPluginGroupAddLeftCb(_handle, _leftCb, IntPtr.Zero); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + _handle.Dispose(); + throw AittPluginErrorFactory.GetException(ret, "Failed to add joined callback."); + } + } + + public void Subscribe() + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginGroup.AittPluginGroupSubscribe(_handle); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to subscribe."); + } + } + + public void Unsubscribe() + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginGroup.AittPluginGroupUnsubscribe(_handle); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, string.Format("Failed to unsubscribe: {0}", ret)); + } + } + + public void Publish(Payload payload) + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginGroup.AittPluginGroupPublish(_handle, payload?._handle); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to publish payload."); + } + } + + protected abstract void OnPayloadReceived(Payload payload, PeerInfo peer); + protected abstract void OnJoined(PeerInfo peerInfo); + protected abstract void OnLeft(PeerInfo peerInfo); + + private bool disposedValue = false; + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + _handle.Dispose(); + } + disposedValue = true; + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +)__cs_cb"; + +constexpr char CB_GROUP_SAFE_HANDLE[] = +R"__cs_cb( + 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.AittPluginGroup.AittPluginGroupDestroy(this.handle); + SetHandle(IntPtr.Zero); + return true; + } + } +)__cs_cb"; + +constexpr char CB_PAYLOAD[] = +R"__cs_cb( + public abstract class Payload + { + private readonly string LogTag = "Tizen.Applications.AittPlugin"; + internal PayloadSafeHandle _handle; + + public abstract PayloadType PayloadType { get; } + + public string Id + { + get + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginPayload.AittPluginPayloadGetPayloadID(_handle, out string id); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to get id of payload."); + return ""; + } + return id; + } + } + } +)__cs_cb"; + +constexpr char CB_PAYLOAD_ASYNC_RESULT[] = +R"__cs_cb( + 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.AittPlugin.ErrorCode ret = Interop.AittPluginPayloadAsyncResult.AittPluginPayloadAsyncResultGetResult(handle, out int code); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Fail to get result code from the AsyncResult"); + } + + ret = Interop.AittPluginPayloadAsyncResult.AittPluginPayloadAsyncResultGetPayloadID(handle, out string payloadId); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Fail to get payload id from the AsyncResult"); + } + + ret = Interop.AittPluginPayloadAsyncResult.AittPluginPayloadAsyncResultGetPeerInfo(handle, out IntPtr peer); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Fail to get peerinfo from the AsyncResult"); + } + ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoClone(peer, out PeerInfoSafeHandle clone); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to clone peer info."); + } + + return new PayloadAsyncResult((PayloadAsyncResultCode)code, new PeerInfo(clone), payloadId); + } + + public PayloadAsyncResultCode Result { get; } + + public PeerInfo PeerInfo { get; } + + public string PayloadId { get; } + + private bool disposedValue = false; + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + PeerInfo?.Dispose(); + } + disposedValue = true; + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +)__cs_cb"; + +constexpr char CB_PAYLOAD_ASYNC_RESULT_CODE[] = +R"__cs_cb( + public enum PayloadAsyncResultCode + { + Error = -1, + Pending = 0, + Success, + Fail, + } +)__cs_cb"; + +constexpr char CB_PAYLOAD_SAFE_HANDLE[] = +R"__cs_cb( + 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.AittPluginPayload.AittPluginPayloadDestroy(this.handle); + SetHandle(IntPtr.Zero); + return true; + } + } +)__cs_cb"; + +constexpr char CB_PAYLOAD_TRANSFER_STATUS[] = +R"__cs_cb( + public enum PayloadTransferStatus + { + Success, + Failure, + InProgress, + } +)__cs_cb"; + +constexpr char CB_PAYLOAD_TYPE[] = +R"__cs_cb( + public enum PayloadType + { + DataPayload, + FilePayload, + } +)__cs_cb"; + +constexpr char CB_PEER_INFO[] = +R"__cs_cb( + public class PeerInfo : IDisposable + { + private readonly string LogTag = "Tizen.Applications.AittPlugin"; + internal PeerInfoSafeHandle _handle; + + internal PeerInfo(PeerInfoSafeHandle handle) + { + _handle = handle; + } + + public string DeviceId + { + get + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoGetDeviceId(_handle, out string deviceId); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to get device id."); + return ""; + } + return deviceId; + } + } + + public string DeviceName + { + get + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoGetDeviceName(_handle, out string deviceName); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to get device name."); + return ""; + } + return deviceName; + } + } + + public string DevicePlatform + { + get + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoGetDevicePlatform(_handle, out string devicePlatform); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to get device platform."); + return ""; + } + return devicePlatform; + } + } + + public string DevicePlatformVersion + { + get + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoGetDevicePlatformVersion(_handle, out string devicePlatformVersion); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to get device platform version."); + return ""; + } + return devicePlatformVersion; + } + } + + public string DeviceType + { + get + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoGetDeviceType(_handle, out string deviceType); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to get device platform type."); + return ""; + } + return deviceType; + } + } + + public string AppId + { + get + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoGetAppId(_handle, out string AppId); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to get application id."); + return ""; + } + return AppId; + } + } + + public string AppVersion + { + get + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoGetAppVersion(_handle, out string AppVersion); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to get application version."); + return ""; + } + return AppVersion; + } + } + + public string UUID + { + get + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoGetUuid(_handle, out string uuid); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to get UUID."); + return ""; + } + return uuid; + } + } + + private bool disposedValue = false; + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + _handle.Dispose(); + } + disposedValue = true; + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +)__cs_cb"; + +constexpr char CB_PEER_INFO_SAFE_HANDLE[] = +R"__cs_cb( + 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.AittPluginPeerInfo.AittPluginPeerInfoDestroy(this.handle); + SetHandle(IntPtr.Zero); + return true; + } + } +)__cs_cb"; + +constexpr char CB_SERVER_BASE[] = +R"__cs_cb( + public abstract class ServerBase : IDisposable + { + private readonly string LogTag = "Tizen.Applications.AittPlugin"; + + private string _displayName; + private readonly ServerSafeHandle _handle; + private Interop.AittPluginServer.AittPluginServerConnectionRequestCb _connectionRequestCb; + private Interop.AittPluginServer.AittPluginServerConnectionResultCb _connectionResultCb; + private Interop.AittPluginServer.AittPluginServerDataReceivedCb _dataReceivedCb; + private Interop.AittPluginServer.AittPluginServerPayloadReceivedCb _payloadRecievedCb; + private Interop.AittPluginServer.AittPluginServerDisconnectedCb _disconnectedCb; + private Interop.AittPluginServer.AittPluginServerPayloadAsyncResultCb _payloadAsyncResultCb; + private Dictionary, TaskCompletionSource> _tcsDictionary = new Dictionary, TaskCompletionSource>(); + + public string ServiceName { get; } + + public string DisplayName + { + get + { + return _displayName; + } + + set + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginServer.AittPluginServerSetDisplayName(_handle, value); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, string.Format("Failed to set display name: {0}", ret)); + } + else + { + _displayName = value; + } + } + } + + public ServerBase(string serviceName, string displayName, string brokerIp, int brokerPort, string userName, string password, string myIp, int port) + { + ServiceName = serviceName; + _displayName = displayName; + + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginServer.AittPluginServerCreate(out _handle, serviceName, displayName, brokerIp, brokerPort, userName, password, myIp, port); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to create server handle."); + } + + _connectionResultCb = new Interop.AittPluginServer.AittPluginServerConnectionResultCb( + (string service, IntPtr peerInfo, IntPtr result, IntPtr userData) => + { + Interop.AittPlugin.ErrorCode clone_ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); + if (clone_ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to clone peer info."); + return; + } + OnConnectionResult(new PeerInfo(clone), new ConnectionResult(result)); + }); + ret = Interop.AittPluginServer.AittPluginServerAddConnectionResultCb(_handle, _connectionResultCb, IntPtr.Zero); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + _handle.Dispose(); + throw AittPluginErrorFactory.GetException(ret, "Failed to add connection status changed callback."); + } + + _dataReceivedCb = new Interop.AittPluginServer.AittPluginServerDataReceivedCb( + (string service, IntPtr peerInfo, IntPtr data, int dataSize, out IntPtr returnData, out int returnDataSize, IntPtr userData) => + { + Interop.AittPlugin.ErrorCode clone_ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); + if (clone_ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to clone peer info."); + returnData = IntPtr.Zero; + returnDataSize = -1; + } + byte[] receivedData = new byte[dataSize]; + Marshal.Copy(data, receivedData, 0, dataSize); + byte[] returnDataRaw = OnDataReceived(receivedData, new PeerInfo(clone)); + returnDataSize = returnDataRaw.Length; + returnData = Interop.AittPlugin.Malloc(returnDataSize); + Marshal.Copy(returnDataRaw, 0, returnData, returnDataSize); + }); + ret = Interop.AittPluginServer.AittPluginServerSetDataReceivedCb(_handle, _dataReceivedCb, IntPtr.Zero); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + _handle.Dispose(); + throw AittPluginErrorFactory.GetException(ret, "Failed to set data received callback."); + } + + _payloadRecievedCb = new Interop.AittPluginServer.AittPluginServerPayloadReceivedCb( + (string service, IntPtr peerInfo, IntPtr payload, int status, IntPtr userData) => + { + Payload receivedPayload; + Interop.AittPluginPayload.AittPluginPayloadGetType(payload, out Interop.AittPluginPayload.PayloadType type); + switch (type) + { + case Interop.AittPluginPayload.PayloadType.Data: + receivedPayload = new DataPayload(new PayloadSafeHandle(payload, false)); + break; + case Interop.AittPluginPayload.PayloadType.File: + receivedPayload = new FilePayload(new PayloadSafeHandle(payload, false)); + break; + default: + Log.Error(LogTag, "Invalid payload type received."); + return; + } + Interop.AittPlugin.ErrorCode clone_ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); + if (clone_ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to clone peer info."); + return; + } + OnPayloadReceived(receivedPayload, new PeerInfo(clone), (PayloadTransferStatus)status); + }); + ret = Interop.AittPluginServer.AittPluginServerAddPayloadReceivedCb(_handle, _payloadRecievedCb, IntPtr.Zero); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + _handle.Dispose(); + throw AittPluginErrorFactory.GetException(ret, "Failed to add payload received callback."); + } + + _disconnectedCb = new Interop.AittPluginServer.AittPluginServerDisconnectedCb( + (string service, IntPtr peerInfo, IntPtr userData) => + { + Interop.AittPlugin.ErrorCode clone_ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); + if (clone_ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, string.Format("Failed to clone peer info.")); + return; + } + OnDisconnected(new PeerInfo(clone)); + }); + ret = Interop.AittPluginServer.AittPluginServerAddDisconnectedCb(_handle, _disconnectedCb, IntPtr.Zero); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + _handle.Dispose(); + throw AittPluginErrorFactory.GetException(ret, "Failed to add disconnected callback."); + } + } + + public void Listen() + { + if (_connectionRequestCb == null) + { + Interop.AittPluginServer.AittPluginServerConnectionRequestCb cb = new Interop.AittPluginServer.AittPluginServerConnectionRequestCb( + (serviceName, peerInfo, userData) => + { + Interop.AittPlugin.ErrorCode clone_ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); + if (clone_ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to clone peer info"); + return; + } + OnConnectionRequest(new PeerInfo(clone)); + }); + _connectionRequestCb = cb; + } + + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginServer.AittPluginServerListen(_handle, _connectionRequestCb, IntPtr.Zero); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to listen server."); + } + } + + public void Stop() + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginServer.AittPluginServerStop(_handle); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to stop server."); + } + } + + public void Disconnect(PeerInfo peerInfo) + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginServer.AittPluginServerDisconnect(_handle, peerInfo?._handle); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to stop server."); + } + } + + public Task SendPayloadAsync(Payload payload, PeerInfo peerInfo) + { + if (payload == null || payload.Id.Length == 0 || peerInfo == null || peerInfo.UUID.Length == 0) + { + throw new ArgumentException("Payload or peerinfo is invalid."); + } + + TaskCompletionSource tcs = new TaskCompletionSource(); + _tcsDictionary[Tuple.Create(payload.Id, peerInfo.UUID)] = tcs; + + if (_payloadAsyncResultCb == null) + { + Interop.AittPluginServer.AittPluginServerPayloadAsyncResultCb cb = new Interop.AittPluginServer.AittPluginServerPayloadAsyncResultCb( + (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 tcsToReturn = _tcsDictionary[Tuple.Create(resultPayload.PayloadId, resultPayload.PeerInfo.UUID)]; + tcsToReturn.SetResult(resultPayload); + _tcsDictionary.Remove(Tuple.Create(resultPayload.PayloadId, resultPayload.PeerInfo.UUID)); + }); + _payloadAsyncResultCb = cb; + } + + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginServer.AittPluginServerSendPayloadAsync(_handle, peerInfo?._handle, payload?._handle, _payloadAsyncResultCb, IntPtr.Zero); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to send payload."); + } + + return tcs.Task; + } + + public void SendPayloadAsync(Payload payload) + { + var peerList = GetConnectedPeerList(); + foreach (var peer in peerList) + { + SendPayloadAsync(payload, peer); + } + } + + public void Accept(PeerInfo peerInfo) + { + Interop.AittPluginServer.AittPluginServerAccept(_handle, peerInfo?._handle); + } + + public void Reject(PeerInfo peerInfo, string reason) + { + Interop.AittPluginServer.AittPluginServerReject(_handle, peerInfo?._handle, reason); + } + + public IEnumerable GetConnectedPeerList() + { + List peerInfoList = new List(); + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginServer.AittPluginServerForeachConnectedPeerInfo(_handle, (peer, userData) => + { + Interop.AittPlugin.ErrorCode clone_ret = Interop.AittPluginPeerInfo.AittPluginPeerInfoClone(peer, out PeerInfoSafeHandle clone); + if (clone_ret != Interop.AittPlugin.ErrorCode.None) + { + Log.Error(LogTag, "Failed to clone peer info."); + return false; + } + peerInfoList.Add(new PeerInfo(clone)); + return true; + }, IntPtr.Zero); + return peerInfoList; + } + + public void SetOndemandLaunchEnabled(bool enable) + { + Interop.AittPlugin.ErrorCode ret = Interop.AittPluginServer.AittPluginServerSetOnDemandLaunchEnabled(_handle, enable); + if (ret != Interop.AittPlugin.ErrorCode.None) + { + throw AittPluginErrorFactory.GetException(ret, "Failed to set ondemand launch enable"); + } + } + + protected abstract void OnConnectionResult(PeerInfo peerInfo, ConnectionResult result); + protected abstract byte[] OnDataReceived(byte[] data, PeerInfo peerInfo); + protected abstract void OnPayloadReceived(Payload data, PeerInfo peerInfo, PayloadTransferStatus status); + protected abstract void OnConnectionRequest(PeerInfo peerInfo); + protected abstract void OnDisconnected(PeerInfo peerInfo); + + private bool disposedValue = false; + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + _handle.Dispose(); + } + disposedValue = true; + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +)__cs_cb"; + +constexpr char CB_SERVER_SAFE_HANDLE[] = +R"__cs_cb( + 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.AittPluginServer.AittPluginServerDestroy(this.handle); + SetHandle(IntPtr.Zero); + return true; + } + } +)__cs_cb"; + +#endif // IDLC_GEN_AITT_PLUGIN_AITT_PLUGIN_CS_BASE_GEN_CB_H_ diff --git a/idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen.cc b/idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen.cc new file mode 100644 index 0000000..9385d9a --- /dev/null +++ b/idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen.cc @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#include "idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen.h" + +#include "idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen_cb.h" + +namespace tidl { + +AittPluginCsInteropGen::AittPluginCsInteropGen(std::shared_ptr doc, + std::shared_ptr trans) : CionPluginBase(doc, trans) { +} + +void AittPluginCsInteropGen::OnInitGen(std::ofstream& stream) { + GenUsing(stream); + stream << "internal static partial class Interop\n"; + stream << "{\n"; + GenLibraries(stream); + GenErrorCode(stream); + GenMalloc(stream); + GenInterop(stream); + stream << "}\n"; +} + +void AittPluginCsInteropGen::OnFiniGen(std::ofstream& stream) { +} + +void AittPluginCsInteropGen::GenUsing(std::ofstream& stream) { + stream << CB_INTEROP_USING; +} + +void AittPluginCsInteropGen::GenLibraries(std::ofstream& stream) { + stream << CB_LIBRARIES; +} + +void AittPluginCsInteropGen::GenErrorCode(std::ofstream& stream) { + stream << CB_ERROR_CODE; +} + +void AittPluginCsInteropGen::GenMalloc(std::ofstream& stream) { + stream << CB_INTEROP_MALLOC; +} + +void AittPluginCsInteropGen::GenInterop(std::ofstream& stream) { + stream << CB_INTEROP_PAYLOAD; + stream << CB_INTEROP_PAYLOAD_ASYNC_RESULT; + stream << CB_INTEROP_PEER_INFO; + stream << CB_INTEROP_CONNECTION_RESULT; + switch (GetType()) { + // client + case 1: + stream << CB_INTEROP_CLIENT; + break; + // server + case 2: + stream << CB_INTEROP_SERVER; + break; + // group + case 3: + stream << CB_INTEROP_GROUP; + break; + default: + break; + } +} + +} // namespace tidl diff --git a/idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen.h b/idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen.h new file mode 100644 index 0000000..87ed016 --- /dev/null +++ b/idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#ifndef IDLC_GEN_AITT_PLUGIN_AITT_PLUGIN_CS_INTEROP_GEN_H_ +#define IDLC_GEN_AITT_PLUGIN_AITT_PLUGIN_CS_INTEROP_GEN_H_ + +#include + +#include "idlc/gen_cion/cion_plugin_base.h" + +namespace tidl { + +class AittPluginCsInteropGen : public CionPluginBase { + public: + explicit AittPluginCsInteropGen(std::shared_ptr doc, + std::shared_ptr trans); + virtual ~AittPluginCsInteropGen() = default; + + void OnInitGen(std::ofstream& stream) override; + void OnFiniGen(std::ofstream& stream) override; + + private: + void GenUsing(std::ofstream& stream); + void GenLibraries(std::ofstream& stream); + void GenErrorCode(std::ofstream& stream); + void GenMalloc(std::ofstream& stream); + void GenInterop(std::ofstream& stream); +}; + +} // namespace tidl + +#endif // IDLC_GEN_AITT_PLUGIN_AITT_PLUGIN_CS_INTEROP_GEN_H_ diff --git a/idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen_cb.h b/idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen_cb.h new file mode 100644 index 0000000..6b3bb56 --- /dev/null +++ b/idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen_cb.h @@ -0,0 +1,374 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#ifndef IDLC_GEN_AITT_PLUGIN_AITT_PLUGIN_CS_INTEROP_GEN_CB_H_ +#define IDLC_GEN_AITT_PLUGIN_AITT_PLUGIN_CS_INTEROP_GEN_CB_H_ + +constexpr char CB_INTEROP_USING[] = +R"__cs_cb( +using System; +using System.Runtime.InteropServices; +using Tizen.Applications.AittPlugin; + +using ErrorCode = Interop.AittPlugin.ErrorCode; + +)__cs_cb"; + +constexpr char CB_LIBRARIES[] = +R"__cs_cb( + internal static partial class Libraries + { + public const string AittPlugin = "libaitt_plugin.so.1"; + public const string Libc = "libc.so.6"; + } +)__cs_cb"; + +constexpr char CB_ERROR_CODE[] = +R"__cs_cb( + internal static partial class AittPlugin + { + internal enum ErrorCode : int + { + None = Tizen.Internals.Errors.ErrorCode.None, + IoError = Tizen.Internals.Errors.ErrorCode.IoError, + OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory, + PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied, + InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter, + InvalidOperation = Tizen.Internals.Errors.ErrorCode.InvalidOperation, + AlreadyInProgress = Tizen.Internals.Errors.ErrorCode.AlreadyInProgress, + NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported, + TimedOut = Tizen.Internals.Errors.ErrorCode.TimedOut, + OperationFailed = -0x030C0000 | 0x01, + } + } +)__cs_cb"; + +constexpr char CB_INTEROP_MALLOC[] = +R"__cs_cb( + internal static partial class AittPlugin + { + [DllImport(Libraries.Libc, EntryPoint = "malloc")] + internal static extern IntPtr Malloc(int size); + } +)__cs_cb"; + +constexpr char CB_INTEROP_CLIENT[] = +R"__cs_cb( + internal static partial class AittPluginClient + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AittPluginClientServerDiscoveredCb(string serviceName, IntPtr peerInfo, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AittPluginClientConnectionResultCb(string serviceName, IntPtr peerInfo, IntPtr result, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AittPluginClientPayloadReceivedCb(string serviceName, IntPtr peerInfo, IntPtr payload, int status, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AittPluginClientDisconnectedCb(string serviceName, IntPtr peerInfo, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AittPluginClientPayloadAsyncResultCb(IntPtr result, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_client_create")] + internal static extern ErrorCode AittPluginClientCreate(out ClientSafeHandle client, string serviceName, string brokerIp, int brokerPort, string userName, string password, string myIp, int protocol); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_client_destroy")] + internal static extern ErrorCode AittPluginClientDestroy(IntPtr client); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_client_try_discovery")] + internal static extern ErrorCode AittPluginClientTryDiscovery(ClientSafeHandle client, AittPluginClientServerDiscoveredCb cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_client_stop_discovery")] + internal static extern ErrorCode AittPluginClientStopDiscovery(ClientSafeHandle client); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_client_connect")] + internal static extern ErrorCode AittPluginClientConnect(ClientSafeHandle client, PeerInfoSafeHandle peerInfo); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_client_disconnect")] + internal static extern ErrorCode AittPluginClientDisconnect(ClientSafeHandle client); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_client_send_data")] + internal static extern ErrorCode AittPluginClientSendData(ClientSafeHandle client, byte[] data, int dataSize, int timeout, out IntPtr returnData, out int returnDataSize); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_client_send_payload_async")] + internal static extern ErrorCode AittPluginClientSendPayloadAsync(ClientSafeHandle client, PayloadSafeHandle payload, AittPluginClientPayloadAsyncResultCb cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_client_add_connection_result_cb")] + internal static extern ErrorCode AittPluginClientAddConnectionResultCb(ClientSafeHandle client, AittPluginClientConnectionResultCb cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_client_remove_connection_result_cb")] + internal static extern ErrorCode AittPluginClientRemoveConnectionResultCb(ClientSafeHandle client, AittPluginClientConnectionResultCb cb); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_client_add_payload_received_cb")] + internal static extern ErrorCode AittPluginClientAddPayloadReceivedCb(ClientSafeHandle client, AittPluginClientPayloadReceivedCb cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_client_remove_payload_received_cb")] + internal static extern ErrorCode AittPluginClientRemovePayloadReceivedCb(ClientSafeHandle client, AittPluginClientPayloadReceivedCb cb); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_client_add_disconnected_cb")] + internal static extern ErrorCode AittPluginClientAddDisconnectedCb(ClientSafeHandle client, AittPluginClientDisconnectedCb cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_client_remove_disconnected_cb")] + internal static extern ErrorCode AittPluginClientRemoveDisconnectedCb(ClientSafeHandle client, AittPluginClientDisconnectedCb cb); + } +)__cs_cb"; + +constexpr char CB_INTEROP_CONNECTION_RESULT[] = +R"__cs_cb( + internal static partial class AittPluginConnectionResult + { + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_connection_result_get_status")] + internal static extern ErrorCode AittPluginConnectionResultGetStatus(IntPtr result, out ConnectionStatus status); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_connection_result_get_reason")] + internal static extern ErrorCode AittPluginConnectionResultGetReason(IntPtr result, out string reason); + } +)__cs_cb"; + +constexpr char CB_INTEROP_GROUP[] = +R"__cs_cb( + internal static partial class AittPluginGroup + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AittPluginGroupPayloadReceivedCb(IntPtr group, IntPtr peerInfo, IntPtr payload, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AittPluginGroupJoinedCb(string topicName, IntPtr peerInfo, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AittPluginGroupLeftCb(string topicName, IntPtr peerInfo, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_group_create")] + internal static extern ErrorCode AittPluginGroupCreate(out GroupSafeHandle group, string topicName, string brokerIp, int brokerPort, string userName, string password, string myIp, int protocol); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_group_destroy")] + internal static extern ErrorCode AittPluginGroupDestroy(IntPtr group); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_group_subscribe")] + internal static extern ErrorCode AittPluginGroupSubscribe(GroupSafeHandle group); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_group_unsubscribe")] + internal static extern ErrorCode AittPluginGroupUnsubscribe(GroupSafeHandle group); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_group_publish")] + internal static extern ErrorCode AittPluginGroupPublish(GroupSafeHandle group, PayloadSafeHandle data); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_group_add_payload_received_cb")] + internal static extern ErrorCode AittPluginGroupAddPayloadReceivedCb(GroupSafeHandle group, AittPluginGroupPayloadReceivedCb cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_group_remove_payload_received_cb")] + internal static extern ErrorCode AittPluginGroupRemovePayloadReceivedCb(GroupSafeHandle group, AittPluginGroupPayloadReceivedCb cb); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_group_add_joined_cb")] + internal static extern ErrorCode AittPluginGroupAddJoinedCb(GroupSafeHandle group, AittPluginGroupJoinedCb cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_group_remove_joined_cb")] + internal static extern ErrorCode AittPluginGroupRemoveJoinedCb(GroupSafeHandle group, AittPluginGroupJoinedCb cb); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_group_add_left_cb")] + internal static extern ErrorCode AittPluginGroupAddLeftCb(GroupSafeHandle group, AittPluginGroupLeftCb cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_group_remove_left_cb")] + internal static extern ErrorCode AittPluginGroupRemoveLeftCb(GroupSafeHandle group, AittPluginGroupLeftCb cb); + } +)__cs_cb"; + +constexpr char CB_INTEROP_PAYLOAD[] = +R"__cs_cb( + internal static partial class AittPluginPayload + { + internal enum PayloadType : int + { + Data, + File, + } + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_payload_create")] + internal static extern ErrorCode AittPluginPayloadCreate(out PayloadSafeHandle payload, PayloadType type); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_payload_destroy")] + internal static extern ErrorCode AittPluginPayloadDestroy(IntPtr payload); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_payload_get_type")] + internal static extern ErrorCode AittPluginPayloadGetType(IntPtr payload, out PayloadType type); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_payload_get_data")] + internal static extern ErrorCode AittPluginPayloadGetData(PayloadSafeHandle payload, out IntPtr data, out int dataSize); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_payload_set_data")] + internal static extern ErrorCode AittPluginPayloadSetData(PayloadSafeHandle payload, byte[] data, int dataSize); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_payload_save_as_file")] + internal static extern ErrorCode AittPluginPayloadSaveAsFile(PayloadSafeHandle payload, string path); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_payload_get_received_file_name")] + internal static extern ErrorCode AittPluginPayloadGetReceivedFileName(PayloadSafeHandle payload, out string path); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_payload_get_received_bytes")] + internal static extern ErrorCode AittPluginPayloadGetReceivedBytes(PayloadSafeHandle payload, out UInt64 bytes); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_payload_get_total_bytes")] + internal static extern ErrorCode AittPluginPayloadGetTotalBytes(PayloadSafeHandle payload, out UInt64 bytes); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_payload_set_file_path")] + internal static extern ErrorCode AittPluginPayloadSetFilePath(PayloadSafeHandle payload, string path); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_payload_get_payload_id")] + internal static extern ErrorCode AittPluginPayloadGetPayloadID(PayloadSafeHandle payload, out string id); + } +)__cs_cb"; + +constexpr char CB_INTEROP_PAYLOAD_ASYNC_RESULT[] = +R"__cs_cb( + internal static partial class AittPluginPayloadAsyncResult + { + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_payload_async_result_get_result")] + internal static extern ErrorCode AittPluginPayloadAsyncResultGetResult(IntPtr result, out int code); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_payload_async_result_get_peer_info")] + internal static extern ErrorCode AittPluginPayloadAsyncResultGetPeerInfo(IntPtr result, out IntPtr peerInfo); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_payload_async_result_get_payload_id")] + internal static extern ErrorCode AittPluginPayloadAsyncResultGetPayloadID(IntPtr result, out string payloadID); + } +)__cs_cb"; + +constexpr char CB_INTEROP_PEER_INFO[] = +R"__cs_cb( + internal static partial class AittPluginPeerInfo + { + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_peer_info_clone")] + internal static extern ErrorCode AittPluginPeerInfoClone(IntPtr peerInfo, out PeerInfoSafeHandle peerInfoClone); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_peer_info_destroy")] + internal static extern ErrorCode AittPluginPeerInfoDestroy(IntPtr peerInfo); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_peer_info_get_device_id")] + internal static extern ErrorCode AittPluginPeerInfoGetDeviceId(PeerInfoSafeHandle peerInfo, out string deviceId); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_peer_info_get_device_name")] + internal static extern ErrorCode AittPluginPeerInfoGetDeviceName(PeerInfoSafeHandle peerInfo, out string deviceName); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_peer_info_get_device_platform")] + internal static extern ErrorCode AittPluginPeerInfoGetDevicePlatform(PeerInfoSafeHandle peerInfo, out string devicePlatform); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_peer_info_get_device_platform_version")] + internal static extern ErrorCode AittPluginPeerInfoGetDevicePlatformVersion(PeerInfoSafeHandle peerInfo, out string devicePlatformVersion); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_peer_info_get_device_type")] + internal static extern ErrorCode AittPluginPeerInfoGetDeviceType(PeerInfoSafeHandle peerInfo, out string deviceType); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_peer_info_get_app_id")] + internal static extern ErrorCode AittPluginPeerInfoGetAppId(PeerInfoSafeHandle peerInfo, out string appId); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_peer_info_get_app_version")] + internal static extern ErrorCode AittPluginPeerInfoGetAppVersion(PeerInfoSafeHandle peerInfo, out string appVersion); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_peer_info_get_uuid")] + internal static extern ErrorCode AittPluginPeerInfoGetUuid(PeerInfoSafeHandle peerInfo, out string uuid); + } +)__cs_cb"; + +constexpr char CB_INTEROP_SERVER[] = +R"__cs_cb( + internal static partial class AittPluginServer + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool AittPluginServerPeerInfoIterator(IntPtr peerInfo, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AittPluginServerPayloadAsyncResultCb(IntPtr result, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AittPluginServerConnectionResultCb(string serviceName, IntPtr peerInfo, IntPtr result, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AittPluginServerDataReceivedCb(string serviceName, IntPtr peerInfo, IntPtr data, int dataSize, out IntPtr returnData, out int returnDataSize, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AittPluginServerPayloadReceivedCb(string serviceName, IntPtr peerInfo, IntPtr payload, int status, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AittPluginServerConnectionRequestCb(string serviceName, IntPtr peerInfo, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AittPluginServerErrorReportedCb(string serviceName, IntPtr peerInfo, int error, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AittPluginServerDisconnectedCb(string serviceName, IntPtr peerInfo, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_create")] + internal static extern ErrorCode AittPluginServerCreate(out ServerSafeHandle server, string serviceName, string displayName, string brokerIp, int brokerPort, string userName, string password, string myIp, int protocol); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_destroy")] + internal static extern ErrorCode AittPluginServerDestroy(IntPtr server); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_listen")] + internal static extern ErrorCode AittPluginServerListen(ServerSafeHandle server, AittPluginServerConnectionRequestCb cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_stop")] + internal static extern ErrorCode AittPluginServerStop(ServerSafeHandle server); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_accept")] + internal static extern ErrorCode AittPluginServerAccept(ServerSafeHandle server, PeerInfoSafeHandle peerInfo); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_reject")] + internal static extern ErrorCode AittPluginServerReject(ServerSafeHandle server, PeerInfoSafeHandle peerInfo, string reason); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_disconnect")] + internal static extern ErrorCode AittPluginServerDisconnect(ServerSafeHandle server, PeerInfoSafeHandle peerInfo); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_send_payload_async")] + internal static extern ErrorCode AittPluginServerSendPayloadAsync(ServerSafeHandle server, PeerInfoSafeHandle peerInfo, PayloadSafeHandle payload, AittPluginServerPayloadAsyncResultCb cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_foreach_connected_peer_info")] + internal static extern ErrorCode AittPluginServerForeachConnectedPeerInfo(ServerSafeHandle server, AittPluginServerPeerInfoIterator cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_add_connection_result_cb")] + internal static extern ErrorCode AittPluginServerAddConnectionResultCb(ServerSafeHandle server, AittPluginServerConnectionResultCb cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_remove_connection_result_cb")] + internal static extern ErrorCode AittPluginServerRemoveConnectionResultCb(ServerSafeHandle server, AittPluginServerConnectionResultCb cb); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_add_payload_received_cb")] + internal static extern ErrorCode AittPluginServerAddPayloadReceivedCb(ServerSafeHandle server, AittPluginServerPayloadReceivedCb cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_remove_payload_received_cb")] + internal static extern ErrorCode AittPluginServerRemovePayloadReceivedCb(ServerSafeHandle server, AittPluginServerPayloadReceivedCb cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_set_data_received_cb")] + internal static extern ErrorCode AittPluginServerSetDataReceivedCb(ServerSafeHandle server, AittPluginServerDataReceivedCb cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_unset_data_received_cb")] + internal static extern ErrorCode AittPluginServerUnsetDataReceivedCb(ServerSafeHandle server, AittPluginServerDataReceivedCb cb); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_add_disconnected_cb")] + internal static extern ErrorCode AittPluginServerAddDisconnectedCb(ServerSafeHandle server, AittPluginServerDisconnectedCb cb, IntPtr userData); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_remove_disconnected_cb")] + internal static extern ErrorCode AittPluginServerRemoveDisconnectedCb(ServerSafeHandle server, AittPluginServerDisconnectedCb cb); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_set_on_demand_launch_enabled")] + internal static extern ErrorCode AittPluginServerSetOnDemandLaunchEnabled(ServerSafeHandle server, bool enable); + + [DllImport(Libraries.AittPlugin, EntryPoint = "aitt_plugin_server_set_display_name")] + internal static extern ErrorCode AittPluginServerSetDisplayName(ServerSafeHandle server, string displayName); + } +)__cs_cb"; + +#endif // IDLC_GEN_AITT_PLUGIN_AITT_PLUGIN_CS_INTEROP_GEN_CB_H_ diff --git a/idlc/gen_aitt_plugin/aitt_plugin_cs_transportable.cc b/idlc/gen_aitt_plugin/aitt_plugin_cs_transportable.cc new file mode 100644 index 0000000..7d427c4 --- /dev/null +++ b/idlc/gen_aitt_plugin/aitt_plugin_cs_transportable.cc @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#include "idlc/gen_aitt_plugin/aitt_plugin_cs_transportable.h" + +#include + +#include "idlc/gen/replace_all.h" + +namespace { + +constexpr const char __USING[] = +R"__cs_cb( +using System; +using System.Collections.Generic; +using Tizen.Applications; +using Tizen.Applications.AittPlugin; +using Tizen.Applications.RPCPort; +)__cs_cb"; + +constexpr const char __FILE_SEND[] = +R"__cs_cb(if (path == null) + throw new ArgumentException("Invalid path"); + + Payload fp = new FilePayload(); + base.SendPayloadAsync(fp); +)__cs_cb"; + +constexpr const char __CLIENT_CTOR[] = +R"__cs_cb( + public ##(string serviceName, string brokerIp, int brokerPort, string userName, string password, string myIp, int protocol) : base(serviceName, brokerIp, brokerPort, userName, password, myIp, protocol) + { + ServiceName = serviceName; + } +)__cs_cb"; + +constexpr const char __GROUP_CTOR[] = +R"__cs_cb( + public ##(string topicName, string brokerIp, int brokerPort, string userName, string password, string myIp, int protocol) : base(topicName, brokerIp, brokerPort, userName, password, myIp, protocol) + { + TopicName = topicName; + try + { + base.Subscribe(); + } + catch + { + throw; + } + } +)__cs_cb"; + +constexpr const char __SERVER_CTOR[] = +R"__cs_cb( + public ##(string serviceName, string displayName, string brokerIp, int brokerPort, string userName, string password, string myIp, int protocol) : base(serviceName, displayName, brokerIp, brokerPort, userName, password, myIp, protocol) + { + } +)__cs_cb"; + +} // namespace + +namespace tidl { + +std::string AittPluginCsTransportable::GenInclude() const { + return __USING; +} + +std::string AittPluginCsTransportable::GenFileSend(std::string path) const { + return std::string(ReplaceAll(__FILE_SEND, { + { "", path } })); +} + +std::string AittPluginCsTransportable::GenGroupType() const { + return "GroupBase"; +} + +std::string AittPluginCsTransportable::GenPayloadTransferStatusType() const { + return "PayloadTransferStatus"; +} + +std::string AittPluginCsTransportable::GenPeerInfoType() const { + return "PeerInfo"; +} + +std::string AittPluginCsTransportable::GenPayloadType() const { + return "Payload"; +} + +std::string AittPluginCsTransportable::GenClientType() const { + return "ClientBase"; +} + +std::string AittPluginCsTransportable::GenServerType() const { + return "ServerBase"; +} + +std::string AittPluginCsTransportable::GenClientExtraHeader() const { + return ""; +} + +std::string AittPluginCsTransportable::GenClientExtraBody() const { + return ""; +} + +std::string AittPluginCsTransportable::GenServerExtraHeader() const { + return ""; +} + +std::string AittPluginCsTransportable::GenServerExtraBody() const { + return ""; +} + +std::string AittPluginCsTransportable::GenPayloadTypeData() const { + return "PayloadType.DataPayload"; +} + +std::string AittPluginCsTransportable::GenPayloadTypeFile() const { + return "PayloadType.FilePayload"; +} + +std::string AittPluginCsTransportable::GenClientBaseCtor( + const Interface& iface) const { + std::string ctor(ReplaceAll(__CLIENT_CTOR, "##", iface.GetID())); + return ctor; +} + +std::string AittPluginCsTransportable::GenGroupBaseCtor( + const Interface& iface) const { + std::string ctor(ReplaceAll(__GROUP_CTOR, "##", iface.GetID())); + return ctor; +} + +std::string AittPluginCsTransportable::GenServerBaseCtor( + const Interface& iface) const { + std::string ctor(ReplaceAll(__SERVER_CTOR, "##", iface.GetID())); + return ctor; +} + +} // namespace tidl diff --git a/idlc/gen_aitt_plugin/aitt_plugin_cs_transportable.h b/idlc/gen_aitt_plugin/aitt_plugin_cs_transportable.h new file mode 100644 index 0000000..fdaf949 --- /dev/null +++ b/idlc/gen_aitt_plugin/aitt_plugin_cs_transportable.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#ifndef IDLC_GEN_AITT_PLUGIN_AITT_PLUGIN_CS_TRANSPORTABLE_H_ +#define IDLC_GEN_AITT_PLUGIN_AITT_PLUGIN_CS_TRANSPORTABLE_H_ + +#include + +#include "idlc/gen_cion/cs_transportable.h" + +namespace tidl { + +class AittPluginCsTransportable : public CsTransportable { + public: + virtual ~AittPluginCsTransportable() = default; + std::string GenInclude() const override; + std::string GenFileSend(std::string path) const override; + std::string GenGroupType() const override; + std::string GenPayloadTransferStatusType() const override; + std::string GenPeerInfoType() const override; + std::string GenPayloadType() const override; + std::string GenClientType() const override; + std::string GenServerType() const override; + std::string GenClientExtraHeader() const override; + std::string GenClientExtraBody() const override; + std::string GenServerExtraHeader() const override; + std::string GenServerExtraBody() const override; + std::string GenPayloadTypeData() const override; + std::string GenPayloadTypeFile() const override; + std::string GenClientBaseCtor(const Interface& iface) const override; + std::string GenGroupBaseCtor(const Interface& iface) const override; + std::string GenServerBaseCtor(const Interface& iface) const override; +}; + +} // namespace tidl + +#endif // IDLC_GEN_AITT_PLUGIN_AITT_PLUGIN_CS_TRANSPORTABLE_H_ diff --git a/idlc/gen_aitt_plugin/aitt_plugin_loader.cc b/idlc/gen_aitt_plugin/aitt_plugin_loader.cc index 6df5431..984a4af 100644 --- a/idlc/gen_aitt_plugin/aitt_plugin_loader.cc +++ b/idlc/gen_aitt_plugin/aitt_plugin_loader.cc @@ -17,6 +17,7 @@ #include "idlc/gen_aitt_plugin/aitt_plugin_loader.h" #include "idlc/gen_aitt_plugin/aitt_plugin_c_transportable.h" +#include "idlc/gen_aitt_plugin/aitt_plugin_cs_transportable.h" #include "idlc/gen_aitt_plugin/aitt_plugin_java_transportable.h" #include "idlc/gen_cion/default_cpp_transportable.h" #include "idlc/gen_cion/default_java_transportable.h" @@ -28,7 +29,7 @@ AIttPluginLoader::AIttPluginLoader(const std::string& plugin_path) { if (plugin_path.empty()) { C_.reset(new AittPluginCTransportable()); // Cpp_.reset(new DefaultCppTransportable()); -// Cs_.reset(new DefaultCsTransportable()); + Cs_.reset(new AittPluginCsTransportable()); Java_.reset(new AittPluginJavaTransportable()); } else { // TODO diff --git a/idlc/gen_cion/cs_cion_group_gen.cc b/idlc/gen_cion/cs_cion_group_gen.cc index 1a0d795..1924610 100644 --- a/idlc/gen_cion/cs_cion_group_gen.cc +++ b/idlc/gen_cion/cs_cion_group_gen.cc @@ -104,48 +104,7 @@ void CsCionGroupGen::GenEvent(std::ofstream& stream, const Declaration& decl) { } void CsCionGroupGen::GenCtor(std::ofstream& stream, const Interface& iface) { - bool securityCheck = false; - stream << NLine(1); - std::string m = - "/// \n" - "/// Constructor for this class\n" - "/// \n" - "/// http://tizen.org/privilege/d2d.datasharing\n" - "/// http://tizen.org/privilege/internet\n" - "/// The maximum length of topic name is 512.\n" - "/// \n" - "/// Thrown when the given topic name is too long.\n" - "/// \n" - "/// \n" - "/// Thrown when an application does not have the privilege.\n" - "/// \n" - "public ##(string topicName) : base(topicName, new SecurityInfo {"; - - for (const auto& attr : iface.GetAttributes()) { - if (attr->GetKey() == "ca_path") { - m += "CaPath = \"" + attr->GetValue() + "\", "; - securityCheck = true; - } else if (attr->GetKey() == "cert_path") { - m += "CertPath = \"" + attr->GetValue() + "\", "; - securityCheck = true; - } else if (attr->GetKey() == "private_key") { - m += "PrivateKeyPath = \"" + attr->GetValue() + "\", "; - securityCheck = true; - } - } - - auto const pos = m.find_last_of(','); - m = m.substr(0, pos); - - if (securityCheck) - m += "})";/* base(serviceName, new SecurityInfo {CertPath = xxx, ... ) */ - else - m += ")"; /* base(serviceName) */ - m = AddIndent(TAB_SIZE * 3, m); - m.pop_back(); - m += CB_CTOR_BODY; - - stream << ReplaceAll(m, "##", iface.GetID()); + stream << GetTransportable().Cs().GenGroupBaseCtor(iface); } void CsCionGroupGen::GenFinalizer(std::ofstream& stream, diff --git a/idlc/gen_cion/cs_cion_group_gen_cb.h b/idlc/gen_cion/cs_cion_group_gen_cb.h index dd01b14..09d3813 100644 --- a/idlc/gen_cion/cs_cion_group_gen_cb.h +++ b/idlc/gen_cion/cs_cion_group_gen_cb.h @@ -39,21 +39,6 @@ R"__cs_cb( public delegate void JoinedHandler(object sender, GetKey() == "ca_path") { - m += "CaPath = \"" + attr->GetValue() + "\", "; - securityCheck = true; - } else if (attr->GetKey() == "cert_path") { - m += "CertPath = \"" + attr->GetValue() + "\", "; - securityCheck = true; - } else if (attr->GetKey() == "private_key") { - m += "PrivateKeyPath = \"" + attr->GetValue() + "\", "; - securityCheck = true; - } - } - - auto const pos = m.find_last_of(','); - m = m.substr(0, pos); - - if (securityCheck) - m += "})";/* base(serviceName, new SecurityInfo {CertPath = xxx, ... ) */ - else - m += ")"; /* base(serviceName) */ - - m += NLine(1); - m += "{\n"; - m += " ServiceName = serviceName;\n"; - m += "}"; - - GenTemplate(AddIndent(TAB_SIZE * 3, m), stream, - [&]()->std::string { - return iface.GetID(); - }); + stream << GetTransportable().Cs().GenClientBaseCtor(iface); } void CsCionProxyGen::GenConnectMethods(std::ofstream& stream, diff --git a/idlc/gen_cion/cs_cion_stub_gen.cc b/idlc/gen_cion/cs_cion_stub_gen.cc index 1b20fdd..82f24d4 100644 --- a/idlc/gen_cion/cs_cion_stub_gen.cc +++ b/idlc/gen_cion/cs_cion_stub_gen.cc @@ -284,38 +284,7 @@ void CsCionStubGen::GenDisconnectedEvent(std::ofstream& stream) { } void CsCionStubGen::GenCtor(std::ofstream& stream, const Interface& iface) { - bool securityCheck = false; - std::string m = "public $$(string serviceName, string displayName) : base(serviceName, displayName, new SecurityInfo {"; - - for (const auto& attr : iface.GetAttributes()) { - if (attr->GetKey() == "ca_path") { - m += "CaPath = \"" + attr->GetValue() + "\", "; - securityCheck = true; - } else if (attr->GetKey() == "cert_path") { - m += "CertPath = \"" + attr->GetValue() + "\", "; - securityCheck = true; - } else if (attr->GetKey() == "private_key") { - m += "PrivateKeyPath = \"" + attr->GetValue() + "\", "; - securityCheck = true; - } - } - - auto const pos = m.find_last_of(','); - m = m.substr(0, pos); - - if (securityCheck) - m += "})";/* base(serviceName, displayName, new SecurityInfo {CertPath = xxx, ... ) */ - else - m += ")"; /* base(serviceName, displayName) */ - - m += NLine(1); - m += "{\n"; - m += "}"; - - GenTemplate(AddIndent(TAB_SIZE * 3, m), stream, - [&]()->std::string { - return iface.GetID(); - }); + stream << GetTransportable().Cs().GenServerBaseCtor(iface); } void CsCionStubGen::GenCommonMethods(std::ofstream& stream) { diff --git a/idlc/gen_cion/cs_transportable.h b/idlc/gen_cion/cs_transportable.h index 317506d..419200a 100644 --- a/idlc/gen_cion/cs_transportable.h +++ b/idlc/gen_cion/cs_transportable.h @@ -19,6 +19,8 @@ #include +#include "idlc/ast/interface.h" + namespace tidl { class CsTransportable { @@ -38,6 +40,9 @@ class CsTransportable { virtual std::string GenServerExtraBody() const = 0; virtual std::string GenPayloadTypeData() const = 0; virtual std::string GenPayloadTypeFile() const = 0; + virtual std::string GenClientBaseCtor(const Interface& iface) const = 0; + virtual std::string GenGroupBaseCtor(const Interface& iface) const = 0; + virtual std::string GenServerBaseCtor(const Interface& iface) const = 0; }; } // namespace tidl diff --git a/idlc/gen_cion/default_cs_transportable.cc b/idlc/gen_cion/default_cs_transportable.cc index 010be78..68b26eb 100644 --- a/idlc/gen_cion/default_cs_transportable.cc +++ b/idlc/gen_cion/default_cs_transportable.cc @@ -34,10 +34,43 @@ constexpr const char __FILE_SEND[] = R"__cs_cb(if (path == null) throw new ArgumentException("Invalid path"); - fp = new FilePayload(); + Payload fp = new FilePayload(); base.SendPayloadAsync(fp); )__cs_cb"; +constexpr const char __CLIENT_CTOR[] = +R"__cs_cb( + public ##(string serviceName) : base(serviceName) + { + ServiceName = serviceName; + } +)__cs_cb"; + +constexpr const char __GROUP_CTOR[] = +R"__cs_cb( + public ##(string topicName) : base(topicName) + { + TopicName = topicName; + try + { + base.Subscribe(); + } + catch + { + throw; + } + } +)__cs_cb"; + +constexpr const char __SERVER_CTOR[] = +R"__cs_cb( + public ##(string serviceName, string displayName) : base(serviceName, displayName) + { + } +)__cs_cb"; + +constexpr int TAB_SIZE = 2; + } // namespace namespace tidl { @@ -99,4 +132,58 @@ std::string DefaultCsTransportable::GenPayloadTypeFile() const { return "PayloadType.FilePayload"; } +std::string DefaultCsTransportable::GenClientBaseCtor( + const Interface& iface) const { + return GenCtor(iface, CtorType::Client); +} + +std::string DefaultCsTransportable::GenGroupBaseCtor( + const Interface& iface) const { + return GenCtor(iface, CtorType::Group); +} + +std::string DefaultCsTransportable::GenServerBaseCtor( + const Interface& iface) const { + return GenCtor(iface, CtorType::Server); +} + +std::string DefaultCsTransportable::GenCtor( + const Interface& iface, CtorType type) const { + bool security_check = false; + std::string security = ", new Security {"; + for (const auto& attr : iface.GetAttributes()) { + if (attr->GetKey() == "ca_path") { + security += "CaPath = \"" + attr->GetValue() + "\", "; + security_check = true; + } else if (attr->GetKey() == "cert_path") { + security += "CertPath = \"" + attr->GetValue() + "\", "; + security_check = true; + } else if (attr->GetKey() == "private_key") { + security += "PrivateKeyPath = \"" + attr->GetValue() + "\", "; + security_check = true; + } + } + security += "}"; + + std::string base; + switch (type) { + case CtorType::Client: + base = __CLIENT_CTOR; + break; + case CtorType::Group: + base = __GROUP_CTOR; + break; + case CtorType::Server: + base = __SERVER_CTOR; + break; + } + + std::string ctor(ReplaceAll(base, { + { "", security_check ? security : "" }, + { "##", iface.GetID() }, + })); + + return ctor; +} + } // namespace tidl diff --git a/idlc/gen_cion/default_cs_transportable.h b/idlc/gen_cion/default_cs_transportable.h index 2f02641..d366d1a 100644 --- a/idlc/gen_cion/default_cs_transportable.h +++ b/idlc/gen_cion/default_cs_transportable.h @@ -19,6 +19,7 @@ #include +#include "idlc/ast/interface.h" #include "idlc/gen_cion/cs_transportable.h" namespace tidl { @@ -40,6 +41,17 @@ class DefaultCsTransportable : public CsTransportable { std::string GenServerExtraBody() const override; std::string GenPayloadTypeData() const override; std::string GenPayloadTypeFile() const override; + std::string GenClientBaseCtor(const Interface& iface) const override; + std::string GenGroupBaseCtor(const Interface& iface) const override; + std::string GenServerBaseCtor(const Interface& iface) const override; + + private: + enum class CtorType { + Client = 0, + Group = 1, + Server = 2, + }; + std::string GenCtor(const Interface& iface, CtorType type) const; }; } // namespace tidl diff --git a/idlc/main.cc b/idlc/main.cc index 1e72e51..7a4cbb5 100644 --- a/idlc/main.cc +++ b/idlc/main.cc @@ -56,6 +56,8 @@ #include "idlc/gen_aitt_plugin/aitt_plugin_internal_body_gen.h" #include "idlc/gen_aitt_plugin/aitt_plugin_c_transportable.h" #include "idlc/gen_aitt_plugin/aitt_plugin_loader.h" +#include "idlc/gen_aitt_plugin/aitt_plugin_cs_base_gen.h" +#include "idlc/gen_aitt_plugin/aitt_plugin_cs_interop_gen.h" #include "idlc/options.h" @@ -157,7 +159,16 @@ void GenerateStubCodes(std::shared_ptr options, } case tidl::Options::LANGUAGE_TYPE_CSHARP: { - break; + tidl::AittPluginCsInteropGen interop(ps.GetDoc(), trans); + interop.SetType(static_cast(options->GetType())); + interop.Run("Interop.AittPlugin.cs"); + tidl::AittPluginCsBaseGen base(ps.GetDoc(), trans); + base.SetType(static_cast(options->GetType())); + base.Run("AittPluginBase.cs"); + + tidl::CsCionStubGen stub(ps.GetDoc(), trans); + stub.Run(options->GetOutput() + ".cs"); + break; } case tidl::Options::LANGUAGE_TYPE_JAVA: { @@ -307,7 +318,16 @@ void GenerateProxyCodes(std::shared_ptr options, } case tidl::Options::LANGUAGE_TYPE_CSHARP: { - break; + tidl::AittPluginCsInteropGen interop(ps.GetDoc(), trans); + interop.SetType(static_cast(options->GetType())); + interop.Run("Interop.AittPlugin.cs"); + tidl::AittPluginCsBaseGen base(ps.GetDoc(), trans); + base.SetType(static_cast(options->GetType())); + base.Run("AittPluginBase.cs"); + + tidl::CsCionProxyGen proxy(ps.GetDoc(), trans); + proxy.Run(options->GetOutput() + ".cs"); + break; } case tidl::Options::LANGUAGE_TYPE_JAVA: { @@ -456,7 +476,16 @@ void GenerateGroupCodes(std::shared_ptr options, } case tidl::Options::LANGUAGE_TYPE_CSHARP: { - break; + tidl::AittPluginCsInteropGen interop(ps.GetDoc(), trans); + interop.SetType(static_cast(options->GetType())); + interop.Run("Interop.AittPlugin.cs"); + tidl::AittPluginCsBaseGen base(ps.GetDoc(), trans); + base.SetType(static_cast(options->GetType())); + base.Run("AittPluginBase.cs"); + + tidl::CsCionGroupGen group(ps.GetDoc(), trans); + group.Run(options->GetOutput() + ".cs"); + break; } case tidl::Options::LANGUAGE_TYPE_JAVA: { -- 2.7.4