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) << StringPrintf("nfa_t4tnfcee_init ()");
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 }
65 }
66 }
67
68 /*******************************************************************************
69 **
70 ** Function nfa_t4tnfcee_deinit
71 **
72 ** Description DeInitialize NFA T4TNFCEE
73 **
74 ** Returns None
75 **
76 *******************************************************************************/
nfa_t4tnfcee_deinit(void)77 void nfa_t4tnfcee_deinit(void) {
78 LOG(DEBUG) << StringPrintf("nfa_t4tnfcee_deinit ()");
79
80 /* reset state */
81 nfa_t4tnfcee_cb.t4tnfcee_state = NFA_T4TNFCEE_STATE_DISABLED;
82 }
83
84 /*******************************************************************************
85 **
86 ** Function nfa_t4tnfcee_conn_cback
87 **
88 ** Description This function Process event from NCI
89 **
90 ** Returns None
91 **
92 *******************************************************************************/
nfa_t4tnfcee_conn_cback(uint8_t conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)93 static void nfa_t4tnfcee_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
94 tNFC_CONN* p_data) {
95 tNFA_CONN_EVT_DATA conn_evt_data;
96 LOG(DEBUG) << StringPrintf("%s : Enter, conn_id = %d, event = 0x%x", __func__,
97 conn_id, event);
98 switch (event) {
99 case NFC_CONN_CREATE_CEVT: {
100 if (p_data->status == NFA_STATUS_OK) {
101 nfa_t4tnfcee_cb.connId = conn_id;
102 conn_evt_data.status = NFA_STATUS_OK;
103 }
104 break;
105 }
106 case NFC_CONN_CLOSE_CEVT: {
107 if (p_data->status != NFA_STATUS_OK) {
108 conn_evt_data.status = NFA_STATUS_FAILED;
109 } else {
110 nfa_t4tnfcee_cb.t4tnfcee_state = NFA_T4TNFCEE_STATE_DISCONNECTED;
111 conn_evt_data.status = p_data->status;
112 }
113 /*reset callbacks*/
114 RW_SetT4tNfceeInfo(NULL, 0);
115 break;
116 }
117 default:
118 conn_evt_data.status = NFA_STATUS_FAILED;
119 RW_SetT4tNfceeInfo(NULL, 0);
120 break;
121 }
122 nfa_dm_act_conn_cback_notify(NFA_T4TNFCEE_EVT, &conn_evt_data);
123 }
124
125 /*******************************************************************************
126 **
127 ** Function nfa_t4tnfcee_info_cback
128 **
129 ** Description Callback function to handle EE configuration events
130 **
131 ** Returns None
132 **
133 *******************************************************************************/
nfa_t4tnfcee_info_cback(tNFA_EE_EVT event,tNFA_EE_CBACK_DATA * p_data)134 void nfa_t4tnfcee_info_cback(tNFA_EE_EVT event, tNFA_EE_CBACK_DATA* p_data) {
135 LOG(DEBUG) << StringPrintf("%s event: %x", __func__, event);
136 int defaultNdefNfcee =
137 NfcConfig::getUnsigned(NAME_DEFAULT_NDEF_NFCEE_ROUTE, 0x10);
138 switch (event) {
139 case NFA_EE_DISCOVER_EVT:
140 if (nfa_t4tnfcee_cb.t4tnfcee_state == NFA_T4TNFCEE_STATE_DISABLED) {
141 nfa_t4tnfcee_cb.t4tnfcee_state = NFA_T4TNFCEE_STATE_TRY_ENABLE;
142 if ((p_data != nullptr) &&
143 (p_data->new_ee.ee_status != NFA_STATUS_OK)) {
144 nfa_t4tnfcee_cb.ndefEmulationSupport = true;
145 NFC_NfceeModeSet(defaultNdefNfcee, NFC_MODE_ACTIVATE);
146 }
147 }
148 break;
149 case NFA_EE_MODE_SET_EVT:
150 if ((p_data != nullptr) && (p_data->mode_set.status != NFA_STATUS_OK) &&
151 (nfa_t4tnfcee_cb.t4tnfcee_state >= NFA_T4TNFCEE_STATE_TRY_ENABLE)) {
152 nfa_t4tnfcee_cb.t4tnfcee_state = NFA_T4TNFCEE_STATE_DISABLED;
153 nfa_sys_cback_notify_enable_complete(NFA_ID_T4TNFCEE);
154 nfa_ee_report_disc_done(true);
155 } else {
156 nfa_ee_report_event(NULL, event, p_data);
157 }
158 break;
159 case NFA_EE_DISCOVER_REQ_EVT:
160 if (nfa_t4tnfcee_cb.t4tnfcee_state == NFA_T4TNFCEE_STATE_TRY_ENABLE) {
161 nfa_t4tnfcee_cb.t4tnfcee_state = NFA_T4TNFCEE_STATE_INITIALIZED;
162 nfa_sys_cback_notify_enable_complete(NFA_ID_T4TNFCEE);
163 nfa_ee_report_disc_done(true);
164 }
165 break;
166 case NFA_EE_CONNECT_EVT:
167 if ((nfa_t4tnfcee_cb.t4tnfcee_state == NFA_T4TNFCEE_STATE_INITIALIZED) ||
168 (nfa_t4tnfcee_cb.t4tnfcee_state == NFA_T4TNFCEE_STATE_DISCONNECTED)) {
169 if (NFC_STATUS_OK ==
170 NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, defaultNdefNfcee,
171 NFC_NFCEE_INTERFACE_APDU, nfa_t4tnfcee_conn_cback))
172 nfa_t4tnfcee_cb.t4tnfcee_state = NFA_T4TNFCEE_STATE_CONNECTED;
173 } else {
174 tNFC_CONN p_data;
175 p_data.status = NFC_STATUS_FAILED;
176 nfa_t4tnfcee_conn_cback(NCI_DEST_TYPE_T4T_NFCEE, NFC_ERROR_CEVT,
177 &p_data);
178 }
179 break;
180 default:
181 nfa_ee_report_event(NULL, event, p_data);
182 break;
183 }
184 return;
185 }
186
187 /*******************************************************************************
188 **
189 ** Function nfa_t4tnfcee_set_ee_cback
190 **
191 ** Description assign t4t callback to receive ee_events
192 **
193 ** Returns None
194 **
195 *******************************************************************************/
nfa_t4tnfcee_set_ee_cback(tNFA_EE_ECB * p_ecb)196 void nfa_t4tnfcee_set_ee_cback(tNFA_EE_ECB* p_ecb) {
197 p_ecb->p_ee_cback = nfa_t4tnfcee_info_cback;
198 return;
199 }
200
201 /*******************************************************************************
202 **
203 ** Function nfa_rw_evt_2_str
204 **
205 ** Description convert nfa_rw evt to string
206 **
207 *******************************************************************************/
nfa_t4tnfcee_evt_2_str(uint16_t event)208 static std::string nfa_t4tnfcee_evt_2_str(uint16_t event) {
209 switch (event) {
210 case NFA_RW_OP_REQUEST_EVT:
211 return "NFA_T4TNFCEE_OP_REQUEST_EVT";
212 default:
213 break;
214 }
215 return "Unknown";
216 }
217
218 /*******************************************************************************
219 **
220 ** Function nfa_t4tnfcee_sys_enable
221 **
222 ** Description Enable NFA HCI
223 **
224 ** Returns None
225 **
226 *******************************************************************************/
nfa_t4tnfcee_sys_enable(void)227 void nfa_t4tnfcee_sys_enable(void) {
228 LOG(DEBUG) << StringPrintf("nfa_t4tnfcee_sys_enable ()");
229 }
230
231 /*******************************************************************************
232 **
233 ** Function nfa_t4tnfcee_sys_disable
234 **
235 ** Description Clean up t4tnfcee sub-system
236 **
237 **
238 ** Returns void
239 **
240 *******************************************************************************/
nfa_t4tnfcee_sys_disable(void)241 void nfa_t4tnfcee_sys_disable(void) {
242 /* Free scratch buffer if any */
243 nfa_t4tnfcee_free_rx_buf();
244
245 /* Free pending command if any */
246 if (nfa_t4tnfcee_cb.p_pending_msg) {
247 GKI_freebuf(nfa_t4tnfcee_cb.p_pending_msg);
248 nfa_t4tnfcee_cb.p_pending_msg = NULL;
249 }
250
251 nfa_sys_deregister(NFA_ID_T4TNFCEE);
252 }
253
254 /*******************************************************************************
255 **
256 ** Function nfa_t4tnfcee_proc_disc_evt
257 **
258 ** Description Called by nfa_dm to handle Ndef Nfcee Requests
259 **
260 ** Returns NFA_STATUS_OK if success else Failed status
261 **
262 *******************************************************************************/
nfa_t4tnfcee_proc_disc_evt(tNFA_T4TNFCEE_OP event)263 tNFC_STATUS nfa_t4tnfcee_proc_disc_evt(tNFA_T4TNFCEE_OP event) {
264 LOG(DEBUG) << StringPrintf("%s Enter. Event = %d ", __func__, (int)event);
265 tNFC_STATUS status = NFC_STATUS_FAILED;
266
267 switch (event) {
268 case NFA_T4TNFCEE_OP_OPEN_CONNECTION:
269 nfa_t4tnfcee_info_cback(NFA_EE_CONNECT_EVT, nullptr);
270 break;
271 case NFA_T4TNFCEE_OP_CLOSE_CONNECTION:
272 if (nfa_t4tnfcee_cb.t4tnfcee_state == NFA_T4TNFCEE_STATE_CONNECTED) {
273 NFC_SetStaticT4tNfceeCback(nfa_t4tnfcee_conn_cback,
274 nfa_t4tnfcee_cb.connId);
275 if (NFC_STATUS_OK != NFC_ConnClose(nfa_t4tnfcee_cb.connId)) {
276 tNFC_CONN p_data;
277 p_data.status = NFC_STATUS_FAILED;
278 nfa_t4tnfcee_conn_cback(nfa_t4tnfcee_cb.connId, NFC_ERROR_CEVT,
279 &p_data);
280 }
281 }
282 break;
283 }
284 return status;
285 }
286
287 /*******************************************************************************
288 **
289 ** Function nfa_t4tnfcee_handle_event
290 **
291 ** Description nfa t4tnfcee main event handling function.
292 **
293 ** Returns true if caller should free p_msg buffer
294 **
295 *******************************************************************************/
nfa_t4tnfcee_handle_event(NFC_HDR * p_msg)296 bool nfa_t4tnfcee_handle_event(NFC_HDR* p_msg) {
297 uint16_t act_idx;
298
299 LOG(DEBUG) << StringPrintf("nfa_t4tnfcee_handle_event event: %s (0x%02x)",
300 nfa_t4tnfcee_evt_2_str(p_msg->event).c_str(),
301 p_msg->event);
302
303 /* Get NFA_T4TNFCEE sub-event */
304 if ((act_idx = (p_msg->event & 0x00FF)) < (NFA_T4TNFCEE_MAX_EVT & 0xFF)) {
305 return (*nfa_t4tnfcee_action_tbl[act_idx])((tNFA_T4TNFCEE_MSG*)p_msg);
306 } else {
307 LOG(DEBUG) << StringPrintf(
308 "nfa_t4tnfcee_handle_event: unhandled event 0x%02X", p_msg->event);
309 return true;
310 }
311 }
312
313 /*******************************************************************************
314 **
315 ** Function nfa_t4tnfcee_is_enabled
316 **
317 ** Description T4T is enabled and initialized.
318 **
319 ** Returns true if T4T Nfcee is enabled initialization
320 **
321 *******************************************************************************/
nfa_t4tnfcee_is_enabled(void)322 bool nfa_t4tnfcee_is_enabled(void) {
323 return (nfa_t4tnfcee_cb.t4tnfcee_state >= NFA_T4TNFCEE_STATE_INITIALIZED);
324 }
325
326 /*******************************************************************************
327 **
328 ** Function NFA_T4tNfcEeIsProcessing
329 **
330 ** Description Indicates if T4tNfcee Read or write under process
331 **
332 ** Returns true if under process else false
333 **
334 *******************************************************************************/
NFA_T4tNfcEeIsProcessing(void)335 bool NFA_T4tNfcEeIsProcessing(void) {
336 return (nfa_t4tnfcee_cb.t4tnfcee_state == NFA_T4TNFCEE_STATE_CONNECTED);
337 }
338
339 /*******************************************************************************
340 **
341 ** Function NFA_T4tNfcEeIsEmulationSupported
342 **
343 ** Description Indicates if T4t NDEF Nfcee emulation is supported or not
344 **
345 ** Returns true if supported else false
346 **
347 *******************************************************************************/
NFA_T4tNfcEeIsEmulationSupported(void)348 bool NFA_T4tNfcEeIsEmulationSupported(void) {
349 return nfa_t4tnfcee_cb.ndefEmulationSupport;
350 }
351