众所周知,Linux系统具有卓越的稳定性和高效性,对硬件配置要求低,真正的多用户等特点。因此,Linux系统被广泛用于IT服务器Linux系统应用领域、嵌入式Linux系统应用领域、个人桌面Linux应用领域、移动端Linux应用领域。随着移动互联网技术的普及,Linux嵌入式的设备和应用场景越来越丰富,嵌入式Linux设备被广泛工控、仿真、医疗仪器、自助终端设备等领域。

在Linux系统的自助医疗终端设备中会使用到社保卡阅读器,所谓,“工欲善其事,必先利其器”今天,我来一一作答。

首先,要了解社保卡阅读器和二代证阅读器具有哪种通信接口。一般情况下是提供USB免驱和RS232串口免驱,也有部分型号支持TTL串口,低功耗蓝牙BLE4.2,标准TCP/IP通信等多种通信方式。针对不同应用场景选择对应的通信端口,例如,上位机距离社保卡阅读器和二代证阅读器的距离很远,USB和RS232串口通信距离达不到的情况下,最好是选择TCP/IP通信。如果上位机是Android设备,没有USB接口和RS232串口引出,而设备有蓝牙通信,可以选择蓝牙通信接口的阅读设备。要因地制宜,根据使用场景合理选择适合自己的设备。

其次,是要选择适合当前应用场景中使用的操作系统并能提供相应开发接口的设备。常见使用的操作系统大多数是windows,随着移动互联网应用的发展和普及越来越多的Android操作系统设备应用在生活的方方面面。除此之外,还有Linux,嵌入式的,国产操作系统统信OS,麒麟,银行之类诸多操作系统。

再次,除了了解设备是否支持当前应用的操作系统之外,还要选择与之对应的开发语言。方便设备与软件系统的对接,提供对接的接口函数和相应API。

首先,我们进行错误代码定义,方便程序调试。

#ifndef __LOTUS_CARD_DRIVER_H__
#define __LOTUS_CARD_DRIVER_H__#if 1 //作为VC demo调用头文件 把0改为1typedef int                              BOOL;typedef unsigned char                          byte;//#undef FALSE//#undef TRUE//#undef NULL#define FALSE   0#define TRUE    1#define NULL    0#define WINAPI#define       RT_NOT_HALT             0x26#define     RT_ALL                  0x52#define     AM_A                    0x60#define     AM_B                    0x61
#define     COS_RESULT_BUFFER_LENGTH        256
#define     COS_SEND_BUFFER_LENGTH          256//#define        FOR_WINDOWS10                   //WINDOWS 10 用long long
#ifdef FOR_WINDOWS10typedef long long LotusHandle;              //针对句柄单独搞个类型 便于改动
#elsetypedef long LotusHandle;              //针对句柄单独搞个类型 便于改动
#endif//错误代码typedef enum _LotusCardErrorCode{LCEC_OK = 0,              //正常执行LCEC_UNKNOWN,             //未知的 LCEC_SEND_FALSE,          //发送失败LCEC_RECV_TIME_OUT,           //接收超时LCEC_RECV_ZERO_LEN,           //接收长度为0LCEC_RECV_CRC_FALSE,        //接收校验失败LCEC_REQUEST,               //寻卡LCEC_ANTICOLL,              //防冲突LCEC_SELECT,               //选卡LCEC_AUTHENTICATION,        //三次验证LCEC_HALT,                    //中止LCEC_READ,                  //读LCEC_WRITE,                  //写LCEC_INCREMENT,              //加值LCEC_DECREMENT,             //减值LCEC_LOADKEY,               //装载密码LCEC_BEEP,                    //蜂鸣LCEC_RESTORE,               //卡数据块传入卡的内部寄存器LCEC_TRANSFER,               //内部寄存器传入卡的卡数据块LCEC_SEND_COMMAND,           //发送14443指令LCEC_WIFI_SCANAP_BEGIN,      //发送扫描动作开始信号LCEC_WIFI_SCANAP_COUNT,     //获取扫描AP计数LCEC_WIFI_SCANAP_RESULT,  //获取扫描结果LCEC_WIFI_GET_STAINFO,  //获取STA信息LCEC_WIFI_SET_STAINFO, //设置STA信息LCEC_WIFI_GET_MODE,        //获取模式LCEC_WIFI_SET_MODE,       //设置模式LCEC_WIFI_RESET,          //复位WIFI模块LCEC_FELICA_POLLING,      //FELICA寻卡动作LCEC_REQUESTB,              //typeb寻卡错误LCEC_SELECTB,                //typeb选卡LCEC_HALTB,                    //typeb中止LCEC_M100_INVENTORY_FAIL,  //轮询操作失败。没有标签返回或者返回数据CRC 校验错误。}LotusCardErrorCode;

社保卡结构定义,由于社保卡有二代社保和三代社保卡,这部分定义进行了分开定义。

