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, len, 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 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 break;
192
193 case NCI_MSG_RF_DISCOVER_MAP:
194 nfc_ncif_rf_management_status(NFC_MAP_DEVT, *pp);
195 break;
196
197 case NCI_MSG_RF_DEACTIVATE:
198 if (nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_RSP) == false) {
199 return;
200 }
201 nfc_ncif_proc_deactivate(*pp, *p_old, false);
202 break;
203
204 #if (NFC_NFCEE_INCLUDED == TRUE)
205 #if (NFC_RW_ONLY == FALSE)
206
207 case NCI_MSG_RF_SET_ROUTING:
208 nfc_ncif_event_status(NFC_SET_ROUTING_REVT, *pp);
209 break;
210
211 case NCI_MSG_RF_GET_ROUTING:
212 if (*pp != NFC_STATUS_OK)
213 nfc_ncif_event_status(NFC_GET_ROUTING_REVT, *pp);
214 break;
215 #endif
216 #endif
217
218 case NCI_MSG_RF_PARAMETER_UPDATE:
219 nfc_ncif_event_status(NFC_RF_COMM_PARAMS_UPDATE_REVT, *pp);
220 break;
221
222 case NCI_MSG_RF_ISO_DEP_NAK_PRESENCE:
223 nfc_ncif_proc_isodep_nak_presence_check_status(*pp, false);
224 break;
225 default:
226 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
227 break;
228 }
229 }
230
231 /*******************************************************************************
232 **
233 ** Function nci_proc_rf_management_ntf
234 **
235 ** Description Process NCI notifications in the RF Management group
236 **
237 ** Returns void
238 **
239 *******************************************************************************/
nci_proc_rf_management_ntf(NFC_HDR * p_msg)240 void nci_proc_rf_management_ntf(NFC_HDR* p_msg) {
241 uint8_t* p;
242 uint8_t *pp, len, op_code;
243
244 /* find the start of the NCI message and parse the NCI header */
245 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
246 pp = p + 1;
247 NCI_MSG_PRS_HDR1(pp, op_code);
248 len = *pp++;
249
250 switch (op_code) {
251 case NCI_MSG_RF_DISCOVER:
252 nfc_ncif_proc_discover_ntf(p, p_msg->len);
253 break;
254
255 case NCI_MSG_RF_DEACTIVATE:
256 if (p_msg->len < 5) {
257 /* NCI_HEADER(3) + Deactivation Type(1) + Deactivation Reason(1) */
258 android_errorWriteLog(0x534e4554, "164440989");
259 return;
260 }
261 if (nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_NTF) == false) {
262 return;
263 }
264 if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
265 nfc_cb.deact_reason = *(pp + 1);
266 }
267 nfc_ncif_proc_deactivate(NFC_STATUS_OK, *pp, true);
268 break;
269
270 case NCI_MSG_RF_INTF_ACTIVATED:
271 if (nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_NTF) == false) {
272 return;
273 }
274 nfc_ncif_proc_activate(pp, len);
275 break;
276
277 case NCI_MSG_RF_FIELD:
278 if (p_msg->len < 4) {
279 android_errorWriteLog(0x534e4554, "176582502");
280 return;
281 }
282 nfc_ncif_proc_rf_field_ntf(*pp);
283 break;
284
285 case NCI_MSG_RF_T3T_POLLING:
286 nfc_ncif_proc_t3t_polling_ntf(pp, len);
287 break;
288
289 #if (NFC_NFCEE_INCLUDED == TRUE)
290 #if (NFC_RW_ONLY == FALSE)
291
292 case NCI_MSG_RF_GET_ROUTING:
293 nfc_ncif_proc_get_routing(pp, len);
294 break;
295
296 case NCI_MSG_RF_EE_ACTION:
297 nfc_ncif_proc_ee_action(pp, len);
298 break;
299
300 case NCI_MSG_RF_EE_DISCOVERY_REQ:
301 nfc_ncif_proc_ee_discover_req(pp, len);
302 break;
303 #endif
304 #endif
305 case NCI_MSG_RF_ISO_DEP_NAK_PRESENCE:
306 if (p_msg->len < 4) {
307 android_errorWriteLog(0x534e4554, "176582502");
308 return;
309 }
310 nfc_ncif_proc_isodep_nak_presence_check_status(*pp, true);
311 break;
312 default:
313 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
314 break;
315 }
316 }
317
318 #if (NFC_NFCEE_INCLUDED == TRUE)
319 #if (NFC_RW_ONLY == FALSE)
320
321 /*******************************************************************************
322 **
323 ** Function nci_proc_ee_management_rsp
324 **
325 ** Description Process NCI responses in the NFCEE Management group
326 **
327 ** Returns void
328 **
329 *******************************************************************************/
nci_proc_ee_management_rsp(NFC_HDR * p_msg)330 void nci_proc_ee_management_rsp(NFC_HDR* p_msg) {
331 uint8_t* p;
332 uint8_t *pp, len, op_code;
333 tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
334 tNFC_RESPONSE nfc_response;
335 tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
336 uint8_t* p_old = nfc_cb.last_cmd;
337
338 /* find the start of the NCI message and parse the NCI header */
339 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
340 pp = p + 1;
341 NCI_MSG_PRS_HDR1(pp, op_code);
342 DLOG_IF(INFO, nfc_debug_enabled)
343 << StringPrintf("nci_proc_ee_management_rsp opcode:0x%x", op_code);
344 len = p_msg->len - NCI_MSG_HDR_SIZE;
345 /* Use pmsg->len in boundary checks, skip *pp */
346 pp++;
347
348 switch (op_code) {
349 case NCI_MSG_NFCEE_DISCOVER:
350 if (len > 1) {
351 nfc_response.nfcee_discover.status = *pp++;
352 nfc_response.nfcee_discover.num_nfcee = *pp++;
353 } else {
354 nfc_response.nfcee_discover.status = NFC_STATUS_FAILED;
355 }
356 if (nfc_response.nfcee_discover.status != NFC_STATUS_OK)
357 nfc_response.nfcee_discover.num_nfcee = 0;
358
359 event = NFC_NFCEE_DISCOVER_REVT;
360 break;
361
362 case NCI_MSG_NFCEE_MODE_SET:
363 if (len > 0) {
364 nfc_response.mode_set.status = *pp;
365 } else {
366 nfc_response.mode_set.status = NFC_STATUS_FAILED;
367 android_errorWriteLog(0x534e4554, "176203800");
368 return;
369 }
370 nfc_response.mode_set.nfcee_id = *p_old++;
371 nfc_response.mode_set.mode = *p_old++;
372 if (nfc_cb.nci_version != NCI_VERSION_2_0 || *pp != NCI_STATUS_OK) {
373 nfc_cb.flags &= ~NFC_FL_WAIT_MODE_SET_NTF;
374 event = NFC_NFCEE_MODE_SET_REVT;
375 } else {
376 /* else response reports OK status on notification */
377 return;
378 }
379 break;
380
381 case NCI_MSG_NFCEE_POWER_LINK_CTRL:
382 if (len > 0) {
383 nfc_response.pl_control.status = *pp;
384 } else {
385 nfc_response.pl_control.status = NFC_STATUS_FAILED;
386 }
387 nfc_response.pl_control.nfcee_id = *p_old++;
388 nfc_response.pl_control.pl_control = *p_old++;
389 event = NFC_NFCEE_PL_CONTROL_REVT;
390 break;
391 default:
392 p_cback = nullptr;
393 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
394 break;
395 }
396
397 if (p_cback) (*p_cback)(event, &nfc_response);
398 }
399
400 /*******************************************************************************
401 **
402 ** Function nci_proc_ee_management_ntf
403 **
404 ** Description Process NCI notifications in the NFCEE Management group
405 **
406 ** Returns void
407 **
408 *******************************************************************************/
nci_proc_ee_management_ntf(NFC_HDR * p_msg)409 void nci_proc_ee_management_ntf(NFC_HDR* p_msg) {
410 uint8_t* p;
411 uint8_t *pp, len, op_code;
412 tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
413 tNFC_RESPONSE nfc_response;
414 tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
415 uint8_t* p_old = nfc_cb.last_cmd;
416 uint8_t xx;
417 uint8_t yy;
418 tNFC_NFCEE_TLV* p_tlv;
419 /* find the start of the NCI message and parse the NCI header */
420 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
421 pp = p + 1;
422 NCI_MSG_PRS_HDR1(pp, op_code);
423 DLOG_IF(INFO, nfc_debug_enabled)
424 << StringPrintf("nci_proc_ee_management_ntf opcode:0x%x", op_code);
425 len = *pp++;
426
427 switch (op_code) {
428 case NCI_MSG_NFCEE_DISCOVER:
429 if (len < 3) {
430 p_cback = nullptr;
431 break;
432 } else {
433 len -= 3;
434 }
435 nfc_response.nfcee_info.nfcee_id = *pp++;
436
437 nfc_response.nfcee_info.ee_status = *pp++;
438 yy = *pp;
439 nfc_response.nfcee_info.num_interface = *pp++;
440 if (len < yy + 1) {
441 p_cback = nullptr;
442 break;
443 } else {
444 len -= yy + 1;
445 }
446 p = pp;
447
448 if (nfc_response.nfcee_info.num_interface > NFC_MAX_EE_INTERFACE)
449 nfc_response.nfcee_info.num_interface = NFC_MAX_EE_INTERFACE;
450
451 for (xx = 0; xx < nfc_response.nfcee_info.num_interface; xx++) {
452 nfc_response.nfcee_info.ee_interface[xx] = *pp++;
453 }
454
455 pp = p + yy;
456 nfc_response.nfcee_info.num_tlvs = *pp++;
457 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
458 "nfcee_id: 0x%x num_interface:0x%x/0x%x, num_tlvs:0x%x",
459 nfc_response.nfcee_info.nfcee_id,
460 nfc_response.nfcee_info.num_interface, yy,
461 nfc_response.nfcee_info.num_tlvs);
462
463 if (nfc_response.nfcee_info.num_tlvs > 0 && len < 2) {
464 p_cback = nullptr;
465 break;
466 }
467 if (nfc_response.nfcee_info.num_tlvs > NFC_MAX_EE_TLVS)
468 nfc_response.nfcee_info.num_tlvs = NFC_MAX_EE_TLVS;
469
470 p_tlv = &nfc_response.nfcee_info.ee_tlv[0];
471
472 for (xx = 0; xx < nfc_response.nfcee_info.num_tlvs; xx++, p_tlv++) {
473 p_tlv->tag = *pp++;
474 p_tlv->len = yy = *pp++;
475 if (len < yy + 2) {
476 p_cback = nullptr;
477 break;
478 } else {
479 len -= yy + 2;
480 }
481 DLOG_IF(INFO, nfc_debug_enabled)
482 << StringPrintf("tag:0x%x, len:0x%x", p_tlv->tag, p_tlv->len);
483 if (p_tlv->len > NFC_MAX_EE_INFO) p_tlv->len = NFC_MAX_EE_INFO;
484 STREAM_TO_ARRAY(p_tlv->info, pp, p_tlv->len);
485 }
486 break;
487 case NCI_MSG_NFCEE_MODE_SET:
488 if (len < 1) {
489 nfc_response.mode_set.status = NCI_STATUS_MESSAGE_CORRUPTED;
490 } else {
491 nfc_response.mode_set.status = *pp;
492 }
493 nfc_response.mode_set.nfcee_id = *p_old++;
494 nfc_response.mode_set.mode = *p_old++;
495 event = NFC_NFCEE_MODE_SET_REVT;
496 nfc_cb.flags &= ~NFC_FL_WAIT_MODE_SET_NTF;
497 nfc_stop_timer(&nfc_cb.nci_mode_set_ntf_timer);
498 break;
499 case NCI_MSG_NFCEE_STATUS:
500 event = NFC_NFCEE_STATUS_REVT;
501 if (len < 2) {
502 nfc_response.nfcee_status.status = NCI_STATUS_MESSAGE_CORRUPTED;
503 break;
504 }
505 nfc_response.nfcee_status.status = NCI_STATUS_OK;
506 nfc_response.nfcee_status.nfcee_id = *pp++;
507 nfc_response.nfcee_status.nfcee_status = *pp;
508 break;
509 default:
510 p_cback = nullptr;
511 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
512 }
513
514 if (p_cback) (*p_cback)(event, &nfc_response);
515 }
516
517 #endif
518 #endif
519
520 /*******************************************************************************
521 **
522 ** Function nci_proc_prop_rsp
523 **
524 ** Description Process NCI responses in the Proprietary group
525 **
526 ** Returns void
527 **
528 *******************************************************************************/
nci_proc_prop_rsp(NFC_HDR * p_msg)529 void nci_proc_prop_rsp(NFC_HDR* p_msg) {
530 uint8_t* p;
531 uint8_t* p_evt;
532 uint8_t *pp, len, op_code;
533 tNFC_VS_CBACK* p_cback = (tNFC_VS_CBACK*)nfc_cb.p_vsc_cback;
534
535 /* find the start of the NCI message and parse the NCI header */
536 p = p_evt = (uint8_t*)(p_msg + 1) + p_msg->offset;
537 pp = p + 1;
538 NCI_MSG_PRS_HDR1(pp, op_code);
539 len = *pp++;
540
541 /*If there's a pending/stored command, restore the associated address of the
542 * callback function */
543 if (p_cback)
544 (*p_cback)((tNFC_VS_EVT)(NCI_RSP_BIT | op_code), p_msg->len, p_evt);
545 }
546
547 /*******************************************************************************
548 **
549 ** Function nci_proc_prop_raw_vs_rsp
550 **
551 ** Description Process RAW VS responses
552 **
553 ** Returns void
554 **
555 *******************************************************************************/
nci_proc_prop_raw_vs_rsp(NFC_HDR * p_msg)556 void nci_proc_prop_raw_vs_rsp(NFC_HDR* p_msg) {
557 uint8_t op_code;
558 tNFC_VS_CBACK* p_cback = (tNFC_VS_CBACK*)nfc_cb.p_vsc_cback;
559
560 /* find the start of the NCI message and parse the NCI header */
561 uint8_t* p_evt = (uint8_t*)(p_msg + 1) + p_msg->offset;
562 uint8_t* p = p_evt + 1;
563 NCI_MSG_PRS_HDR1(p, op_code);
564
565 /* If there's a pending/stored command, restore the associated address of the
566 * callback function */
567 if (p_cback) {
568 (*p_cback)((tNFC_VS_EVT)(NCI_RSP_BIT | op_code), p_msg->len, p_evt);
569 nfc_cb.p_vsc_cback = nullptr;
570 }
571 nfc_cb.rawVsCbflag = false;
572 nfc_ncif_update_window();
573 }
574
575 /*******************************************************************************
576 **
577 ** Function nci_proc_prop_ntf
578 **
579 ** Description Process NCI notifications in the Proprietary group
580 **
581 ** Returns void
582 **
583 *******************************************************************************/
nci_proc_prop_ntf(NFC_HDR * p_msg)584 void nci_proc_prop_ntf(NFC_HDR* p_msg) {
585 uint8_t* p;
586 uint8_t* p_evt;
587 uint8_t *pp, len, op_code;
588 int i;
589
590 /* find the start of the NCI message and parse the NCI header */
591 p = p_evt = (uint8_t*)(p_msg + 1) + p_msg->offset;
592 pp = p + 1;
593 NCI_MSG_PRS_HDR1(pp, op_code);
594 len = *pp++;
595
596 for (i = 0; i < NFC_NUM_VS_CBACKS; i++) {
597 if (nfc_cb.p_vs_cb[i]) {
598 (*nfc_cb.p_vs_cb[i])((tNFC_VS_EVT)(NCI_NTF_BIT | op_code), p_msg->len,
599 p_evt);
600 }
601 }
602 }
603