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