Release 4.0.0-preview1-00051
[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     /// <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         /// Event that is called when receiving 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         /// Event that is called when receiving Secure Element(SIM/UICC(Universal Integrated Circuit Card)) transaction event for '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         /// Event that is called when receiving Secure Element(SIM/UICC(Universal Integrated Circuit Card)) transaction event for '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         /// Event that is called when when receiving 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         ~NfcCardEmulationAdapter()
145         {
146             Dispose(false);
147         }
148
149         public void Dispose()
150         {
151             Dispose(true);
152             GC.SuppressFinalize(this);
153         }
154
155         private void Dispose(bool disposing)
156         {
157             if (disposed)
158                 return;
159
160             if (disposing)
161             {
162                 // Free managed objects.
163             }
164             //Free unmanaged objects
165             disposed = true;
166         }
167
168         /// <summary>
169         /// Enable card emulation mode.
170         /// </summary>
171         /// <since_tizen> 3 </since_tizen>
172         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
173         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
174         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
175         public void EnableCardEmulation()
176         {
177             int ret = Interop.Nfc.CardEmulation.EnableCardEmulation();
178             if (ret != (int)NfcError.None)
179             {
180                 Log.Error(Globals.LogTag, "Failed to enable card emulation mode, Error - " + (NfcError)ret);
181                 NfcErrorFactory.ThrowNfcException(ret);
182             }
183         }
184
185         /// <summary>
186         /// Disable card emulation mode.
187         /// </summary>
188         /// <since_tizen> 3 </since_tizen>
189         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
190         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
191         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
192         public void DisableCardEmulation()
193         {
194             int ret = Interop.Nfc.CardEmulation.DisableCardEmulatiion();
195             if (ret != (int)NfcError.None)
196             {
197                 Log.Error(Globals.LogTag, "Failed to disable card emulation mode, Error - " + (NfcError)ret);
198                 NfcErrorFactory.ThrowNfcException(ret);
199             }
200         }
201
202         /// <summary>
203         /// Get the current card emulation mode.
204         /// </summary>
205         /// <since_tizen> 3 </since_tizen>
206         /// <returns>Enumeration value of NfcSecureElementCardEmulationMode.</returns>
207         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
208         public NfcSecureElementCardEmulationMode GetCardEmulationMode()
209         {
210             int mode = 0;
211             int ret = Interop.Nfc.CardEmulation.GetCardEmulationMode(out mode);
212             if (ret != (int)NfcError.None)
213             {
214                 Log.Error(Globals.LogTag, "Failed to get card emulation mode, Error - " + (NfcError)ret);
215             }
216
217             return (NfcSecureElementCardEmulationMode)mode;
218         }
219
220         /// <summary>
221         /// Give the priority to the foreground application when dispatching transaction event.
222         /// </summary>
223         /// <since_tizen> 3 </since_tizen>
224         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
225         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
226         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
227         public void EnableTransactionForegroundDispatch()
228         {
229             int ret = Interop.Nfc.EnableTransactionForegroundDispatch();
230             if (ret != (int)NfcError.None)
231             {
232                 Log.Error(Globals.LogTag, "Failed to enable foreground dispatch, Error - " + (NfcError)ret);
233                 NfcErrorFactory.ThrowNfcException(ret);
234             }
235         }
236
237         /// <summary>
238         /// Disable foreground dispatch for "EVT_TRANSACTION" to the givin application.
239         /// </summary>
240         /// <since_tizen> 3 </since_tizen>
241         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
242         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
243         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
244         public void DisableTransactionForegroundDispatch()
245         {
246             int ret = Interop.Nfc.DisableTransactionForegroundDispatch();
247             if (ret != (int)NfcError.None)
248             {
249                 Log.Error(Globals.LogTag, "Failed to disable foreground dispatch, Error - " + (NfcError)ret);
250                 NfcErrorFactory.ThrowNfcException(ret);
251             }
252         }
253
254         /// <summary>
255         /// Gets the state whether an application to call this api is currently the activated handler for specific AID.
256         /// </summary>
257         /// <since_tizen> 3 </since_tizen>
258         /// <returns>'True' when application is currently the activated handler, otherwise 'False'.</returns>
259         /// <param name="seType">The type of Secure Element.</param>
260         /// <param name="aid">Application Id, specified in ISO/IEC 7816-4.</param>
261         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
262         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
263         /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
264         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
265         public bool IsActivatedHandlerForAid(NfcSecureElementType seType, string aid)
266         {
267             bool isActivatedHandle = false;
268             int ret = Interop.Nfc.CardEmulation.IsActivatedHandlerForAid((int)seType, aid, out isActivatedHandle);
269             if (ret != (int)NfcError.None)
270             {
271                 Log.Error(Globals.LogTag, "Failed to check activated handle for aid, Error - " + (NfcError)ret);
272                 NfcErrorFactory.ThrowNfcException(ret);
273             }
274
275             return isActivatedHandle;
276         }
277
278         /// <summary>
279         /// Gets the state whether an application to call this api is currently the activated handler for category.
280         /// </summary>
281         /// <since_tizen> 3 </since_tizen>
282         /// <returns>'True' when application is currently the activated handler, otherwise 'False'.</returns>
283         /// <param name="seType">The type of Secure Element.</param>
284         /// <param name="category">Enumeration value of category.</param>
285         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
286         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
287         /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
288         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
289         public bool IsActivatedHandlerForCategory(NfcSecureElementType seType, NfcCardEmulationCategoryType category)
290         {
291             bool isActivatedHandle = false;
292             int ret = Interop.Nfc.CardEmulation.IsActivatedHandlerForCategory((int)seType, (int)category, out isActivatedHandle);
293             if (ret != (int)NfcError.None)
294             {
295                 Log.Error(Globals.LogTag, "Failed to check activated handle for category, Error - " + (NfcError)ret);
296                 NfcErrorFactory.ThrowNfcException(ret);
297             }
298
299             return isActivatedHandle;
300         }
301
302         /// <summary>
303         /// Registers a AID for a specific category.
304         /// </summary>
305         /// <since_tizen> 3 </since_tizen>
306         /// <param name="seType">The type of Secure Element.</param>
307         /// <param name="category">Enumeration value of category.</param>
308         /// <param name="aid">Application Id, specified in ISO/IEC 7816-4.</param>
309         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
310         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
311         /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
312         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
313         public void RegisterAid(NfcSecureElementType seType, NfcCardEmulationCategoryType category, string aid)
314         {
315             int ret = Interop.Nfc.CardEmulation.RegisterAid((int)seType, (int)category, aid);
316             if (ret != (int)NfcError.None)
317             {
318                 Log.Error(Globals.LogTag, "Failed to register aid, Error - " + (NfcError)ret);
319                 NfcErrorFactory.ThrowNfcException(ret);
320             }
321         }
322
323         /// <summary>
324         /// Unregisters a previously registered AID for the specified category.
325         /// </summary>
326         /// <since_tizen> 3 </since_tizen>
327         /// <param name="seType">The type of Secure Element.</param>
328         /// <param name="category">Enumeration value of category.</param>
329         /// <param name="aid">Application Id, specified in ISO/IEC 7816-4.</param>
330         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
331         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
332         /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
333         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
334         public void UnregisterAid(NfcSecureElementType seType, NfcCardEmulationCategoryType category, string aid)
335         {
336             int ret = Interop.Nfc.CardEmulation.UnregisterAid((int)seType, (int)category, aid);
337             if (ret != (int)NfcError.None)
338             {
339                 Log.Error(Globals.LogTag, "Failed to unregister aid, Error - " + (NfcError)ret);
340                 NfcErrorFactory.ThrowNfcException(ret);
341             }
342         }
343
344         /// <summary>
345         /// Sets the application as a preferred handler.
346         /// </summary>
347         /// <since_tizen> 3 </since_tizen>
348         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
349         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
350         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
351         public void SetPreferredApplication()
352         {
353             int ret = Interop.Nfc.CardEmulation.SetPreferredHandler();
354             if (ret != (int)NfcError.None)
355             {
356                 Log.Error(Globals.LogTag, "Failed to set preferred handler, Error - " + (NfcError)ret);
357                 NfcErrorFactory.ThrowNfcException(ret);
358             }
359         }
360
361         /// <summary>
362         /// Unsets the application as a preferred handler.
363         /// </summary>
364         /// <since_tizen> 3 </since_tizen>
365         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
366         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
367         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
368         public void UnsetPreferredApplication()
369         {
370             int ret = Interop.Nfc.CardEmulation.UnsetPreferredHandler();
371             if (ret != (int)NfcError.None)
372             {
373                 Log.Error(Globals.LogTag, "Failed to unset preferred handler, Error - " + (NfcError)ret);
374                 NfcErrorFactory.ThrowNfcException(ret);
375             }
376         }
377
378         /// <summary>
379         /// Retrieves all registered AID.
380         /// </summary>
381         /// <since_tizen> 3 </since_tizen>
382         /// <returns>List of NfcRegisteredAidInformation objects.</returns>
383         /// <param name="seType">The type of Secure Element.</param>
384         /// <param name="category">Enumeration value of category.</param>
385         /// <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
386         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
387         /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
388         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
389         public IEnumerable<NfcRegisteredAidInformation> GetRegisteredAidInformation(NfcSecureElementType seType, NfcCardEmulationCategoryType category)
390         {
391             List<NfcRegisteredAidInformation> infoList = new List<NfcRegisteredAidInformation>();
392             Interop.Nfc.SecureElementRegisteredAidCallback callback = (int type, IntPtr aid, bool readOnly, IntPtr userData) =>
393             {
394                 if (aid != IntPtr.Zero)
395                 {
396                     NfcRegisteredAidInformation aidInfo = new NfcRegisteredAidInformation((NfcSecureElementType)type, Marshal.PtrToStringAnsi(aid), readOnly);
397
398                     infoList.Add(aidInfo);
399                 }
400             };
401
402             int ret = Interop.Nfc.CardEmulation.ForeachRegisterdAids((int)seType, (int)category, callback, IntPtr.Zero);
403             if (ret != (int)NfcError.None)
404             {
405                 Log.Error(Globals.LogTag, "Failed to get all registerd aid informations, Error - " + (NfcError)ret);
406                 NfcErrorFactory.ThrowNfcException(ret);
407             }
408
409             return infoList;
410         }
411
412         private void RegisterSecureElementEvent()
413         {
414             _secureElementEventCallback = (int eventType, IntPtr userData) =>
415             {
416                 NfcSecureElementEvent _eventType = (NfcSecureElementEvent)eventType;
417                 SecureElementEventArgs e = new SecureElementEventArgs(_eventType);
418                 _secureElementEvent.SafeInvoke(null, e);
419             };
420
421             int ret = Interop.Nfc.SetSecureElementEventCallback(_secureElementEventCallback, IntPtr.Zero);
422             if (ret != (int)NfcError.None)
423             {
424                 Log.Error(Globals.LogTag, "Failed to set secure element event callback, Error - " + (NfcError)ret);
425             }
426         }
427
428         private void UnregisterSecureElementEvent()
429         {
430             Interop.Nfc.UnsetSecureElementEventCallback();
431         }
432
433         private void RegisterSecureElementTransactionEvent(NfcSecureElementType seType)
434         {
435             _secureElementTransactionEventCallback = (int type, IntPtr aid, int aidSize, IntPtr param, int paramSize, IntPtr userData) =>
436             {
437                 NfcSecureElementType _secureElementType = (NfcSecureElementType)type;
438                 byte[] _aid = NfcConvertUtil.IntLengthIntPtrToByteArray(aid, aidSize);
439                 byte[] _param = NfcConvertUtil.IntLengthIntPtrToByteArray(param, paramSize);
440                 SecureElementTranscationEventArgs e = new SecureElementTranscationEventArgs(_secureElementType, _aid, _param);
441                 _secureElementTransactionEvent.SafeInvoke(null, e);
442             };
443
444             int ret = Interop.Nfc.SetSecureElementTransactionEventCallback((int)seType, _secureElementTransactionEventCallback, IntPtr.Zero);
445             if (ret != (int)NfcError.None)
446             {
447                 Log.Error(Globals.LogTag, "Failed to set secure element transaction event callback, Error - " + (NfcError)ret);
448             }
449         }
450
451         private void UnregisterSecureElementTransactionEvent(NfcSecureElementType seType)
452         {
453             Interop.Nfc.UnsetSecureElementTransactionEventCallback((int)seType);
454         }
455
456         private void RegisterHostCardEmulationEvent()
457         {
458             _hostCardEmulationEventCallback = (IntPtr handle, int eventType, IntPtr apdu, uint apduLen, IntPtr userData) =>
459             {
460                 IntPtr _seHandle = handle;
461                 NfcHceEvent _hcdEventType = (NfcHceEvent)eventType;
462                 byte[] _apdu = NfcConvertUtil.UintLengthIntPtrToByteArray(apdu, apduLen);
463                 HostCardEmulationEventArgs e = new HostCardEmulationEventArgs(_seHandle, _hcdEventType, _apdu);
464                 _hostCardEmulationEvent.SafeInvoke(null, e);
465             };
466
467             int ret = Interop.Nfc.SetHostCardEmulationEventCallback(_hostCardEmulationEventCallback, IntPtr.Zero);
468             if (ret != (int)NfcError.None)
469             {
470                 Log.Error(Globals.LogTag, "Failed to set host card emulation event callback, Error - " + (NfcError)ret);
471                 NfcErrorFactory.ThrowNfcException(ret);
472             }
473         }
474
475         private void UnregisterHostCardEmulationEvent()
476         {
477             Interop.Nfc.UnsetHostCardEmulationEventCallback();
478         }
479     }
480 }