前言
近期,我需要使用讀卡機來讀取健保卡資訊,並將取得資訊作為身分驗證使用;但是手上僅有Windows 11筆電且日後標的作業系統為Linux類型的作業系統。因此,為了要達到此目的,需要使用WSL作為測試與開發環境;在本文中,將展示如何設定讀卡機供WSL 2使用,並插上健保卡後能夠讀取到健保卡資訊。
前置條件
需要達到前言所描述的目的,則需要完成與準備下列的項目:
- 一台讀卡機,且需要是虹堡科技所出廠的機器,晶片需要確認為:EZ100PU。
- 一台Win11機器,可以是筆電或是桌機,並啟用了WSL 2;且Ubuntu版本為22.04以上。
- 後續示範以22.04版本為例子。
- 需要事先在前述的Ubuntu 22.04版本中,安裝好最新的Docker版本,並能夠使用「docker」指令。
設定USB讀卡機
首先,以「系統管理員」身分開啟Windows終端機,後續關於操作USB讀卡機指令皆在此終端機執行,開啟後的示意圖如下所示:
接著,執行下列的指令並下載USB管理工具:
winget install --interactive --exact dorssel.usbipd-win
若尚未安裝此工具,則會跳出安裝視窗,並依照視窗呈現的訊息指示執行安裝即可。若已經安裝此工具,則會顯示下列的圖示。
完成USB管理工具的安裝後,插上讀卡機,並在系統管理員下的Windows終端機中,執行下列的指令來取得目前電腦上所有的USB清單:
usbipd list
執行前述的指令後,輸出的USB清單如下圖所示:
從上述的截圖,我們能夠得知「EZ100PU Smart Card Reader 」之Bus ID為2-4。接著,開啟WSL 2之「Ubuntu 22.04」後,執行下列的指令,「–busid」為前述截圖讀卡機裝置所對應的Bus ID:
usbipd bind --busid 2-4
執行完成後,可能會出現「usbipd: warning: USB filter ‘USBPcap’ is known to be incompatible with this software; ‘bind –force’ will be required.」之警告訊息,若要讓警告訊息不會輸出,則需要在前述的指令中,加入「–force」參數;但是,此警告訊息這不會影響後續的操作。
接下來,我們可以再執行「usbipd list」指令來驗證此讀卡機之狀態是否變成「Shared」。
確定USB讀卡機的狀態後,再執行下列指令將讀卡機交由WSL 2的作業系統作為管理。
usbipd attach --wsl --busid 2-4
需要注意的是,此指令執行完成後,將會發生下列的事項:
- Windows中,我們將無法使用與存取此USB讀卡機,原因是已經交由WSL 2上的作業系統操作與管理。
- 在「Ubuntu 22.04」中,執行「lsusb」指令來驗證USN讀卡機能夠使用與存取。
- 若「lsusb」指令不存在,則需要先執行「sudo apt update」與「sudo apt install -y usbutils」指令。
建置健保卡讀卡服務
接著,切換至「Ubuntu 22.04」,並依序執行下列的指令來安裝與設定讀取健保卡服務,此健保卡讀卡服務是使用了「magiclen/tw-nhi-icc」專案並加以容器化後的版本:
git clone https://github.com/peter279k/docker-tw-nhi-icc cd docker-tw-nhi-icc/ docker compose build
完成後,再執行「docker compose up -d」即可將健保卡讀卡服務運行在此Ubuntu 22.04上了。
我們同時可以執行「docker compose ps」來檢查目前健保卡讀卡服務運行的狀態:
此服務同時具有讀卡資訊頁面可以透過Windows上的瀏覽器,瀏覽「http://localhost:12346/demo.html」之頁面,作並為簡易判斷健保卡所讀取到的資訊;若沒有讀取到訊息則會呈現下列的截圖:
當使用自己的健保卡讀取到資訊,則會呈現如下截圖:
健保卡讀取服務能夠將讀取到的資訊以JSON陣列的方式呈現,讀取到的訊息與欄位如下:
- readerName,讀取健保卡的讀卡機型號。
- cardNo,健保卡卡號。
- fullName,完整性名。
- idNo,身分證字號。
- birthday,生日。
- sex,性別;若顯示「M」為男性(male),女性則為「F」(female)。
- issueDate,發卡時間。
除了能夠透過既有健保讀卡服務的簡易頁面取得健保卡資訊外,也能夠使用API的方式來呼叫並取的健保卡資訊,健保卡讀卡的後端服務預設是監聽在「12345」,因此我們能夠使用下列的cURL與jq指令取得健保卡資訊:
curl -q http://localhost:12345/ | jq
從API所取得到的健保卡資訊,其欄位名稱有些許不同:
- reader_name,讀卡機型號名稱。
- card_no,健保卡卡號。
- full_name,健保卡持有者姓名。
- id_no,身分證字號。
- birth_date,持卡人之生日。
- birth_date_timetstamp,持卡人生日之時間戳記。
- sex,持卡人性別;若顯示「M」則為男性(male),女性則為「F」(female)。
- issue_date,此健保卡發卡日期。
- issue_date_timestamp,此健保卡發卡日期之時間戳記。
當完成讀卡後,即可將健保卡取出,並換下一張健保卡讀取。
故障排除
以下是有可能發生問題的原因:
- USB讀卡機找不到,或是執行usbipd指令後,Ubuntu 22.04仍找不到。這問題有可能讀卡機接觸不良,因此需要重新插讀卡機、更換USB孔後,再次執行「usbipd attach –wsl –busid 2-4」指令。
- 此情況只會在Windows上才執行的設定,若主體的機器本身是Linux則只需要確保USB讀卡機有讀取到,可以使用「lsusb」做驗證。
- port number衝突,此情形只會發生健保卡讀卡機服務無法運行容器化的問題,最簡單方法就是手動更換port number,或是將使用服務的埠號先暫停並供給健保卡讀卡服務使用。
- 預設健保卡讀卡服務的後端(以Rust開發)會運行於12345的埠號。
- 健保卡讀卡服務的簡易頁面會運行於12346的埠號。
- 由於讀卡機之Linux驅動在虹堡科技網站上已經無法取得,因此我們使用的是GitHub上遺留的驅動作為安裝的作法;詳細的安裝與設定方法已經定義於Dockerfile中。
- 驅動網址:https://github.com/chihchun/ez100pu
- 若無故移除讀卡機再插上時,前述執行接管動作的「usbipd」指令需要再一次,若主體的機器本身是Linux作業系統則沒有此步驟。
參考資料
- https://magiclen.org/tw-nhi-icc
- https://github.com/chihchun/ez100pu
- https://github.com/magiclen/tw-nhi-icc
- https://github.com/magiclen/tw-nhi-icc-service
- https://gist.github.com/0xcafed00d/f25d042c33f3cac142b650985c12fd0b
- https://dev.to/cyrilmarpaud/embedded-rust-on-bbc-micro-bit-unlocking-vec-and-hashmap-2nm0