20#include "ByteArrayUtil.h"
34using namespace keyple::core::util;
35using namespace keyple::core::util::cpp;
37const std::map<const int, const std::shared_ptr<StatusProperties>>
38 CmdCardSearchRecordMultiple::STATUS_TABLE = initStatusTable();
42 const std::shared_ptr<SearchCommandDataAdapter> data)
46 const int searchDataLength =
static_cast<int>(data->getSearchData().size());
47 const uint8_t p2 = data->getSfi() * 8 + 7;
49 std::vector<uint8_t> dataIn(3 + (2 * searchDataLength));
50 if (data->isEnableRepeatedOffset()) {
54 if (data->isFetchFirstMatchingResult()) {
58 dataIn[1] =
static_cast<uint8_t
>(data->getOffset());
59 dataIn[2] =
static_cast<uint8_t
>(searchDataLength);
61 System::arraycopy(data->getSearchData(), 0, dataIn, 3, searchDataLength);
63 if (data->getMask().empty()) {
66 dataIn.size() - searchDataLength,
68 static_cast<uint8_t
>(0xFF));
70 System::arraycopy(data->getMask(),
73 dataIn.size() - searchDataLength,
74 data->getMask().size());
75 if (
static_cast<int>(data->getMask().size()) != searchDataLength) {
78 dataIn.size() - searchDataLength + data->getMask().size(),
80 static_cast<uint8_t
>(0xFF));
85 std::make_shared<ApduRequestAdapter>(
86 ApduUtil::build(calypsoCardClass.
getValue(),
88 data->getRecordNumber(),
93 std::stringstream extraInfo;
94 extraInfo <<
"SFI:" << data->getSfi() <<
"h, "
95 <<
"RECORD_NUMBER:" << data->getRecordNumber() <<
", "
96 <<
"OFFSET:" << data->getOffset() <<
", "
97 <<
"REPEATED_OFFSET:" << data->isEnableRepeatedOffset() <<
", "
98 <<
"FETCH_FIRST_RESULT:" << data->isFetchFirstMatchingResult() <<
", "
99 <<
"SEARCH_DATA:" << ByteArrayUtil::toHex(data->getSearchData()) <<
"h, "
100 <<
"MASK:" << ByteArrayUtil::toHex(data->getMask()) <<
"h";
110const std::map<const int, const std::shared_ptr<StatusProperties>>
111 CmdCardSearchRecordMultiple::initStatusTable()
113 std::map<const int, const std::shared_ptr<StatusProperties>> m =
117 std::make_shared<StatusProperties>(
"Data Out overflow (outgoing data would be too" \
121 std::make_shared<StatusProperties>(
"Lc value not supported (<4).",
122 typeid(CardIllegalParameterException))});
124 std::make_shared<StatusProperties>(
"Incorrect EF type: Binary EF.",
125 typeid(CardDataAccessException))});
127 std::make_shared<StatusProperties>(
"Security conditions not fulfilled (PIN code " \
128 "not presented, encryption required).",
129 typeid(CardSecurityContextException))});
131 std::make_shared<StatusProperties>(
"Access forbidden (Never access mode, Stored " \
132 "Value log file and a Stored Value operation was" \
133 "done during the current secure session).",
134 typeid(CardAccessForbiddenException))});
136 std::make_shared<StatusProperties>(
"Incorrect file type: the Current File is not " \
137 "an EF. Supersedes 6981h.",
138 typeid(CardDataAccessException))});
140 std::make_shared<StatusProperties>(
"Incorrect command data (S. Length incompatible " \
141 "with Lc, S. Length > RecSize, S. Offset + S. " \
142 "Length > RecSize, S. Mask bigger than S. Data).",
143 typeid(CardIllegalParameterException))});
145 std::make_shared<StatusProperties>(
"File not found.",
146 typeid(CardDataAccessException))});
148 std::make_shared<StatusProperties>(
"Record not found (record index is 0, or above " \
150 typeid(CardDataAccessException))});
152 std::make_shared<StatusProperties>(
"P1 or P2 value not supported.",
153 typeid(CardIllegalParameterException))});
158const std::map<const int, const std::shared_ptr<StatusProperties>>&
165 const std::shared_ptr<ApduResponseApi> apduResponse)
169 if (apduResponse->getDataOut().size() > 0) {
170 const std::vector<uint8_t> dataOut = apduResponse->getDataOut();
172 const int nbRecords = dataOut[0];
173 for (
int i = 1; i <= nbRecords; i++) {
174 mData->getMatchingRecordNumbers().push_back(dataOut[i]);
177 if (mData->isFetchFirstMatchingResult() && nbRecords > 0) {
178 mFirstMatchingRecordContent =
179 Arrays::copyOfRange(dataOut, nbRecords + 1, dataOut.size());
194 return !mFirstMatchingRecordContent.empty() ?
195 mFirstMatchingRecordContent : std::vector<uint8_t>();
static const std::map< const int, const std::shared_ptr< StatusProperties > > STATUS_TABLE
virtual void addSubName(const std::string &subName) final
virtual void setApduRequest(const std::shared_ptr< ApduRequestAdapter > apduRequest) final
const CalypsoCardCommand & getCommandRef() const override
AbstractCardCommand & setApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
const std::vector< uint8_t > getFirstMatchingRecordContent() const
CmdCardSearchRecordMultiple(const CalypsoCardClass calypsoCardClass, const std::shared_ptr< SearchCommandDataAdapter > data)
const std::shared_ptr< SearchCommandDataAdapter > getSearchCommandData() const
CmdCardSearchRecordMultiple & setApduResponse(const std::shared_ptr< ApduResponseApi > apduResponse) override
bool isSessionBufferUsed() const override
const std::map< const int, const std::shared_ptr< StatusProperties > > & getStatusTable() const override