一、背景
当前不少政企单位电脑设备采购换新,使用国产电脑和国产操作系统;曾经部署在客户端的C#软件面临更新换代,我们给客户提供了多种思路:包括采用wine模拟器、wind(Windows in Docker Container)等。最终彻底将C#软件翻版为web网页系统!原来的C#软件支持读取身份证读卡器,因此技术组面临一个难题,如何实现web浏览器在国产鲲鹏CPU-ARM64位架构下读取身份证读卡器的问题。
二、前期准备
客户采购的国产台式机型号为:华为擎云W585x-A081。登录系统后,在终端内输入如下命令,查看操作系统/CPU/GPU/内存信息:
# apt是Debian/Ubuntu及其衍生Linux发行版(如统信UOS、Deepin、Kali Linux)中用于软件包管理的核心命令行工具
sudo apt install hardinfo
hardinfo
三、技术分析
在统信桌面20专业版操作系统,华为鲲鹏ARM64位CPU架构下,要实现web浏览器通过USB端口调用身份证读卡器硬件,经过技术测试最有效的方法,是在客户的电脑上部署一个插件服务,由该插件服务与硬件身份证读卡器通信,同时暴露端口给web浏览器调用。
- 思考点1:有多台客户端电脑,每台客户端电脑都要部署一个插件服务,该服务需要稳定可靠。
- 思考点2:插件最好使用轻量级的开发语言,由此想到采用Python脚本语言。
- 思考点3:插件需要开机自启,统信操作系统基于Linux内核,支持配置systemd服务。
3.1、驱动查找
客户有两款身份证读卡器设备,一是新中新F200A、一款是神思电子台式居民身份证阅读机具-SS628(100)。我们需要找到能在ARM架构下调用的SDK。
国产化适配硬件驱动网址:https://ecology.chinauos.com/
经过查找,找到神思读卡器:通用型多合一SDK(arm麒麟)V3.22.20.7 版本。
四、Python环境准备
一般统信UOS 20 通常预装了 Python 3.7 或 3.8,直接执行命令检查:
python3 --version
4.1 检查pip
检查pip是否安装,如果没有安装需要安装,如果已经安装则可能是没有配置终端命令。
# 检查pip是否安装
python3 -m pip --version
# 没有安装执行下面语句
sudo apt update
sudo apt install python3-pip # 安装 pip
pip3 --version
4.2 升级pip和安装必要的包
# 升级pip版本:
python3 -m pip install --upgrade pip
# 安装必要的包:
# 注意加上 sudo,让其全局生效,否则后面会报错
sudo pip3 install flask
sudo pip3 install ctype
sudo pip3 install numpy
有些同学要去安装 pip3 install ctypes ,这样会报错。(ctypes 是 Python 自带的模块,从 Python 2.5 开始,不需要通过 pip 安装)
五、Python脚本
脚本命名为:uos_ss_id_card_read.py,脚本代码如下(已上线生产):
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
import time
import signal
import logging
from ctypes import cdll, c_char_p, c_ubyte, c_long, create_string_buffer
from flask import Flask, jsonify
from threading import Thread
import socket
import json
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('/opt/idcard/sds_id_reader.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger("SDS_IDReader")
app = Flask(__name__)
# 动态库加载(ARM64 Linux环境)
try:
lib_path = "/usr/lib/idcard/libCommonInterface.so" # 标准库路径
if not os.path.exists(lib_path):
lib_path = os.path.join(os.path.dirname(__file__), "libCommonInterface.so")
common_interface = cdll.LoadLibrary(lib_path)
logger.info(f"成功加载神思SDK库: {
lib_path}")
except Exception as e:
logger.error(f"无法加载神思SDK库: {
e}")
sys.exit(1)
# 定义函数原型
common_interface.OpenDevice.restype