/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Runtime.InteropServices; using System.ComponentModel; namespace Tizen.Convergence { /// /// The class abstracts the features provided by Tizen D2D Convergence. /// /// [EditorBrowsable(EditorBrowsableState.Never)] public abstract class InternalService : IDisposable { internal Interop.Internal.ConvServiceHandle _serviceHandle; internal const string ServiceIdKey = "service_id"; internal const string ServiceVersionKey = "service_version"; private event EventHandler _serviceEventOccured; internal InternalService(Interop.Internal.ServiceType type) { int ret = Interop.Internal.ConvService.Create(out _serviceHandle); if (ret != (int)ConvErrorCode.None) { Log.Error(ErrorFactory.LogTag, "Failed to create service handle"); throw ErrorFactory.GetException(ret); } ret = Interop.Internal.ConvService.SetType(_serviceHandle, (int)type); if (ret != (int)ConvErrorCode.None) { Log.Error(ErrorFactory.LogTag, "Failed to create service handle"); throw ErrorFactory.GetException(ret); } } internal InternalService(IntPtr existingServiceHandle) { int ret = Interop.Internal.ConvService.Clone(existingServiceHandle, out _serviceHandle); if (ret != (int)ConvErrorCode.None) { Log.Error(ErrorFactory.LogTag, "Failed to clone device"); throw ErrorFactory.GetException(ret); } IntPtr stringPtr = IntPtr.Zero; ret = Interop.Internal.ConvService.GetPropertyString(_serviceHandle, ServiceIdKey, out stringPtr); if (ret != (int)ConvErrorCode.None) { Log.Error(ErrorFactory.LogTag, "Failed to get service Id"); throw ErrorFactory.GetException(ret); } Id = Marshal.PtrToStringAnsi(stringPtr); Interop.Libc.Free(stringPtr); ret = Interop.Internal.ConvService.GetPropertyString(_serviceHandle, ServiceVersionKey, out stringPtr); if (ret != (int)ConvErrorCode.None) { Log.Error(ErrorFactory.LogTag, "Failed to get service version"); throw ErrorFactory.GetException(ret); } Version = Marshal.PtrToStringAnsi(stringPtr); Interop.Libc.Free(stringPtr); } /// /// The ID of the service /// public string Id { get; } /// /// The Version of the service /// public string Version { get; } /// /// The event handler for Service Events(Start/Publish/Read/Stop) /// public event EventHandler ServiceEventOccurred { add { if (_serviceEventOccured == null) { RegisterServiceEventListener(); } _serviceEventOccured += value; } remove { _serviceEventOccured -= value; if (_serviceEventOccured == null) { UnregisterServiceEventListener(); } } } /// /// The event handler for service error events /// public event EventHandler ServiceErrorOccured; /// /// The dispose method /// public void Dispose() { _serviceHandle.Dispose(); } internal static InternalService GetService(IntPtr serviceHandle) { InternalService service = null; int serviceType; int ret = Interop.Internal.ConvService.GetType(serviceHandle, out serviceType); if (ret != (int)ConvErrorCode.None) { Log.Error(ErrorFactory.LogTag, "Failed to get service version"); throw ErrorFactory.GetException(ret); } if (serviceType == (int)Interop.Internal.ServiceType.AppCommunication) { service = new InternalAppCommunicationService(serviceHandle); } return service; } private void RegisterServiceEventListener() { int ret = Interop.Internal.ConvService.SetListenerCb(_serviceHandle, serviceEventsCb, IntPtr.Zero); if (ret != (int)ConvErrorCode.None) { Log.Error(ErrorFactory.LogTag, "Failed to set listener for service events"); throw ErrorFactory.GetException(ret); } } private void UnregisterServiceEventListener() { int ret = Interop.Internal.ConvService.UnsetListenerCb(_serviceHandle); if (ret != (int)ConvErrorCode.None) { Log.Error(ErrorFactory.LogTag, "Failed to unset listener for service events"); throw ErrorFactory.GetException(ret); } } private void serviceEventsCb(IntPtr serviceHandle, IntPtr channelHandle, int error, IntPtr resultPayloadHandle, IntPtr userData) { Log.Debug(ErrorFactory.LogTag, "service event occured. error code :[" + error + "]"); if (error == (int)ConvErrorCode.None) { var channel = (channelHandle == IntPtr.Zero) ? null : new InternalChannel(channelHandle); var payload = (resultPayloadHandle == IntPtr.Zero) ? null : new InternalPayload(resultPayloadHandle); _serviceEventOccured?.Invoke(this, new InternalServiceEventOccuredEventArgs() { Payload = payload, Channel = channel }); } else { var eventArgs = new InternalServiceErrorOccuredEventArgs() { Exception = ErrorFactory.GetException(error) }; ServiceErrorOccured?.Invoke(this, eventArgs); } } } }