e445da38d0379aedc52c4da95bc6cf696050e888
[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 the NFC CardEmulation mode. It allows applications to handle Card Emulation informations.
25     /// </summary>
26     /// <since_tizen> 3 </since_tizen>
27     /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
28     public class NfcCardEmulationAdapter : IDisposable
29     {
30         private bool disposed = false;
31
32         private event EventHandler<SecureElementEventArgs> _secureElementEvent;
33         private event EventHandler<SecureElementTranscationEventArgs> _secureElementTransactionEvent;
34         private event EventHandler<HostCardEmulationEventArgs> _hostCardEmulationEvent;
35
36         private Interop.Nfc.SecureElementEventCallback _secureElementEventCallback;
37         private Interop.Nfc.SecureElementTransactionEventCallback _secureElementTransactionEventCallback;
38         private Interop.Nfc.HostCardEmulationEventCallback _hostCardEmulationEventCallback;
39
40         /// <summary>
41         /// An event that is called when receiving the Secure Element (SIM/UICC(Universal Integrated Circuit Card)) event.
42         /// </summary>
43         /// <since_tizen> 3 </since_tizen>
44         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
45         public event EventHandler<SecureElementEventArgs> SecureElementEvent
46         {
47             add
48             {
49                 if (_secureElementEvent == null)
50                 {
51                     RegisterSecureElementEvent();
52                 }
53                 _secureElementEvent += value;
54             }
55             remove
56             {
57                 _secureElementEvent -= value;
58                 if (_secureElementEvent == null)
59                 {
60                     UnregisterSecureElementEvent();
61                 }
62             }
63         }
64
65         /// <summary>
66         /// An event that is called when receiving the Secure Element (SIM/UICC (Universal Integrated Circuit Card)) transaction event for the 'ESE(SmartMX)' type.
67         /// </summary>
68         /// <since_tizen> 3 </since_tizen>
69         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
70         public event EventHandler<SecureElementTranscationEventArgs> EseSecureElementTransactionEvent
71         {
72             add
73             {
74                 if (_secureElementTransactionEvent == null)
75                 {
76                     RegisterSecureElementTransactionEvent(NfcSecureElementType.EmbeddedSE);
77                 }
78                 _secureElementTransactionEvent += value;
79             }
80             remove
81             {
82                 _secureElementTransactionEvent -= value;
83                 if (_secureElementTransactionEvent == null)
84                 {
85                     UnregisterSecureElementTransactionEvent(NfcSecureElementType.EmbeddedSE);
86                 }
87             }
88         }
89
90         /// <summary>
91         /// An event that is called when receiving the Secure Element (SIM/UICC (Universal Integrated Circuit Card)) transaction event for the 'UICC' type.
92         /// </summary>
93         /// <since_tizen> 3 </since_tizen>
94         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
95         public event EventHandler<SecureElementTranscationEventArgs> UiccSecureElementTransactionEvent
96         {
97             add
98             {
99                 if (_secureElementTransactionEvent == null)
100                 {
101                     RegisterSecureElementTransactionEvent(NfcSecureElementType.Uicc);
102                 }
103                 _secureElementTransactionEvent += value;
104             }
105             remove
106             {
107                 _secureElementTransactionEvent -= value;
108                 if (_secureElementTransactionEvent == null)
109                 {
110                     UnregisterSecureElementTransactionEvent(NfcSecureElementType.Uicc);
111                 }
112             }
113         }
114
115         /// <summary>
116         /// An event that is called when receiving the HCE (Host Card Emulation) event.
117         /// </summary>
118         /// <since_tizen> 3 </since_tizen>
119         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
120         public event EventHandler<HostCardEmulationEventArgs> HostCardEmulationEvent
121         {
122             add
123             {
124                 if (_hostCardEmulationEvent == null)
125                 {
126                     RegisterHostCardEmulationEvent();
127                 }
128                 _hostCardEmulationEvent += value;
129             }
130             remove
131             {
132                 _hostCardEmulationEvent -= value;
133                 if (_hostCardEmulationEvent == null)
134                 {
135                     UnregisterHostCardEmulationEvent();
136                 }
137             }
138         }
139
140         internal NfcCardEmulationAdapter()
141         {
142         }
143
144         /// <summary>
145         /// NfcCardEmulationAdpater destructor.
146         /// </summary>
147         ~NfcCardEmulationAdapter()
148         {
149             Dispose(false);
150         }
151
152         /// <summary>
153         /// Dispose
154         /// </summary>
155         public void Dispose()
156         {
157             Dispose(true);
158             GC.SuppressFinalize(this);
159         }
160
161         private void Dispose(bool disposing)
162         {
163             if (disposed)
164                 return;
165
166             if (disposing)
167             {
168                 // Free managed objects.
169             }
170             //Free unmanaged objects
171             disposed = true;
172         }
173
174         /// <summary>
175         /// Enables the card emulation mode.
176         /// </summary>
177         /// <since_tizen> 3 </since_tizen>
178         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
179         /// <exception cref="NotSupportedException">Thrown when the NFC is not supported.</exception>
180         /// <exception cref="InvalidOperationException">Thrown when the method fails due to an invalid operation.</exception>
181         public void EnableCardEmulation()
182         {
183             int ret = Interop.Nfc.CardEmulation.EnableCardEmulation();
184             if (ret != (int)NfcError.None)
185             {
186                 Log.Error(Globals.LogTag, "Failed to enable card emulation mode, Error - " + (NfcError)ret);
187                 NfcErrorFactory.ThrowNfcException(ret);
188             }
189         }
190
191         /// <summary>
192         /// Disables the card emulation mode.
193         /// </summary>
194         /// <since_tizen> 3 </since_tizen>
195         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
196         /// <exception cref="NotSupportedException">Thrown when the NFC is not supported.</exception>
197         /// <exception cref="InvalidOperationException">Thrown when the method fails due to an invalid operation.</exception>
198         public void DisableCardEmulation()
199         {
200             int ret = Interop.Nfc.CardEmulation.DisableCardEmulatiion();
201             if (ret != (int)NfcError.None)
202             {
203                 Log.Error(Globals.LogTag, "Failed to disable card emulation mode, Error - " + (NfcError)ret);
204                 NfcErrorFactory.ThrowNfcException(ret);
205             }
206         }
207
208         /// <summary>
209         /// Gets the current card emulation mode.
210         /// </summary>
211         /// <since_tizen> 3 </since_tizen>
212         /// <returns>Enumeration value for the NfcSecureElementCardEmulationMode.</returns>
213         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
214         public NfcSecureElementCardEmulationMode GetCardEmulationMode()
215         {
216             int mode = 0;
217             int ret = Interop.Nfc.CardEmulation.GetCardEmulationMode(out mode);
218             if (ret != (int)NfcError.None)
219             {
220                 Log.Error(Globals.LogTag, "Failed to get card emulation mode, Error - " + (NfcError)ret);
221             }
222
223             return (NfcSecureElementCardEmulationMode)mode;
224         }
225
226         /// <summary>
227         /// Gives the priority to the foreground application when dispatching the transaction event.
228         /// </summary>
229         /// <since_tizen> 3 </since_tizen>
230         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
231         /// <exception cref="NotSupportedException">Thrown when the NFC is not supported.</exception>
232         /// <exception cref="InvalidOperationException">Thrown when the method fails due to an invalid operation.</exception>
233         public void EnableTransactionForegroundDispatch()
234         {
235             int ret = Interop.Nfc.EnableTransactionForegroundDispatch();
236             if (ret != (int)NfcError.None)
237             {
238                 Log.Error(Globals.LogTag, "Failed to enable foreground dispatch, Error - " + (NfcError)ret);
239                 NfcErrorFactory.ThrowNfcException(ret);
240             }
241         }
242
243         /// <summary>
244         /// Disables the foreground dispatch for the "EVT_TRANSACTION" to the given application.
245         /// </summary>
246         /// <since_tizen> 3 </since_tizen>
247         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
248         /// <exception cref="NotSupportedException">Thrown when the NFC is not supported.</exception>
249         /// <exception cref="InvalidOperationException">Thrown when the method fails due to an invalid operation.</exception>
250         public void DisableTransactionForegroundDispatch()
251         {
252             int ret = Interop.Nfc.DisableTransactionForegroundDispatch();
253             if (ret != (int)NfcError.None)
254             {
255                 Log.Error(Globals.LogTag, "Failed to disable foreground dispatch, Error - " + (NfcError)ret);
256                 NfcErrorFactory.ThrowNfcException(ret);
257             }
258         }
259
260         /// <summary>
261         /// Gets the state, whether an application to call this API is currently the activated handler for the specific AID.
262         /// </summary>
263         /// <since_tizen> 3 </since_tizen>
264         /// <returns>'True' when application is currently the activated handler, otherwise 'False'.</returns>
265         /// <param name="seType">The type of the Secure Element.</param>
266         /// <param name="aid">The application ID specified in the ISO/IEC 7816-4.</param>
267         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
268         /// <exception cref="NotSupportedException">Thrown when the NFC is not supported.</exception>
269         /// <exception cref="ArgumentException">Thrown when the method fails due to an invalid parameter.</exception>
270         /// <exception cref="InvalidOperationException">Thrown when the method fails due to an invalid operation.</exception>
271         public bool IsActivatedHandlerForAid(NfcSecureElementType seType, string aid)
272         {
273             bool isActivatedHandle = false;
274             int ret = Interop.Nfc.CardEmulation.IsActivatedHandlerForAid((int)seType, aid, out isActivatedHandle);
275             if (ret != (int)NfcError.None)
276             {
277                 Log.Error(Globals.LogTag, "Failed to check activated handle for aid, Error - " + (NfcError)ret);
278                 NfcErrorFactory.ThrowNfcException(ret);
279             }
280
281             return isActivatedHandle;
282         }
283
284         /// <summary>
285         /// Gets the state, whether an application to call this API is currently the activated handler for the category.
286         /// </summary>
287         /// <since_tizen> 3 </since_tizen>
288         /// <returns>'True' when application is currently the activated handler, otherwise 'False'.</returns>
289         /// <param name="seType">The type of the secure element.</param>
290         /// <param name="category">Enumeration value of the category.</param>
291         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
292         /// <exception cref="NotSupportedException">Thrown when the NFC is not supported.</exception>
293         /// <exception cref="ArgumentException">Thrown when the method fails due to an invalid parameter.</exception>
294         /// <exception cref="InvalidOperationException">Thrown when the method fails due to an invalid operation.</exception>
295         public bool IsActivatedHandlerForCategory(NfcSecureElementType seType, NfcCardEmulationCategoryType category)
296         {
297             bool isActivatedHandle = false;
298             int ret = Interop.Nfc.CardEmulation.IsActivatedHandlerForCategory((int)seType, (int)category, out isActivatedHandle);
299             if (ret != (int)NfcError.None)
300             {
301                 Log.Error(Globals.LogTag, "Failed to check activated handle for category, Error - " + (NfcError)ret);
302                 NfcErrorFactory.ThrowNfcException(ret);
303             }
304
305             return isActivatedHandle;
306         }
307
308         /// <summary>
309         /// Registers the AID for a specific category.
310         /// </summary>
311         /// <since_tizen> 3 </since_tizen>
312         /// <param name="seType">The type of the secure element.</param>
313         /// <param name="category">Enumeration value of the category.</param>
314         /// <param name="aid">The application ID specified in the ISO/IEC 7816-4.</param>
315         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
316         /// <exception cref="NotSupportedException">Thrown when the NFC is not supported.</exception>
317         /// <exception cref="ArgumentException">Thrown when the method fails due to an invalid parameter.</exception>
318         /// <exception cref="InvalidOperationException">Thrown when the method fails due to an invalid operation.</exception>
319         public void RegisterAid(NfcSecureElementType seType, NfcCardEmulationCategoryType category, string aid)
320         {
321             int ret = Interop.Nfc.CardEmulation.RegisterAid((int)seType, (int)category, aid);
322             if (ret != (int)NfcError.None)
323             {
324                 Log.Error(Globals.LogTag, "Failed to register aid, Error - " + (NfcError)ret);
325                 NfcErrorFactory.ThrowNfcException(ret);
326             }
327         }
328
329         /// <summary>
330         /// Unregisters a previously registered AID for the specified category.
331         /// </summary>
332         /// <since_tizen> 3 </since_tizen>
333         /// <param name="seType">The type of the secure element.</param>
334         /// <param name="category">Enumeration value of the category.</param>
335         /// <param name="aid">The application ID specified in the ISO/IEC 7816-4.</param>
336         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
337         /// <exception cref="NotSupportedException">Thrown when the NFC is not supported.</exception>
338         /// <exception cref="ArgumentException">Thrown when the method fails due to an invalid parameter.</exception>
339         /// <exception cref="InvalidOperationException">Thrown when the method fails due to an invalid operation.</exception>
340         public void UnregisterAid(NfcSecureElementType seType, NfcCardEmulationCategoryType category, string aid)
341         {
342             int ret = Interop.Nfc.CardEmulation.UnregisterAid((int)seType, (int)category, aid);
343             if (ret != (int)NfcError.None)
344             {
345                 Log.Error(Globals.LogTag, "Failed to unregister aid, Error - " + (NfcError)ret);
346                 NfcErrorFactory.ThrowNfcException(ret);
347             }
348         }
349
350         /// <summary>
351         /// Sets the application as a preferred handler.
352         /// </summary>
353         /// <since_tizen> 3 </since_tizen>
354         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
355         /// <exception cref="NotSupportedException">Thrown when the NFC is not supported.</exception>
356         /// <exception cref="InvalidOperationException">Thrown when the method fails due to an invalid operation.</exception>
357         public void SetPreferredApplication()
358         {
359             int ret = Interop.Nfc.CardEmulation.SetPreferredHandler();
360             if (ret != (int)NfcError.None)
361             {
362                 Log.Error(Globals.LogTag, "Failed to set preferred handler, Error - " + (NfcError)ret);
363                 NfcErrorFactory.ThrowNfcException(ret);
364             }
365         }
366
367         /// <summary>
368         /// Unsets the application as a preferred handler.
369         /// </summary>
370         /// <since_tizen> 3 </since_tizen>
371         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
372         /// <exception cref="NotSupportedException">Thrown when the NFC is not supported.</exception>
373         /// <exception cref="InvalidOperationException">Thrown when the method fails due to an invalid operation.</exception>
374         public void UnsetPreferredApplication()
375         {
376             int ret = Interop.Nfc.CardEmulation.UnsetPreferredHandler();
377             if (ret != (int)NfcError.None)
378             {
379                 Log.Error(Globals.LogTag, "Failed to unset preferred handler, Error - " + (NfcError)ret);
380                 NfcErrorFactory.ThrowNfcException(ret);
381             }
382         }
383
384         /// <summary>
385         /// Retrieves all registered AIDs.
386         /// </summary>
387         /// <since_tizen> 3 </since_tizen>
388         /// <returns>The list of NfcRegisteredAidInformation objects.</returns>
389         /// <param name="seType">The type of the secure element.</param>
390         /// <param name="category">Enumeration value of the category.</param>
391         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
392         /// <exception cref="NotSupportedException">Thrown when the NFC is not supported.</exception>
393         /// <exception cref="ArgumentException">Thrown when the method fails due to an invalid parameter.</exception>
394         /// <exception cref="InvalidOperationException">Thrown when the method fails due to an invalid operation.</exception>
395         public IEnumerable<NfcRegisteredAidInformation> GetRegisteredAidInformation(NfcSecureElementType seType, NfcCardEmulationCategoryType category)
396         {
397             List<NfcRegisteredAidInformation> infoList = new List<NfcRegisteredAidInformation>();
398             Interop.Nfc.SecureElementRegisteredAidCallback callback = (int type, IntPtr aid, bool readOnly, IntPtr userData) =>
399             {
400                 if (aid != IntPtr.Zero)
401                 {
402                     NfcRegisteredAidInformation aidInfo = new NfcRegisteredAidInformation((NfcSecureElementType)type, Marshal.PtrToStringAnsi(aid), readOnly);
403
404                     infoList.Add(aidInfo);
405                 }
406             };
407
408             int ret = Interop.Nfc.CardEmulation.ForeachRegisterdAids((int)seType, (int)category, callback, IntPtr.Zero);
409             if (ret != (int)NfcError.None)
410             {
411                 Log.Error(Globals.LogTag, "Failed to get all registerd aid informations, Error - " + (NfcError)ret);
412                 NfcErrorFactory.ThrowNfcException(ret);
413             }
414
415             return infoList;
416         }
417
418         private void RegisterSecureElementEvent()
419         {
420             _secureElementEventCallback = (int eventType, IntPtr userData) =>
421             {
422                 NfcSecureElementEvent _eventType = (NfcSecureElementEvent)eventType;
423                 SecureElementEventArgs e = new SecureElementEventArgs(_eventType);
424                 _secureElementEvent.SafeInvoke(null, e);
425             };
426
427             int ret = Interop.Nfc.SetSecureElementEventCallback(_secureElementEventCallback, IntPtr.Zero);
428             if (ret != (int)NfcError.None)
429             {
430                 Log.Error(Globals.LogTag, "Failed to set secure element event callback, Error - " + (NfcError)ret);
431             }
432         }
433
434         private void UnregisterSecureElementEvent()
435         {
436             Interop.Nfc.UnsetSecureElementEventCallback();
437         }
438
439         private void RegisterSecureElementTransactionEvent(NfcSecureElementType seType)
440         {
441             _secureElementTransactionEventCallback = (int type, IntPtr aid, int aidSize, IntPtr param, int paramSize, IntPtr userData) =>
442             {
443                 NfcSecureElementType _secureElementType = (NfcSecureElementType)type;
444                 byte[] _aid = NfcConvertUtil.IntLengthIntPtrToByteArray(aid, aidSize);
445                 byte[] _param = NfcConvertUtil.IntLengthIntPtrToByteArray(param, paramSize);
446                 SecureElementTranscationEventArgs e = new SecureElementTranscationEventArgs(_secureElementType, _aid, _param);
447                 _secureElementTransactionEvent.SafeInvoke(null, e);
448             };
449
450             int ret = Interop.Nfc.SetSecureElementTransactionEventCallback((int)seType, _secureElementTransactionEventCallback, IntPtr.Zero);
451             if (ret != (int)NfcError.None)
452             {
453                 Log.Error(Globals.LogTag, "Failed to set secure element transaction event callback, Error - " + (NfcError)ret);
454             }
455         }
456
457         private void UnregisterSecureElementTransactionEvent(NfcSecureElementType seType)
458         {
459             Interop.Nfc.UnsetSecureElementTransactionEventCallback((int)seType);
460         }
461
462         private void RegisterHostCardEmulationEvent()
463         {
464             _hostCardEmulationEventCallback = (IntPtr handle, int eventType, IntPtr apdu, uint apduLen, IntPtr userData) =>
465             {
466                 IntPtr _seHandle = handle;
467                 NfcHceEvent _hcdEventType = (NfcHceEvent)eventType;
468                 byte[] _apdu = NfcConvertUtil.UintLengthIntPtrToByteArray(apdu, apduLen);
469                 HostCardEmulationEventArgs e = new HostCardEmulationEventArgs(_seHandle, _hcdEventType, _apdu);
470                 _hostCardEmulationEvent.SafeInvoke(null, e);
471             };
472
473             int ret = Interop.Nfc.SetHostCardEmulationEventCallback(_hostCardEmulationEventCallback, IntPtr.Zero);
474             if (ret != (int)NfcError.None)
475             {
476                 Log.Error(Globals.LogTag, "Failed to set host card emulation event callback, Error - " + (NfcError)ret);
477                 NfcErrorFactory.ThrowNfcException(ret);
478             }
479         }
480
481         private void UnregisterHostCardEmulationEvent()
482         {
483             Interop.Nfc.UnsetHostCardEmulationEventCallback();
484         }
485     }
486 }