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