blob: fbba7e2f0eef3e66f7163b5a2fd1089996f009cd [file] [log] [blame]
nxf24591c1cbeab2018-02-21 17:32:26 +05301/******************************************************************************
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"
hariprasad nalacheruvu4668c152018-05-24 16:46:24 +053038#if (NXP_EXTNS == TRUE)
39#include "nfa_ee_int.h"
40#endif
nxf24591c1cbeab2018-02-21 17:32:26 +053041
42using android::base::StringPrintf;
43
44extern bool nfc_debug_enabled;
45
46/*******************************************************************************
47**
48** Function nci_proc_core_rsp
49**
50** Description Process NCI responses in the CORE group
51**
52** Returns TRUE-caller of this function to free the GKI buffer p_msg
53**
54*******************************************************************************/
55bool nci_proc_core_rsp(NFC_HDR* p_msg) {
56 uint8_t* p;
57 uint8_t *pp, len, op_code;
58 bool free = true;
59 uint8_t* p_old = nfc_cb.last_cmd;
60
61 /* find the start of the NCI message and parse the NCI header */
62 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
63 pp = p + 1;
64 NCI_MSG_PRS_HDR1(pp, op_code);
65 DLOG_IF(INFO, nfc_debug_enabled)
66 << StringPrintf("nci_proc_core_rsp opcode:0x%x", op_code);
67 len = *pp++;
68
69 /* process the message based on the opcode and message type */
70 switch (op_code) {
71 case NCI_MSG_CORE_RESET:
72 nfc_ncif_proc_reset_rsp(pp, false);
73 break;
74
75 case NCI_MSG_CORE_INIT:
76 nfc_ncif_proc_init_rsp(p_msg);
77 free = false;
78 break;
79
80 case NCI_MSG_CORE_GET_CONFIG:
81 nfc_ncif_proc_get_config_rsp(p_msg);
82 break;
83
84 case NCI_MSG_CORE_SET_CONFIG:
85 nfc_ncif_set_config_status(pp, len);
86 break;
87
88 case NCI_MSG_CORE_CONN_CREATE:
89 nfc_ncif_proc_conn_create_rsp(p, p_msg->len, *p_old);
90 break;
91
92 case NCI_MSG_CORE_CONN_CLOSE:
93 nfc_ncif_report_conn_close_evt(*p_old, *pp);
94 break;
95 case NCI_MSG_CORE_SET_POWER_SUB_STATE:
96 nfc_ncif_event_status(NFC_SET_POWER_SUB_STATE_REVT, *pp);
97 break;
98 default:
99 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
100 break;
101 }
102
103 return free;
104}
105
106/*******************************************************************************
107**
108** Function nci_proc_core_ntf
109**
110** Description Process NCI notifications in the CORE group
111**
112** Returns void
113**
114*******************************************************************************/
115void nci_proc_core_ntf(NFC_HDR* p_msg) {
116 uint8_t* p;
117 uint8_t *pp, len, op_code;
118 uint8_t conn_id;
119
120 /* find the start of the NCI message and parse the NCI header */
121 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
122 pp = p + 1;
123 NCI_MSG_PRS_HDR1(pp, op_code);
124 DLOG_IF(INFO, nfc_debug_enabled)
125 << StringPrintf("nci_proc_core_ntf opcode:0x%x", op_code);
126 len = *pp++;
127
128 /* process the message based on the opcode and message type */
129 switch (op_code) {
130 case NCI_MSG_CORE_RESET:
131 nfc_ncif_proc_reset_rsp(pp, true);
132 break;
133
134 case NCI_MSG_CORE_GEN_ERR_STATUS:
135 /* process the error ntf */
136 /* in case of timeout: notify the static connection callback */
137 nfc_ncif_event_status(NFC_GEN_ERROR_REVT, *pp);
138 nfc_ncif_error_status(NFC_RF_CONN_ID, *pp);
139 break;
140
141 case NCI_MSG_CORE_INTF_ERR_STATUS:
142 conn_id = *(pp + 1);
143 nfc_ncif_error_status(conn_id, *pp);
144 break;
145
146 case NCI_MSG_CORE_CONN_CREDITS:
147 nfc_ncif_proc_credits(pp, len);
148 break;
149
150 default:
151 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
152 break;
153 }
154}
155
156/*******************************************************************************
157**
158** Function nci_proc_rf_management_rsp
159**
160** Description Process NCI responses in the RF Management group
161**
162** Returns void
163**
164*******************************************************************************/
165void nci_proc_rf_management_rsp(NFC_HDR* p_msg) {
166 uint8_t* p;
167 uint8_t *pp, len, op_code;
168 uint8_t* p_old = nfc_cb.last_cmd;
169
170 /* find the start of the NCI message and parse the NCI header */
171 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
172 pp = p + 1;
173 NCI_MSG_PRS_HDR1(pp, op_code);
174 len = *pp++;
175
176 switch (op_code) {
177 case NCI_MSG_RF_DISCOVER:
178 nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_RSP);
179 nfc_ncif_rf_management_status(NFC_START_DEVT, *pp);
180 break;
181
182 case NCI_MSG_RF_DISCOVER_SELECT:
183 nfc_ncif_rf_management_status(NFC_SELECT_DEVT, *pp);
184 break;
185
186 case NCI_MSG_RF_T3T_POLLING:
187 break;
188
189 case NCI_MSG_RF_DISCOVER_MAP:
190 nfc_ncif_rf_management_status(NFC_MAP_DEVT, *pp);
191 break;
192
193 case NCI_MSG_RF_DEACTIVATE:
194 if (nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_RSP) == false) {
195 return;
196 }
197 nfc_ncif_proc_deactivate(*pp, *p_old, false);
198 break;
199
200#if (NFC_NFCEE_INCLUDED == TRUE)
201#if (NFC_RW_ONLY == FALSE)
202
203 case NCI_MSG_RF_SET_ROUTING:
204 nfc_ncif_event_status(NFC_SET_ROUTING_REVT, *pp);
205 break;
206
207 case NCI_MSG_RF_GET_ROUTING:
208 if (*pp != NFC_STATUS_OK)
209 nfc_ncif_event_status(NFC_GET_ROUTING_REVT, *pp);
210 break;
211#endif
212#endif
213
214 case NCI_MSG_RF_PARAMETER_UPDATE:
215 nfc_ncif_event_status(NFC_RF_COMM_PARAMS_UPDATE_REVT, *pp);
216 break;
217
218 case NCI_MSG_RF_ISO_DEP_NAK_PRESENCE:
219 nfc_ncif_proc_isodep_nak_presence_check_status(*pp, false);
220 break;
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*******************************************************************************/
236void 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 (nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_NTF) == false) {
253 return;
254 }
255 if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
256 nfc_cb.deact_reason = *(pp + 1);
257 }
258 nfc_ncif_proc_deactivate(NFC_STATUS_OK, *pp, true);
259 break;
260
261 case NCI_MSG_RF_INTF_ACTIVATED:
262 if (nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_NTF) == false) {
263 return;
264 }
265 nfc_ncif_proc_activate(pp, len);
266 break;
267
268 case NCI_MSG_RF_FIELD:
269 nfc_ncif_proc_rf_field_ntf(*pp);
270 break;
271
272 case NCI_MSG_RF_T3T_POLLING:
273 nfc_ncif_proc_t3t_polling_ntf(pp, len);
274 break;
275
276#if (NFC_NFCEE_INCLUDED == TRUE)
277#if (NFC_RW_ONLY == FALSE)
278
279 case NCI_MSG_RF_GET_ROUTING:
280 nfc_ncif_proc_get_routing(pp, len);
281 break;
282
283 case NCI_MSG_RF_EE_ACTION:
284 nfc_ncif_proc_ee_action(pp, len);
285 break;
286
287 case NCI_MSG_RF_EE_DISCOVERY_REQ:
288 nfc_ncif_proc_ee_discover_req(pp, len);
289 break;
290#endif
291#endif
292 case NCI_MSG_RF_ISO_DEP_NAK_PRESENCE:
293 nfc_ncif_proc_isodep_nak_presence_check_status(*pp, true);
294 break;
295 default:
296 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
297 break;
298 }
299}
300
301#if (NFC_NFCEE_INCLUDED == TRUE)
302#if (NFC_RW_ONLY == FALSE)
303
304/*******************************************************************************
305**
306** Function nci_proc_ee_management_rsp
307**
308** Description Process NCI responses in the NFCEE Management group
309**
310** Returns void
311**
312*******************************************************************************/
313void nci_proc_ee_management_rsp(NFC_HDR* p_msg) {
314 uint8_t* p;
315 uint8_t *pp, len, op_code;
316 tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
317 tNFC_RESPONSE nfc_response;
318 tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
319 uint8_t* p_old = nfc_cb.last_cmd;
320
321 /* find the start of the NCI message and parse the NCI header */
322 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
323 pp = p + 1;
324 NCI_MSG_PRS_HDR1(pp, op_code);
325 DLOG_IF(INFO, nfc_debug_enabled)
326 << StringPrintf("nci_proc_ee_management_rsp opcode:0x%x", op_code);
327 len = *pp++;
328
329 switch (op_code) {
330 case NCI_MSG_NFCEE_DISCOVER:
331 nfc_response.nfcee_discover.status = *pp++;
332 nfc_response.nfcee_discover.num_nfcee = *pp++;
333
334 if (nfc_response.nfcee_discover.status != NFC_STATUS_OK)
335 nfc_response.nfcee_discover.num_nfcee = 0;
336
337 event = NFC_NFCEE_DISCOVER_REVT;
338 break;
339
340 case NCI_MSG_NFCEE_MODE_SET:
341 nfc_response.mode_set.status = *pp;
342 nfc_response.mode_set.nfcee_id = *p_old++;
343 nfc_response.mode_set.mode = *p_old++;
344 if (nfc_cb.nci_version != NCI_VERSION_2_0 || *pp != NCI_STATUS_OK) {
345 nfc_cb.flags &= ~NFC_FL_WAIT_MODE_SET_NTF;
346 event = NFC_NFCEE_MODE_SET_REVT;
347 } else {
348 /* else response reports OK status on notification */
349 return;
350 }
351 break;
352
353 case NCI_MSG_NFCEE_POWER_LINK_CTRL:
354 nfc_response.pl_control.status = *pp;
355 nfc_response.pl_control.nfcee_id = *p_old++;
356 nfc_response.pl_control.pl_control = *p_old++;
357 event = NFC_NFCEE_PL_CONTROL_REVT;
358 break;
359 default:
360 p_cback = NULL;
361 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
362 break;
363 }
364
365 if (p_cback) (*p_cback)(event, &nfc_response);
366}
367
368/*******************************************************************************
369**
370** Function nci_proc_ee_management_ntf
371**
372** Description Process NCI notifications in the NFCEE Management group
373**
374** Returns void
375**
376*******************************************************************************/
377void nci_proc_ee_management_ntf(NFC_HDR* p_msg) {
378 uint8_t* p;
379 uint8_t *pp, len, op_code;
380 tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
381 tNFC_RESPONSE nfc_response;
382 tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
hariprasad nalacheruvu4668c152018-05-24 16:46:24 +0530383#if (NXP_EXTNS != TRUE)
nxf24591c1cbeab2018-02-21 17:32:26 +0530384 uint8_t* p_old = nfc_cb.last_cmd;
hariprasad nalacheruvu4668c152018-05-24 16:46:24 +0530385#endif
386
nxf24591c1cbeab2018-02-21 17:32:26 +0530387 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 p = pp;
432 STREAM_TO_ARRAY(p_tlv->info, pp, p_tlv->len);
433 pp = p += yy;
434 }
435 } else if (op_code == NCI_MSG_NFCEE_MODE_SET) {
436 nfc_response.mode_set.status = *pp;
hariprasad nalacheruvu4668c152018-05-24 16:46:24 +0530437#if (NXP_EXTNS != TRUE)
nxf24591c1cbeab2018-02-21 17:32:26 +0530438 nfc_response.mode_set.nfcee_id = *p_old++;
439 nfc_response.mode_set.mode = *p_old++;
hariprasad nalacheruvu4668c152018-05-24 16:46:24 +0530440#else
441 nfc_response.mode_set.nfcee_id = nfa_ee_cb.nfcee_id;
442 nfc_response.mode_set.mode = nfa_ee_cb.mode;
443#endif
nxf24591c1cbeab2018-02-21 17:32:26 +0530444 event = NFC_NFCEE_MODE_SET_REVT;
445 nfc_cb.flags &= ~NFC_FL_WAIT_MODE_SET_NTF;
446 nfc_stop_timer(&nfc_cb.nci_mode_set_ntf_timer);
447 } else if (op_code == NCI_MSG_NFCEE_STATUS) {
448 event = NFC_NFCEE_STATUS_REVT;
449 nfc_response.nfcee_status.status = NCI_STATUS_OK;
450 nfc_response.nfcee_status.nfcee_id = *pp++;
451 nfc_response.nfcee_status.nfcee_status = *pp;
452 } else {
453 p_cback = NULL;
454 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code);
455 }
456
457 if (p_cback) (*p_cback)(event, &nfc_response);
458}
459
460#endif
461#endif
462
463/*******************************************************************************
464**
465** Function nci_proc_prop_rsp
466**
467** Description Process NCI responses in the Proprietary group
468**
469** Returns void
470**
471*******************************************************************************/
472void nci_proc_prop_rsp(NFC_HDR* p_msg) {
473 uint8_t* p;
474 uint8_t* p_evt;
475 uint8_t *pp, len, op_code;
476 tNFC_VS_CBACK* p_cback = (tNFC_VS_CBACK*)nfc_cb.p_vsc_cback;
477
478 /* find the start of the NCI message and parse the NCI header */
479 p = p_evt = (uint8_t*)(p_msg + 1) + p_msg->offset;
480 pp = p + 1;
481 NCI_MSG_PRS_HDR1(pp, op_code);
482 len = *pp++;
483
484 /*If there's a pending/stored command, restore the associated address of the
485 * callback function */
486 if (p_cback)
487 (*p_cback)((tNFC_VS_EVT)(NCI_RSP_BIT | op_code), p_msg->len, p_evt);
488}
489
490/*******************************************************************************
491**
492** Function nci_proc_prop_raw_vs_rsp
493**
494** Description Process RAW VS responses
495**
496** Returns void
497**
498*******************************************************************************/
499void nci_proc_prop_raw_vs_rsp(NFC_HDR* p_msg) {
500 uint8_t op_code;
501 tNFC_VS_CBACK* p_cback = (tNFC_VS_CBACK*)nfc_cb.p_vsc_cback;
502
503 /* find the start of the NCI message and parse the NCI header */
504 uint8_t* p_evt = (uint8_t*)(p_msg + 1) + p_msg->offset;
505 uint8_t* p = p_evt + 1;
506 NCI_MSG_PRS_HDR1(p, op_code);
507
508 /* If there's a pending/stored command, restore the associated address of the
509 * callback function */
510 if (p_cback) {
511 (*p_cback)((tNFC_VS_EVT)(NCI_RSP_BIT | op_code), p_msg->len, p_evt);
512 nfc_cb.p_vsc_cback = NULL;
513 }
514 nfc_cb.rawVsCbflag = false;
515 nfc_ncif_update_window();
516}
517
518/*******************************************************************************
519**
520** Function nci_proc_prop_ntf
521**
522** Description Process NCI notifications in the Proprietary group
523**
524** Returns void
525**
526*******************************************************************************/
527void nci_proc_prop_ntf(NFC_HDR* p_msg) {
528 uint8_t* p;
529 uint8_t* p_evt;
530 uint8_t *pp, len, op_code;
531 int i;
532
533 /* find the start of the NCI message and parse the NCI header */
534 p = p_evt = (uint8_t*)(p_msg + 1) + p_msg->offset;
535 pp = p + 1;
536 NCI_MSG_PRS_HDR1(pp, op_code);
537 len = *pp++;
538
539 for (i = 0; i < NFC_NUM_VS_CBACKS; i++) {
540 if (nfc_cb.p_vs_cb[i]) {
541 (*nfc_cb.p_vs_cb[i])((tNFC_VS_EVT)(NCI_NTF_BIT | op_code), p_msg->len,
542 p_evt);
543 }
544 }
545}