Release 4.0.0-preview1-00295
[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     /// The class for Smartcard channel information. It allows applications to handle the channel information.
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         /// <summary>
119         /// SmartcardChannel destructor.
120         /// </summary>
121         ~SmartcardChannel()
122         {
123             Dispose(false);
124         }
125
126         /// <summary>
127         /// Dispose
128         /// </summary>
129         public void Dispose()
130         {
131             Dispose(true);
132             GC.SuppressFinalize(this);
133         }
134
135         private void Dispose(bool disposing)
136         {
137             if (disposed)
138                 return;
139
140             if (disposing)
141             {
142                 // Free managed objects.
143             }
144             //Free unmanaged objects
145             disposed = true;
146         }
147
148         /// <summary>
149         /// Closes the given channel to the Secure Element.
150         /// </summary>
151         /// <since_tizen> 3 </since_tizen>
152         /// <exception cref="NotSupportedException">Thrown when the Smartcard is not supported.</exception>
153         /// <exception cref="InvalidOperationException">Thrown when the method failed due to an invalid operation.</exception>
154         public void Close()
155         {
156             int ret = Interop.Smartcard.Channel.ChannelClose(_channelHandle);
157             if (ret != (int)SmartcardError.None)
158             {
159                 Log.Error(Globals.LogTag, "Failed to channel close, Error - " + (SmartcardError)ret);
160                 SmartcardErrorFactory.ThrowSmartcardException(ret);
161             }
162             Dispose(true);
163         }
164
165         /// <summary>
166         /// Gets the response to the select command.
167         /// </summary>
168         /// <since_tizen> 3 </since_tizen>
169         /// <returns>Byte array to retrieve the select response.</returns>
170         public byte[] GetSelectedResponse()
171         {
172             byte[] respList;
173             IntPtr strAtr;
174             int len;
175             int ret = Interop.Smartcard.Channel.ChannelGetSelectResponse(_channelHandle, out strAtr, out len);
176             if (ret != (int)SmartcardError.None)
177             {
178                 Log.Error(Globals.LogTag, "Failed to get select response, Error - " + (SmartcardError)ret);
179             }
180
181             respList = new byte[len];
182             for (int i = 0; i < len; i++)
183             {
184                 respList[i] = Marshal.ReadByte(strAtr);
185                 strAtr += sizeof(byte);
186             }
187             return respList;
188         }
189
190         /// <summary>
191         /// Transmits the APDU command (as per ISO/IEC 7816-4) to the secure element.
192         /// </summary>
193         /// <since_tizen> 3 </since_tizen>
194         /// <returns>Byte array for the response APDU plus status words.</returns>
195         /// <param name="cmd">Command APDU to be sent to the secure element.</param>
196         public byte[] Transmit(byte[] cmd)
197         {
198             byte[] atrList;
199             IntPtr strAtr;
200             int len;
201             int ret = Interop.Smartcard.Channel.ChannelTransmit(_channelHandle, cmd, cmd.Length, out strAtr, out len);
202             if (ret != (int)SmartcardError.None)
203             {
204                 Log.Error(Globals.LogTag, "Failed to transmit, Error - " + (SmartcardError)ret);
205             }
206
207             atrList = new byte[len];
208             for (int i = 0; i < len; i++)
209             {
210                 atrList[i] = Marshal.ReadByte(strAtr);
211                 strAtr += sizeof(byte);
212             }
213
214             return atrList;
215         }
216
217         /// <summary>
218         /// Helper function to retrieve the response APDU of the previous transmit() call.
219         /// </summary>
220         /// <since_tizen> 3 </since_tizen>
221         /// <returns>Byte array for the response APDU plus status words.</returns>
222         public byte[] GetTransmittedResponse()
223         {
224             byte[] respList;
225             IntPtr strAtr;
226             int len;
227             int ret = Interop.Smartcard.Channel.ChannelTransmitRetrieveResponse(_channelHandle, out strAtr, out len);
228             if (ret != (int)SmartcardError.None)
229             {
230                 Log.Error(Globals.LogTag, "Failed to get trasmit retrieve response, Error - " + (SmartcardError)ret);
231             }
232
233             respList = new byte[len];
234             for (int i = 0; i < len; i++)
235             {
236                 respList[i] = Marshal.ReadByte(strAtr);
237                 strAtr += sizeof(byte);
238             }
239             return respList;
240         }
241
242         /// <summary>
243         /// Performs a selection of the next applet on the given channel that matches to the partial application ID (AID).
244         /// </summary>
245         /// <since_tizen> 3 </since_tizen>
246         /// <returns>True or false depending whether another applet with the partial application ID (AID).</returns>
247         public bool SelectNext()
248         {
249             bool selectNext;
250             int ret = Interop.Smartcard.Channel.ChannelSelectNext(_channelHandle, out selectNext);
251             if (ret != (int)SmartcardError.None)
252             {
253                 Log.Error(Globals.LogTag, "Failed to select next, Error - " + (SmartcardError)ret);
254             }
255             return selectNext;
256         }
257     }
258 }