Linux下通过CCID协议与USB设备进行交互经验总结

  • 1.目标
  • 2. 实现方法
    • 2.1 安装libudev
      • 2.1.1 编译安装
      • 2.1.2 安装提示错误
    • 2.2 编译安装libusb
      • 2.2.1 下载libusb
      • 2.2.2 编译安装过程
      • 2.2.3 安装时提示的错误
    • 2.3 编译安装pcsc-lite
      • 2.3.1 下载pcsc-lite
      • 2.3.2 编译安装过程
    • 2.4 编译安装ccid
      • 2.4.1 下载ccid
      • 2.4.2 编译安装过程
    • 2.5 配置环境变量
    • 2.6 ccid通讯协议测试
      • 2.6.1 启动pcsc服务
      • 2.6.2 测试结果
    • 2.7 其他软件包的安装
      • 2.7.1 编译安装boost
        • 2.7.1.1 下载boost
        • 2.7.1.2 编译安装过程
        • 2.7.1.3 安装时提示错误
  • 3. 通讯接口封装
  • 4. 接口使用中遇到的问题
  • 5. 参考链接

1.目标

  在linux系统下通过ccid协议与USB设备实现通讯。

2. 实现方法

  通过参考其他人的博客,决定采用如下方式来实现ccid通讯。

2.1 安装libudev

  udev 是Linux2.6内核里的一个功能,它替代了原来的devfs,成为当前Linux 默认的设备管理工具。udev以守护进程的形式运行,通过侦听内核发出来的uevent来管理/dev目录下的设备文件。不像之前的设备管理工具,udev在用户空间(userspace) 运行,而不在内核空间(kernel space) 运行。

2.1.1 编译安装

  如果是Centos可以通过执行:sudo yum install systemd-devel 或者sudo yum install libudev-devel;如果是Ubuntu可以通过:sudo apt-get install systemd-devel 或者 sudo apt-get install libudev-devel;如果已经有libudev-devel.rpm包,可以执行sudo rpm -ivh libudev-devel.rpm。

2.1.2 安装提示错误

  在Ubuntu14.04下,直接执行sudo apt-get install systemd-devel 或者 sudo apt-get install libudev-devel,有的时候并不能安装成功,会出现下面的提示:

  一般apt-get出现上面的情况,就是没有更新APT库,安装如下方式进行更新即可(需要等待一段时间~):

sudo apt-get update
sudo apt-get upgrade

  执行结束后,我们再执行sudo apt-get install libudev-devel即可成功。

2.2 编译安装libusb

  对于连接到电脑的USB设备,一般都会需要安装对应的USB driver来支持。有一款开源的跨平台的USB driver,就是libusb,可以用来进行自定义的USB设备的驱动开发。
  libusb是一个C语言编写的库,可以供上层的应用来调用,和连接在笔记本上的USB设备进行通信。易于移植,而且有对应的libusb-API的文档,可以用于Linux, OS X, Windows, Android, OpenBSD等系统。而且支持USB 1.0到3.1的规范。一般在Linux系统上会自带了libusb的。其他的平台一般需要安装libusb。

2.2.1 下载libusb

  在https://github.com/libusb/libusb/releases/ 地址中选择一个版本进行下载,本文使用的是libusb-1.0.18。

2.2.2 编译安装过程

(1)解压libusb-1.0.18.tar.gz安装包,执行tar -xvf libusb-1.0.18.tar.gz。
(2)进入到libusb-1.0.18文件下,执行三步:(a)./configure; (b) make; (c)sudo make install;

2.2.3 安装时提示的错误

(1)错误提示
  checking for inline… inline
  checking operating system… Linux
  checking for library containing clock_gettime… -lrt
  checking libudev.h usability… no
  checking libudev.h presence… no
  checking for libudev.h… no
  configure: error: “udev support requested but libudev not installed”
(2)解决办法
  安装libudev-devel即可解决,安装方法已2.1节介绍。

2.3 编译安装pcsc-lite

  pcsc-lite 封装了访问使用 SCard API (PC/SC) 访问智能卡设备的开发包。

2.3.1 下载pcsc-lite

在https://alioth-archive.debian.org/releases/pcsclite/pcsclite/地址中选择一个版本进行下载,本文选择的是pcsc-lite-1.8.11版本。

2.3.2 编译安装过程

