2

Well these days Im trying to design a software which use smart card readers, I am using ACR1252u and I have discovered how to buzz my smart card reader if a tag or card is on the reader. but still wondering how can I do this without the card on the reader. the code which works for when the card is on the reader is below:

retCode = Card.SCardConnect(hContext, readername, Card.SCARD_SHARE_SHARED, Card.SCARD_PROTOCOL_T0 | Card.SCARD_PROTOCOL_T1, ref hCard, ref Protocol); Byte[] setBuzzerLoud = new Byte[6]; setBuzzerLoud[0] = 0xE0; setBuzzerLoud[1] = 0x00; setBuzzerLoud[2] = 0x00; setBuzzerLoud[3] = 0x21; setBuzzerLoud[4] = 0x01; setBuzzerLoud[5] = 0x77; uint pcBytesReturned = 0; Byte[] RecieveBuff = new Byte[64]; uint controlcode = 3225264; int status = Card.SCardControl(hCard, controlcode, ref setBuzzerLoud[0], 6, ref RecieveBuff[0], RecieveBuff.Length, ref pcBytesReturned); MessageBox.Show(status.ToString()); 

The problem is when hcard is on the reader the status which is the error shows 6. which means wrong handle!. But why buzzing a reader is connected to if the card is over the reader? is there anyway to turn this over? cause after this I want to turn on LEDs while the card is not over the reader- Guys plz if anyone have solved this problem tell us.

6
  • This really is wrong forum, i imagine that there are better places to ask these questions, perhaps call ACS, the maker of the reader and designer of the API? Commented Jul 19, 2016 at 21:09
  • But I think they do this with PS SC communications which is written in windows.h, the point is which function can set the reader without using hcard handle! Commented Jul 19, 2016 at 21:24
  • Ok, i did this, googled your readers name, got the ACS site from the result, found a pdf describing the API, read some.. ..and found this lube: "The reader's peripheral control commands are implemented by using SCardControl with Control Code SCARD_CTL_CODE(3500)". And by the look of it, you are using the PCSC API. Commented Jul 20, 2016 at 5:49
  • I knew that , I also found uint controlcode = 3225264; by debugging SCARD_CTL_CODE(3500) in c++. the problem is with windows.h functions which are scardcontrol and scardTransmit. and they give errors when the card is not on the card reader. and I want to control the reader without presence of the card!. my objective is to turn off the Rf ,Leds and buzzer when the card is on it; and then if i trigger a button in my software while the card is not present on the reader all of these turn on. Commented Jul 20, 2016 at 7:29
  • The cause is that SCARD_CTL_CODE is a macro that is resolved at compile, there is no guarantee that you get that particular uint. So you do right by calling the macro as in you answer. Commented Jul 20, 2016 at 8:59

2 Answers 2

2

I have found the solution in a c++ code: only in the linker we need to add 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; } 
2
  • Aren't you tired yet to write std:: every 2nd line, sometimes even multiple times on a line? Commented Sep 20, 2016 at 21:30
  • 2
    The point is to include std sometimes make big problem when you include many classes. there will be overlapping! Commented Sep 21, 2016 at 9:56
0

The problem with your code is that you call Card.SCardConnect() with Card.SCARD_PROTOCOL_T0 | Card.SCARD_PROTOCOL_T1. This is not allowed when there is no card in the reader. Replace that part with 0, then the call will succeed.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.