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