16#include "DesynchronizedExchangesException.h"
19#include "ParseException.h"
22#include "ByteArrayUtil.h"
23#include "KeypleAssert.h"
24#include "PatternSyntaxException.h"
37using namespace calypsonet::terminal::calypso::transaction;
38using namespace calypsonet::terminal::card::spi;
39using namespace keyple::core::util;
40using namespace keyple::core::util::cpp::exception;
48 std::vector<std::shared_ptr<ApduRequestSpi>> cardSelectionApduRequests;
51 if (!mUnlockData.empty()) {
52 mSamCommands.push_back(
53 std::make_shared<CmdSamUnlock>(mProductType, ByteArrayUtil::fromHex(mUnlockData)));
54 for (
const auto& samCommand : mSamCommands) {
55 cardSelectionApduRequests.push_back(samCommand->getApduRequest());
59 mSamCardSelector->filterByPowerOnData(buildAtrRegex(mProductType, mSerialNumberRegex));
61 if (!cardSelectionApduRequests.empty()) {
62 return std::make_shared<CardSelectionRequestAdapter>(
64 std::make_shared<CardRequestAdapter>(cardSelectionApduRequests,
false));
66 return std::make_shared<CardSelectionRequestAdapter>(mSamCardSelector,
nullptr);
71 const std::shared_ptr<CardSelectionResponseApi> cardSelectionResponse)
73 if (mSamCommands.size() == 1) {
75 if (cardSelectionResponse->getCardResponse() ==
nullptr ||
76 cardSelectionResponse->getCardResponse()->getApduResponses().empty()) {
77 throw DesynchronizedExchangesException(
"Mismatch in the number of requests/responses");
80 const std::shared_ptr<ApduResponseApi> apduResponse =
81 cardSelectionResponse->getCardResponse()->getApduResponses()[0];
85 mSamCommands[0]->setApduResponse(apduResponse).checkStatus();
87 throw ParseException(
"An exception occurred while parse the SAM responses.",
88 std::make_shared<CalypsoSamCommandException>(e));
92 return std::make_shared<CalypsoSamAdapter>(cardSelectionResponse);
98 mProductType = productType;
104 const std::string& serialNumberRegex)
107 Pattern::compile(serialNumberRegex);
108 }
catch (
const PatternSyntaxException& exception) {
110 throw IllegalArgumentException(
"Invalid regular expression: '" +
115 mSerialNumberRegex = serialNumberRegex;
122 Assert::getInstance().isTrue(unlockData.size() == 16 || unlockData.size() == 32,
"length");
124 if (!ByteArrayUtil::isValidHexString(unlockData)) {
125 throw IllegalArgumentException(
"Invalid hexadecimal string.");
128 mUnlockData = unlockData;
133const std::string CalypsoSamSelectionAdapter::buildAtrRegex(
135 const std::string& samSerialNumberRegex)
137 std::string atrRegex;
141 if (samSerialNumberRegex.empty()) {
146 snRegex = samSerialNumberRegex;
154 std::string applicationTypeMask;
155 if (productType != CalypsoSam::ProductType::UNKNOWN) {
156 switch (productType) {
157 case CalypsoSam::ProductType::SAM_C1:
158 applicationTypeMask =
"C1";
160 case CalypsoSam::ProductType::SAM_S1DX:
161 applicationTypeMask =
"D?";
163 case CalypsoSam::ProductType::SAM_S1E1:
164 applicationTypeMask =
"E1";
166 case CalypsoSam::ProductType::CSAM_F:
168 applicationTypeMask =
"??";
171 throw IllegalArgumentException(
"Unknown SAM subtype.");
174 atrRegex =
"3B(.{6}|.{10})805A..80" + applicationTypeMask +
"20.{4}" + snRegex +
"829000";
CalypsoSamSelection & setUnlockData(const std::string &unlockData) override
CalypsoSamSelectionAdapter()
CalypsoSamSelection & filterByProductType(const CalypsoSam::ProductType productType) override
const std::shared_ptr< SmartCardSpi > parse(const std::shared_ptr< CardSelectionResponseApi > cardSelectionResponse) override
const std::shared_ptr< CardSelectionRequestSpi > getCardSelectionRequest() override
CalypsoSamSelection & filterBySerialNumber(const std::string &serialNumberRegex) override
CalypsoSam::ProductType ProductType