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