internal static PayloadAsyncResult CreateFromHandle(IntPtr handle) { Interop.Cion.ErrorCode ret = Interop.CionPayloadAsyncResult.CionPayloadAsyncResultGetResult(handle, out int code); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Fail to get result code from the AsyncResult"); } ret = Interop.CionPayloadAsyncResult.CionPayloadAsyncResultGetPayloadID(handle, out string payloadId); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Fail to get payload id from the AsyncResult"); } ret = Interop.CionPayloadAsyncResult.CionPayloadAsyncResultGetPeerInfo(handle, out IntPtr peer); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Fail to get peerinfo from the AsyncResult"); } ret = Interop.CionPeerInfo.CionPeerInfoClone(peer, out PeerInfoSafeHandle clone); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to clone peer info."); } return(new PayloadAsyncResult((PayloadAsyncResultCode)code, new PeerInfo(clone), payloadId)); }
/// <summary> /// Starts discovering cion servers. /// </summary> /// <exception cref="InvalidOperationException">Thrown when the discovery operation is already in progress.</exception> /// <since_tizen> 9 </since_tizen> public void TryDiscovery() { Log.Error(LogTag, string.Format("Try discovery start")); if (_discoveredCb == null) { Interop.CionClient.CionClientDiscoveredCb cb = new Interop.CionClient.CionClientDiscoveredCb( (string serviceName, IntPtr peerInfo, IntPtr userData) => { Log.Error(LogTag, string.Format("callback called !!")); Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); if (clone_ret != Interop.Cion.ErrorCode.None) { Log.Error(LogTag, "Failed to clone peer info."); return; } OnDiscovered(new PeerInfo(clone)); }); _discoveredCb = cb; } Interop.Cion.ErrorCode ret = Interop.CionClient.CionClientTryDiscovery(_handle, _discoveredCb, IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to try discovery."); } }
/// <summary> /// Connects with the cion server. /// </summary> /// <param name="peer">The peer to connect.</param> /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege> /// <since_tizen> 9 </since_tizen> public void Connect(PeerInfo peer) { Interop.Cion.ErrorCode ret = Interop.CionClient.CionClientConnect(_handle, peer?._handle); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to connect."); } }
/// <summary> /// Stops the listen operation. /// </summary> /// <exception cref="InvalidOperationException">Thrown when the server is not listening.</exception> /// <since_tizen> 9 </since_tizen> public void Stop() { Interop.Cion.ErrorCode ret = Interop.CionServer.CionServerStop(_handle); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to stop server."); } }
/// <summary> /// Publishes payload to current group. /// </summary> /// <param name="payload">The payload to publish.</param> /// <exception cref="ArgumentException">Thrown when the payload is invalid.</exception> /// <since_tizen> 9 </since_tizen> public void Publish(Payload payload) { Interop.Cion.ErrorCode ret = Interop.CionGroup.CionGroupPublish(_handle, payload?._handle); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to publish payload."); } }
/// <summary> /// Saves file of payload to speicific path. /// </summary> /// <param name="path">The path of file to save.</param> /// <since_tizen> 9 </since_tizen> public void SaveAsFile(string path) { Interop.Cion.ErrorCode ret = Interop.CionPayload.CionPayloadSaveAsFile(_handle, path); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to save as file."); } }
/// <summary> /// Sets ondemand launch enabled flag. /// </summary> /// <param name="enable">Whether ondemand launch is enabled or not.</param> /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception> /// <privilege>http://tizen.org/privilege/d2d.remotelaunch</privilege> /// <since_tizen> 9 </since_tizen> public void SetOndemandLaunchEnabled(bool enable) { Interop.Cion.ErrorCode ret = Interop.CionServer.CionServerSetOndemandLaunchEnable(_handle, enable); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to set ondemand launch enable"); } }
/// <summary> /// Disconnects with the peer. /// </summary> /// <param name="peerInfo">The peer to disconnect.</param> /// <exception cref="ArgumentException">Thrown when the given peer info is invalid.</exception> /// <since_tizen> 9 </since_tizen> public void Disconnect(PeerInfo peerInfo) { Interop.Cion.ErrorCode ret = Interop.CionServer.CionServerDisconnect(_handle, peerInfo?._handle); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to stop server."); } }
/// <summary> /// Unsubscribes the topic. /// </summary> /// <since_tizen> 9 </since_tizen> public void Unsubscribe() { Interop.Cion.ErrorCode ret = Interop.CionGroup.CionGroupUnsubscribe(_handle); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to unsubscribe."); } }
/// <summary> /// Stops discovering. /// </summary> /// <exception cref="InvalidOperationException">Thrown when the client is not discovering.</exception> /// <since_tizen> 9 </since_tizen> public void StopDiscovery() { Interop.Cion.ErrorCode ret = Interop.CionClient.CionClientStopDiscovery(_handle); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to stop discovery."); } }
/// <summary> /// Disconnects from the cion server. /// </summary> /// <since_tizen> 9 </since_tizen> public void Disconnect() { Interop.Cion.ErrorCode ret = Interop.CionClient.CionClientDisconnect(_handle); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to disconnect."); } _peer = null; }
/// <summary> /// Sends data synchronously to the connected cion server. /// </summary> /// <param name="data">The data to send.</param> /// <param name="timeout">The timeout of sending operation.</param> /// <exception cref="ArgumentException">Thrown when the given data is invalid.</exception> /// <exception cref="InvalidOperationException">Thrown when there is no connected cion server.</exception> /// <since_tizen> 9 </since_tizen> public byte[] SendData(byte[] data, int timeout) { Interop.Cion.ErrorCode ret = Interop.CionClient.CionClientSendData(_handle, data, data?.Length ?? -1, timeout, out IntPtr returnDataPtr, out int returnDataSize); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to send data."); } byte[] returnData = new byte[returnDataSize]; Marshal.Copy(returnDataPtr, returnData, 0, returnDataSize); Log.Info(LogTag, string.Format("Returned data size: {0}", returnDataSize)); return(returnData); }
/// <summary> /// Gets connected peers. /// </summary> /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception> /// <since_tizen> 9 </since_tizen> public IEnumerable <PeerInfo> GetConnectedPeerList() { List <PeerInfo> peerInfoList = new List <PeerInfo>(); Interop.Cion.ErrorCode ret = Interop.CionServer.CionServerForeachConnectedPeerInfo(_handle, (peer, userData) => { Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peer, out PeerInfoSafeHandle clone); if (clone_ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(clone_ret, "Failed to clone peer info."); } peerInfoList.Add(new PeerInfo(clone)); }, IntPtr.Zero); return(peerInfoList); }
/// <summary> /// Sends payload asynchronously to the connected cion server. /// </summary> /// <param name="payload">The payload to send.</param> /// <exception cref="ArgumentException">Thrown when the payload is not valid.</exception> /// <exception cref="InvalidOperationException">Thrown when there is no connected cion server.</exception> /// <since_tizen> 9 </since_tizen> public Task <PayloadAsyncResult> SendPayloadAsync(Payload payload) { if (payload?.Id.Length == 0) { throw new ArgumentException("Payload is invalid."); } TaskCompletionSource <PayloadAsyncResult> tcs = new TaskCompletionSource <PayloadAsyncResult>(); _tcsDictionary[payload.Id] = tcs; if (_payloadAsyncResultCb == null) { Interop.CionClient.CionClientPayloadAsyncResultCb cb = new Interop.CionClient.CionClientPayloadAsyncResultCb( (IntPtr result, IntPtr userData) => { TaskCompletionSource <PayloadAsyncResult> tcsToReturn = _tcsDictionary[payload.Id]; PayloadAsyncResult resultPayload = null; try { resultPayload = PayloadAsyncResult.CreateFromHandle(result); } catch (Exception e) { Log.Error(LogTag, string.Format("Failed to create PayloadAsyncResult from result handle: {0}.", e.Message)); tcsToReturn.SetException(e); return; } tcsToReturn.SetResult(resultPayload); _tcsDictionary.Remove(resultPayload.PayloadId); }); _payloadAsyncResultCb = cb; } Interop.Cion.ErrorCode ret = Interop.CionClient.CionClientSendPayloadAsync(_handle, payload?._handle, _payloadAsyncResultCb, IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to send payload."); } return(tcs.Task); }
/// <summary> /// Starts server and listens for requests from cion clients. /// </summary> /// <exception cref="InvalidOperationException">Thrown when the listen operation is already in progress.</exception> /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege> /// <since_tizen> 9 </since_tizen> public void Listen() { if (_connectionRequestCb == null) { Interop.CionServer.CionServerConnectionRequestCb cb = new Interop.CionServer.CionServerConnectionRequestCb( (serviceName, peerInfo, userData) => { Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); if (clone_ret != Interop.Cion.ErrorCode.None) { Log.Error(LogTag, "Failed to clone peer info"); return; } OnConnentionRequest(new PeerInfo(clone)); }); _connectionRequestCb = cb; } Interop.Cion.ErrorCode ret = Interop.CionServer.CionServerListen(_handle, _connectionRequestCb, IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to listen server."); } }
/// <summary> /// The constructor of ServerBase class. /// </summary> /// <param name="serviceName">The name of service.</param> /// <param name="displayName">The display name of service.</param> /// <param name="security">The security configuration.</param> /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception> /// <since_tizen> 9 </since_tizen> public ServerBase(string serviceName, string displayName, Cion.SecurityInfo security) { ServiceName = serviceName; DisplayName = displayName; Cion.SecuritySafeHandle handle = security?._handle; Interop.Cion.ErrorCode ret = Interop.CionServer.CionServerCreate(out _handle, serviceName, displayName, handle?.DangerousGetHandle() ?? IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to create server handle."); } _connectionResultCb = new Interop.CionServer.CionServerConnectionResultCb( (string service, IntPtr peerInfo, IntPtr result, IntPtr userData) => { Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); if (clone_ret != Interop.Cion.ErrorCode.None) { Log.Error(LogTag, "Failed to clone peer info."); return; } OnConnectionResult(new PeerInfo(clone), new ConnectionResult(result)); }); ret = Interop.CionServer.CionServerAddConnectionResultCb(_handle, _connectionResultCb, IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { _handle.Dispose(); throw CionErrorFactory.GetException(ret, "Failed to add connection status changed callback."); } _dataReceivedCb = new Interop.CionServer.CionServerDataReceivedCb( (string service, IntPtr peerInfo, byte[] data, int dataSize, out byte[] returnData, out int returnDataSize, IntPtr userData) => { returnData = OnDataReceived(data, new PeerInfo(new PeerInfoSafeHandle(peerInfo, false))); returnDataSize = returnData.Length; }); ret = Interop.CionServer.CionServerSetDataReceivedCb(_handle, _dataReceivedCb, IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { _handle.Dispose(); throw CionErrorFactory.GetException(ret, "Failed to set data received callback."); } _payloadRecievedCb = new Interop.CionServer.CionServerPayloadRecievedCb( (string service, IntPtr peerInfo, IntPtr payload, int status, IntPtr userData) => { Payload receivedPayload; Interop.CionPayload.CionPayloadGetType(payload, out Interop.CionPayload.PayloadType type); switch (type) { case Interop.CionPayload.PayloadType.Data: receivedPayload = new DataPayload(new PayloadSafeHandle(payload, false)); break; case Interop.CionPayload.PayloadType.File: receivedPayload = new FilePayload(new PayloadSafeHandle(payload, false)); break; default: Log.Error(LogTag, "Invalid payload type received."); return; } OnPayloadReceived(receivedPayload, new PeerInfo(new PeerInfoSafeHandle(peerInfo, false)), (PayloadTransferStatus)status); }); ret = Interop.CionServer.CionServerAddPayloadReceivedCb(_handle, _payloadRecievedCb, IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { _handle.Dispose(); throw CionErrorFactory.GetException(ret, "Failed to add payload received callback."); } _disconnectedCb = new Interop.CionServer.CionServerDisconnectedCb( (string service, IntPtr peerInfo, IntPtr userData) => { Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); if (clone_ret != Interop.Cion.ErrorCode.None) { Log.Error(LogTag, string.Format("Failed to clone peer info.")); return; } OnDisconnected(new PeerInfo(clone)); }); ret = Interop.CionServer.CionServerAddDisconnectedCb(_handle, _disconnectedCb, IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { _handle.Dispose(); throw CionErrorFactory.GetException(ret, "Failed to add disconnected callback."); } }
/// <summary> /// The constructor of GroupBase class. /// </summary> /// <param name="topicName">The topic of group.</param> /// <param name="security">The security configuration.</param> /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception> /// <since_tizen> 9 </since_tizen> public GroupBase(string topicName, Cion.SecurityInfo security) { Topic = topicName; Cion.SecuritySafeHandle handle = security?._handle; Interop.Cion.ErrorCode ret = Interop.CionGroup.CionGroupCreate(out _handle, topicName, handle?.DangerousGetHandle() ?? IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to create group."); } _payloadReceivedCb = new Interop.CionGroup.CionGroupPayloadReceivedCb( (IntPtr group, IntPtr peerInfo, IntPtr payload, IntPtr userData) => { Payload receivedPayload; Interop.CionPayload.CionPayloadGetType(payload, out Interop.CionPayload.PayloadType type); switch (type) { case Interop.CionPayload.PayloadType.Data: receivedPayload = new DataPayload(new PayloadSafeHandle(payload, false)); break; case Interop.CionPayload.PayloadType.File: receivedPayload = new FilePayload(new PayloadSafeHandle(payload, false)); break; default: throw new ArgumentException("Invalid payload type received."); } OnPayloadReceived(receivedPayload, new PeerInfo(new PeerInfoSafeHandle(peerInfo, false))); }); ret = Interop.CionGroup.CionGroupAddPayloadReceivedCb(_handle, _payloadReceivedCb, IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { _handle.Dispose(); throw CionErrorFactory.GetException(ret, "Failed to add payload received callback."); } _joinedCb = new Interop.CionGroup.CionGroupJoinedCb( (string name, IntPtr peerInfo, IntPtr userData) => { Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); if (clone_ret != Interop.Cion.ErrorCode.None) { return; } OnJoined(new PeerInfo(clone)); }); ret = Interop.CionGroup.CionGroupAddJoinedCb(_handle, _joinedCb, IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { _handle.Dispose(); throw CionErrorFactory.GetException(ret, "Failed to add joined callback."); } _leftCb = new Interop.CionGroup.CionGroupLeftCb( (string name, IntPtr peerInfo, IntPtr userData) => { Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); if (clone_ret != Interop.Cion.ErrorCode.None) { return; } OnLeft(new PeerInfo(clone)); }); ret = Interop.CionGroup.CionGroupAddLeftCb(_handle, _leftCb, IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { _handle.Dispose(); throw CionErrorFactory.GetException(ret, "Failed to add joined callback."); } }
/// <summary> /// The constructor of ClientBase class. /// </summary> /// <param name="serviceName">The name of service.</param> /// <param name="security">The security configuration.</param> /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception> /// <since_tizen> 9 </since_tizen> public ClientBase(string serviceName, Cion.SecurityInfo security) { ServiceName = serviceName; Cion.SecuritySafeHandle handle = security?._handle; Interop.Cion.ErrorCode ret = Interop.CionClient.CionClientCreate(out _handle, serviceName, handle?.DangerousGetHandle() ?? IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { throw CionErrorFactory.GetException(ret, "Failed to create client."); } _connectionResultCb = new Interop.CionClient.CionClientConnectionResultCb( (string service, IntPtr peerInfo, IntPtr result, IntPtr userData) => { Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); if (clone_ret != Interop.Cion.ErrorCode.None) { Log.Error(LogTag, string.Format("Failed to clone peer info.")); return; } PeerInfo peer = new PeerInfo(clone); ConnectionResult connectionResult = new ConnectionResult(result); if (connectionResult.Status == ConnectionStatus.OK) { _peer = peer; } OnConnectionResult(peer, connectionResult); }); ret = Interop.CionClient.CionClientAddConnectionResultCb(_handle, _connectionResultCb, IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { _handle.Dispose(); throw CionErrorFactory.GetException(ret, "Failed to add connection status changed callback."); } _payloadRecievedCb = new Interop.CionClient.CionClientPayloadRecievedCb( (string service, IntPtr peerInfo, IntPtr payload, int status, IntPtr userData) => { Payload receivedPayload; Interop.CionPayload.CionPayloadGetType(payload, out Interop.CionPayload.PayloadType type); switch (type) { case Interop.CionPayload.PayloadType.Data: receivedPayload = new DataPayload(new PayloadSafeHandle(payload, false)); break; case Interop.CionPayload.PayloadType.File: receivedPayload = new FilePayload(new PayloadSafeHandle(payload, false)); break; default: Log.Error(LogTag, "Invalid payload type received."); return; } OnPayloadReceived(receivedPayload, (PayloadTransferStatus)status); }); ret = Interop.CionClient.CionClientAddPayloadReceivedCb(_handle, _payloadRecievedCb, IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { _handle.Dispose(); throw CionErrorFactory.GetException(ret, "Failed to add payload received callback."); } _disconnectedCb = new Interop.CionClient.CionClientDisconnectedCb( (string service, IntPtr peerInfo, IntPtr userData) => { Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone); if (clone_ret != Interop.Cion.ErrorCode.None) { Log.Error(LogTag, string.Format("Failed to clone peer info.")); return; } OnDisconnected(new PeerInfo(clone)); }); ret = Interop.CionClient.CionClientAddDisconnectedCb(_handle, _disconnectedCb, IntPtr.Zero); if (ret != Interop.Cion.ErrorCode.None) { _handle.Dispose(); throw CionErrorFactory.GetException(ret, "Failed to add disconnected callback."); } }