1 /******************************************************************************
2 *
3 * Copyright (C) 2024 The Android Open Source Project.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #include <android-base/logging.h>
19 #include <android-base/stringprintf.h>
20 #include <string.h>
21
22 #include "nfa_dm_int.h"
23 #include "nfa_ee_int.h"
24 #include "nfa_nfcee_int.h"
25 #include "nfa_rw_int.h"
26 #include "nfc_config.h"
27
28 using android::base::StringPrintf;
29
30 tNFA_T4TNFCEE_CB nfa_t4tnfcee_cb;
31 void nfa_t4tnfcee_info_cback(tNFA_EE_EVT event, tNFA_EE_CBACK_DATA* p_data);
32 static void nfa_t4tnfcee_sys_enable(void);
33 static void nfa_t4tnfcee_sys_disable(void);
34
35 /*****************************************************************************
36 ** Constants and types
37 *****************************************************************************/
38 static const tNFA_SYS_REG nfa_t4tnfcee_sys_reg = {
39 nfa_t4tnfcee_sys_enable, nfa_t4tnfcee_handle_event,
40 nfa_t4tnfcee_sys_disable, NULL};
41 /* NFA_T4TNFCEE actions */
42 const tNFA_T4TNFCEE_ACTION nfa_t4tnfcee_action_tbl[] = {
43 nfa_t4tnfcee_handle_op_req, /* NFA_T4TNFCEE_OP_REQUEST_EVT */
44 };
45
46 /*******************************************************************************
47 **
48 ** Function nfa_t4tnfcee_init
49 **
50 ** Description Initialize NFA T4TNFCEE
51 **
52 ** Returns None
53 **
54 *******************************************************************************/
nfa_t4tnfcee_init(void)55 void nfa_t4tnfcee_init(void) {
56 if (NfcConfig::hasKey(NAME_T4T_NFCEE_ENABLE)) {
57 if (NfcConfig::getUnsigned(NAME_T4T_NFCEE_ENABLE)) {
58 LOG(DEBUG) << __func__;
59 /* initialize control block */
60 memset(&nfa_t4tnfcee_cb, 0, sizeof(tNFA_T4TNFCEE_CB));
61 nfa_t4tnfcee_cb.t4tnfcee_state = NFA_T4TNFCEE_STATE_DISABLED;
62 /* register message handler on NFA SYS */
63 nfa_sys_register(NFA_ID_T4TNFCEE, &nfa_t4tnfcee_sys_reg);
64 nfa_t4tnfcee_cb.ndefEmulationConfig = true;
65 return;
66 }
67 }
68 nfa_t4tnfcee_cb.ndefEmulationConfig = false;
69 }
70
71 /*******************************************************************************
72 **
73 ** Function nfa_t4tnfcee_deinit
74 **
75 ** Description DeInitialize NFA T4TNFCEE
76 **
77 ** Returns None
78 **
79 *******************************************************************************/
nfa_t4tnfcee_deinit(void)80 void nfa_t4tnfcee_deinit(void) {
81 LOG(DEBUG) << __func__;
82
83 /* reset state */
84 nfa_t4tnfcee_cb.t4tnfcee_state = NFA_T4TNFCEE_STATE_DISABLED;
85 }
86
87 /*******************************************************************************
88 **
89 ** Function nfa_t4tnfcee_conn_cback
90 **
91 ** Description This function Process event from NCI
92 **
93 ** Returns None
94 **
95 *******************************************************************************/
nfa_t4tnfcee_conn_cback(uint8_t conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)96 static void nfa_t4tnfcee_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
97 tNFC_CONN* p_data) {
98 tNFA_CONN_EVT_DATA conn_evt_data;
99 switch (event) {
100 case NFC_CONN_CREATE_CEVT: {
101 LOG(VERBOSE) << StringPrintf("%s: NFC_CONN_CREATE_CEVT", __func__);
102 if (p_data->status == NFA_STATUS_OK) {
103 nfa_t4tnfcee_cb.connId = conn_id;
104 conn_evt_data.status = NFA_STATUS_OK;
105 }
106 break;
107 }
108 case NFC_CONN_CLOSE_CEVT: {
109 LOG(VERBOSE) << StringPrintf("%s: NFC_CONN_CLOSE_CEVT", __func__);
110 if (p_data->status != NFA_STATUS_OK) {
111 conn_evt_data.status = NFA_STATUS_FAILED;
112 } else {
113 nfa_t4tnfcee_cb.t4tnfcee_state = NFA_T4TNFCEE_STATE_DISCONNECTED;
114 conn_evt_data.status = p_data->status;
115 }
116 /*reset callbacks*/
117 RW_SetT4tNfceeInfo(NULL, 0);
118 break;
119 }
120 default:
121 conn_evt_data.status = NFA_STATUS_FAILED;
122 RW_SetT4tNfceeInfo(NULL, 0);
123 break;
124 }
125 nfa_dm_act_conn_cback_notify(NFA_T4TNFCEE_EVT, &conn_evt_data);
126 }
127
128 /*******************************************************************************
129 **
130 ** Function nfa_t4tnfcee_info_cback
131 **
132 ** Description Callback function to handle EE configuration events
133 **
134 ** Returns None
135 **
136 *******************************************************************************/
nfa_t4tnfcee_info_cback(tNFA_EE_EVT event,tNFA_EE_CBACK_DATA * p_data)137 void nfa_t4tnfcee_info_cback(tNFA_EE_EVT event, tNFA_EE_CBACK_DATA* p_data) {
138 int defaultNdefNfcee =
139 NfcConfig::getUnsigned(NAME_DEFAULT_NDEF_NFCEE_ROUTE, 0x10);
140 switch (event) {
141 case NFA_EE_DISCOVER_EVT:
142 LOG(VERBOSE) << StringPrintf("%s: NFA_EE_DISCOVER_EVT", __func__);
143 if (nfa_t4tnfcee_cb.t4tnfcee_state == NFA_T4TNFCEE_STATE_DISABLED) {
144 nfa_t4tnfcee_cb.t4tnfcee_state = NFA_T4TNFCEE_STATE_TRY_ENABLE;
145 if ((p_data != nullptr) &&
146 (p_data->new_ee.ee_status != NFA_STATUS_OK)) {
147 nfa_t4tnfcee_cb.ndefEmulationSupport = true;
148 NFC_NfceeModeSet(defaultNdefNfcee, NFC_MODE_ACTIVATE);
149 }
150 }
151 break;
152 case NFA_EE_MODE_SET_EVT:
153 LOG(VERBOSE) << StringPrintf("%s: NFA_EE_MODE_SET_EVT", __func__);
154 if ((p_data != nullptr) && (p_data->mode_set.status != NFA_STATUS_OK) &&
155 (nfa_t4tnfcee_cb.t4tnfcee_state >= NFA_T4TNFCEE_STATE_TRY_ENABLE)) {
156 nfa_t4tnfcee_cb.t4tnfcee_state = NFA_T4TNFCEE_STATE_DISABLED;
157 nfa_sys_cback_notify_enable_complete(NFA_ID_T4TNFCEE);
158 nfa_ee_report_disc_done(true);
159 } else {
160 nfa_ee_report_event(NULL, event, p_data);
161 }
162 break;
163 case NFA_EE_DISCOVER_REQ_EVT:
164 LOG(VERBOSE) << StringPrintf("%s: NFA_EE_DISCOVER_REQ_EVT", __func__);
165 if (nfa_t4tnfcee_cb.t4tnfcee_state == NFA_T4TNFCEE_STATE_TRY_ENABLE) {
166 nfa_t4tnfcee_cb.t4tnfcee_state = NFA_T4TNFCEE_STATE_INITIALIZED;
167 nfa_sys_cback_notify_enable_complete(NFA_ID_T4TNFCEE);
168 nfa_ee_report_disc_done(true);
169 }
170 break;
171 case NFA_EE_CONNECT_EVT:
172 LOG(VERBOSE) << StringPrintf("%s: NFA_EE_CONNECT_EVT", __func__);
173 if ((nfa_t4tnfcee_cb.t4tnfcee_state == NFA_T4TNFCEE_STATE_INITIALIZED) ||
174 (nfa_t4tnfcee_cb.t4tnfcee_state == NFA_T4TNFCEE_STATE_DISCONNECTED)) {
175 if (NFC_STATUS_OK ==
176 NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, defaultNdefNfcee,
177 NFC_NFCEE_INTERFACE_APDU, nfa_t4tnfcee_conn_cback))
178 nfa_t4tnfcee_cb.t4tnfcee_state = NFA_T4TNFCEE_STATE_CONNECTED;
179 } else {
180 tNFC_CONN p_data;
181 p_data.status = NFC_STATUS_FAILED;
182 nfa_t4tnfcee_conn_cback(NCI_DEST_TYPE_T4T_NFCEE, NFC_ERROR_CEVT,
183 &p_data);
184 }
185 break;
186 default:
187 nfa_ee_report_event(NULL, event, p_data);
188 break;
189 }
190 return;
191 }
192
193 /*******************************************************************************
194 **
195 ** Function nfa_t4tnfcee_set_ee_cback
196 **
197 ** Description assign t4t callback to receive ee_events
198 **
199 ** Returns None
200 **
201 *******************************************************************************/
nfa_t4tnfcee_set_ee_cback(tNFA_EE_ECB * p_ecb)202 void nfa_t4tnfcee_set_ee_cback(tNFA_EE_ECB* p_ecb) {
203 p_ecb->p_ee_cback = nfa_t4tnfcee_info_cback;
204 return;
205 }
206
207 /*******************************************************************************
208 **
209 ** Function nfa_rw_evt_2_str
210 **
211 ** Description convert nfa_rw evt to string
212 **
213 *******************************************************************************/
nfa_t4tnfcee_evt_2_str(uint16_t event)214 static std::string nfa_t4tnfcee_evt_2_str(uint16_t event) {
215 switch (event) {
216 case NFA_RW_OP_REQUEST_EVT:
217 return "NFA_T4TNFCEE_OP_REQUEST_EVT";
218 default:
219 break;
220 }
221 return "Unknown";
222 }
223
224 /*******************************************************************************
225 **
226 ** Function nfa_t4tnfcee_sys_enable
227 **
228 ** Description Enable NFA HCI
229 **
230 ** Returns None
231 **
232 *******************************************************************************/
nfa_t4tnfcee_sys_enable(void)233 void nfa_t4tnfcee_sys_enable(void) { LOG(DEBUG) << __func__; }
234
235 /*******************************************************************************
236 **
237 ** Function nfa_t4tnfcee_sys_disable
238 **
239 ** Description Clean up t4tnfcee sub-system
240 **
241 **
242 ** Returns void
243 **
244 *******************************************************************************/
nfa_t4tnfcee_sys_disable(void)245 void nfa_t4tnfcee_sys_disable(void) {
246 /* Free scratch buffer if any */
247 nfa_t4tnfcee_free_rx_buf();
248
249 /* Free pending command if any */
250 if (nfa_t4tnfcee_cb.p_pending_msg) {
251 GKI_freebuf(nfa_t4tnfcee_cb.p_pending_msg);
252 nfa_t4tnfcee_cb.p_pending_msg = NULL;
253 }
254
255 nfa_sys_deregister(NFA_ID_T4TNFCEE);
256 }
257
258 /*******************************************************************************
259 **
260 ** Function nfa_t4tnfcee_proc_disc_evt
261 **
262 ** Description Called by nfa_dm to handle Ndef Nfcee Requests
263 **
264 ** Returns NFA_STATUS_OK if success else Failed status
265 **
266 *******************************************************************************/
nfa_t4tnfcee_proc_disc_evt(tNFA_T4TNFCEE_OP event)267 tNFC_STATUS nfa_t4tnfcee_proc_disc_evt(tNFA_T4TNFCEE_OP event) {
268 tNFC_STATUS status = NFC_STATUS_FAILED;
269
270 switch (event) {
271 case NFA_T4TNFCEE_OP_OPEN_CONNECTION:
272 LOG(VERBOSE) << StringPrintf("%s: NFA_T4TNFCEE_OP_OPEN_CONNECTION",
273 __func__);
274 nfa_t4tnfcee_info_cback(NFA_EE_CONNECT_EVT, nullptr);
275 break;
276 case NFA_T4TNFCEE_OP_CLOSE_CONNECTION:
277 LOG(VERBOSE) << StringPrintf("%s: NFA_T4TNFCEE_OP_CLOSE_CONNECTION",
278 __func__);
279 if (nfa_t4tnfcee_cb.t4tnfcee_state == NFA_T4TNFCEE_STATE_CONNECTED) {
280 NFC_SetStaticT4tNfceeCback(nfa_t4tnfcee_conn_cback,
281 nfa_t4tnfcee_cb.connId);
282 if (NFC_STATUS_OK != NFC_ConnClose(nfa_t4tnfcee_cb.connId)) {
283 tNFC_CONN p_data;
284 p_data.status = NFC_STATUS_FAILED;
285 nfa_t4tnfcee_conn_cback(nfa_t4tnfcee_cb.connId, NFC_ERROR_CEVT,
286 &p_data);
287 }
288 }
289 break;
290 }
291 return status;
292 }
293
294 /*******************************************************************************
295 **
296 ** Function nfa_t4tnfcee_handle_event
297 **
298 ** Description nfa t4tnfcee main event handling function.
299 **
300 ** Returns true if caller should free p_msg buffer
301 **
302 *******************************************************************************/
nfa_t4tnfcee_handle_event(NFC_HDR * p_msg)303 bool nfa_t4tnfcee_handle_event(NFC_HDR* p_msg) {
304 uint16_t act_idx;
305
306 LOG(DEBUG) << StringPrintf("%s: event=%s (0x%02x)", __func__,
307 nfa_t4tnfcee_evt_2_str(p_msg->event).c_str(),
308 p_msg->event);
309
310 /* Get NFA_T4TNFCEE sub-event */
311 if ((act_idx = (p_msg->event & 0x00FF)) < (NFA_T4TNFCEE_MAX_EVT & 0xFF)) {
312 return (*nfa_t4tnfcee_action_tbl[act_idx])((tNFA_T4TNFCEE_MSG*)p_msg);
313 } else {
314 LOG(DEBUG) << StringPrintf("%s: unhandled event 0x%02X", __func__,
315 p_msg->event);
316 return true;
317 }
318 }
319
320 /*******************************************************************************
321 **
322 ** Function nfa_t4tnfcee_is_enabled
323 **
324 ** Description T4T is enabled and initialized.
325 **
326 ** Returns true if T4T Nfcee is enabled initialization
327 **
328 *******************************************************************************/
nfa_t4tnfcee_is_enabled(void)329 bool nfa_t4tnfcee_is_enabled(void) {
330 return (nfa_t4tnfcee_cb.t4tnfcee_state >= NFA_T4TNFCEE_STATE_INITIALIZED);
331 }
332
333 /*******************************************************************************
334 **
335 ** Function NFA_T4tNfcEeIsProcessing
336 **
337 ** Description Indicates if T4tNfcee Read or write under process
338 **
339 ** Returns true if under process else false
340 **
341 *******************************************************************************/
NFA_T4tNfcEeIsProcessing(void)342 bool NFA_T4tNfcEeIsProcessing(void) {
343 return (nfa_t4tnfcee_cb.t4tnfcee_state == NFA_T4TNFCEE_STATE_CONNECTED);
344 }
345
346 /*******************************************************************************
347 **
348 ** Function NFA_T4tNfcEeIsEmulationSupported
349 **
350 ** Description Indicates if T4t NDEF Nfcee emulation is supported or not
351 **
352 ** Returns true if supported else false
353 **
354 *******************************************************************************/
NFA_T4tNfcEeIsEmulationSupported(void)355 bool NFA_T4tNfcEeIsEmulationSupported(void) {
356 return nfa_t4tnfcee_cb.ndefEmulationSupport;
357 }
358
359 /*******************************************************************************
360 **
361 ** Function nfa_t4tnfcee_is_config
362 **
363 ** Description Indicates if T4t NDEF Nfcee emulation is configured or not
364 **
365 ** Returns true if supported else false
366 **
367 *******************************************************************************/
nfa_t4tnfcee_is_config()368 bool nfa_t4tnfcee_is_config() { return nfa_t4tnfcee_cb.ndefEmulationConfig; }
369
370 /*******************************************************************************
371 **
372 ** Function nfa_t4tnfcee_is_enabled
373 **
374 ** Description T4T is enabled and initialized.
375 **
376 ** Returns true if T4T Nfcee is enabled initialization
377 **
378 *******************************************************************************/
nfa_t4tnfcee_is_discovered(void)379 bool nfa_t4tnfcee_is_discovered(void) {
380 return (nfa_t4tnfcee_cb.t4tnfcee_state >= NFA_T4TNFCEE_STATE_TRY_ENABLE);
381 }
382