Develop and Download Open Source Software

Browse Subversion Repository

Contents of /tags/FeliCa2Money-2.7/Card.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 194 - (show annotations) (download)
Sat Apr 19 11:18:51 2008 UTC (15 years, 11 months ago) by tmurakam
File size: 7489 byte(s)
ver 2.7

1 /*
2 * FeliCa2Money
3 *
4 * Copyright (C) 2001-2008 Takuya Murakami
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 using System;
22 using System.Collections.Generic;
23 using System.Text;
24 using FelicaLib;
25
26 namespace FeliCa2Money
27 {
28 // Card クラス
29 abstract class Card
30 {
31 protected string ident; // 組織名
32 protected int bankId = 0; // 銀行番号
33 protected string branchId = "0"; // 支店番号
34 protected string accountId = ""; // 口座番号
35 protected string cardName; // カード名
36
37 public abstract List<Transaction> ReadCard();
38
39 public string Ident
40 {
41 get { return ident; }
42 }
43
44 public int BankId
45 {
46 get { return bankId; }
47 }
48 public string BranchId
49 {
50 get {
51 if (branchId == "") return "0";
52 return branchId;
53 }
54 }
55 public string CardName
56 {
57 get { return cardName; }
58 }
59
60 public string AccountId
61 {
62 set { accountId = value; }
63 get {
64 if (accountId == "") return "0";
65 return accountId;
66 }
67 }
68
69 // タブ区切りの分解 (SFCPeep用)
70 protected string[] ParseLine(string line)
71 {
72 return line.Split('\t');
73 }
74 }
75
76 // FeliCa カードクラス
77 abstract class CardWithFelicaLib : Card, IDisposable
78 {
79 protected int systemCode; // システムコード
80 protected int serviceCode; // サービスコード
81 protected int blocksPerTransaction = 1; // 1トランザクションあたりのブロック数
82 protected int maxTransactions = 100; // 最大トランザクション数
83 protected bool needReverse = false; // レコード順序を逆転するかどうか
84 protected bool needCalcValue = true; // 入出金額を残高から計算するかどうか
85
86 //--------------------------------------------------------------------
87 // 以下のメソッドはサブクラスで必要に応じてオーバライドする
88
89 // Transaction 解析
90 public abstract bool analyzeTransaction(Transaction t, byte[] data);
91
92 // 後処理
93 protected virtual void PostProcess(List<Transaction> list) { }
94
95 // Dispose 処理
96 public virtual void Dispose() { }
97
98 // カード ID 取得
99 public virtual bool analyzeCardId(Felica f)
100 {
101 // デフォルトでは、IDm を用いる。
102 byte[] data = f.IDm();
103 if (data == null)
104 {
105 return false;
106 }
107
108 accountId = binString(data, 0, 8);
109
110 return true;
111 }
112
113 //--------------------------------------------------------------------
114
115 // カード読み込み
116 public sealed override List<Transaction> ReadCard()
117 {
118 List<Transaction> list = new List<Transaction>();
119
120 using (Felica f = new Felica())
121 {
122 f.Polling(systemCode);
123
124 if (!analyzeCardId(f)) {
125 throw new Exception(Properties.Resources.CantReadCardNo);
126 }
127
128 for (int i = 0; i < maxTransactions; i++)
129 {
130 byte[] data = new byte[16 * blocksPerTransaction];
131 byte[] block = null;
132
133 for (int j = 0; j < blocksPerTransaction; j++)
134 {
135 block = f.ReadWithoutEncryption(serviceCode, i * blocksPerTransaction + j);
136 if (block == null)
137 {
138 break;
139 }
140
141 block.CopyTo(data, j * 16);
142 }
143 if (block == null)
144 {
145 break;
146 }
147
148 Transaction t = new Transaction();
149
150 // データが全0かどうかチェック
151 int x = 0;
152 foreach (int xx in data)
153 {
154 x |= xx;
155 }
156 if (x == 0)
157 {
158 // データが全0なら無視(空エントリ)
159 t.Invalidate();
160 }
161
162 // トランザクション解析
163 else if (!analyzeTransaction(t, data))
164 {
165 t.Invalidate();
166 }
167 list.Add(t);
168 }
169 }
170 if (needReverse)
171 {
172 list.Reverse();
173 }
174 if (needCalcValue)
175 {
176 CalcValueFromBalance(list);
177 }
178 PostProcess(list);
179
180 return list;
181 }
182
183 //-------------------------------------------------------------------
184 // ユーティリティ
185
186 // バイナリデータを16進文字列に変換
187 protected string binString(byte[] data, int offset, int len)
188 {
189 string s = "";
190 for (int i = offset; i < offset + len; i++)
191 {
192 s += data[i].ToString("X2");
193 }
194 return s;
195 }
196
197 // 残高から金額を計算する
198 private void CalcValueFromBalance(List<Transaction> list)
199 {
200 int prevBalance = 0;
201
202 foreach (Transaction t in list)
203 {
204 t.value = t.balance - prevBalance;
205 prevBalance = t.balance;
206 }
207 list.RemoveAt(0); // 最古のエントリは捨てる
208 }
209
210 // 複数バイト読み込み (big endian)
211 protected int read2b(byte[] b, int pos)
212 {
213 int ret = b[pos] << 8 | b[pos + 1];
214 return ret;
215 }
216
217 protected int read3b(byte[] b, int pos)
218 {
219 int ret = b[pos] << 16 | b[pos + 1] << 8 | b[pos + 2];
220 return ret;
221 }
222
223 protected int read4b(byte[] b, int pos)
224 {
225 int ret = b[pos] << 24 | b[pos + 1] << 16 | b[pos + 2] << 8 | b[pos + 3];
226 return ret;
227 }
228
229 // little endian
230 protected int read2l(byte[] b, int pos)
231 {
232 int ret = b[pos + 1] << 8 | b[pos];
233 return ret;
234 }
235 }
236 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26