typedef struct _SocialSecurityCardStruct//社保卡结构 里面存放公开信息
{char szCardNo[16];//实际只有9个字符char szName[32];//一般是4-8个字符 考虑到特殊人名 搞多点char szSSCNo[32];//一般是身份证号18个字符char szSex[8];//性别char szNation[32];//民族 有的民族名称有点长char szBankNo[32];//对应的银行卡号char szSignedDate[32];//签发日期char szValidityEndDate[32];//到期日期
}SocialSecurityCardStruct;
typedef struct _SocialSecurityCardStructV3//社保卡结构 里面存放公开信息
{//以下为发卡机构数据文件EF05 根据V2.0 构造 后续有了V3.0的东东再处理 这个应该是一致的char szIdentificationCode[64];//卡的识别码 实际只有16个字节 转成hex字串 便于显示 长度就搞长点char szType[4];//卡类型 实际只有1个字节 char szVersion[4];//卡版本 实际4个字节 char szInstitutionalNumber[32];//发卡机构 实际只有12个字节 char szSignedDate[32];//签发日期 实际只有4个字节 char szValidityEndDate[32];//到期日期 实际只有4个字节 char szCardNo[32];//卡号 实际只有9个字节
}SocialSecurityCardStructV3;

完成错误代码定义和社保卡结构定义之后,进行社保卡阅读功能实现。

