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