95 lines
3.0 KiB
C#
95 lines
3.0 KiB
C#
|
|
using System;
|
||
|
|
using System.Text;
|
||
|
|
|
||
|
|
namespace GemCard
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// This class represents a command APDU
|
||
|
|
/// </summary>
|
||
|
|
public class APDUCommand
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// Minimun size of an APDU command in bytes
|
||
|
|
/// </summary>
|
||
|
|
public const int APDU_MIN_LENGTH = 4;
|
||
|
|
|
||
|
|
public byte Class; /// Class byte
|
||
|
|
public byte Ins; /// Instruction byte
|
||
|
|
public byte P1; /// Parameter P1 byte
|
||
|
|
public byte P2; /// Parameter P2 byte
|
||
|
|
public byte[] Data; /// Data to send to the card if any, null if no data to send
|
||
|
|
public byte Le; /// Number of data expected, 0 if none
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Constructor
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="bCla">Class byte</param>
|
||
|
|
/// <param name="bIns">Instruction byte</param>
|
||
|
|
/// <param name="bP1">Parameter P1 byte</param>
|
||
|
|
/// <param name="bP2">Parameter P2 byte</param>
|
||
|
|
/// <param name="baData">Data to send to the card if any, null if no data to send</param>
|
||
|
|
/// <param name="bLe">Number of data expected, 0 if none</param>
|
||
|
|
public APDUCommand(byte bCla, byte bIns, byte bP1, byte bP2, byte[] baData, byte bLe)
|
||
|
|
{
|
||
|
|
this.Class = bCla;
|
||
|
|
this.Ins = bIns;
|
||
|
|
this.P1 = bP1;
|
||
|
|
this.P2 = bP2;
|
||
|
|
this.Data = baData;
|
||
|
|
this.Le = bLe;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Update the current APDU with selected parameters
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="apduParam">APDU parameters</param>
|
||
|
|
public void Update(APDUParam apduParam)
|
||
|
|
{
|
||
|
|
if (apduParam.UseData) Data = apduParam.Data;
|
||
|
|
if (apduParam.UseLe) Le = apduParam.Le;
|
||
|
|
if (apduParam.UseP1) P1 = apduParam.P1;
|
||
|
|
if (apduParam.UseP2) P2 = apduParam.P2;
|
||
|
|
if (apduParam.UseChannel) Class += apduParam.Channel;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Overrides the ToString method to format to a string the APDUCommand object
|
||
|
|
/// </summary>
|
||
|
|
/// <returns></returns>
|
||
|
|
public override string ToString()
|
||
|
|
{
|
||
|
|
string strData = null;
|
||
|
|
byte bLc = 0;
|
||
|
|
byte bP3 = Le;
|
||
|
|
|
||
|
|
if (Data != null)
|
||
|
|
{
|
||
|
|
StringBuilder sData = new StringBuilder(Data.Length * 2);
|
||
|
|
for (int nI = 0; nI < Data.Length; nI++)
|
||
|
|
{
|
||
|
|
sData.AppendFormat("{0:X02}", Data[nI]);
|
||
|
|
}
|
||
|
|
|
||
|
|
strData = "Data=" + sData.ToString();
|
||
|
|
bLc = (byte) Data.Length;
|
||
|
|
bP3 = bLc;
|
||
|
|
}
|
||
|
|
|
||
|
|
//string strApdu = string.Format("Class={0:X02} Ins={1:X02} P1={2:X02} P2={3:X02} Le={4:X02} Lc={5:X02} ",
|
||
|
|
//m_bCla, m_bIns, m_bP1, m_bP2, m_bLe, bLc);
|
||
|
|
StringBuilder strApdu = new StringBuilder();
|
||
|
|
|
||
|
|
strApdu.AppendFormat("Class={0:X02} Ins={1:X02} P1={2:X02} P2={3:X02} P3={4:X02} ",
|
||
|
|
Class, Ins, P1, P2, bP3);
|
||
|
|
|
||
|
|
if (Data != null)
|
||
|
|
{
|
||
|
|
strApdu.Append(strData);
|
||
|
|
}
|
||
|
|
|
||
|
|
return strApdu.ToString();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|