source: mac/PaSoRi/trunk/EdyExample/MyAppController.m @ 36

Revision 36, 6.6 KB checked in by gnue, 3 years ago (diff)

1.0.1

Line 
1#import "PasoriKit/pasori.h"
2#import "PasoriKit/felica.h"
3#import "PasoriKit/edy.h"
4#import "PasoriKit/PasoriRequest.h"
5
6#import "MyAppController.h"
7
8
9@implementation MyAppController
10
11
12- (id)init
13{
14    self = [super init];
15    if (self) {
16        edyValues = [[NSMutableArray array] retain];
17    }
18    return self;
19}
20
21
22- (void)dealloc
23{
24    [edyValues release];
25
26    [usbPasori release];
27    // PaSoRi のノーティフィケーション通知を削除
28    [usbNotify release];
29
30    [super dealloc];
31}
32
33
34#pragma mark -
35
36
37
38/// Edy番号のアップデート
39- (void)updateEdyNo:(uint8_t *)binary index:(uint8_t)index
40{
41    if (index == 0)
42    {
43        edy_info0_t *   info = (edy_info0_t *)binary;
44       
45        NSString *  edyNo = [NSString stringWithFormat:@"%02x%02x-%02x%02x-%02x%02x-%02x%02x",
46                             info->edyno[0], info->edyno[1],
47                             info->edyno[2], info->edyno[3],
48                             info->edyno[4], info->edyno[5],
49                             info->edyno[6], info->edyno[7]];
50       
51        [edyNoTextField setStringValue:edyNo];
52    }
53}
54
55
56/// Edy利用履歴のアップデート
57- (void)updateEdyValue:(uint8_t *)binary index:(uint8_t)index
58{
59    edy_value_t *   value = (edy_value_t *)binary;
60    NSMutableDictionary *   edyValue = [NSMutableDictionary dictionary];
61
62    // 利用年月日
63    struct tm   tm;
64    time_t      t;
65    int         days;
66       
67    days = edy_days(value);
68   
69    memset(&tm, 0, sizeof(tm));
70    tm.tm_year = 2000 - 1900;
71    tm.tm_mday = 1;
72    t = mktime(&tm);
73   
74    t += days * 24 * 60 * 60;
75    t += edy_sec(value);
76   
77    [edyValue setObject:[NSDate dateWithTimeIntervalSince1970:t] forKey:@"date"];
78
79    // 入出金
80    switch (value->type)
81    {
82        case 0x02:  // 入金(チャージ)
83        case 0x04:  // 入金(Edyギフト)
84            [edyValue setObject:[NSNumber numberWithUnsignedShort:edy_use(value)] forKey:@"charge"];
85            break;
86           
87        case 0x20:
88            // 出金
89            [edyValue setObject:[NSNumber numberWithUnsignedShort:edy_use(value)] forKey:@"use"];
90            break;
91    }
92
93    // 残額
94    [edyValue setObject:[NSNumber numberWithUnsignedShort:edy_rest(value)] forKey:@"rest"];
95    if (index == 0)
96    {
97        [restView setIntValue:edy_rest(value)];
98    }
99
100    // 備考
101    switch (value->type)
102    {
103        case 0x04:  // 入金(Edyギフト)
104            [edyValue setObject:@"Edyギフト" forKey:@"note"];
105            break;
106    }
107
108    // データの更新
109    [edyValues addObject:edyValue];
110    [edyTableView noteNumberOfRowsChanged];
111}
112
113
114/// Edyデータをクリアする
115- (void)edyValueClean
116{
117    [edyNoTextField setStringValue:@""];
118    [restView setStringValue:@""];
119   
120    [edyValues removeAllObjects];
121    [edyTableView reloadData];
122}
123
124
125#pragma mark -
126
127
128// アプリケーション起動完了通知
129- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
130{
131    // ① PaSoRi のノーティフィケーション通知を登録
132    usbNotify = [[USBNotification usbNotificationWithClass:[USBDevicePasori class]
133                                                  delegate:self
134                                                    vendor:PASORI_USB_VENDOR
135                                                   product:PASORI_USB_PRODUCT] retain];
136}
137
138
139/// ② USBコネクタにデバイスが挿入された
140- (BOOL)usbAddDevice:(USBDevice *)usbDevice
141{
142    if (usbPasori)
143    {   // 既に使っているので新しく挿入されたデバイスは使わない
144        return NO;
145    }
146
147    // あとで使う場合はインスタンス変数に登録しておく
148    usbPasori = (USBDevicePasori *)[usbDevice retain];
149
150    // 接続インディケータを変更
151    [levelIndicator setIntValue:1];
152
153    // このデバイスは使うので YES を返す
154    return YES;
155}
156
157
158/// ③ USBコネクタからデバイスが抜かれた
159- (void)usbRemoveDevice:(USBDevice *)usbDevice
160{
161    if ([usbDevice isEqual:usbPasori])
162    {   // 使っているデバイスならば後始末をする
163        [usbPasori release];
164        usbPasori = nil;
165        // 接続インディケータを変更
166        [levelIndicator setIntValue:0];
167    }
168}
169
170
171/// ④ PaSoRiからのイベント通知
172- (BOOL)pasoriEvent:(USBDevicePasori *)pasori state:(pasori_state_t)state
173{
174    BOOL    handled = NO;
175
176    switch (state)
177    {
178        case PASORI_STATE_INITED:
179            // PaSoRiの初期化完了
180            // 接続インディケータを変更
181            [levelIndicator setIntValue:2];
182            // ポーリングを行う
183            [pasori felicaPolling:FELICA_POLLING_EDY];
184            handled = YES;
185            break;
186
187        case PASORI_STATE_POLLING_DONE:
188            // ポーリング成功
189            // 接続インディケータを変更
190            [levelIndicator setIntValue:3];
191            // プログレスインディケータを開始
192            [progressIndicator startAnimation:self];
193
194            // Edyの表示データをクリア
195            [self edyValueClean];
196            // Edy番号を読出す
197            [pasori felicaReadWithoutEncryption02:FELICA_SC_EDY_INFO];
198            // Edyの履歴を読出す
199            [pasori felicaReadWithoutEncryption02:FELICA_SC_EDY_VALUE];
200            handled = YES;
201            break;
202
203        case PASORI_STATE_READING_DONE:
204            // データの読出し終了
205            // プログレスインディケータを終了
206            [progressIndicator stopAnimation:self];
207            break;
208           
209        case PASORI_STATE_UNTOUCHED:
210            // カードがアンタッチされた
211            // 接続インディケータを変更
212            [levelIndicator setIntValue:2];
213            // 再度ポーリングを行う
214            [pasori felicaPolling:FELICA_POLLING_EDY];
215            // 実行中だったかもしれないのでプログレスインディケータを終了しておく
216            [progressIndicator stopAnimation:self];
217            handled = YES;
218            break;
219    }
220
221    return handled;
222}
223
224
225/// ⑤ Felicaデータの受信
226- (BOOL)felicaReceive:(USBDevicePasori *)pasori data:(felica_ans_t *)ans numBytesRead:(uint32_t)numBytesRead
227{
228    BOOL    handled = NO;
229
230    switch (ans->as.normal.cmd)
231    {
232        case FELICA_ANS_READ_WITHOUT_ENCRYPTION:
233            {
234                PasoriRequest * currRequest = [pasori currRequest];
235                int     serviceCode = [[[currRequest param] objectForKey:@"serviceCode"] unsignedShortValue];
236                int     index = [[[currRequest param] objectForKey:@"address"] unsignedShortValue];
237
238                switch (serviceCode)
239                {
240                    case FELICA_SC_EDY_INFO:
241                        // Edy 番号のアップデート
242                        [self updateEdyNo:ans->as.read_wo_enc02.data index:index];
243                        break;
244
245                    case FELICA_SC_EDY_VALUE:
246                        // Edy 利用履歴のアップデート
247                        [self updateEdyValue:ans->as.read_wo_enc02.data index:index];
248                        break;
249                }
250            }
251            handled = YES;
252            break;
253    }
254
255    return handled;
256}
257
258
259/// ⑥ USBデータの受信
260- (BOOL)usbReceive:(USBDevicePasori *)pasori data:(uint8_t *)buffer numBytesRead:(uint32_t)numBytesRead
261{
262    int     i;
263
264    printf("STATE = %2d: ", [pasori currState]);
265
266    for (i = 0; i < numBytesRead; i++)
267    {
268        printf("0x%02x, ", buffer[i]);
269    }
270
271    printf("(len = %d)\n", numBytesRead);
272
273    return YES;
274}
275
276
277#pragma mark -
278
279
280- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
281{
282    return [edyValues count];
283}
284
285
286- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
287{
288    return [[edyValues objectAtIndex:row] objectForKey:[tableColumn identifier]];
289}
290
291
292
293@end
Note: See TracBrowser for help on using the repository browser.