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