/* * 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.Collections.Generic; namespace Tizen.Network.Nfc { /// /// A class for the NFC CardEmulation mode. It allows applications to handle Card Emulation informations. /// /// 3 /// http://tizen.org/privilege/nfc.cardemulation public class NfcCardEmulationAdapter : IDisposable { private bool disposed = false; private event EventHandler _secureElementEvent; private event EventHandler _secureElementTransactionEvent; private event EventHandler _hostCardEmulationEvent; private Interop.Nfc.SecureElementEventCallback _secureElementEventCallback; private Interop.Nfc.SecureElementTransactionEventCallback _secureElementTransactionEventCallback; private Interop.Nfc.HostCardEmulationEventCallback _hostCardEmulationEventCallback; /// /// An event that is called when receiving the Secure Element (SIM/UICC(Universal Integrated Circuit Card)) event. /// /// 3 /// http://tizen.org/privilege/nfc.cardemulation public event EventHandler SecureElementEvent { add { if (_secureElementEvent == null) { RegisterSecureElementEvent(); } _secureElementEvent += value; } remove { _secureElementEvent -= value; if (_secureElementEvent == null) { UnregisterSecureElementEvent(); } } } /// /// An event that is called when receiving the Secure Element (SIM/UICC (Universal Integrated Circuit Card)) transaction event for the 'ESE(SmartMX)' type. /// /// 3 /// http://tizen.org/privilege/nfc.cardemulation public event EventHandler EseSecureElementTransactionEvent { add { if (_secureElementTransactionEvent == null) { RegisterSecureElementTransactionEvent(NfcSecureElementType.EmbeddedSE); } _secureElementTransactionEvent += value; } remove { _secureElementTransactionEvent -= value; if (_secureElementTransactionEvent == null) { UnregisterSecureElementTransactionEvent(NfcSecureElementType.EmbeddedSE); } } } /// /// An event that is called when receiving the Secure Element (SIM/UICC (Universal Integrated Circuit Card)) transaction event for the 'UICC' type. /// /// 3 /// http://tizen.org/privilege/nfc.cardemulation public event EventHandler UiccSecureElementTransactionEvent { add { if (_secureElementTransactionEvent == null) { RegisterSecureElementTransactionEvent(NfcSecureElementType.Uicc); } _secureElementTransactionEvent += value; } remove { _secureElementTransactionEvent -= value; if (_secureElementTransactionEvent == null) { UnregisterSecureElementTransactionEvent(NfcSecureElementType.Uicc); } } } /// /// An event that is called when receiving the HCE (Host Card Emulation) event. /// /// 3 /// http://tizen.org/privilege/nfc.cardemulation public event EventHandler HostCardEmulationEvent { add { if (_hostCardEmulationEvent == null) { RegisterHostCardEmulationEvent(); } _hostCardEmulationEvent += value; } remove { _hostCardEmulationEvent -= value; if (_hostCardEmulationEvent == null) { UnregisterHostCardEmulationEvent(); } } } internal NfcCardEmulationAdapter() { } /// /// NfcCardEmulationAdpater destructor. /// ~NfcCardEmulationAdapter() { Dispose(false); } /// /// Dispose /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (disposed) return; if (disposing) { // Free managed objects. } //Free unmanaged objects disposed = true; } /// /// Enables the card emulation mode. /// /// 3 /// http://tizen.org/privilege/nfc.cardemulation /// Thrown when the NFC is not supported. /// Thrown when the method fails due to an invalid operation. public void EnableCardEmulation() { int ret = Interop.Nfc.CardEmulation.EnableCardEmulation(); if (ret != (int)NfcError.None) { Log.Error(Globals.LogTag, "Failed to enable card emulation mode, Error - " + (NfcError)ret); NfcErrorFactory.ThrowNfcException(ret); } } /// /// Disables the card emulation mode. /// /// 3 /// http://tizen.org/privilege/nfc.cardemulation /// Thrown when the NFC is not supported. /// Thrown when the method fails due to an invalid operation. public void DisableCardEmulation() { int ret = Interop.Nfc.CardEmulation.DisableCardEmulatiion(); if (ret != (int)NfcError.None) { Log.Error(Globals.LogTag, "Failed to disable card emulation mode, Error - " + (NfcError)ret); NfcErrorFactory.ThrowNfcException(ret); } } /// /// Gets the current card emulation mode. /// /// 3 /// Enumeration value for the NfcSecureElementCardEmulationMode. /// http://tizen.org/privilege/nfc.cardemulation public NfcSecureElementCardEmulationMode GetCardEmulationMode() { int mode = 0; int ret = Interop.Nfc.CardEmulation.GetCardEmulationMode(out mode); if (ret != (int)NfcError.None) { Log.Error(Globals.LogTag, "Failed to get card emulation mode, Error - " + (NfcError)ret); } return (NfcSecureElementCardEmulationMode)mode; } /// /// Gives the priority to the foreground application when dispatching the transaction event. /// /// 3 /// http://tizen.org/privilege/nfc.cardemulation /// Thrown when the NFC is not supported. /// Thrown when the method fails due to an invalid operation. public void EnableTransactionForegroundDispatch() { int ret = Interop.Nfc.EnableTransactionForegroundDispatch(); if (ret != (int)NfcError.None) { Log.Error(Globals.LogTag, "Failed to enable foreground dispatch, Error - " + (NfcError)ret); NfcErrorFactory.ThrowNfcException(ret); } } /// /// Disables the foreground dispatch for the "EVT_TRANSACTION" to the given application. /// /// 3 /// http://tizen.org/privilege/nfc.cardemulation /// Thrown when the NFC is not supported. /// Thrown when the method fails due to an invalid operation. public void DisableTransactionForegroundDispatch() { int ret = Interop.Nfc.DisableTransactionForegroundDispatch(); if (ret != (int)NfcError.None) { Log.Error(Globals.LogTag, "Failed to disable foreground dispatch, Error - " + (NfcError)ret); NfcErrorFactory.ThrowNfcException(ret); } } /// /// Gets the state, whether an application to call this API is currently the activated handler for the specific AID. /// /// 3 /// 'True' when application is currently the activated handler, otherwise 'False'. /// The type of the Secure Element. /// The application ID specified in the ISO/IEC 7816-4. /// http://tizen.org/privilege/nfc.cardemulation /// Thrown when the NFC is not supported. /// Thrown when the method fails due to an invalid parameter. /// Thrown when the method fails due to an invalid operation. public bool IsActivatedHandlerForAid(NfcSecureElementType seType, string aid) { bool isActivatedHandle = false; int ret = Interop.Nfc.CardEmulation.IsActivatedHandlerForAid((int)seType, aid, out isActivatedHandle); if (ret != (int)NfcError.None) { Log.Error(Globals.LogTag, "Failed to check activated handle for aid, Error - " + (NfcError)ret); NfcErrorFactory.ThrowNfcException(ret); } return isActivatedHandle; } /// /// Gets the state, whether an application to call this API is currently the activated handler for the category. /// /// 3 /// 'True' when application is currently the activated handler, otherwise 'False'. /// The type of the secure element. /// Enumeration value of the category. /// http://tizen.org/privilege/nfc.cardemulation /// Thrown when the NFC is not supported. /// Thrown when the method fails due to an invalid parameter. /// Thrown when the method fails due to an invalid operation. public bool IsActivatedHandlerForCategory(NfcSecureElementType seType, NfcCardEmulationCategoryType category) { bool isActivatedHandle = false; int ret = Interop.Nfc.CardEmulation.IsActivatedHandlerForCategory((int)seType, (int)category, out isActivatedHandle); if (ret != (int)NfcError.None) { Log.Error(Globals.LogTag, "Failed to check activated handle for category, Error - " + (NfcError)ret); NfcErrorFactory.ThrowNfcException(ret); } return isActivatedHandle; } /// /// Registers the AID for a specific category. /// /// 3 /// The type of the secure element. /// Enumeration value of the category. /// The application ID specified in the ISO/IEC 7816-4. /// http://tizen.org/privilege/nfc.cardemulation /// Thrown when the NFC is not supported. /// Thrown when the method fails due to an invalid parameter. /// Thrown when the method fails due to an invalid operation. public void RegisterAid(NfcSecureElementType seType, NfcCardEmulationCategoryType category, string aid) { int ret = Interop.Nfc.CardEmulation.RegisterAid((int)seType, (int)category, aid); if (ret != (int)NfcError.None) { Log.Error(Globals.LogTag, "Failed to register aid, Error - " + (NfcError)ret); NfcErrorFactory.ThrowNfcException(ret); } } /// /// Unregisters a previously registered AID for the specified category. /// /// 3 /// The type of the secure element. /// Enumeration value of the category. /// The application ID specified in the ISO/IEC 7816-4. /// http://tizen.org/privilege/nfc.cardemulation /// Thrown when the NFC is not supported. /// Thrown when the method fails due to an invalid parameter. /// Thrown when the method fails due to an invalid operation. public void UnregisterAid(NfcSecureElementType seType, NfcCardEmulationCategoryType category, string aid) { int ret = Interop.Nfc.CardEmulation.UnregisterAid((int)seType, (int)category, aid); if (ret != (int)NfcError.None) { Log.Error(Globals.LogTag, "Failed to unregister aid, Error - " + (NfcError)ret); NfcErrorFactory.ThrowNfcException(ret); } } /// /// Sets the application as a preferred handler. /// /// 3 /// http://tizen.org/privilege/nfc.cardemulation /// Thrown when the NFC is not supported. /// Thrown when the method fails due to an invalid operation. public void SetPreferredApplication() { int ret = Interop.Nfc.CardEmulation.SetPreferredHandler(); if (ret != (int)NfcError.None) { Log.Error(Globals.LogTag, "Failed to set preferred handler, Error - " + (NfcError)ret); NfcErrorFactory.ThrowNfcException(ret); } } /// /// Unsets the application as a preferred handler. /// /// 3 /// http://tizen.org/privilege/nfc.cardemulation /// Thrown when the NFC is not supported. /// Thrown when the method fails due to an invalid operation. public void UnsetPreferredApplication() { int ret = Interop.Nfc.CardEmulation.UnsetPreferredHandler(); if (ret != (int)NfcError.None) { Log.Error(Globals.LogTag, "Failed to unset preferred handler, Error - " + (NfcError)ret); NfcErrorFactory.ThrowNfcException(ret); } } /// /// Retrieves all registered AIDs. /// /// 3 /// The list of NfcRegisteredAidInformation objects. /// The type of the secure element. /// Enumeration value of the category. /// http://tizen.org/privilege/nfc.cardemulation /// Thrown when the NFC is not supported. /// Thrown when the method fails due to an invalid parameter. /// Thrown when the method fails due to an invalid operation. public IEnumerable GetRegisteredAidInformation(NfcSecureElementType seType, NfcCardEmulationCategoryType category) { List infoList = new List(); Interop.Nfc.SecureElementRegisteredAidCallback callback = (int type, IntPtr aid, bool readOnly, IntPtr userData) => { if (aid != IntPtr.Zero) { NfcRegisteredAidInformation aidInfo = new NfcRegisteredAidInformation((NfcSecureElementType)type, Marshal.PtrToStringAnsi(aid), readOnly); infoList.Add(aidInfo); } }; int ret = Interop.Nfc.CardEmulation.ForeachRegisterdAids((int)seType, (int)category, callback, IntPtr.Zero); if (ret != (int)NfcError.None) { Log.Error(Globals.LogTag, "Failed to get all registerd aid informations, Error - " + (NfcError)ret); NfcErrorFactory.ThrowNfcException(ret); } return infoList; } private void RegisterSecureElementEvent() { _secureElementEventCallback = (int eventType, IntPtr userData) => { NfcSecureElementEvent _eventType = (NfcSecureElementEvent)eventType; SecureElementEventArgs e = new SecureElementEventArgs(_eventType); _secureElementEvent.SafeInvoke(null, e); }; int ret = Interop.Nfc.SetSecureElementEventCallback(_secureElementEventCallback, IntPtr.Zero); if (ret != (int)NfcError.None) { Log.Error(Globals.LogTag, "Failed to set secure element event callback, Error - " + (NfcError)ret); } } private void UnregisterSecureElementEvent() { Interop.Nfc.UnsetSecureElementEventCallback(); } private void RegisterSecureElementTransactionEvent(NfcSecureElementType seType) { _secureElementTransactionEventCallback = (int type, IntPtr aid, int aidSize, IntPtr param, int paramSize, IntPtr userData) => { NfcSecureElementType _secureElementType = (NfcSecureElementType)type; byte[] _aid = NfcConvertUtil.IntLengthIntPtrToByteArray(aid, aidSize); byte[] _param = NfcConvertUtil.IntLengthIntPtrToByteArray(param, paramSize); SecureElementTranscationEventArgs e = new SecureElementTranscationEventArgs(_secureElementType, _aid, _param); _secureElementTransactionEvent.SafeInvoke(null, e); }; int ret = Interop.Nfc.SetSecureElementTransactionEventCallback((int)seType, _secureElementTransactionEventCallback, IntPtr.Zero); if (ret != (int)NfcError.None) { Log.Error(Globals.LogTag, "Failed to set secure element transaction event callback, Error - " + (NfcError)ret); } } private void UnregisterSecureElementTransactionEvent(NfcSecureElementType seType) { Interop.Nfc.UnsetSecureElementTransactionEventCallback((int)seType); } private void RegisterHostCardEmulationEvent() { _hostCardEmulationEventCallback = (IntPtr handle, int eventType, IntPtr apdu, uint apduLen, IntPtr userData) => { IntPtr _seHandle = handle; NfcHceEvent _hcdEventType = (NfcHceEvent)eventType; byte[] _apdu = NfcConvertUtil.UintLengthIntPtrToByteArray(apdu, apduLen); HostCardEmulationEventArgs e = new HostCardEmulationEventArgs(_seHandle, _hcdEventType, _apdu); _hostCardEmulationEvent.SafeInvoke(null, e); }; int ret = Interop.Nfc.SetHostCardEmulationEventCallback(_hostCardEmulationEventCallback, IntPtr.Zero); if (ret != (int)NfcError.None) { Log.Error(Globals.LogTag, "Failed to set host card emulation event callback, Error - " + (NfcError)ret); NfcErrorFactory.ThrowNfcException(ret); } } private void UnregisterHostCardEmulationEvent() { Interop.Nfc.UnsetHostCardEmulationEventCallback(); } } }