16#include "InconsistentDataException.h"
19#include "ParseException.h"
22#include "ByteArrayUtil.h"
24#include "KeypleAssert.h"
26#include "PatternSyntaxException.h"
40using namespace calypsonet::terminal::calypso::transaction;
41using namespace calypsonet::terminal::card::spi;
42using namespace keyple::core::util;
43using namespace keyple::core::util::cpp;
44using namespace keyple::core::util::cpp::exception;
46const int CalypsoSamSelectionAdapter::SW_NOT_LOCKED = 0x6985;
53 mSamCardSelector->filterByPowerOnData(buildAtrRegex(mProductType, mSerialNumberRegex));
56 if (mUnlockCommand !=
nullptr) {
57 std::vector<std::shared_ptr<ApduRequestSpi>> cardSelectionApduRequests;
58 std::shared_ptr<ApduRequestAdapter> request = mUnlockCommand->getApduRequest();
59 request->addSuccessfulStatusWord(SW_NOT_LOCKED);
60 cardSelectionApduRequests.push_back(request);
61 return std::make_shared<CardSelectionRequestAdapter>(
63 std::make_shared<CardRequestAdapter>(cardSelectionApduRequests,
false));
65 return std::make_shared<CardSelectionRequestAdapter>(mSamCardSelector,
nullptr);
70 const std::shared_ptr<CardSelectionResponseApi> cardSelectionResponse)
72 if (mUnlockCommand !=
nullptr) {
74 if (cardSelectionResponse->getCardResponse() ==
nullptr ||
75 cardSelectionResponse->getCardResponse()->getApduResponses().empty()) {
76 throw InconsistentDataException(
"Mismatch in the number of requests/responses");
79 const std::shared_ptr<ApduResponseApi> apduResponse =
80 cardSelectionResponse->getCardResponse()->getApduResponses()[0];
84 mUnlockCommand->setApduResponse(apduResponse).checkStatus();
87 mLogger->warn(
"SAM not locked or already unlocked\n");
89 throw ParseException(
"An exception occurred while parse the SAM responses.",
90 std::make_shared<CalypsoSamCommandException>(e));
94 return std::make_shared<CalypsoSamAdapter>(cardSelectionResponse);
100 mProductType = productType;
106 const std::string& serialNumberRegex)
109 Pattern::compile(serialNumberRegex);
110 }
catch (
const PatternSyntaxException& exception) {
112 throw IllegalArgumentException(
"Invalid regular expression: '" +
117 mSerialNumberRegex = serialNumberRegex;
124 Assert::getInstance().isTrue(unlockData.size() == 16 || unlockData.size() == 32,
125 "unlock data length == 16 or 32")
126 .isHexString(unlockData,
"unlockData");
128 if (!ByteArrayUtil::isValidHexString(unlockData)) {
129 throw IllegalArgumentException(
"Invalid hexadecimal string.");
132 mUnlockCommand = std::make_shared<CmdSamUnlock>(mProductType, HexUtil::toByteArray(unlockData));
137const std::string CalypsoSamSelectionAdapter::buildAtrRegex(
139 const std::string& samSerialNumberRegex)
141 std::string atrRegex;
145 if (samSerialNumberRegex.empty()) {
150 snRegex = samSerialNumberRegex;
158 std::string applicationTypeMask;
159 if (productType != CalypsoSam::ProductType::UNKNOWN) {
160 switch (productType) {
161 case CalypsoSam::ProductType::SAM_C1:
162 case CalypsoSam::ProductType::HSM_C1:
163 applicationTypeMask =
"C1";
165 case CalypsoSam::ProductType::SAM_S1DX:
166 applicationTypeMask =
"D?";
168 case CalypsoSam::ProductType::SAM_S1E1:
169 applicationTypeMask =
"E1";
171 case CalypsoSam::ProductType::CSAM_F:
173 applicationTypeMask =
"??";
176 throw IllegalArgumentException(
"Unknown SAM subtype.");
179 atrRegex =
"3B(.{6}|.{10})805A..80" + applicationTypeMask +
".{6}" + 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