(1)解压pcsc-lite-1.8.11.tar.bz2安装包,执行tar -xvf pcsc-lite-1.8.11.tar.bz2。
(2)进入pcsc-lite-1.8.11文件夹下,执行三步:(a)./configure;(b)make;(c)sudo make install

2.4 编译安装ccid

  该库为符合CCID协议的USB智能卡驱动程序提供了PC / SC IFD处理程序实现。需要此软件包才能通过PC / SC Lite资源管理器(pcscd)与CCID智能卡读取器进行通信。

2.4.1 下载ccid

  在https://alioth-archive.debian.org/releases/pcsclite/ccid/ 地址中选择一个版本进行下载,本文使用的是ccid-1.4.16版本。

2.4.2 编译安装过程

(1)解压ccid-1.4.16.tar.bz2安装包,执行tar -xvf ccid-1.4.16.tar.bz2。
(2)进入ccid-1.4.16文件下,找到readers/supported_readers.txt文件,进行如下修改:(a)增加:设备名称(自定义);(b)增加:VID:PID:设备描述符;
(3)执行编译及安装,(a)./configure;(b)make;(c)sudo make install;

2.5 配置环境变量

  将编译生成的共享库的路径添加到环境变量中。执行如下操作:
(1)通过vim /etc/profile的指令,打开profile文件。
(2)增加:export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH,保存退出。
(3)执行 source /etc/profile。

2.6 ccid通讯协议测试

2.6.1 启动pcsc服务

  在命令行中执行pcscd,注意如果不是root账户执行sudo pcscd。

2.6.2 测试结果

  在pcsc-lite-1.8.11/src/ 的路径下找到testpcsc可执行文件,插入设备后,执行./testpcsc,结果如下则证明CCID协议通讯成功。

2.7 其他软件包的安装

  因为项目需要安装一些其他的开源库,因此在这里记录一下。

2.7.1 编译安装boost

  Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称。

2.7.1.1 下载boost

在https://sourceforge.net/projects/boost/files/boost/ 地址中选择一个版本下载,本文中使用的是boost_1_43_0。

2.7.1.2 编译安装过程

(1)解压boost_1_43_0.tar.gz安装包,执行tar -xvf boost_1_43_0.tar.gz。
(2)进入boost_1_43_0文件中,执行如下步骤:(a)./bootstrap.sh;(b)./bjam(需要等待很长一段时间~);

2.7.1.3 安装时提示错误


  由第一行可知有78个目标失败,经过分析有一下几个问题需要修改:
(1)./boost/python/detail/wrap_python.hpp:50:23: fatal error: pyconfig.h: No such file or directory,即pyconfig.h文件无法找到。导致该问题产生的原因是,默认情况下在/usr/include/python2.7路径下查找pyconfig.h,但实际情况为该路径并不存在(原因可能是python2升级成python3所致),只有一个python3.5m文件夹存在,且其中不包含pyconfig.h的文件,此时我们需要在终端执行:

sudo apt-get install python3.5-dev

  执行完上述命令之后,发现python3.5m文件夹下已经存在pyconfig.h文件。接下来按照参考链接中第8篇博客 ,修改/boost_1_43_0/tools/build/v2/tools/python.jam的551行。

原来为:includes ?= $(prefix)/include/python$(version)
修改为:includes ?= $(prefix)/include/python$(version)m

  重新编译boost代码:(a)./bootstrap.sh --with-python=python3(其中python代表的就是python3.5);(b)./bjam。执行结果如下:

  由上图可见,失败的数量缩减了78-26=52个。
(2)./boost/config/requires_threads.hpp:29:4: error: #error “Threading support unavaliable: it has been explicitly disabled with BOOST_DISABLE_THREADS”
#error “Threading support unavaliable: it has been explicitly disabled with BOOST_DISABLE_THREADS”。该问题参考第9篇博客,对/boost_1_43_0/boost/config/stdlib/libstdcpp3.hpp文件进行如下修改:

原本为:
#ifdef __GLIBCXX__ // gcc 3.4 and greater:
#  if defined(_GLIBCXX_HAVE_GTHR_DEFAULT) \|| defined(_GLIBCXX__PTHREADS)修改为:
#  if defined(_GLIBCXX_HAVE_GTHR_DEFAULT) \|| defined(_GLIBCXX__PTHREADS) \|| defined(_GLIBCXX_HAS_GTHREADS)

  按照上面内容修改完之后,再执行./bjam的结果如下:

