1 /******************************************************************************
2 *
3 * Copyright (C) 2010-2014 Broadcom Corporation
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
19 /******************************************************************************
20 *
21 * This file contains function of the NFC unit to receive/process NCI
22 * commands.
23 *
24 ******************************************************************************/
25 #include <string.h>
26
27 #include <android-base/stringprintf.h>
28 #include <base/logging.h>
29
30 #include "nfc_target.h"
31
32 #include "bt_types.h"
33 #include "gki.h"
34 #include "nci_defs.h"
35 #include "nci_hmsgs.h"
36 #include "nfc_api.h"
37 #include "nfc_int.h"
38
39 using android::base::StringPrintf;
40
41 extern bool nfc_debug_enabled;
42
43 /*******************************************************************************
44 **
45 ** Function nci_proc_core_rsp
46 **
47 ** Description Process NCI responses in the CORE group
48 **
49 ** Returns TRUE-caller of this function to free the GKI buffer p_msg
50 **
51 *******************************************************************************/
nci_proc_core_rsp(NFC_HDR * p_msg)52 bool nci_proc_core_rsp(NFC_HDR* p_msg) {
53 uint8_t* p;
54 uint8_t *pp, len, op_code;
55 bool free = true;
56 uint8_t* p_old = nfc_cb.last_cmd;
57
58 /* find the start of the NCI message and parse the NCI header */
59 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
60 pp = p + 1;
61 NCI_MSG_PRS_HDR1(pp, op_code);
62 DLOG_IF(INFO, nfc_debug_enabled)
63 << StringPrintf("nci_proc_core_rsp opcode:0x%x", op_code);
64 len = *pp++;
65
66 /* process the message based on the opcode and message type */
67 switch (op_code) {
68 case NCI_MSG_CORE_RESET:
69 nfc_ncif_proc_reset_rsp(pp, false);
70 break;
71
72 case NCI_MSG_CORE_INIT:
73 nfc_ncif_proc_init_rsp(p_msg);
74 free = false;
75 break;
76
77 case NCI_MSG_CORE_GET_CONFIG:
78 nfc_ncif_proc_get_config_rsp(p_msg);
79 break;
80
81 case NCI_MSG_CORE_SET_CONFIG:
82 nfc_ncif_set_config_status(pp, len);
83 break;
84
85 case NCI_MSG_CORE_CONN_CREATE:
86 nfc_ncif_proc_conn_create_rsp(p, p_msg->len, *p_old);
87 break;
88
89 case NCI_MSG_CORE_CONN_CLOSE:
90 nfc_ncif_report_conn_close_evt(*p_old, *pp);
91 break;
92 case NCI_MSG_CORE_SET_POWER_SUB_STATE:
93 nfc_ncif_event_status(NFC_SET_POWER_SUB_STATE_REVT, *pp);
94 break;
95 default:
96 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
97 break;
98 }
99
100 return free;
101 }
102
103 /*******************************************************************************
104 **
105 ** Function nci_proc_core_ntf
106 **
107 ** Description Process NCI notifications in the CORE group
108 **
109 ** Returns void
110 **
111 *******************************************************************************/
nci_proc_core_ntf(NFC_HDR * p_msg)112 void nci_proc_core_ntf(NFC_HDR* p_msg) {
113 uint8_t* p;
114 uint8_t *pp, len, op_code;
115 uint8_t conn_id;
116
117 /* find the start of the NCI message and parse the NCI header */
118 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
119 len = p_msg->len;
120 pp = p + 1;
121
122 if (len == 0) {
123 LOG(ERROR) << __func__ << ": Invalid packet length";
124 return;
125 }
126 NCI_MSG_PRS_HDR1(pp, op_code);
127 DLOG_IF(INFO, nfc_debug_enabled)
128 << StringPrintf("nci_proc_core_ntf opcode:0x%x", op_code);
129 pp++;
130 len--;
131 /* process the message based on the opcode and message type */
132 switch (op_code) {
133 case NCI_MSG_CORE_RESET:
134 nfc_ncif_proc_reset_rsp(pp, true);
135 break;
136
137 case NCI_MSG_CORE_GEN_ERR_STATUS:
138 /* process the error ntf */
139 /* in case of timeout: notify the static connection callback */
140 nfc_ncif_event_status(NFC_GEN_ERROR_REVT, *pp);
141 nfc_ncif_error_status(NFC_RF_CONN_ID, *pp);
142 break;
143
144 case NCI_MSG_CORE_INTF_ERR_STATUS:
145 conn_id = *(pp + 1);
146 nfc_ncif_error_status(conn_id, *pp);
147 break;
148
149 case NCI_MSG_CORE_CONN_CREDITS:
150 nfc_ncif_proc_credits(pp, len);
151 break;
152
153 default:
154 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
155 break;
156 }
157 }
158
159 /*******************************************************************************
160 **
161 ** Function nci_proc_rf_management_rsp
162 **
163 ** Description Process NCI responses in the RF Management group
164 **
165 ** Returns void
166 **
167 *******************************************************************************/
nci_proc_rf_management_rsp(NFC_HDR * p_msg)168 void nci_proc_rf_management_rsp(NFC_HDR* p_msg) {
169 uint8_t* p;
170 uint8_t *pp, len, op_code;
171 uint8_t* p_old = nfc_cb.last_cmd;
172
173 /* find the start of the NCI message and parse the NCI header */
174 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
175 pp = p + 1;
176 NCI_MSG_PRS_HDR1(pp, op_code);
177 len = *pp++;
178
179 switch (op_code) {
180 case NCI_MSG_RF_DISCOVER:
181 nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_RSP);
182 nfc_ncif_rf_management_status(NFC_START_DEVT, *pp);
183 break;
184
185 case NCI_MSG_RF_DISCOVER_SELECT:
186 nfc_ncif_rf_management_status(NFC_SELECT_DEVT, *pp);
187 break;
188
189 case NCI_MSG_RF_T3T_POLLING:
190 break;
191
192 case NCI_MSG_RF_DISCOVER_MAP:
193 nfc_ncif_rf_management_status(NFC_MAP_DEVT, *pp);
194 break;
195
196 case NCI_MSG_RF_DEACTIVATE:
197 if (nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_RSP) == false) {
198 return;
199 }
200 nfc_ncif_proc_deactivate(*pp, *p_old, false);
201 break;
202
203 #if (NFC_NFCEE_INCLUDED == TRUE)
204 #if (NFC_RW_ONLY == FALSE)
205
206 case NCI_MSG_RF_SET_ROUTING:
207 nfc_ncif_event_status(NFC_SET_ROUTING_REVT, *pp);
208 break;
209
210 case NCI_MSG_RF_GET_ROUTING:
211 if (*pp != NFC_STATUS_OK)
212 nfc_ncif_event_status(NFC_GET_ROUTING_REVT, *pp);
213 break;
214 #endif
215 #endif
216
217 case NCI_MSG_RF_PARAMETER_UPDATE:
218 nfc_ncif_event_status(NFC_RF_COMM_PARAMS_UPDATE_REVT, *pp);
219 break;
220
221 case NCI_MSG_RF_ISO_DEP_NAK_PRESENCE:
222 nfc_ncif_proc_isodep_nak_presence_check_status(*pp, false);
223 break;
224 default:
225 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
226 break;
227 }
228 }
229
230 /*******************************************************************************
231 **
232 ** Function nci_proc_rf_management_ntf
233 **
234 ** Description Process NCI notifications in the RF Management group
235 **
236 ** Returns void
237 **
238 *******************************************************************************/
nci_proc_rf_management_ntf(NFC_HDR * p_msg)239 void nci_proc_rf_management_ntf(NFC_HDR* p_msg) {
240 uint8_t* p;
241 uint8_t *pp, len, op_code;
242
243 /* find the start of the NCI message and parse the NCI header */
244 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
245 pp = p + 1;
246 NCI_MSG_PRS_HDR1(pp, op_code);
247 len = *pp++;
248
249 switch (op_code) {
250 case NCI_MSG_RF_DISCOVER:
251 nfc_ncif_proc_discover_ntf(p, p_msg->len);
252 break;
253
254 case NCI_MSG_RF_DEACTIVATE:
255 if (nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_NTF) == false) {
256 return;
257 }
258 if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
259 nfc_cb.deact_reason = *(pp + 1);
260 }
261 nfc_ncif_proc_deactivate(NFC_STATUS_OK, *pp, true);
262 break;
263
264 case NCI_MSG_RF_INTF_ACTIVATED:
265 if (nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_NTF) == false) {
266 return;
267 }
268 nfc_ncif_proc_activate(pp, len);
269 break;
270
271 case NCI_MSG_RF_FIELD:
272 nfc_ncif_proc_rf_field_ntf(*pp);
273 break;
274
275 case NCI_MSG_RF_T3T_POLLING:
276 nfc_ncif_proc_t3t_polling_ntf(pp, len);
277 break;
278
279 #if (NFC_NFCEE_INCLUDED == TRUE)
280 #if (NFC_RW_ONLY == FALSE)
281
282 case NCI_MSG_RF_GET_ROUTING:
283 nfc_ncif_proc_get_routing(pp, len);
284 break;
285
286 case NCI_MSG_RF_EE_ACTION:
287 nfc_ncif_proc_ee_action(pp, len);
288 break;
289
290 case NCI_MSG_RF_EE_DISCOVERY_REQ:
291 nfc_ncif_proc_ee_discover_req(pp, len);
292 break;
293 #endif
294 #endif
295 case NCI_MSG_RF_ISO_DEP_NAK_PRESENCE:
296 nfc_ncif_proc_isodep_nak_presence_check_status(*pp, true);
297 break;
298 default:
299 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
300 break;
301 }
302 }
303
304 #if (NFC_NFCEE_INCLUDED == TRUE)
305 #if (NFC_RW_ONLY == FALSE)
306
307 /*******************************************************************************
308 **
309 ** Function nci_proc_ee_management_rsp
310 **
311 ** Description Process NCI responses in the NFCEE Management group
312 **
313 ** Returns void
314 **
315 *******************************************************************************/
nci_proc_ee_management_rsp(NFC_HDR * p_msg)316 void nci_proc_ee_management_rsp(NFC_HDR* p_msg) {
317 uint8_t* p;
318 uint8_t *pp, len, op_code;
319 tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
320 tNFC_RESPONSE nfc_response;
321 tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
322 uint8_t* p_old = nfc_cb.last_cmd;
323
324 /* find the start of the NCI message and parse the NCI header */
325 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
326 pp = p + 1;
327 NCI_MSG_PRS_HDR1(pp, op_code);
328 DLOG_IF(INFO, nfc_debug_enabled)
329 << StringPrintf("nci_proc_ee_management_rsp opcode:0x%x", op_code);
330 len = *pp++;
331
332 switch (op_code) {
333 case NCI_MSG_NFCEE_DISCOVER:
334 nfc_response.nfcee_discover.status = *pp++;
335 nfc_response.nfcee_discover.num_nfcee = *pp++;
336
337 if (nfc_response.nfcee_discover.status != NFC_STATUS_OK)
338 nfc_response.nfcee_discover.num_nfcee = 0;
339
340 event = NFC_NFCEE_DISCOVER_REVT;
341 break;
342
343 case NCI_MSG_NFCEE_MODE_SET:
344 nfc_response.mode_set.status = *pp;
345 nfc_response.mode_set.nfcee_id = *p_old++;
346 nfc_response.mode_set.mode = *p_old++;
347 if (nfc_cb.nci_version != NCI_VERSION_2_0 || *pp != NCI_STATUS_OK) {
348 nfc_cb.flags &= ~NFC_FL_WAIT_MODE_SET_NTF;
349 event = NFC_NFCEE_MODE_SET_REVT;
350 } else {
351 /* else response reports OK status on notification */
352 return;
353 }
354 break;
355
356 case NCI_MSG_NFCEE_POWER_LINK_CTRL:
357 nfc_response.pl_control.status = *pp;
358 nfc_response.pl_control.nfcee_id = *p_old++;
359 nfc_response.pl_control.pl_control = *p_old++;
360 event = NFC_NFCEE_PL_CONTROL_REVT;
361 break;
362 default:
363 p_cback = nullptr;
364 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
365 break;
366 }
367
368 if (p_cback) (*p_cback)(event, &nfc_response);
369 }
370
371 /*******************************************************************************
372 **
373 ** Function nci_proc_ee_management_ntf
374 **
375 ** Description Process NCI notifications in the NFCEE Management group
376 **
377 ** Returns void
378 **
379 *******************************************************************************/
nci_proc_ee_management_ntf(NFC_HDR * p_msg)380 void nci_proc_ee_management_ntf(NFC_HDR* p_msg) {
381 uint8_t* p;
382 uint8_t *pp, len, op_code;
383 tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
384 tNFC_RESPONSE nfc_response;
385 tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
386 uint8_t* p_old = nfc_cb.last_cmd;
387 uint8_t xx;
388 uint8_t yy;
389 tNFC_NFCEE_TLV* p_tlv;
390 /* find the start of the NCI message and parse the NCI header */
391 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
392 pp = p + 1;
393 NCI_MSG_PRS_HDR1(pp, op_code);
394 DLOG_IF(INFO, nfc_debug_enabled)
395 << StringPrintf("nci_proc_ee_management_ntf opcode:0x%x", op_code);
396 len = *pp++;
397
398 if (op_code == NCI_MSG_NFCEE_DISCOVER) {
399 nfc_response.nfcee_info.nfcee_id = *pp++;
400
401 nfc_response.nfcee_info.ee_status = *pp++;
402 yy = *pp;
403 nfc_response.nfcee_info.num_interface = *pp++;
404 p = pp;
405
406 if (nfc_response.nfcee_info.num_interface > NFC_MAX_EE_INTERFACE)
407 nfc_response.nfcee_info.num_interface = NFC_MAX_EE_INTERFACE;
408
409 for (xx = 0; xx < nfc_response.nfcee_info.num_interface; xx++) {
410 nfc_response.nfcee_info.ee_interface[xx] = *pp++;
411 }
412
413 pp = p + yy;
414 nfc_response.nfcee_info.num_tlvs = *pp++;
415 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
416 "nfcee_id: 0x%x num_interface:0x%x/0x%x, num_tlvs:0x%x",
417 nfc_response.nfcee_info.nfcee_id, nfc_response.nfcee_info.num_interface,
418 yy, nfc_response.nfcee_info.num_tlvs);
419
420 if (nfc_response.nfcee_info.num_tlvs > NFC_MAX_EE_TLVS)
421 nfc_response.nfcee_info.num_tlvs = NFC_MAX_EE_TLVS;
422
423 p_tlv = &nfc_response.nfcee_info.ee_tlv[0];
424
425 for (xx = 0; xx < nfc_response.nfcee_info.num_tlvs; xx++, p_tlv++) {
426 p_tlv->tag = *pp++;
427 p_tlv->len = yy = *pp++;
428 DLOG_IF(INFO, nfc_debug_enabled)
429 << StringPrintf("tag:0x%x, len:0x%x", p_tlv->tag, p_tlv->len);
430 if (p_tlv->len > NFC_MAX_EE_INFO) p_tlv->len = NFC_MAX_EE_INFO;
431 STREAM_TO_ARRAY(p_tlv->info, pp, p_tlv->len);
432 }
433 } else if (op_code == NCI_MSG_NFCEE_MODE_SET) {
434 nfc_response.mode_set.status = *pp;
435 nfc_response.mode_set.nfcee_id = *p_old++;
436 nfc_response.mode_set.mode = *p_old++;
437 event = NFC_NFCEE_MODE_SET_REVT;
438 nfc_cb.flags &= ~NFC_FL_WAIT_MODE_SET_NTF;
439 nfc_stop_timer(&nfc_cb.nci_mode_set_ntf_timer);
440 } else if (op_code == NCI_MSG_NFCEE_STATUS) {
441 event = NFC_NFCEE_STATUS_REVT;
442 nfc_response.nfcee_status.status = NCI_STATUS_OK;
443 nfc_response.nfcee_status.nfcee_id = *pp++;
444 nfc_response.nfcee_status.nfcee_status = *pp;
445 } else {
446 p_cback = nullptr;
447 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
448 }
449
450 if (p_cback) (*p_cback)(event, &nfc_response);
451 }
452
453 #endif
454 #endif
455
456 /*******************************************************************************
457 **
458 ** Function nci_proc_prop_rsp
459 **
460 ** Description Process NCI responses in the Proprietary group
461 **
462 ** Returns void
463 **
464 *******************************************************************************/
nci_proc_prop_rsp(NFC_HDR * p_msg)465 void nci_proc_prop_rsp(NFC_HDR* p_msg) {
466 uint8_t* p;
467 uint8_t* p_evt;
468 uint8_t *pp, len, op_code;
469 tNFC_VS_CBACK* p_cback = (tNFC_VS_CBACK*)nfc_cb.p_vsc_cback;
470
471 /* find the start of the NCI message and parse the NCI header */
472 p = p_evt = (uint8_t*)(p_msg + 1) + p_msg->offset;
473 pp = p + 1;
474 NCI_MSG_PRS_HDR1(pp, op_code);
475 len = *pp++;
476
477 /*If there's a pending/stored command, restore the associated address of the
478 * callback function */
479 if (p_cback)
480 (*p_cback)((tNFC_VS_EVT)(NCI_RSP_BIT | op_code), p_msg->len, p_evt);
481 }
482
483 /*******************************************************************************
484 **
485 ** Function nci_proc_prop_raw_vs_rsp
486 **
487 ** Description Process RAW VS responses
488 **
489 ** Returns void
490 **
491 *******************************************************************************/
nci_proc_prop_raw_vs_rsp(NFC_HDR * p_msg)492 void nci_proc_prop_raw_vs_rsp(NFC_HDR* p_msg) {
493 uint8_t op_code;
494 tNFC_VS_CBACK* p_cback = (tNFC_VS_CBACK*)nfc_cb.p_vsc_cback;
495
496 /* find the start of the NCI message and parse the NCI header */
497 uint8_t* p_evt = (uint8_t*)(p_msg + 1) + p_msg->offset;
498 uint8_t* p = p_evt + 1;
499 NCI_MSG_PRS_HDR1(p, op_code);
500
501 /* If there's a pending/stored command, restore the associated address of the
502 * callback function */
503 if (p_cback) {
504 (*p_cback)((tNFC_VS_EVT)(NCI_RSP_BIT | op_code), p_msg->len, p_evt);
505 nfc_cb.p_vsc_cback = nullptr;
506 }
507 nfc_cb.rawVsCbflag = false;
508 nfc_ncif_update_window();
509 }
510
511 /*******************************************************************************
512 **
513 ** Function nci_proc_prop_ntf
514 **
515 ** Description Process NCI notifications in the Proprietary group
516 **
517 ** Returns void
518 **
519 *******************************************************************************/
nci_proc_prop_ntf(NFC_HDR * p_msg)520 void nci_proc_prop_ntf(NFC_HDR* p_msg) {
521 uint8_t* p;
522 uint8_t* p_evt;
523 uint8_t *pp, len, op_code;
524 int i;
525
526 /* find the start of the NCI message and parse the NCI header */
527 p = p_evt = (uint8_t*)(p_msg + 1) + p_msg->offset;
528 pp = p + 1;
529 NCI_MSG_PRS_HDR1(pp, op_code);
530 len = *pp++;
531
532 for (i = 0; i < NFC_NUM_VS_CBACKS; i++) {
533 if (nfc_cb.p_vs_cb[i]) {
534 (*nfc_cb.p_vs_cb[i])((tNFC_VS_EVT)(NCI_NTF_BIT | op_code), p_msg->len,
535 p_evt);
536 }
537 }
538 }
539