因此,我的任务是编写代码来处理智能卡。环境为C#.Net,Xamarin。智能卡读取器(联系人,而不是NFC)连接到霍尼韦尔手持设备上。所以,有了稀疏的部分,我不能仅仅因为各种原因而使用第三方库,我要承担这个任务。
Using Android.Hardware.Usb, I can get to the following.
UsbManager - created to context of application.
Scan connected USB devices to the handheld
Properly detecting the specific device.
Getting the configuration object.
Then to the interface
and finally finding the 3 endpoints.. Isochronous, Inbound and Outbound.
Request permission to use the specific device.
and finally Open the device for a UsbConnection handle.因此,既然通信的大门是敞开的,我显然需要向外发送一个请求,并从相应的出站和端点中得到一个答复。
我可以构建APDU命令的BulkTransfer,并得到一个响应,其中有2个字节可供接收。然后,我尝试在入站端口上执行另一个带有APDU响应的BulkTransfer,但是它总是在-1中失败。
我见过其他关于设置通信协议、波特率等问题的帖子,但不确定这是否是问题所在。我对这种粒度级的串行/usb通信完全陌生。不确定接下来的步骤,以获得设备的前后通信。
以下是我为连接到设备所做的工作的简略总结。至于具体的设备,它是一个霍尼韦尔CN80手持扫描仪设备,附带一个CAC阅读器(也是霍尼韦尔)。至于我想要做的事情,只想打电话给验证卡(或不存在)。我并不是真正地向设备发送数据,只是一个命令来询问设备并得到一个正确的答案。
public void attemptingSmartCommunications()
{
_myUsbManager = (UsbManager)_myMainActivity.GetSystemService(Context.UsbService);
foreach (var d in _myUsbManager.DeviceList)
{ // method checks the device for proper VID/PID
var dev = d.Value;
if (isExpectedDevice(dev))
{
for (var dc = 0; dc < dev.ConfigurationCount; dc++)
{
// SHOULD only be 1 configuration from what I have encountered.
_myUsbConfiguration = dev.GetConfiguration(dc);
for (var di = 0; di < _myUsbConfiguration.InterfaceCount; di++)
{
_myUsbInterface = _myUsbConfiguration.GetInterface(di);
// Add on context of each endpoint
for (var ep = 0; ep < _myUsbInterface.EndpointCount; ep++)
{
var intEndpoint = _myUsbInterface.GetEndpoint(ep);
// which one do we need, store into their own respecive properties
// for in/out/isochronous
switch (intEndpoint.Address.ToString())
{
case "XferIsochronous":
// Control pipe for communication
_myIsochronousEndpoint = intEndpoint;
break;
case "130":
// Read IN FROM the USB Device with response
_myInEndpoint = intEndpoint;
break;
case "131":
// Write OUT TO the USB Device with command/request
_myOutEndpoint = intEndpoint;
break;
}
}
// now, I have the endpoints to request send and read back, make sure permission
if( _myUsbManager.HasPermission(_myUsbDevice))
{
myConnection = _myUsbManager.OpenDevice(_myUsbDevice);
var apdu = MyStaticSmartCardAPDUCommand;
// prepares the 4-byte request of CLA, INS, P1, P2 (no data in request)
var byteBuffer = apdu.CommandAsBytes();
var bufferLen = byteBuffer.Length;
var resultBytes = _myUsbDeviceConnection.BulkTransfer(_myOutEndpoint, byteBuffer, bufferLen, 2000);
// I get indication of 2 byte response
if( resultBytes > 0 )
{
// default buffer prepared with 4 bytes. SW1, SW2 + 2 expected bytes
var apduResp = new APDUResponse(resultBytes);
byteBuffer = apduResp.GetResponseBuffer();
var responseStatus = _myUsbDeviceConnection.BulkTransfer(_myInEndpoint, byteBuffer, byteBuffer.Length, 3000);
// HERE is where it always fails.
// Am I on the right track? Completely out of it?
}
}
}
}
}
}
}发布于 2022-10-04 09:09:36
(想写一篇评论,但写得很长.)
从技术上讲,有两种可能性,不使用制造商的驱动程序:
要区分这两者,请参考读取器规范和/或检查它的USB描述符。您可能还想看看这里和这里。
一些额外的(随机)注释:
免责声明:我不是Xamarin专家,所以请验证我的想法。
祝你的项目好运!
EDIT2>有一个PoC javascript CCID实现,您可能会发现它更容易理解。
https://stackoverflow.com/questions/73922375
复制相似问题