(3)./boost/thread/xtime.hpp:23:5: error: expected identifier before numeric constant TIME_UTC=1,该问题产生的原因是这个宏定义重复定义了,这里手动将TIME_UTC改成TIME_UTC_。在将/boost_1_43_0/libs/thread/src/pthread/timeconv.inl文件中所有使用TIME_UTC的地方替换成TIME_UTC_。(之前开发时使用的是Centos7到这一步时,应该就没有失败目标了,但是后来为了验证并记录流程选择了Ubuntu16.04,执行到这步时还有20个失败目标,这块内容等我找到解决办法再更新~~~)

3. 通讯接口封装

  本块内容主要记录,在PCSC-LITE的基础上进行CCID通讯接口的封装。主要的功能接口如下:
(1)建立上下文,调用SCardEstablishContext实现。
(2)连接设备,调用SCardConnect实现。
(3)关闭设备,调用SCardDisconnect实现。
(4)复位设备,调用SCardReconnect和SCardStatus实现。
(5)设备通讯,调用SCardTransmit实现。
(6)枚举设备,调用SCardListReaderGroups和SCardListReaders实现。
(7)释放上下文,调用SCardReleaseContext实现。
(8)开始通讯,调用SCardBeginTransaction实现。
(9)结束通讯,调用SCardEndTransaction实现。

4. 接口使用中遇到的问题

  首先根据接口返回的错误码,我们可以通过官方的错误列表 初步定位问题的原因,但是有些时候即使知道了错误描述,也无法定位产生的原因。比如我在使用过程中碰见一个问题:当给设备发送某条指令时,SCardTransmit接口总是返回SCARD_E_NOT_TRANSACTED,错误描述为An attempt was made to end a non-existent transaction(试图终止一个不存在的事务),这么官方的描述请恕我无法理解,我的事务为什么就不存在了?是什么引起的?感觉一头雾水。在网上也没有找到类似问题,求助无门。
  经过一段时间的研究后发现,我发送的那条指令,对于设备而言有较长的响应时间,从而联想到可能接口的响应时间即timeout太短所致。终于找到了突破口,但是却发现SCardTransmit的接口参数里并没有这个参数,没办法就去看pcsc-lite的源码,还是没有找到设置timeout的地方(此时的心情有点小失望)。后来通过和其他人沟通,了解到在linux下USB设备都可以通过libusb发送指令的,而libusb的通讯接口libusb_bulk_transfer,其接口参数中是有timeout的设置的。因此回想了一下我之前安装的几个安装包,分别为libudev、libusb、ccid、pcsclite,此时想到的就是这样一组依赖关系:pcsclite : ccid : libusb : libudev (其中 : 代表 依赖于),有了这样的猜想,我就去查看ccid的源码,果然在ccid_usb_.c文件中的找到了如下结果:

接着顺藤摸瓜找到赋值readTimeout的地方,其默认值为DEFAULT_COM_READ_TIMEOUT,该宏定义在/ccid-1.4.16/src/defs.h文件中,初始值为3s,改成8s后,问题终于迎刃而解。因为第一次做这方面的工作,所以在这里记录一下,方便以后回顾。

5. 参考链接

(1)https://blog.csdn.net/fafactx/article/details/22931141
(2)https://blog.51cto.com/seiang/1950594
(3)https://blog.csdn.net/suxiang198/article/details/75106296
(4)https://www.jianshu.com/p/8581d232dd6c
(5)https://blog.csdn.net/magic_ninja/article/details/87981662
(6)https://baike.baidu.com/item/boost/69144?fr=aladdin
(7)https://blog.csdn.net/yujun_huoxu/article/details/7913135
(8)https://blog.csdn.net/qq_25867649/article/details/80163639
(9)https://blog.csdn.net/linuxchyu/article/details/12611193
(10)https://blog.csdn.net/leumber/article/details/79086998
(11)https://docs.microsoft.com/en-us/previous-versions/windows/embedded/ee498507(v=winembedded.70)?redirectedfrom=MSDN

