F.moghaddampoor Ответов: 1

Как управлять считывателями смарт-карт без карты на них?


Ну, в эти дни я пытаюсь разработать программное обеспечение, которое использует считыватели смарт-карт, я использую ACR1252u и обнаружил, как жужжать мой считыватель смарт-карт, если на считывателе есть метка или карта. но все же интересно, как я могу это сделать без карты на считывателе. код, который работает, когда карта находится на считывателе, находится ниже:

retCode = Card.SCardConnect(hContext, readername, Card.SCARD_SHARE_SHARED, Card.SCARD_PROTOCOL_T0 | Card.SCARD_PROTOCOL_T1, ref hCard, ref Protocol);

           Byte[] setBuzzerOff = new Byte[6];
           setBuzzerOff[0] = 0xE0;
           setBuzzerOff[1] = 0x00;
           setBuzzerOff[2] = 0x00;
           setBuzzerOff[3] = 0x28;
           setBuzzerOff[4] = 0x01;
           setBuzzerOff[5] = 0x00;
           UInt32 controlcode = 3500;
           int pcBytesReturned = 0;
           Byte[] RecieveBuff = new Byte[1];
           int status=Card.SCardControl(hCard, controlcode,ref setBuzzerOff[0],6,ref RecieveBuff[0], RecieveBuff.Length,ref pcBytesReturned);
           MessageBox.Show(status.ToString());

Проблема-это когда, смотря по ситуации на читателя статусом, который ошибки показывает 6. что значит неверный дескриптор!. Но почему жужжание считывателя связано с тем, что карта находится над считывателем? есть ли в любом случае, чтобы перевернуть это? потому что после этого я хочу включить светодиоды, пока карта не находится над считывателем - ребята, плз, если кто-то решил эту проблему, скажите нам.

Что я уже пробовал:

Я прошел через http://the--semicolon.blogspot.it/p/this-is-simple-way-to-restart-your.html

а также здесь было сказано, что можно использовать SCardControl для доступа к считывателю без доступной карты.

http://pvbookmarks.readthedocs.io/en/latest/devel/drivers/usb/classes/ccid/pc_sc/pcsc_tools/proprietary/commands.html

1 Ответов

Рейтинг:
7

F.moghaddampoor

Я нашел решение в коде c++ :
только в линкер нам нужно добавить winscard.h

#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <cstdint>
#include <cstring>
#include <winscard.h>

std::wstring s2ws(const std::string& s);

int main(int argc, char* argv[]) {
	SCARDCONTEXT context = 0;
	LONG ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, nullptr, nullptr, &context);

	if (ret != SCARD_S_SUCCESS) {
		std::cout << "SCardEstablishContext: " << ret<< std::endl;
	}
	else {
		LPTSTR allReaderNames = nullptr;
		DWORD readerCount = SCARD_AUTOALLOCATE;

		ret = SCardListReaders(context, nullptr, reinterpret_cast<LPTSTR>(&allReaderNames), &readerCount);

		if (ret != SCARD_S_SUCCESS) {
			std::cout << "SCardListReaders: " << ret << std::endl;
		}
		else {
			std::string readerName("ACS ACR1252 1S CL Reader PICC 0");
			std::wstring stemp = s2ws(readerName);
			LPCWSTR result = stemp.c_str();
			DWORD activeProtocol = 0;
			SCARDHANDLE card = 0;

			ret = SCardConnect(context, result, SCARD_SHARE_DIRECT, 0, &card, &activeProtocol);

			if (ret != SCARD_S_SUCCESS) {
				std::cout << "SCardConnect: " << ret << std::endl;
			}
			else {
				std::vector<std::uint8_t> outputBuffer{ 0xE0, 0x0, 0x0, 0x21, 0x01, 0x71 };
				std::vector<std::uint8_t> inputBuffer(64, 0);
				DWORD bytesReturned = 0;

				DWORD controlcode = SCARD_CTL_CODE(3500);
				ret = SCardControl(card, controlcode, outputBuffer.data(), outputBuffer.size(), inputBuffer.data(), inputBuffer.size(), &bytesReturned);

				if (ret != SCARD_S_SUCCESS) {
					std::cout << "SCardControl: " << ret << std::endl;
				}
				else {
					std::cout << "Response: " << std::hex << std::setfill('0');
					for (std::size_t i = 0; i < bytesReturned; ++i) {
						std::cout << std::setw(2) << static_cast<std::uint32_t>(inputBuffer[i]) << " ";
					}
					std::cout << std::dec << std::endl;

					SCardDisconnect(card, SCARD_LEAVE_CARD);
				}
			}

			// Release the memory that SCardListReaders allocated for us
			SCardFreeMemory(context, allReaderNames);
		}

		ret = SCardReleaseContext(context);

		if (ret != SCARD_S_SUCCESS) {
			std::cout << "SCardReleaseContext: " << ret << std::endl;
		}
		std::getchar();
	}

	return 0;
}


std::wstring s2ws(const std::string& s)
{
	int len;
	int slength = (int)s.length() + 1;
	len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
	wchar_t* buf = new wchar_t[len];
	MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
	std::wstring r(buf);
	delete[] buf;
	return r;
}


и код c# будет таким

retCode = Card.SCardEstablishContext(Card.SCARD_SCOPE_SYSTEM, 0, 0, ref hContext);
            if (retCode != Card.SCARD_S_SUCCESS)
            {
                MessageBox.Show("Check your device and please restart again", "Reader not connected", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                connActive = false;
                return;
            }
            retCode = Card.SCardConnect(hContext, readername, 3, 0, ref hCard, ref Protocol);
            if (retCode != Card.SCARD_S_SUCCESS)
            {
                MessageBox.Show("Error: " + retCode.ToString());
            }
            Byte[] setRFOff = new Byte[6];
            setRFOff[0] = 0xE0;
            setRFOff[1] = 0x00;
            setRFOff[2] = 0x00;
            setRFOff[3] = 0x21;
            setRFOff[4] = 0x01;
            setRFOff[5] = 0x71;
            uint pcBytesReturned = 0;
            Byte[] RecieveBuff = new Byte[64];
            uint controlcode = 3225264;
            uint pCard = hCard;
            int status = Card.SCardControl(hCard, controlcode, ref setRFOff[0], 6, ref RecieveBuff[0], RecieveBuff.Length, ref pcBytesReturned);
            if (status != Card.SCARD_S_SUCCESS)
            {
                MessageBox.Show("Error: " + status.ToString());
            }
            status = Card.SCardDisconnect(pCard, Card.SCARD_RESET_CARD);
            if (status != Card.SCARD_S_SUCCESS)
            {
                MessageBox.Show("Error: " + status.ToString());
            }
            rtbStatus.Text = "success";