Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.Smartcard / Tizen.Network.Smartcard / SmartcardChannel.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 channel informations. It allows applications to handle channel informations.
25     /// </summary>
26     /// <since_tizen> 3 </since_tizen>
27     /// <privilege>http://tizen.org/privilege/secureelement</privilege>
28     public class SmartcardChannel : IDisposable
29     {
30         private int _channelHandle = -1;
31         private bool disposed = false;
32         private SmartcardSession _sessionObject;
33
34         /// <summary>
35         /// Whether the kind of channel is basic.
36         /// </summary>
37         /// <since_tizen> 3 </since_tizen>
38         public bool IsBasicChannel
39         {
40             get
41             {
42                 bool isBasicChannel;
43                 int ret = Interop.Smartcard.Channel.ChannelIsBasicChannel(_channelHandle, out isBasicChannel);
44                 if (ret != (int)SmartcardError.None)
45                 {
46                     Log.Error(Globals.LogTag, "Failed to get basic channel, Error - " + (SmartcardError)ret);
47                 }
48                 return isBasicChannel;
49             }
50         }
51
52         /// <summary>
53         /// Whether the kind of channel is logical.
54         /// </summary>
55         /// <since_tizen> 3 </since_tizen>
56         public bool IsLogicalChannel
57         {
58             get
59             {
60                 bool isBasicChannel;
61                 int ret = Interop.Smartcard.Channel.ChannelIsBasicChannel(_channelHandle, out isBasicChannel);
62                 if (ret != (int)SmartcardError.None)
63                 {
64                     Log.Error(Globals.LogTag, "Failed to get logical channel, Error - " + (SmartcardError)ret);
65                 }
66                 return !isBasicChannel;
67             }
68         }
69
70         /// <summary>
71         /// Whether the channel is closed.
72         /// </summary>
73         /// <since_tizen> 3 </since_tizen>
74         public bool IsClosed
75         {
76             get
77             {
78                 bool isClosed;
79                 int ret = Interop.Smartcard.Channel.ChannelIsClosed(_channelHandle, out isClosed);
80                 if (ret != (int)SmartcardError.None)
81                 {
82                     Log.Error(Globals.LogTag, "Failed to get closed, Error - " + (SmartcardError)ret);
83                 }
84                 return isClosed;
85             }
86         }
87
88         /// <summary>
89         /// The session that has opened the given channel.
90         /// </summary>
91         /// <since_tizen> 3 </since_tizen>
92         public SmartcardSession Session
93         {
94             get
95             {
96                 int session;
97                 int ret = Interop.Smartcard.Channel.ChannelGetSession(_channelHandle, out session);
98                 if (ret != (int)SmartcardError.None)
99                 {
100                     Log.Error(Globals.LogTag, "Failed to get session, Error - " + (SmartcardError)ret);
101                 }
102
103                 if (_sessionObject.GetHandle() != session)
104                 {
105                     Log.Error(Globals.LogTag, "Does not correspond with session, Error - " + _sessionObject.GetHandle() + " " + session);
106                 }
107
108                 return _sessionObject;
109             }
110         }
111
112         internal SmartcardChannel(SmartcardSession sessionHandle, int channelHandle)
113         {
114             _sessionObject = sessionHandle;
115             _channelHandle = channelHandle;
116         }
117
118         ~SmartcardChannel()
119         {
120             Dispose(false);
121         }
122
123         public void Dispose()
124         {
125             Dispose(true);
126             GC.SuppressFinalize(this);
127         }
128
129         private void Dispose(bool disposing)
130         {
131             if (disposed)
132                 return;
133
134             if (disposing)
135             {
136                 // Free managed objects.
137             }
138             //Free unmanaged objects
139             disposed = true;
140         }
141
142         /// <summary>
143         /// Closes the given channel to the Secure Element.
144         /// </summary>
145         /// <since_tizen> 3 </since_tizen>
146         /// <exception cref="NotSupportedException">Thrown when Smartcard is not supported.</exception>
147         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
148         public void Close()
149         {
150             int ret = Interop.Smartcard.Channel.ChannelClose(_channelHandle);
151             if (ret != (int)SmartcardError.None)
152             {
153                 Log.Error(Globals.LogTag, "Failed to channel close, Error - " + (SmartcardError)ret);
154                 SmartcardErrorFactory.ThrowSmartcardException(ret);
155             }
156             Dispose(true);
157         }
158
159         /// <summary>
160         /// Gets the response to the select command.
161         /// </summary>
162         /// <since_tizen> 3 </since_tizen>
163         /// <returns>Byte array to retrieve the SELECT response.</returns>
164         public byte[] GetSelectedResponse()
165         {
166             byte[] respList;
167             IntPtr strAtr;
168             int len;
169             int ret = Interop.Smartcard.Channel.ChannelGetSelectResponse(_channelHandle, out strAtr, out len);
170             if (ret != (int)SmartcardError.None)
171             {
172                 Log.Error(Globals.LogTag, "Failed to get select response, Error - " + (SmartcardError)ret);
173             }
174
175             respList = new byte[len];
176             for (int i = 0; i < len; i++)
177             {
178                 respList[i] = Marshal.ReadByte(strAtr);
179                 strAtr += sizeof(byte);
180             }
181             return respList;
182         }
183
184         /// <summary>
185         /// Transmits an APDU command (as per ISO/IEC 7816-4) to the Secure Element.
186         /// </summary>
187         /// <since_tizen> 3 </since_tizen>
188         /// <returns>Byte array for the response APDU plus status words.</returns>
189         /// <param name="cmd">Command APDU to be send to the secure element.</param>
190         public byte[] Transmit(byte[] cmd)
191         {
192             byte[] atrList;
193             IntPtr strAtr;
194             int len;
195             int ret = Interop.Smartcard.Channel.ChannelTransmit(_channelHandle, cmd, cmd.Length, out strAtr, out len);
196             if (ret != (int)SmartcardError.None)
197             {
198                 Log.Error(Globals.LogTag, "Failed to transmit, Error - " + (SmartcardError)ret);
199             }
200
201             atrList = new byte[len];
202             for (int i = 0; i < len; i++)
203             {
204                 atrList[i] = Marshal.ReadByte(strAtr);
205                 strAtr += sizeof(byte);
206             }
207
208             return atrList;
209         }
210
211         /// <summary>
212         /// Helper function to retrieves the response APDU of the previous transmit() call.
213         /// </summary>
214         /// <since_tizen> 3 </since_tizen>
215         /// <returns>Byte array for the response APDU plus status words.</returns>
216         public byte[] GetTransmittedResponse()
217         {
218             byte[] respList;
219             IntPtr strAtr;
220             int len;
221             int ret = Interop.Smartcard.Channel.ChannelTransmitRetrieveResponse(_channelHandle, out strAtr, out len);
222             if (ret != (int)SmartcardError.None)
223             {
224                 Log.Error(Globals.LogTag, "Failed to get trasmit retrieve response, Error - " + (SmartcardError)ret);
225             }
226
227             respList = new byte[len];
228             for (int i = 0; i < len; i++)
229             {
230                 respList[i] = Marshal.ReadByte(strAtr);
231                 strAtr += sizeof(byte);
232             }
233             return respList;
234         }
235
236         /// <summary>
237         /// Performs a selection of the next Applet on the given channel that matches to the partial Application ID(AID).
238         /// </summary>
239         /// <since_tizen> 3 </since_tizen>
240         /// <returns>True or false depending whether another applet with the partial Application ID(AID).</returns>
241         public bool SelectNext()
242         {
243             bool selectNext;
244             int ret = Interop.Smartcard.Channel.ChannelSelectNext(_channelHandle, out selectNext);
245             if (ret != (int)SmartcardError.None)
246             {
247                 Log.Error(Globals.LogTag, "Failed to select next, Error - " + (SmartcardError)ret);
248             }
249             return selectNext;
250         }
251     }
252 }