Add since_tizen Tag
[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         public void Close()
147         {
148             int ret = Interop.Smartcard.Channel.ChannelClose(_channelHandle);
149             if (ret != (int)SmartcardError.None)
150             {
151                 Log.Error(Globals.LogTag, "Failed to channel close, Error - " + (SmartcardError)ret);
152                 SmartcardErrorFactory.ThrowSmartcardException(ret);
153             }
154             Dispose(true);
155         }
156
157         /// <summary>
158         /// Gets the response to the select command.
159         /// </summary>
160         /// <since_tizen> 3 </since_tizen>
161         /// <returns>Byte array to retrieve the SELECT response.</returns>
162         public byte[] GetSelectedResponse()
163         {
164             byte[] respList;
165             IntPtr strAtr;
166             int len;
167             int ret = Interop.Smartcard.Channel.ChannelGetSelectResponse(_channelHandle, out strAtr, out len);
168             if (ret != (int)SmartcardError.None)
169             {
170                 Log.Error(Globals.LogTag, "Failed to get select response, Error - " + (SmartcardError)ret);
171             }
172
173             respList = new byte[len];
174             for (int i = 0; i < len; i++)
175             {
176                 respList[i] = Marshal.ReadByte(strAtr);
177                 strAtr += sizeof(byte);
178             }
179             return respList;
180         }
181
182         /// <summary>
183         /// Transmits an APDU command (as per ISO/IEC 7816-4) to the Secure Element.
184         /// </summary>
185         /// <since_tizen> 3 </since_tizen>
186         /// <returns>Byte array for the response APDU plus status words.</returns>
187         /// <param name="cmd">Command APDU to be send to the secure element.</param>
188         public byte[] Transmit(byte[] cmd)
189         {
190             byte[] atrList;
191             IntPtr strAtr;
192             int len;
193             int ret = Interop.Smartcard.Channel.ChannelTransmit(_channelHandle, cmd, cmd.Length, out strAtr, out len);
194             if (ret != (int)SmartcardError.None)
195             {
196                 Log.Error(Globals.LogTag, "Failed to transmit, Error - " + (SmartcardError)ret);
197             }
198
199             atrList = new byte[len];
200             for (int i = 0; i < len; i++)
201             {
202                 atrList[i] = Marshal.ReadByte(strAtr);
203                 strAtr += sizeof(byte);
204             }
205
206             return atrList;
207         }
208
209         /// <summary>
210         /// Helper function to retrieves the response APDU of the previous transmit() call.
211         /// </summary>
212         /// <since_tizen> 3 </since_tizen>
213         /// <returns>Byte array for the response APDU plus status words.</returns>
214         public byte[] GetTransmittedResponse()
215         {
216             byte[] respList;
217             IntPtr strAtr;
218             int len;
219             int ret = Interop.Smartcard.Channel.ChannelTransmitRetrieveResponse(_channelHandle, out strAtr, out len);
220             if (ret != (int)SmartcardError.None)
221             {
222                 Log.Error(Globals.LogTag, "Failed to get trasmit retrieve response, Error - " + (SmartcardError)ret);
223             }
224
225             respList = new byte[len];
226             for (int i = 0; i < len; i++)
227             {
228                 respList[i] = Marshal.ReadByte(strAtr);
229                 strAtr += sizeof(byte);
230             }
231             return respList;
232         }
233
234         /// <summary>
235         /// Performs a selection of the next Applet on the given channel that matches to the partial Application ID(AID).
236         /// </summary>
237         /// <since_tizen> 3 </since_tizen>
238         /// <returns>True or false depending whether another applet with the partial Application ID(AID).</returns>
239         public bool SelectNext()
240         {
241             bool selectNext;
242             int ret = Interop.Smartcard.Channel.ChannelSelectNext(_channelHandle, out selectNext);
243             if (ret != (int)SmartcardError.None)
244             {
245                 Log.Error(Globals.LogTag, "Failed to select next, Error - " + (SmartcardError)ret);
246             }
247             return selectNext;
248         }
249     }
250 }