16#include "ParseException.h"
19#include "ByteArrayUtil.h"
21#include "KeypleAssert.h"
23#include "PatternSyntaxException.h"
24#include "RuntimeException.h"
38using namespace calypsonet::terminal::card::spi;
39using namespace keyple::core::util;
40using namespace keyple::core::util::cpp;
41using namespace keyple::core::util::cpp::exception;
43const int CalypsoSamSelectionAdapter::SW_NOT_LOCKED = 0x6985;
50 mSamCardSelector->filterByPowerOnData(buildAtrRegex(mProductType, mSerialNumberRegex));
53 if (mUnlockCommand !=
nullptr) {
54 std::vector<std::shared_ptr<ApduRequestSpi>> cardSelectionApduRequests;
55 std::shared_ptr<ApduRequestAdapter> request = mUnlockCommand->getApduRequest();
56 request->addSuccessfulStatusWord(SW_NOT_LOCKED);
57 cardSelectionApduRequests.push_back(request);
58 return std::make_shared<CardSelectionRequestAdapter>(
60 std::make_shared<CardRequestAdapter>(cardSelectionApduRequests,
false));
62 return std::make_shared<CardSelectionRequestAdapter>(mSamCardSelector,
nullptr);
67 const std::shared_ptr<CardSelectionResponseApi> cardSelectionResponse)
69 if (mUnlockCommand !=
nullptr) {
72 if (cardSelectionResponse->getCardResponse() ==
nullptr ||
73 cardSelectionResponse->getCardResponse()->getApduResponses().empty()) {
74 throw ParseException(
"Mismatch in the number of requests/responses");
78 const std::shared_ptr<ApduResponseApi> apduResponse =
79 cardSelectionResponse->getCardResponse()->getApduResponses()[0];
83 mUnlockCommand->parseApduResponse(apduResponse);
86 mLogger->warn(
"SAM not locked or already unlocked\n");
88 throw ParseException(
"An exception occurred while parsing the SAM response.",
89 std::make_shared<CalypsoSamCommandException>(e));
95 return std::make_shared<CalypsoSamAdapter>(cardSelectionResponse);
97 }
catch (
const RuntimeException& e) {
99 throw ParseException(
"An exception occurred while parsing the SAM response.",
100 std::make_shared<RuntimeException>(e));
107 mProductType = productType;
113 const std::string& serialNumberRegex)
116 Pattern::compile(serialNumberRegex);
117 }
catch (
const PatternSyntaxException& exception) {
119 throw IllegalArgumentException(
"Invalid regular expression: '" +
124 mSerialNumberRegex = serialNumberRegex;
131 Assert::getInstance().isTrue(unlockData.size() == 16 || unlockData.size() == 32,
132 "unlock data length == 16 or 32")
133 .isHexString(unlockData,
"unlockData");
135 if (!ByteArrayUtil::isValidHexString(unlockData)) {
136 throw IllegalArgumentException(
"Invalid hexadecimal string.");
139 mUnlockCommand = std::make_shared<CmdSamUnlock>(mProductType, HexUtil::toByteArray(unlockData));
144const std::string CalypsoSamSelectionAdapter::buildAtrRegex(
146 const std::string& samSerialNumberRegex)
148 std::string atrRegex;
152 if (samSerialNumberRegex.empty()) {
157 snRegex = samSerialNumberRegex;
165 std::string applicationTypeMask;
166 if (productType != CalypsoSam::ProductType::UNKNOWN) {
167 switch (productType) {
168 case CalypsoSam::ProductType::SAM_C1:
169 case CalypsoSam::ProductType::HSM_C1:
170 applicationTypeMask =
"C1";
172 case CalypsoSam::ProductType::SAM_S1DX:
173 applicationTypeMask =
"D?";
175 case CalypsoSam::ProductType::SAM_S1E1:
176 applicationTypeMask =
"E1";
178 case CalypsoSam::ProductType::CSAM_F:
180 applicationTypeMask =
"??";
183 throw IllegalArgumentException(
"Unknown SAM subtype.");
186 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