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 *
22 * This file contains function of the NFC unit to receive/process NCI
23 * commands.
24 *
25 ******************************************************************************/
26 #include <string.h>
27 #include "nfc_target.h"
28 #include "bt_types.h"
29 #include "gki.h"
30
31 #if NFC_INCLUDED == TRUE
32 #include "nci_defs.h"
33 #include "nci_hmsgs.h"
34 #include "nfc_api.h"
35 #include "nfc_int.h"
36
37 /*******************************************************************************
38 **
39 ** Function nci_proc_core_rsp
40 **
41 ** Description Process NCI responses in the CORE group
42 **
43 ** Returns TRUE-caller of this function to free the GKI buffer p_msg
44 **
45 *******************************************************************************/
nci_proc_core_rsp(BT_HDR * p_msg)46 BOOLEAN nci_proc_core_rsp (BT_HDR *p_msg)
47 {
48 UINT8 *p;
49 UINT8 *pp, len, op_code;
50 BOOLEAN free = TRUE;
51 UINT8 *p_old = nfc_cb.last_cmd;
52
53 /* find the start of the NCI message and parse the NCI header */
54 p = (UINT8 *) (p_msg + 1) + p_msg->offset;
55 pp = p+1;
56 NCI_MSG_PRS_HDR1 (pp, op_code);
57 NFC_TRACE_DEBUG1 ("nci_proc_core_rsp opcode:0x%x", op_code);
58 len = *pp++;
59
60 /* process the message based on the opcode and message type */
61 switch (op_code)
62 {
63 case NCI_MSG_CORE_RESET:
64 nfc_ncif_proc_reset_rsp (pp, FALSE);
65 break;
66
67 case NCI_MSG_CORE_INIT:
68 nfc_ncif_proc_init_rsp (p_msg);
69 free = FALSE;
70 break;
71
72 case NCI_MSG_CORE_GET_CONFIG:
73 nfc_ncif_proc_get_config_rsp (p_msg);
74 break;
75
76 case NCI_MSG_CORE_SET_CONFIG:
77 nfc_ncif_set_config_status (pp, len);
78 break;
79
80 case NCI_MSG_CORE_CONN_CREATE:
81 nfc_ncif_proc_conn_create_rsp (p, p_msg->len, *p_old);
82 break;
83
84 case NCI_MSG_CORE_CONN_CLOSE:
85 nfc_ncif_report_conn_close_evt (*p_old, *pp);
86 break;
87
88 default:
89 NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
90 break;
91 }
92
93 return free;
94 }
95
96 /*******************************************************************************
97 **
98 ** Function nci_proc_core_ntf
99 **
100 ** Description Process NCI notifications in the CORE group
101 **
102 ** Returns void
103 **
104 *******************************************************************************/
nci_proc_core_ntf(BT_HDR * p_msg)105 void nci_proc_core_ntf (BT_HDR *p_msg)
106 {
107 UINT8 *p;
108 UINT8 *pp, len, op_code;
109 UINT8 conn_id;
110
111 /* find the start of the NCI message and parse the NCI header */
112 p = (UINT8 *) (p_msg + 1) + p_msg->offset;
113 pp = p+1;
114 NCI_MSG_PRS_HDR1 (pp, op_code);
115 NFC_TRACE_DEBUG1 ("nci_proc_core_ntf opcode:0x%x", op_code);
116 len = *pp++;
117
118 /* process the message based on the opcode and message type */
119 switch (op_code)
120 {
121 case NCI_MSG_CORE_RESET:
122 nfc_ncif_proc_reset_rsp (pp, TRUE);
123 break;
124
125 case NCI_MSG_CORE_GEN_ERR_STATUS:
126 /* process the error ntf */
127 /* in case of timeout: notify the static connection callback */
128 nfc_ncif_event_status (NFC_GEN_ERROR_REVT, *pp);
129 nfc_ncif_error_status (NFC_RF_CONN_ID, *pp);
130 break;
131
132 case NCI_MSG_CORE_INTF_ERR_STATUS:
133 conn_id = *(pp+1);
134 nfc_ncif_error_status (conn_id, *pp);
135 break;
136
137 case NCI_MSG_CORE_CONN_CREDITS:
138 nfc_ncif_proc_credits(pp, len);
139 break;
140
141 default:
142 NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
143 break;
144 }
145 }
146
147
148 /*******************************************************************************
149 **
150 ** Function nci_proc_rf_management_rsp
151 **
152 ** Description Process NCI responses in the RF Management group
153 **
154 ** Returns void
155 **
156 *******************************************************************************/
nci_proc_rf_management_rsp(BT_HDR * p_msg)157 void nci_proc_rf_management_rsp (BT_HDR *p_msg)
158 {
159 UINT8 *p;
160 UINT8 *pp, len, op_code;
161 UINT8 *p_old = nfc_cb.last_cmd;
162
163 /* find the start of the NCI message and parse the NCI header */
164 p = (UINT8 *) (p_msg + 1) + p_msg->offset;
165 pp = p+1;
166 NCI_MSG_PRS_HDR1 (pp, op_code);
167 len = *pp++;
168
169 switch (op_code)
170 {
171 case NCI_MSG_RF_DISCOVER:
172 nfa_dm_p2p_prio_logic (op_code, pp, NFA_DM_P2P_PRIO_RSP);
173 nfc_ncif_rf_management_status (NFC_START_DEVT, *pp);
174 break;
175
176 case NCI_MSG_RF_DISCOVER_SELECT:
177 nfc_ncif_rf_management_status (NFC_SELECT_DEVT, *pp);
178 break;
179
180 case NCI_MSG_RF_T3T_POLLING:
181 break;
182
183 case NCI_MSG_RF_DISCOVER_MAP:
184 nfc_ncif_rf_management_status (NFC_MAP_DEVT, *pp);
185 break;
186
187 case NCI_MSG_RF_DEACTIVATE:
188 if (FALSE == nfa_dm_p2p_prio_logic (op_code, pp, NFA_DM_P2P_PRIO_RSP))
189 {
190 return;
191 }
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 default:
214 NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
215 break;
216 }
217 }
218
219 /*******************************************************************************
220 **
221 ** Function nci_proc_rf_management_ntf
222 **
223 ** Description Process NCI notifications in the RF Management group
224 **
225 ** Returns void
226 **
227 *******************************************************************************/
nci_proc_rf_management_ntf(BT_HDR * p_msg)228 void nci_proc_rf_management_ntf (BT_HDR *p_msg)
229 {
230 UINT8 *p;
231 UINT8 *pp, len, op_code;
232
233 /* find the start of the NCI message and parse the NCI header */
234 p = (UINT8 *) (p_msg + 1) + p_msg->offset;
235 pp = p+1;
236 NCI_MSG_PRS_HDR1 (pp, op_code);
237 len = *pp++;
238
239 switch (op_code)
240 {
241 case NCI_MSG_RF_DISCOVER :
242 nfc_ncif_proc_discover_ntf (p, p_msg->len);
243 break;
244
245 case NCI_MSG_RF_DEACTIVATE:
246 if (FALSE == nfa_dm_p2p_prio_logic (op_code, pp, NFA_DM_P2P_PRIO_NTF))
247 {
248 return;
249 }
250 nfc_ncif_proc_deactivate (NFC_STATUS_OK, *pp, TRUE);
251 break;
252
253 case NCI_MSG_RF_INTF_ACTIVATED:
254 if (FALSE == nfa_dm_p2p_prio_logic (op_code, pp, NFA_DM_P2P_PRIO_NTF))
255 {
256 return;
257 }
258 nfc_ncif_proc_activate (pp, len);
259 break;
260
261 case NCI_MSG_RF_FIELD:
262 nfc_ncif_proc_rf_field_ntf (*pp);
263 break;
264
265 case NCI_MSG_RF_T3T_POLLING:
266 nfc_ncif_proc_t3t_polling_ntf (pp, len);
267 break;
268
269 #if (NFC_NFCEE_INCLUDED == TRUE)
270 #if (NFC_RW_ONLY == FALSE)
271
272 case NCI_MSG_RF_GET_ROUTING:
273 nfc_ncif_proc_get_routing (pp, len);
274 break;
275
276 case NCI_MSG_RF_EE_ACTION:
277 nfc_ncif_proc_ee_action (pp, len);
278 break;
279
280 case NCI_MSG_RF_EE_DISCOVERY_REQ:
281 nfc_ncif_proc_ee_discover_req (pp, len);
282 break;
283 #endif
284 #endif
285
286 default:
287 NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
288 break;
289 }
290 }
291
292 #if (NFC_NFCEE_INCLUDED == TRUE)
293 #if (NFC_RW_ONLY == FALSE)
294
295 /*******************************************************************************
296 **
297 ** Function nci_proc_ee_management_rsp
298 **
299 ** Description Process NCI responses in the NFCEE Management group
300 **
301 ** Returns void
302 **
303 *******************************************************************************/
nci_proc_ee_management_rsp(BT_HDR * p_msg)304 void nci_proc_ee_management_rsp (BT_HDR *p_msg)
305 {
306 UINT8 *p;
307 UINT8 *pp, len, op_code;
308 tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
309 tNFC_NFCEE_DISCOVER_REVT nfcee_discover;
310 tNFC_NFCEE_INFO_REVT nfcee_info;
311 tNFC_NFCEE_MODE_SET_REVT mode_set;
312 tNFC_RESPONSE *p_evt = (tNFC_RESPONSE *) &nfcee_info;
313 tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
314 UINT8 *p_old = nfc_cb.last_cmd;
315
316 /* find the start of the NCI message and parse the NCI header */
317 p = (UINT8 *) (p_msg + 1) + p_msg->offset;
318 pp = p+1;
319 NCI_MSG_PRS_HDR1 (pp, op_code);
320 NFC_TRACE_DEBUG1 ("nci_proc_ee_management_rsp opcode:0x%x", op_code);
321 len = *pp++;
322
323 switch (op_code)
324 {
325 case NCI_MSG_NFCEE_DISCOVER:
326 p_evt = (tNFC_RESPONSE *) &nfcee_discover;
327 nfcee_discover.status = *pp++;
328 nfcee_discover.num_nfcee = *pp++;
329
330 if (nfcee_discover.status != NFC_STATUS_OK)
331 nfcee_discover.num_nfcee = 0;
332
333 event = NFC_NFCEE_DISCOVER_REVT;
334 break;
335
336 case NCI_MSG_NFCEE_MODE_SET:
337 p_evt = (tNFC_RESPONSE *) &mode_set;
338 mode_set.status = *pp;
339 mode_set.nfcee_id = 0;
340 event = NFC_NFCEE_MODE_SET_REVT;
341 mode_set.nfcee_id = *p_old++;
342 mode_set.mode = *p_old++;
343 break;
344
345 default:
346 p_cback = NULL;
347 NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
348 break;
349 }
350
351 if (p_cback)
352 (*p_cback) (event, p_evt);
353 }
354
355 /*******************************************************************************
356 **
357 ** Function nci_proc_ee_management_ntf
358 **
359 ** Description Process NCI notifications in the NFCEE Management group
360 **
361 ** Returns void
362 **
363 *******************************************************************************/
nci_proc_ee_management_ntf(BT_HDR * p_msg)364 void nci_proc_ee_management_ntf (BT_HDR *p_msg)
365 {
366 UINT8 *p;
367 UINT8 *pp, len, op_code;
368 tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
369 tNFC_NFCEE_INFO_REVT nfcee_info;
370 tNFC_RESPONSE *p_evt = (tNFC_RESPONSE *) &nfcee_info;
371 tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
372 UINT8 xx;
373 UINT8 yy;
374 UINT8 ee_status;
375 tNFC_NFCEE_TLV *p_tlv;
376
377 /* find the start of the NCI message and parse the NCI header */
378 p = (UINT8 *) (p_msg + 1) + p_msg->offset;
379 pp = p+1;
380 NCI_MSG_PRS_HDR1 (pp, op_code);
381 NFC_TRACE_DEBUG1 ("nci_proc_ee_management_ntf opcode:0x%x", op_code);
382 len = *pp++;
383
384 if (op_code == NCI_MSG_NFCEE_DISCOVER)
385 {
386 nfcee_info.nfcee_id = *pp++;
387 ee_status = *pp++;
388
389 nfcee_info.ee_status = ee_status;
390 yy = *pp;
391 nfcee_info.num_interface = *pp++;
392 p = pp;
393
394 if (nfcee_info.num_interface > NFC_MAX_EE_INTERFACE)
395 nfcee_info.num_interface = NFC_MAX_EE_INTERFACE;
396
397 for (xx = 0; xx < nfcee_info.num_interface; xx++)
398 {
399 nfcee_info.ee_interface[xx] = *pp++;
400 }
401
402 pp = p + yy;
403 nfcee_info.num_tlvs = *pp++;
404 NFC_TRACE_DEBUG4 ("nfcee_id: 0x%x num_interface:0x%x/0x%x, num_tlvs:0x%x",
405 nfcee_info.nfcee_id, nfcee_info.num_interface, yy, nfcee_info.num_tlvs);
406
407 if (nfcee_info.num_tlvs > NFC_MAX_EE_TLVS)
408 nfcee_info.num_tlvs = NFC_MAX_EE_TLVS;
409
410 p_tlv = &nfcee_info.ee_tlv[0];
411
412 for (xx = 0; xx < nfcee_info.num_tlvs; xx++, p_tlv++)
413 {
414 p_tlv->tag = *pp++;
415 p_tlv->len = yy = *pp++;
416 NFC_TRACE_DEBUG2 ("tag:0x%x, len:0x%x", p_tlv->tag, p_tlv->len);
417 if (p_tlv->len > NFC_MAX_EE_INFO)
418 p_tlv->len = NFC_MAX_EE_INFO;
419 p = pp;
420 STREAM_TO_ARRAY (p_tlv->info, pp, p_tlv->len);
421 pp = p += yy;
422 }
423 }
424 else
425 {
426 p_cback = NULL;
427 NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
428 }
429
430 if (p_cback)
431 (*p_cback) (event, p_evt);
432 }
433
434 #endif
435 #endif
436
437 /*******************************************************************************
438 **
439 ** Function nci_proc_prop_rsp
440 **
441 ** Description Process NCI responses in the Proprietary group
442 **
443 ** Returns void
444 **
445 *******************************************************************************/
nci_proc_prop_rsp(BT_HDR * p_msg)446 void nci_proc_prop_rsp (BT_HDR *p_msg)
447 {
448 UINT8 *p;
449 UINT8 *p_evt;
450 UINT8 *pp, len, op_code;
451 tNFC_VS_CBACK *p_cback = (tNFC_VS_CBACK *)nfc_cb.p_vsc_cback;
452
453 /* find the start of the NCI message and parse the NCI header */
454 p = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset;
455 pp = p+1;
456 NCI_MSG_PRS_HDR1 (pp, op_code);
457 len = *pp++;
458
459 /*If there's a pending/stored command, restore the associated address of the callback function */
460 if (p_cback)
461 (*p_cback) ((tNFC_VS_EVT) (NCI_RSP_BIT|op_code), p_msg->len, p_evt);
462 }
463
464 /*******************************************************************************
465 **
466 ** Function nci_proc_prop_ntf
467 **
468 ** Description Process NCI notifications in the Proprietary group
469 **
470 ** Returns void
471 **
472 *******************************************************************************/
nci_proc_prop_ntf(BT_HDR * p_msg)473 void nci_proc_prop_ntf (BT_HDR *p_msg)
474 {
475 UINT8 *p;
476 UINT8 *p_evt;
477 UINT8 *pp, len, op_code;
478 int i;
479
480 /* find the start of the NCI message and parse the NCI header */
481 p = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset;
482 pp = p+1;
483 NCI_MSG_PRS_HDR1 (pp, op_code);
484 len = *pp++;
485
486 for (i = 0; i < NFC_NUM_VS_CBACKS; i++)
487 {
488 if (nfc_cb.p_vs_cb[i])
489 {
490 (*nfc_cb.p_vs_cb[i]) ((tNFC_VS_EVT) (NCI_NTF_BIT|op_code), p_msg->len, p_evt);
491 }
492 }
493 }
494
495 #endif /* NFC_INCLUDED == TRUE*/
496