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