size_t MifareSTidSTRCommands::updateBinary(unsigned char blockno, const void* buf, size_t buflen)
	{
		INFO_("Update binary block {0x%x(%u)} [in] buffer len {%d}", blockno, blockno, buflen);

		if ((buflen >= 256) || (!buf))
		{
			THROW_EXCEPTION_WITH_LOG(std::invalid_argument, "Bad buffer parameter.");
		}

		if (d_useSKB)
		{
			INFO_SIMPLE_("Need to use reader memory key storage (SKB) !");
			return updateBinaryIndex(d_skbIndex, blockno, buf, buflen);
		}

		INFO_SIMPLE_(" => Rescanning card to avoid bad authentication");
		scanMifare();
		INFO_SIMPLE_("Scan done ! Continue to update binary block.");

		if (blockno != 0)
		{
			std::vector<unsigned char> command;
			command.push_back(static_cast<unsigned char>(d_lastKeyType));
			command.push_back(blockno);
			command.insert(command.end(), (unsigned char*)buf, (unsigned char*)buf + buflen);

			getSTidSTRReaderCardAdapter()->sendCommand(0x00D2, command);
		}

		INFO_("Returns final [out] buffer len {%d}", buflen);
		return buflen;
	}	
	size_t MifareSTidSTRCommands::readBinary(unsigned char blockno, size_t len, void* buf, size_t buflen)
	{
		INFO_("Read binary block {0x%x(%u)} len {%d} [out] buffer len {%d}", blockno, blockno, len, buflen);
		
		if ((len >= 256) || (len > buflen) || (!buf))
		{
			THROW_EXCEPTION_WITH_LOG(std::invalid_argument, "Bad buffer parameter.");
		}

		if (d_useSKB)
		{
			INFO_SIMPLE_("Need to use reader memory key storage (SKB) !");
			return readBinaryIndex(d_skbIndex, blockno, len, buf, buflen);
		}

		INFO_SIMPLE_(" => Rescanning card to avoid bad authentication");
		scanMifare();
		INFO_SIMPLE_("Scan done ! Continue to read binary block.");

		std::vector<unsigned char> command;
		command.push_back(static_cast<unsigned char>(d_lastKeyType));
		command.push_back(blockno);

		std::vector<unsigned char> sbuf = getSTidSTRReaderCardAdapter()->sendCommand(0x00B2, command);

		INFO_("Read binary buffer returned %s len {%d}", BufferHelper::getHex(sbuf).c_str(), sbuf.size());
		EXCEPTION_ASSERT_WITH_LOG(sbuf.size() == 16, LibLogicalAccessException, "The read value should always be 16 bytes long");
		EXCEPTION_ASSERT_WITH_LOG(sbuf.size() <= buflen, LibLogicalAccessException, "Buffer is too small to get all response value");

		memcpy(buf, &sbuf[0], sbuf.size());

		return sbuf.size();
	}
    void STidSTRLEDBuzzerDisplay::setPort()
    {
        LOG(LogLevel::INFOS) << "Sending LED/Buzzer command for: red{" << d_red_led << "} green{" << d_green_led << "} buzzer{" << d_buzzer << "}...";
        std::vector<unsigned char> data;
        data.push_back(static_cast<unsigned char>((d_red_led ? 2 : 0) | (d_green_led ? 1 : 0)));
        data.push_back(0xFF); // LED duration
        data.push_back((d_buzzer) ? 0xFF : 0x00); // Buzzer duration

        getSTidSTRReaderCardAdapter()->sendCommand(0x0007, data);
    }
	void STidSTRLEDBuzzerDisplay::setPort()
	{
		INFO_("Sending LED/Buzzer command for: red{%d} green{%d} buzzer{%d}...", d_red_led, d_green_led, d_buzzer);
		std::vector<unsigned char> data;
		data.push_back(static_cast<unsigned char>((d_red_led ? 2 : 0) | (d_green_led ? 1 : 0)));
		data.push_back(0xFF); // LED duration
		data.push_back((d_buzzer) ? 0xFF : 0x00); // Buzzer duration

		getSTidSTRReaderCardAdapter()->sendCommand(0x0007, data);
	}
	bool MifareSTidSTRCommands::loadKey(unsigned char keyno, MifareKeyType keytype, const void* key, size_t keylen, bool vol)
	{
		INFO_("Loading key... key number {0x%x(%u)} key type {0x%x(%d)} key len {%d} volatile ? {%d}", keyno, keyno, keytype, keytype, keylen, vol);
		std::vector<unsigned char> command;
		command.push_back(static_cast<unsigned char>(keytype));
		command.push_back(vol ? 0x00 : 0x01);
		command.push_back(keyno);
		command.insert(command.end(), (unsigned char*)key, (unsigned char*)key + keylen);
		command.push_back(0x00);	// Diversify ?

		getSTidSTRReaderCardAdapter()->sendCommand(0x00D0, command);

		return true;
	}
	std::vector<unsigned char> MifareSTidSTRCommands::scanMifare()
	{
		INFO_SIMPLE_("Scanning mifare card...");
		std::vector<unsigned char> uid;
		std::vector<unsigned char> r = getSTidSTRReaderCardAdapter()->sendCommand(0x00A0, std::vector<unsigned char>());

		bool hasCard = (r[0] == 0x01);
		if (hasCard)
		{
			INFO_SIMPLE_("Card detected !");
			unsigned char uidLength = r[1];
			uid = std::vector<unsigned char>(r.begin() + 2, r.begin() + 2 + uidLength);

			INFO_("Card uid %s-{%s}", BufferHelper::getHex(uid).c_str(), BufferHelper::getStdString(uid).c_str());
		}
		else
		{
			INFO_SIMPLE_("No card detected !");
		}

		return uid;
	}
	size_t MifareSTidSTRCommands::updateBinaryIndex(unsigned char keyindex, unsigned char blockno, const void* buf, size_t buflen)
	{
		INFO_("Update binary index key index {0x%x(%u)} block {0x%x(%u)} [in] buffer len {%d}", keyindex, keyindex, blockno, blockno, buflen);

		INFO_SIMPLE_(" => Rescanning card to avoid bad authentication");
		scanMifare();
		INFO_SIMPLE_("Scan done ! Continue to update binary index.");

		if (blockno != 0)
		{
			std::vector<unsigned char> command;
			command.push_back(static_cast<unsigned char>(d_lastKeyType));
			command.push_back(keyindex);
			command.push_back(blockno);
			command.insert(command.end(), (unsigned char*)buf, (unsigned char*)buf + buflen);

			getSTidSTRReaderCardAdapter()->sendCommand(0x00D3, command);
		}

		INFO_("Returns final [out] buffer len {%d}", buflen);
		return buflen;
	}
	size_t MifareSTidSTRCommands::readBinaryIndex(unsigned char keyindex, unsigned char blockno, size_t /*len*/, void* buf, size_t buflen)
	{
		INFO_("Read binary index key index {0x%x(%u)} block {0x%x(%u)} [out] buffer len {%d}",
				keyindex, keyindex, blockno, blockno, buflen);

		INFO_SIMPLE_(" => Rescanning card to avoid bad authentication");
		scanMifare();
		INFO_SIMPLE_("Scan done ! Continue to read binary index.");

		std::vector<unsigned char> command;
		command.push_back(static_cast<unsigned char>(d_lastKeyType));
		command.push_back(keyindex);
		command.push_back(blockno);

		std::vector<unsigned char> sbuf = getSTidSTRReaderCardAdapter()->sendCommand(0x00B1, command);

		EXCEPTION_ASSERT_WITH_LOG(sbuf.size() == 16, LibLogicalAccessException, "The read value should always be 16 bytes long");
		EXCEPTION_ASSERT_WITH_LOG(buflen >= sbuf.size(), LibLogicalAccessException, "The buffer is too short to store the result.");

		memcpy(buf, &sbuf[0], sbuf.size());

		return sbuf.size();
	}
	void MifareSTidSTRCommands::releaseRFIDField()
	{
		INFO_SIMPLE_("Releasing RFID field...");
		getSTidSTRReaderCardAdapter()->sendCommand(0x00A1, std::vector<unsigned char>());
	}