Linux下通过CCID协议与USB设备进行交互经验总结相关推荐

  1. Linux下如何挂载FAT32格式USB设备

    From: http://hi.baidu.com/enovo/blog/item/c901eb249c0783064c088db3.html 挂u盘之前,运行命令cat /proc/partitio ...

  2. 如何实现Linux下的U盘(USB Mass Storage)驱动

    如何实现Linux下的U盘(USB Mass Storage)驱动 版本:v0.7 How to Write LinuxUSB MSC (Mass Storage Class) Driver Crif ...

  3. Windwos10下安装使用老旧USB设备——宏碁Acer ScanPrisa 640u扫描仪

    Windwos10下安装使用老旧USB设备--宏碁Acer ScanPrisa 640u扫描仪 一款老旧的USB设备640u扫描仪,一直都完好无损,就是没有最新的Win10驱动程序而闲置在那.今天就以 ...

  4. linux下利用RTMP协议接收数据

    在windows下利用RTMP接收数据的代码有很多的例子可以参考,但是在linux下利用rtmp协议接收数据,例子特别少.在无计可用的情况下,只能自己写代码了. 在写代码之前需要做一点事情,去rtmp ...

  5. Linux下的网络协议分析工具-tcpdump快速入门手册

    TCPDUMP简介 在传统的网络分析和测试技术中,嗅探器(sniffer)是最常见,也是最重要的技术之一.sniffer工具首先是为网络管理员和网络程序员进行网络分析而设计的.对于网络管理人员来说,使 ...

  6. linux系统制作win安装盘,在Ubuntu Linux下制作Windows 启动安装 USB盘

    最近想 ,在Ubuntu上刻录个Windows的安装U盘,在网上看了些资料,不过好多都说的很模糊,于是乎,我走了不少弯路.这里记录下来,希望了帮到大家. 首先你的有个USB吧,这里我们假定USB在ub ...

  7. linux刻录win10u盘_在Ubuntu Linux下制作Windows 启动安装 USB盘

    最近想 ,在Ubuntu上刻录个windows的安装U盘,在网上看了些资料,不过好多都说的很模糊,于是乎,我走了不少弯路.这里记录下来,希望了帮到大家. 首先你的有个USB吧,这里我们假定USB在ub ...

  8. linux系统如何连接串口,Linux下如何测试及使用USB转串口线

    1.将设备u口插入pc 2.输入#lsmod 先看看能否检测到这个设备,就看有没有pl2303字眼可以了.如果有,则不需要再装驱动.另外如果有的话最好再用dmesg | grep usb查找如果看到: ...

  9. 在linux中的virtualbox无法挂载usb设备的解决方法

    方法来源于网络. 在安装完virtualbox之后,virtualbox会建立一个名为 vboxusers 的组,将你的用户名加入到该组即可. 命令参考: #usermod -a -G vboxuse ...

最新文章

  1. typedef的四个用途和两大陷阱
  2. Java 查看文件绝对路径,JAVA获取文件绝对路径的方法
  3. asp创建mysql表_创建一个数据库,用ASP怎么写?
  4. jfinal怎么连接oracle,如何用Jfinal连接多个数据库
  5. hdu 1176 dp 数塔问题
  6. 开源软件的安全性风险_开源安全性,Google惊喜等
  7. java selenium ie_Selenium webdriver Java 操作IE浏览器
  8. 挑战程序设计竞赛(第2版)
  9. SQLServer2012 查询分析器的快捷键
  10. NAS安装迅雷远程下载
  11. C语言中file文件指针概念及其操作 (转载)
  12. 如何打开CMD界面呢?打开CMD界面有四种方式。
  13. Ubuntu18.04笔记本插入耳机没有声音 解决方案
  14. uni-app 封装接口 405错误
  15. 微信小程序canvas绘制图片真机不显示问题
  16. 脖子酸疼怎么办?初探解决方案
  17. 帝国时代3手机单机版java_帝国时代3手游单机版
  18. 百度竞价排名曝光_全球塑胶网:百度爱采购模式推广效果怎么样?
  19. 2022-6-13 咒语和药水的成功对数,替换字符后匹配,统计得分小于 K 的子数组数目,......
  20. 【Activiti工作流】11.并行网关

热门文章

  1. 热伤风和感冒有什么区别
  2. Unreal Engine 4(虚幻UE4)GameplayAbilities 插件入门教程(三)技能标签(Ability Tags)
  3. python转行成数据分析_大数据专业成热门,该如何转行做大数据分析师
  4. 科技爱好者周刊(第 160 期):中年码农的困境
  5. font: 12px/1.5 Tahoma, Helvetica, Arial, sans-serif;网页设计中的默认字体
  6. 小程序项目:基于微信小程序的答题系统——计算机毕业设计
  7. XYplorer设置
  8. 利用filezilla下载文件,出现无法启动传输和严重文件错误
  9. adb模拟器安装xposed
  10. 7-9 龟兔赛跑 (20分)