イヤホンと一緒に歩んでいく

某家電量販店のオーディオコーナーで働いていました。みごとに沼にはまりました。はい。

【C++】PaSoRi RC-S380と標準ライブラリでICカードを読み込みたい

こんにちは。mugiHaLです。

唐突に出退勤アプリが作りたくなったので、VisualStudioで遊んでいます。

調べた内容の覚え書きです。

はじめに

IDEMicrosoft Visual Studio Community 2019
言語:C++
使用デバイスSONY PaSoRi RC-S380/P

まず、言語の選定理由は、PC/SCライブラリを使用するためです。
SONYの開発ライブラリが10万円くらいするらしくって(無償のLite版もありますが)、無料で出来るならそれで良いじゃんと。
最終的には、Windowsデスクトップアプリケーションを作成したいので、C#を使用したいのですが、ライブラリが標準で用意されているC++にしました。デスクトップアプリはMFCで作ろうか・・・。
C#だとDLLのインポートが必要なので諦めました。調べればC#の実装も出てきますがそんなやる気ありません。

それから、ICカードリーダーの選定ですが、ISO14443準拠なら何でもよくて、非接触だけで良いので、近所のビックカメラに売っていたのは以下の2つ。
・RC-S380
・ACR1251CL

無難にPaSoRiにしておきました。

余談ですが、ICカードリーダーって開発用途しか無いと思っていましたが、市販のICカードリーダーにはSuicaの残高確認ソフトとか、確定申告にも使えるみたいで需要があるみたいですね。知らない世界でした。

実装について

最終的な仕様・設計は以下のようにしたいです。

使用機器:
ICカードリーダー(RC-S380)
ICカードAmazonで10枚2000円くらいで売ってた)
・Windows10 PC(Windows7でも動くと思う。XPとかもう考えなくていいでしょ。)

ファイル:
・実行ファイル(.exe)
・利用者リスト(.dat)・・・カードIDと社員情報を紐付けする
・出退勤情報(.csv)・・・出退勤の情報を書き出す

考慮する点:
・紛失した場合・・・新規カードを使用する。ユーザと紐づいたIDの書き換え。
・打刻忘れ・・・その日最初のタッチで出勤、2回目で退勤など。メニューから出勤のみ退勤のみ設定。
・管理者権限・・・好きな時間に。悪用してはいけない。
・基準となる時間・・・インターネットにつなげてTCPで取得したいけど、個人情報アプリなのでスタンドアローンにしたい・・・。基準から相対時間で計算する?

アルゴリズム
① ICカードリーダーと接続する。
② ICカードリーダーの状態を監視する。
②-1 ICカードを検知したらカードのIDを取得する。
③ ICカードリーダーと切断する。

ソースコード

インクルード

#include <winscard.h>

接続

LONG lResult;
SCARDCONTEXT scardtext;

// 接続
lResult = SCardEstablishContext(
  SCARD_SCOPE_USER,
  NULL,
  NULL,
  &scardtext
);

カードリーダーの監視

LONG lResult;

// カードリーダーを列挙する
LPTSTR	lpszReaderName;
DWORD	dwAutoAllocate = SCARD_AUTOALLOCATE;

lResult = SCardListReaders(
  scardtext, SCARD_ALL_READERS, (LPTSTR)&lpszReaderName, &dwAutoAllocate);

//カードリーダーの状態の取得する(カードが存在するか)
SCARD_READERSTATE	readerState;
readerState.szReader = lpszReaderName; // リーダー名を設定する
readerState.dwCurrentState = SCARD_STATE_UNAWARE; // 初期状態を設定する

// リーダーの状態を知る
lResult = SCardGetStatusChange(scardtext, 0, &readerState, 1);

// カードセットしていない場合
if (readerState.dwEventState & SCARD_STATE_EMPTY){
  while (1) {
    readerState.dwCurrentState = readerState.dwEventState;

    // カードセット待ち
    lResult = SCardGetStatusChange(scardtext, INFINITE, &readerState, 1);

    if (readerState.dwEventState & SCARD_STATE_PRESENT)
    //カードセット

    else if (readerState.dwEventState & SCARD_STATE_UNAVAILABLE)
    //カードリーダ切断
  }
}

//カードリーダー名領域を開放する
lResult = SCardFreeMemory(scardtext, lpszReaderName);

切断

LONG lResult;

// 切断
lResult = SCardReleaseContext(scardtext);
最後に

仕事が終わっておうちに帰ってソースコードなんて見たくないですね。元気があるときにチャレンジします。
実家で使わせてみたいと思いましたが、うちは従業員いないから意味ないんですよね・・・。

どうでもよいことですが、初めて目次使ってみました。手動でリンクさせるのかと思いきや簡単でした。

それでは!


[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

非接触ICカードリーダー/ライター PaSoRi USB対応 RC-S380
価格:2779円(税込、送料無料) (2019/10/23時点)