#include "LotusCardDriver.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include <unistd.h>
#define CHAR_LEN_UNICODE    2
#define CHAR_LEN_UTF8       3
void TestIcCard(long hLotusCard);
void TestGetTwoGenerationIdCardNo(long hLotusCard);
void TestIdCard(LotusHandle hLotusCard);
void Test7816(LotusHandle hLotusCard);
int wstrlen(char * pWideChar,int Len = 0);
int wstrlen(char * pWideChar,int Len)
{int Result=0;short * pWideTemp=(short *)pWideChar;if(Len){for(long lngCyc=0;lngCyc < Len/CHAR_LEN_UNICODE; lngCyc++){if(pWideTemp[lngCyc]==0){Result=lngCyc;break;}}}else{while(pWideTemp[Result]){Result++;}}return Result;
}void testSocialSecurityCard(LotusCardDriver driver, long nHandle) {LotusCardSocialSecurityCardParam tSocialSecurityCardParam = new LotusCardSocialSecurityCardParam();LotusCardAppConfig tAppConfig = new LotusCardAppConfig();boolean bResult = false;String temp;int nErrorCode = 0;int nCardInsertStatus = 0;TwoIdInfoParam tTwoIdInfo = new TwoIdInfoParam();LotusCardParam tLotusCardParam1 = new LotusCardParam();if (null == driver) return;if (nHandle == -1) return;nCardInsertStatus = driver.Get7816CardInsertStatus(nHandle);if (1 == (nCardInsertStatus & 0xff)) {AddLog("card insert !");} else {AddLog("card not insert !");return;}// 以下动作设置5V输出 5V:VSel0=0 VSel1=1 3V:VSel0=1 VSel1=0 1.8V:VSel0=1 VSel1=1bResult = driver.SetSamVSel0(nHandle, (byte) 0, (byte) 0);if (!bResult) {AddLog("Call SetSamVSel0 Error!");return;}bResult = driver.SetSamVSel1(nHandle, (byte) 0, (byte) 1);if (!bResult) {AddLog("Call SetSamVSel1 Error!");return;}// 下电bResult = driver.SetSamPowerOnOff(nHandle, (byte) 0);if (!bResult) {AddLog("Call SetSamPowerOnOff Error!");return;}// 上电bResult = driver.SetSamPowerOnOff(nHandle, (byte) 1);if (!bResult) {AddLog("Call SetSamPowerOnOff Error!");return;}//AddLog("设置5V");AddLog("设置5V");bResult = driver.ResetSam(nHandle, tLotusCardParam1);if (!bResult) {AddLog("Call ResetSam Error!");return;}if (0 == tLotusCardParam1.unCosReultBufferLength) {AddLog("unCosReultBufferLength Error!");return;}AddLog("Call ResetSam Ok!");AddLog("Reset result:"+ driver.toHexString(tLotusCardParam1.arrCosResultBuffer, 0, tLotusCardParam1.unCosReultBufferLength));//测试一下社保卡bResult = driver.GetSocialSecurityInfoBy7816(nHandle, tSocialSecurityCardParam);if (!bResult) {AddLog("Call GetSocialSecurityInfoBy7816 Error!");return;}AddLog("卡号:" + tSocialSecurityCardParam.strCardNo);AddLog("姓名:" + new String(tSocialSecurityCardParam.arrName, Charset.forName("gbk")));AddLog("身份证号:" + tSocialSecurityCardParam.strSSCNo);if (tSocialSecurityCardParam.strSex.equals("1")) {AddLog("性别:男");} else {AddLog("性别:女");}AddLog("民族:" + new String(tSocialSecurityCardParam.arrNation, Charset.forName("gbk")));AddLog("银行卡号:" + tSocialSecurityCardParam.strBankNo);AddLog("签发日期:" + tSocialSecurityCardParam.strSignedDate);AddLog("到期日期:" + tSocialSecurityCardParam.strValidityEndDate);}

以上内容是在Linux系统中进行社保卡阅读的部分内容,产品功能持续更新中。。。。。。

Linux系统中社保卡阅读相关推荐

  1. linux中读pdf的软件,Linux 系统中的pdf阅读器以及工具

    evince pdf-filename & #这个是pdf阅读器 evince-2.28.2-14.el6_0.1.x86_64.rpm 这个软件也是centos6默认的pdf阅读器 xour ...

  2. 成功恢复 Linux 系统中已删除的文件

    点击关注公众号,回复"1024"获取2TB学习资源! 当用户意外地删除了一个仍然需要的文件时,大多数情况下,是没有简便的方法可以重新找回或重建这个文件.不过,幸运的是文件是可以通过 ...

  3. linux redis数据库安装配置,Linux系统中redis的安装配置步骤

    Linux系统中redis的安装配置步骤 发布时间:2020-06-23 10:13:36 来源:亿速云 阅读:87 作者:Leah 这篇文章将为大家详细讲解有关Linux系统中redis的安装配置步 ...

  4. linux查找最近访问的文件,教您在Linux系统中查找最近修改的文件/文件夹

    如果您使用Linux系统进行日常操作,则主目录文件将随时间急剧增加.如果您有成千上万个文件,很可能不记得最近更改的文件名,本文将教您在Linux系统中查找最近修改的文件/文件夹.另外,如果要检查出于任 ...

  5. linux 权限管理 lvm,Linux系统中RAID及LVM管理

    本节索引 一.RAID概念及管理 二.LVM逻辑卷的介绍及使用 Linux系统中如何提高磁盘的读写性能,如何实现磁盘冗余,当磁盘快被占满时,又如何弹性拓展磁盘容量,RAID及LVM技术可以帮你轻松解决 ...

  6. 基于Linux系统中进程调度分析

    本文作者(院 浩),请您在阅读本文时尊重作者版权. [摘要]Linux是一个多用户多任务的操作系统,Linux中实现了对多个进程公平.高效的调度,并不是采用单一的调度策略,而是几种调度策略有机地综合应 ...

  7. bash命令怎么在linux系统中使用

    这篇文章将为大家详细讲解有关bash命令怎么在linux系统中使用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解.  什么是Linux系统Linux是一 ...

  8. linux中bash的功能主要有,Linux系统中的Bash功能的介绍

    今天小编要跟大家分享的文章是关于Linux系统中的Bash功能的介绍.一个完整计算机的体系结构包括:硬件与软件,而软件又分为系统软件与应用软件,负责对硬件仅需管理与操作的是系统软件的内核部分,用户是无 ...

  9. linux 内核日志等级,Linux系统中日志级别详情

    日志信息分类 1.等级由低到高:debug 2.区别: debug 级别最低,可以随意的使用于任何觉得有利于在调试时更详细的了解系统运行状态的东东: info  重要,输出信息:用来反馈系统的当前状态 ...

最新文章

  1. TypeError: string argument without an encoding
  2. Kubernetes应用程序开发认证(CKAD) 经验分享
  3. css如何调整红心样式_在JavaScript应用程序中包含CSS的多种方法「渡一」
  4. Mac 终端连接linux程服务器并相互传输文件
  5. 1090 危险品装箱 (25分)
  6. 2020中考可不可以用计算机,2020北京中考录取规则:北京中考计算机的录取规则...
  7. Windows10浏览器被劫持时,一种解决方法。
  8. python-20180103-1
  9. 我本科毕业,当了外卖骑手最终是为了赚钱学编程
  10. linux最多多少主分区,Linux为什么最多能分4个四个主分区
  11. 利用正则表达式做验证登录
  12. getline()详解
  13. 5G承载网,到底有哪些关键技术?
  14. 注意了!朋友圈发一张照片,是如何泄露你的地址信息的?
  15. 截取计算机全屏画面的方法有,电脑怎么截图全屏 详细方法介绍
  16. 第一个字母变成第26个字母,第i个字母变成第(26-i+1)个字母——C语言
  17. 《Python语言程序设计》王恺 王志 李涛 机械工业出版社 第6章 字符串 课后习题答案【强烈推荐】
  18. 自动驾驶汽车的车道检测
  19. android 手机一直进安全模式 解决方法
  20. Chrome不能拖拽安装插件

热门文章

  1. Mac 下终端运行C++
  2. 2022烷基化工艺操作证考试题库及模拟考试
  3. CabloyJS一站式助力微信、企业微信、钉钉开发 - 钉钉篇
  4. android关机重启流程代码
  5. A Complete ActiveX Web Control Tutorial
  6. html转pdf文件下载之最合理的方法支持中文
  7. 主从模式的数据库搭建(主从复制)
  8. 腾讯混合云存储 TStor 系列再添新成员,并行存储一体机正式发布​
  9. 2022年,在NLP中还有没有比较新的研究方向?
  10. wma格式怎么转换mp3,4种方法超快学