a9cef59ca5de5d27e98b6b519e194ad81c404de1
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.Nfc / Tizen.Network.Nfc / NfcCardEmulationAdapter.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Runtime.InteropServices;
19 using System.Collections.Generic;
20
21 namespace Tizen.Network.Nfc
22 {
23     /// <summary>
24     /// A class for NFC CardEmulation mode. It allows applications to handle Card Emulation informations.
25     /// </summary>
26     /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
27     public class NfcCardEmulationAdapter : IDisposable
28     {
29         private bool disposed = false;
30
31         private event EventHandler<SecureElementEventArgs> _secureElementEvent;
32         private event EventHandler<SecureElementTranscationEventArgs> _secureElementTransactionEvent;
33         private event EventHandler<HostCardEmulationEventArgs> _hostCardEmulationEvent;
34
35         private Interop.Nfc.SecureElementEventCallback _secureElementEventCallback;
36         private Interop.Nfc.SecureElementTransactionEventCallback _secureElementTransactionEventCallback;
37         private Interop.Nfc.HostCardEmulationEventCallback _hostCardEmulationEventCallback;
38
39         /// <summary>
40         /// Event that is called when receiving Secure Element (SIM/UICC(Universal Integrated Circuit Card)) event.
41         /// </summary>
42         public event EventHandler<SecureElementEventArgs> SecureElementEvent
43         {
44             add
45             {
46                 if (_secureElementEvent == null)
47                 {
48                     RegisterSecureElementEvent();
49                 }
50                 _secureElementEvent += value;
51             }
52             remove
53             {
54                 _secureElementEvent -= value;
55                 if (_secureElementEvent == null)
56                 {
57                     UnregisterSecureElementEvent();
58                 }
59             }
60         }
61
62         /// <summary>
63         /// Event that is called when receiving Secure Element(SIM/UICC(Universal Integrated Circuit Card)) transaction event for 'ESE(SmartMX)' type.
64         /// </summary>
65         public event EventHandler<SecureElementTranscationEventArgs> EseSecureElementTransactionEvent
66         {
67             add
68             {
69                 if (_secureElementTransactionEvent == null)
70                 {
71                     RegisterSecureElementTransactionEvent(NfcSecureElementType.EmbeddedSE);
72                 }
73                 _secureElementTransactionEvent += value;
74             }
75             remove
76             {
77                 _secureElementTransactionEvent -= value;
78                 if (_secureElementTransactionEvent == null)
79                 {
80                     UnregisterSecureElementTransactionEvent(NfcSecureElementType.EmbeddedSE);
81                 }
82             }
83         }
84
85         /// <summary>
86         /// Event that is called when receiving Secure Element(SIM/UICC(Universal Integrated Circuit Card)) transaction event for 'UICC' type.
87         /// </summary>
88         public event EventHandler<SecureElementTranscationEventArgs> UiccSecureElementTransactionEvent
89         {
90             add
91             {
92                 if (_secureElementTransactionEvent == null)
93                 {
94                     RegisterSecureElementTransactionEvent(NfcSecureElementType.Uicc);
95                 }
96                 _secureElementTransactionEvent += value;
97             }
98             remove
99             {
100                 _secureElementTransactionEvent -= value;
101                 if (_secureElementTransactionEvent == null)
102                 {
103                     UnregisterSecureElementTransactionEvent(NfcSecureElementType.Uicc);
104                 }
105             }
106         }
107
108         /// <summary>
109         /// Event that is called when when receiving HCE(Host Card Emulation) event.
110         /// </summary>
111         public event EventHandler<HostCardEmulationEventArgs> HostCardEmulationEvent
112         {
113             add
114             {
115                 if (_hostCardEmulationEvent == null)
116                 {
117                     RegisterHostCardEmulationEvent();
118                 }
119                 _hostCardEmulationEvent += value;
120             }
121             remove
122             {
123                 _hostCardEmulationEvent -= value;
124                 if (_hostCardEmulationEvent == null)
125                 {
126                     UnregisterHostCardEmulationEvent();
127                 }
128             }
129         }
130
131         internal NfcCardEmulationAdapter()
132         {
133         }
134
135         ~NfcCardEmulationAdapter()
136         {
137             Dispose(false);
138         }
139
140         public void Dispose()
141         {
142             Dispose(true);
143             GC.SuppressFinalize(this);
144         }
145
146         private void Dispose(bool disposing)
147         {
148             if (disposed)
149                 return;
150
151             if (disposing)
152             {
153                 // Free managed objects.
154             }
155             //Free unmanaged objects
156             disposed = true;
157         }
158
159         /// <summary>
160         /// Enable card emulation mode.
161         /// </summary>
162         public void EnableCardEmulation()
163         {
164             int ret = Interop.Nfc.CardEmulation.EnableCardEmulation();
165             if (ret != (int)NfcError.None)
166             {
167                 Log.Error(Globals.LogTag, "Failed to enable card emulation mode, Error - " + (NfcError)ret);
168                 NfcErrorFactory.ThrowNfcException(ret);
169             }
170         }
171
172         /// <summary>
173         /// Disable card emulation mode.
174         /// </summary>
175         public void DisableCardEmulation()
176         {
177             int ret = Interop.Nfc.CardEmulation.DisableCardEmulatiion();
178             if (ret != (int)NfcError.None)
179             {
180                 Log.Error(Globals.LogTag, "Failed to disable card emulation mode, Error - " + (NfcError)ret);
181                 NfcErrorFactory.ThrowNfcException(ret);
182             }
183         }
184
185         /// <summary>
186         /// Get the current card emulation mode.
187         /// </summary>
188         /// <returns>Enumeration value of NfcSecureElementCardEmulationMode.</returns>
189         public NfcSecureElementCardEmulationMode GetCardEmulationMode()
190         {
191             int mode = 0;
192             int ret = Interop.Nfc.CardEmulation.GetCardEmulationMode(out mode);
193             if (ret != (int)NfcError.None)
194             {
195                 Log.Error(Globals.LogTag, "Failed to get card emulation mode, Error - " + (NfcError)ret);
196             }
197
198             return (NfcSecureElementCardEmulationMode)mode;
199         }
200
201         /// <summary>
202         /// Give the priority to the foreground application when dispatching transaction event.
203         /// </summary>
204         public void EnableTransactionForegroundDispatch()
205         {
206             int ret = Interop.Nfc.EnableTransactionForegroundDispatch();
207             if (ret != (int)NfcError.None)
208             {
209                 Log.Error(Globals.LogTag, "Failed to enable foreground dispatch, Error - " + (NfcError)ret);
210                 NfcErrorFactory.ThrowNfcException(ret);
211             }
212         }
213
214         /// <summary>
215         /// Disable foreground dispatch for "EVT_TRANSACTION" to the givin application.
216         /// </summary>
217         public void DisableTransactionForegroundDispatch()
218         {
219             int ret = Interop.Nfc.DisableTransactionForegroundDispatch();
220             if (ret != (int)NfcError.None)
221             {
222                 Log.Error(Globals.LogTag, "Failed to disable foreground dispatch, Error - " + (NfcError)ret);
223                 NfcErrorFactory.ThrowNfcException(ret);
224             }
225         }
226
227         /// <summary>
228         /// Gets the state whether an application to call this api is currently the activated handler for specific AID.
229         /// </summary>
230         /// <returns>'True' when application is currently the activated handler, otherwise 'False'.</returns>
231         /// <param name="seType">The type of Secure Element.</param>
232         /// <param name="aid">Application Id, specified in ISO/IEC 7816-4.</param>
233         public bool IsActivatedHandlerForAid(NfcSecureElementType seType, string aid)
234         {
235             bool isActivatedHandle = false;
236             int ret = Interop.Nfc.CardEmulation.IsActivatedHandlerForAid((int)seType, aid, out isActivatedHandle);
237             if (ret != (int)NfcError.None)
238             {
239                 Log.Error(Globals.LogTag, "Failed to check activated handle for aid, Error - " + (NfcError)ret);
240                 NfcErrorFactory.ThrowNfcException(ret);
241             }
242
243             return isActivatedHandle;
244         }
245
246         /// <summary>
247         /// Gets the state whether an application to call this api is currently the activated handler for category.
248         /// </summary>
249         /// <returns>'True' when application is currently the activated handler, otherwise 'False'.</returns>
250         /// <param name="seType">The type of Secure Element.</param>
251         /// <param name="category">Enumeration value of category.</param>
252         public bool IsActivatedHandlerForCategory(NfcSecureElementType seType, NfcCardEmulationCategoryType category)
253         {
254             bool isActivatedHandle = false;
255             int ret = Interop.Nfc.CardEmulation.IsActivatedHandlerForCategory((int)seType, (int)category, out isActivatedHandle);
256             if (ret != (int)NfcError.None)
257             {
258                 Log.Error(Globals.LogTag, "Failed to check activated handle for category, Error - " + (NfcError)ret);
259                 NfcErrorFactory.ThrowNfcException(ret);
260             }
261
262             return isActivatedHandle;
263         }
264
265         /// <summary>
266         /// Registers a AID for a specific category.
267         /// </summary>
268         /// <param name="seType">The type of Secure Element.</param>
269         /// <param name="category">Enumeration value of category.</param>
270         /// <param name="aid">Application Id, specified in ISO/IEC 7816-4.</param>
271         public void RegisterAid(NfcSecureElementType seType, NfcCardEmulationCategoryType category, string aid)
272         {
273             int ret = Interop.Nfc.CardEmulation.RegisterAid((int)seType, (int)category, aid);
274             if (ret != (int)NfcError.None)
275             {
276                 Log.Error(Globals.LogTag, "Failed to register aid, Error - " + (NfcError)ret);
277                 NfcErrorFactory.ThrowNfcException(ret);
278             }
279         }
280
281         /// <summary>
282         /// Unregisters a previously registered AID for the specified category.
283         /// </summary>
284         /// <param name="seType">The type of Secure Element.</param>
285         /// <param name="category">Enumeration value of category.</param>
286         /// <param name="aid">Application Id, specified in ISO/IEC 7816-4.</param>
287         public void UnregisterAid(NfcSecureElementType seType, NfcCardEmulationCategoryType category, string aid)
288         {
289             int ret = Interop.Nfc.CardEmulation.UnregisterAid((int)seType, (int)category, aid);
290             if (ret != (int)NfcError.None)
291             {
292                 Log.Error(Globals.LogTag, "Failed to unregister aid, Error - " + (NfcError)ret);
293                 NfcErrorFactory.ThrowNfcException(ret);
294             }
295         }
296
297         /// <summary>
298         /// Sets the application as a preferred handler.
299         /// </summary>
300         public void SetPreferredApplication()
301         {
302             int ret = Interop.Nfc.CardEmulation.SetPreferredHandler();
303             if (ret != (int)NfcError.None)
304             {
305                 Log.Error(Globals.LogTag, "Failed to set preferred handler, Error - " + (NfcError)ret);
306                 NfcErrorFactory.ThrowNfcException(ret);
307             }
308         }
309
310         /// <summary>
311         /// Unsets the application as a preferred handler.
312         /// </summary>
313         public void UnsetPreferredApplication()
314         {
315             int ret = Interop.Nfc.CardEmulation.UnsetPreferredHandler();
316             if (ret != (int)NfcError.None)
317             {
318                 Log.Error(Globals.LogTag, "Failed to unset preferred handler, Error - " + (NfcError)ret);
319                 NfcErrorFactory.ThrowNfcException(ret);
320             }
321         }
322
323         /// <summary>
324         /// Retrieves all registered AID.
325         /// </summary>
326         /// <returns>List of NfcRegisteredAidInformation objects.</returns>
327         /// <param name="seType">The type of Secure Element.</param>
328         /// <param name="category">Enumeration value of category.</param>
329         public IEnumerable<NfcRegisteredAidInformation> ForeachRegisteredAidInformations(NfcSecureElementType seType, NfcCardEmulationCategoryType category)
330         {
331             List<NfcRegisteredAidInformation> infoList = new List<NfcRegisteredAidInformation>();
332             Interop.Nfc.SecureElementRegisteredAidCallback callback = (int type, IntPtr aid, bool readOnly, IntPtr userData) =>
333             {
334                 if (aid != IntPtr.Zero)
335                 {
336                     NfcRegisteredAidInformation aidInfo = new NfcRegisteredAidInformation();
337
338                     aidInfo.SeType = (NfcSecureElementType)type;
339                     aidInfo.Aid = Marshal.PtrToStringAnsi(aid);
340                     aidInfo.ReadOnly = readOnly;
341
342                     infoList.Add(aidInfo);
343                 }
344             };
345
346             int ret = Interop.Nfc.CardEmulation.ForeachRegisterdAids((int)seType, (int)category, callback, IntPtr.Zero);
347             if (ret != (int)NfcError.None)
348             {
349                 Log.Error(Globals.LogTag, "Failed to get all registerd aid informations, Error - " + (NfcError)ret);
350                 NfcErrorFactory.ThrowNfcException(ret);
351             }
352
353             return infoList;
354         }
355
356         private void RegisterSecureElementEvent()
357         {
358             _secureElementEventCallback = (int eventType, IntPtr userData) =>
359             {
360                 NfcSecureElementEvent _eventType = (NfcSecureElementEvent)eventType;
361                 SecureElementEventArgs e = new SecureElementEventArgs(_eventType);
362                 _secureElementEvent.SafeInvoke(null, e);
363             };
364
365             int ret = Interop.Nfc.SetSecureElementEventCallback(_secureElementEventCallback, IntPtr.Zero);
366             if (ret != (int)NfcError.None)
367             {
368                 Log.Error(Globals.LogTag, "Failed to set secure element event callback, Error - " + (NfcError)ret);
369             }
370         }
371
372         private void UnregisterSecureElementEvent()
373         {
374             Interop.Nfc.UnsetSecureElementEventCallback();
375         }
376
377         private void RegisterSecureElementTransactionEvent(NfcSecureElementType seType)
378         {
379             _secureElementTransactionEventCallback = (int type, IntPtr aid, int aidSize, IntPtr param, int paramSize, IntPtr userData) =>
380             {
381                 NfcSecureElementType _secureElementType = (NfcSecureElementType)type;
382                 byte[] _aid = NfcConvertUtil.IntLengthIntPtrToByteArray(aid, aidSize);
383                 byte[] _param = NfcConvertUtil.IntLengthIntPtrToByteArray(param, paramSize);
384                 SecureElementTranscationEventArgs e = new SecureElementTranscationEventArgs(_secureElementType, _aid, _param);
385                 _secureElementTransactionEvent.SafeInvoke(null, e);
386             };
387
388             int ret = Interop.Nfc.SetSecureElementTransactionEventCallback((int)seType, _secureElementTransactionEventCallback, IntPtr.Zero);
389             if (ret != (int)NfcError.None)
390             {
391                 Log.Error(Globals.LogTag, "Failed to set secure element transaction event callback, Error - " + (NfcError)ret);
392             }
393         }
394
395         private void UnregisterSecureElementTransactionEvent(NfcSecureElementType seType)
396         {
397             Interop.Nfc.UnsetSecureElementTransactionEventCallback((int)seType);
398         }
399
400         private void RegisterHostCardEmulationEvent()
401         {
402             _hostCardEmulationEventCallback = (IntPtr handle, int eventType, IntPtr apdu, uint apduLen, IntPtr userData) =>
403             {
404                 IntPtr _seHandle = handle;
405                 NfcHceEvent _hcdEventType = (NfcHceEvent)eventType;
406                 byte[] _apdu = NfcConvertUtil.UintLengthIntPtrToByteArray(apdu, apduLen);
407                 HostCardEmulationEventArgs e = new HostCardEmulationEventArgs(_seHandle, _hcdEventType, _apdu);
408                 _hostCardEmulationEvent.SafeInvoke(null, e);
409             };
410
411             int ret = Interop.Nfc.SetHostCardEmulationEventCallback(_hostCardEmulationEventCallback, IntPtr.Zero);
412             if (ret != (int)NfcError.None)
413             {
414                 Log.Error(Globals.LogTag, "Failed to set host card emulation event callback, Error - " + (NfcError)ret);
415                 NfcErrorFactory.ThrowNfcException(ret);
416             }
417         }
418
419         private void UnregisterHostCardEmulationEvent()
420         {
421             Interop.Nfc.UnsetHostCardEmulationEventCallback();
422         }
423     }
424 }