Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.Smartcard / Tizen.Network.Smartcard / SmartcardSession.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.Smartcard
22 {
23     /// <summary>
24     /// A class for Smartcard session informations. It allows applications to handle session informations.
25     /// </summary>
26     /// <since_tizen> 3 </since_tizen>
27     /// <privilege>http://tizen.org/privilege/secureelement</privilege>
28     public class SmartcardSession : IDisposable
29     {
30         private int _sessionHandle = -1;
31         private bool disposed = false;
32         private List<SmartcardChannel> _basicChannelList = new List<SmartcardChannel>();
33         private List<SmartcardChannel> _logicalChannelList = new List<SmartcardChannel>();
34         private SmartcardReader _readerObject;
35         private int _basicChannel = 0;
36         private int _logicalChannel = 0;
37
38         /// <summary>
39         /// The reader object that provides the given session.
40         /// </summary>
41         /// <since_tizen> 3 </since_tizen>
42         public SmartcardReader Reader
43         {
44             get
45             {
46                 int reader;
47                 int ret = Interop.Smartcard.Session.SessionGetReader(_sessionHandle, out reader);
48                 if (ret != (int)SmartcardError.None)
49                 {
50                     Log.Error(Globals.LogTag, "Failed to get reader, Error - " + (SmartcardError)ret);
51                 }
52
53                 if (_readerObject.GetHandle() != reader)
54                 {
55                     Log.Error(Globals.LogTag, "Does not correspond with reader, Error - " + _readerObject.GetHandle() + " " + reader);
56                 }
57
58                 return _readerObject;
59             }
60         }
61
62         /// <summary>
63         /// The Answer to Reset(ATR) of this Secure Element.
64         /// </summary>
65         /// <since_tizen> 3 </since_tizen>
66         public byte[] Atr
67         {
68             get
69             {
70                 byte[] atrList;
71                 IntPtr strAtr;
72                 int len;
73                 int ret = Interop.Smartcard.Session.SessionGetAtr(_sessionHandle, out strAtr, out len);
74                 if (ret != (int)SmartcardError.None)
75                 {
76                     Log.Error(Globals.LogTag, "Failed to get atr, Error - " + (SmartcardError)ret);
77                 }
78
79                 atrList = new byte[len];
80                 for (int i = 0; i < len; i++)
81                 {
82                     atrList[i] = Marshal.ReadByte(strAtr);
83                     strAtr += sizeof(byte);
84                 }
85                 return atrList;
86             }
87         }
88
89         /// <summary>
90         /// Whether the session is closed.
91         /// </summary>
92         /// <since_tizen> 3 </since_tizen>
93         public bool IsClosed
94         {
95             get
96             {
97                 bool isClosed;
98                 int ret = Interop.Smartcard.Session.SessionIsClosed(_sessionHandle, out isClosed);
99                 if (ret != (int)SmartcardError.None)
100                 {
101                     Log.Error(Globals.LogTag, "Failed to get present, Error - " + (SmartcardError)ret);
102                 }
103                 return isClosed;
104             }
105         }
106
107         internal SmartcardSession(SmartcardReader readerHandle, int sessionHandle)
108         {
109             _readerObject = readerHandle;
110             _sessionHandle = sessionHandle;
111         }
112
113         ~SmartcardSession()
114         {
115             Dispose(false);
116         }
117
118         public void Dispose()
119         {
120             Dispose(true);
121             GC.SuppressFinalize(this);
122         }
123
124         private void Dispose(bool disposing)
125         {
126             if (disposed)
127                 return;
128
129             if (disposing)
130             {
131                 // Free managed objects.
132                 foreach (SmartcardChannel channel in _basicChannelList)
133                 {
134                     channel.Dispose();
135                     _basicChannelList.Remove(channel);
136                 }
137
138                 foreach (SmartcardChannel channel in _logicalChannelList)
139                 {
140                     channel.Dispose();
141                     _logicalChannelList.Remove(channel);
142                 }
143             }
144             //Free unmanaged objects
145             disposed = true;
146         }
147
148         internal int GetHandle()
149         {
150             return _sessionHandle;
151         }
152
153         /// <summary>
154         /// Closes the connection with the Secure Element.
155         /// </summary>
156         /// <since_tizen> 3 </since_tizen>
157         /// <exception cref="NotSupportedException">Thrown when Smartcard is not supported.</exception>
158         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
159         public void Close()
160         {
161             int ret = Interop.Smartcard.Session.SessionClose(_sessionHandle);
162             if (ret != (int)SmartcardError.None)
163             {
164                 Log.Error(Globals.LogTag, "Failed to close, Error - " + (SmartcardError)ret);
165                 SmartcardErrorFactory.ThrowSmartcardException(ret);
166             }
167             Dispose(true);
168         }
169
170         /// <summary>
171         /// Closes any channel opened on the given session.
172         /// </summary>
173         /// <since_tizen> 3 </since_tizen>
174         /// <exception cref="NotSupportedException">Thrown when Smartcard is not supported.</exception>
175         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
176         public void CloseChannels()
177         {
178             int ret = Interop.Smartcard.Session.SessionCloseChannels(_sessionHandle);
179             if (ret != (int)SmartcardError.None)
180             {
181                 Log.Error(Globals.LogTag, "Failed to close, Error - " + (SmartcardError)ret);
182                 SmartcardErrorFactory.ThrowSmartcardException(ret);
183             }
184
185             foreach (SmartcardChannel channel in _basicChannelList)
186             {
187                 channel.Close();
188             }
189
190             foreach (SmartcardChannel channel in _logicalChannelList)
191             {
192                 channel.Close();
193             }
194         }
195
196         /// <summary>
197         /// Gets an access to the basic channel, as defined in the ISO/IEC 7816-4 specification (the one that has number 0).
198         /// </summary>
199         /// <since_tizen> 3 </since_tizen>
200         /// <returns>The SmartcardChannel object for basic channel.</returns>
201         /// <param name="aid">Byte array containing the Application ID(AID) to be selected on the given channel.</param>
202         /// <param name="p2">P2 byte of the SELECT command if executed.</param>
203         /// <exception cref="NotSupportedException">Thrown when Smartcard is not supported.</exception>
204         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
205         public SmartcardChannel OpenBasicChannel(byte[] aid, byte p2)
206         {
207             int ret = Interop.Smartcard.Session.SessionOpenBasicChannel(_sessionHandle, aid, aid.Length, p2, out _basicChannel);
208             if (ret != (int)SmartcardError.None)
209             {
210                 Log.Error(Globals.LogTag, "Failed to open basic channel, Error - " + (SmartcardError)ret);
211                 SmartcardErrorFactory.ThrowSmartcardException(ret);
212             }
213             SmartcardChannel basicChannel = new SmartcardChannel(this, _basicChannel);
214             _basicChannelList.Add(basicChannel);
215
216             return basicChannel;
217         }
218
219         /// <summary>
220         /// Open a logical channel with the Secure Element, selecting the Applet represented by the given Application ID(AID).
221         /// </summary>
222         /// <since_tizen> 3 </since_tizen>
223         /// <returns>The SmartcardChannel object for logical channel.</returns>
224         /// <param name="aid">Byte array containing the Application ID(AID) to be selected on the given channel.</param>
225         /// <param name="p2">P2 byte of the SELECT command if executed.</param>
226         /// <exception cref="NotSupportedException">Thrown when Smartcard is not supported.</exception>
227         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
228         public SmartcardChannel OpenLogicalChannel(byte[] aid, byte p2)
229         {
230             int ret = Interop.Smartcard.Session.SessionOpenLogicalChannel(_sessionHandle, aid, aid.Length, p2, out _logicalChannel);
231             if (ret != (int)SmartcardError.None)
232             {
233                 Log.Error(Globals.LogTag, "Failed to open logical channel, Error - " + (SmartcardError)ret);
234                 SmartcardErrorFactory.ThrowSmartcardException(ret);
235             }
236             SmartcardChannel logicalChannel = new SmartcardChannel(this, _logicalChannel);
237             _logicalChannelList.Add(logicalChannel);
238
239             return logicalChannel;
240         }
241     }
242 }