-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathHkNfcA.cpp
155 lines (129 loc) · 3.29 KB
/
HkNfcA.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include "HkNfcRule.h"
#ifdef HKNFCRW_USE_NFCA
#include <string.h>
#include "HkNfcRw.h"
#include "HkNfcA.h"
#include "NfcPcd.h"
#include "misc.h"
#define LOG_TAG "HkNfcA"
#include "nfclog.h"
uint16_t HkNfcA::m_SensRes;
HkNfcA::SelRes HkNfcA::m_SelRes;
namespace {
//Polling
const uint8_t INLISTPASSIVETARGET[] = { 0x00 };
//Key A Authentication
const uint8_t KEY_A_AUTH = 0x60;
const uint8_t KEY_B_AUTH = 0x61;
const uint8_t READ = 0x30;
const uint8_t UPDATE = 0xa0;
}
/**
* [NFC-A]Polling
*
* @retval true 成功
* @retval false 失敗
*/
bool HkNfcA::polling()
{
int ret;
uint8_t responseLen;
uint8_t* pData;
ret = NfcPcd::inListPassiveTarget(
INLISTPASSIVETARGET, sizeof(INLISTPASSIVETARGET),
&pData, &responseLen);
if (!ret
|| (responseLen < 12)
|| (responseLen < 7 + *(pData + 7))) {
LOGE("pollingA fail: ret=%d/len=%d\n", ret, responseLen);
return false;
}
//[0] d5
//[1] 4b
//[2] NbTg
//[3] Tg
if(*(pData + 3) != 0x01) {
LOGE("bad TargetNo : %02x\n", *(pData + 3));
return false;
}
m_SensRes = (uint16_t)((*(pData + 4) << 8) | *(pData + 5));
LOGD("SENS_RES:%04x\n", m_SensRes);
m_SelRes = (SelRes)*(pData + 6);
const char* sel_res;
switch(m_SelRes) {
case MIFARE_UL: sel_res = "MIFARE Ultralight"; break;
case MIFARE_1K: sel_res = "MIFARE 1K"; break;
case MIFARE_MINI: sel_res = "MIFARE MINI"; break;
case MIFARE_4K: sel_res = "MIFARE 4K"; break;
case MIFARE_DESFIRE: sel_res = "MIFARE DESFIRE"; break;
case JCOP30: sel_res = "JCOP30"; break;
case GEMPLUS_MPCOS: sel_res = "Gemplus MPCOS"; break;
default:
m_SelRes = SELRES_UNKNOWN;
sel_res = "???";
}
LOGD("SEL_RES:%02x(%s)\n", m_SelRes, sel_res);
if(responseLen < 7 + *(pData + 7)) {
LOGE("bad length\n");
return false;
}
NfcPcd::setNfcId(pData + 8, *(pData + 7));
return true;
}
bool HkNfcA::read(uint8_t* buf, uint8_t blockNo, bool bClassic/*=false*/)
{
NfcPcd::commandBuf(0) = 0x01;
NfcPcd::commandBuf(2) = blockNo;
NfcPcd::commandBuf(3) = 0xff;
NfcPcd::commandBuf(4) = 0xff;
NfcPcd::commandBuf(5) = 0xff;
NfcPcd::commandBuf(6) = 0xff;
NfcPcd::commandBuf(7) = 0xff;
NfcPcd::commandBuf(8) = 0xff;
memcpy(NfcPcd::commandBuf() + 9, NfcPcd::nfcId(), NfcPcd::nfcIdLen());
uint8_t len;
bool ret;
if (bClassic) {
// Key A Authentication
NfcPcd::commandBuf(1) = KEY_A_AUTH;
ret = NfcPcd::inDataExchange(
NfcPcd::commandBuf(), 9 + NfcPcd::nfcIdLen(),
NfcPcd::responseBuf(), &len);
if(!ret) {
LOGE("read fail1\n");
return false;
}
}
if (bClassic) {
// Key B Authentication
NfcPcd::commandBuf(1) = KEY_B_AUTH;
ret = NfcPcd::inDataExchange(
NfcPcd::commandBuf(), 9 + NfcPcd::nfcIdLen(),
NfcPcd::responseBuf(), &len);
if(!ret) {
LOGE("read fail2\n");
return false;
}
}
// Read
if (bClassic) {
NfcPcd::commandBuf(1) = READ;
} else {
NfcPcd::commandBuf(0) = READ;
NfcPcd::commandBuf(1) = blockNo;
}
ret = NfcPcd::inDataExchange(
NfcPcd::commandBuf(), (bClassic) ? 3 : 2,
NfcPcd::responseBuf(), &len);
if(ret) {
memcpy(buf, NfcPcd::responseBuf(), len);
} else {
LOGE("read fail3\n");
}
return ret;
}
bool HkNfcA::write(const uint8_t* buf, uint8_t blockNo)
{
return false;
}
#endif /* HKNFCRW_USE_NFCA */