xref: /aosp_15_r20/system/nfc/src/nfa/dm/nfa_dm_discover.cc (revision 7eba2f3b06c51ae21384f6a4f14577b668a869b3)
1 /******************************************************************************
2  *
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at:
7  *
8  *  http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  ******************************************************************************/
17 
18 /******************************************************************************
19  *
20  *  This file contains the action functions for device manager discovery
21  *  function.
22  *
23  ******************************************************************************/
24 #include <android-base/logging.h>
25 #include <android-base/stringprintf.h>
26 
27 #include <string>
28 
29 #include "nci_hmsgs.h"
30 #include "nfa_api.h"
31 #include "nfa_dm_int.h"
32 
33 #if (NFC_NFCEE_INCLUDED == TRUE)
34 #include "nfa_ee_api.h"
35 #include "nfa_ee_int.h"
36 #endif
37 #include "nfa_rw_int.h"
38 #include "nfa_wlc_int.h"
39 #include "nfc_int.h"
40 
41 using android::base::StringPrintf;
42 
43 /*
44 **  static functions
45 */
46 static uint8_t nfa_dm_get_rf_discover_config(
47     tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
48     tNFC_DISCOVER_PARAMS disc_params[], uint8_t max_params);
49 static tNFA_STATUS nfa_dm_set_rf_listen_mode_config(
50     tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask);
51 static void nfa_dm_set_rf_listen_mode_raw_config(
52     tNFA_DM_DISC_TECH_PROTO_MASK* p_disc_mask);
53 static tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_disc_get_disc_mask(
54     tNFC_RF_TECH_N_MODE tech_n_mode, tNFC_PROTOCOL protocol);
55 static void nfa_dm_notify_discovery(tNFA_DM_RF_DISC_DATA* p_data);
56 static tNFA_STATUS nfa_dm_disc_notify_activation(tNFC_DISCOVER* p_data);
57 static void nfa_dm_disc_notify_deactivation(tNFA_DM_RF_DISC_SM_EVENT sm_event,
58                                             tNFC_DISCOVER* p_data);
59 static void nfa_dm_disc_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
60                                    tNFC_CONN* p_data);
61 static void nfa_dm_disc_kovio_timeout_cback(TIMER_LIST_ENT* p_tle);
62 static void nfa_dm_disc_report_kovio_presence_check(tNFC_STATUS status);
63 
64 static std::string nfa_dm_disc_state_2_str(uint8_t state);
65 static std::string nfa_dm_disc_event_2_str(uint8_t event);
66 
67 extern uint8_t mute_tech_route_option;
68 /*
69 ** static parameters
70 */
71 tNFA_TECHNOLOGY_MASK dm_disc_listen_mask_dfl = 0;
72 tNFA_TECHNOLOGY_MASK dm_disc_poll_mask_dfl = 0;
73 
nfa_dm_change_listen_mask(tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,tNFA_TECHNOLOGY_MASK change_listen_mask)74 tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_change_listen_mask(
75     tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
76     tNFA_TECHNOLOGY_MASK change_listen_mask) {
77   if (mute_tech_route_option) {
78     /* Check listening tech */
79     LOG(VERBOSE) << StringPrintf("listen tech will be changed to 0x%x",
80                                  change_listen_mask);
81     dm_disc_mask &= NFA_DM_DISC_MASK_POLL;
82     if (change_listen_mask & NFA_TECHNOLOGY_MASK_A) {
83       dm_disc_mask |= (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T |
84                        NFA_DM_DISC_MASK_LA_ISO_DEP);
85     }
86     if (change_listen_mask & NFA_TECHNOLOGY_MASK_B)
87       dm_disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
88 
89     if (change_listen_mask & NFA_TECHNOLOGY_MASK_F)
90       dm_disc_mask |= NFA_DM_DISC_MASK_LF_T3T;
91 
92     LOG(VERBOSE) << StringPrintf("listen tech will set to 0x%x",
93                                  (dm_disc_mask & NFA_DM_DISC_MASK_LISTEN));
94   } else {
95     LOG(VERBOSE) << StringPrintf(
96         "%s; listen tech: 0x%x, unset tech muted in RT, added to discovery",
97         __func__, change_listen_mask);
98     if ((change_listen_mask & NFA_TECHNOLOGY_MASK_A) == 0) {
99       dm_disc_mask |= (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T |
100                        NFA_DM_DISC_MASK_LA_ISO_DEP);
101     }
102     if ((change_listen_mask & NFA_TECHNOLOGY_MASK_B) == 0) {
103       dm_disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
104     }
105     if ((change_listen_mask & NFA_TECHNOLOGY_MASK_F) == 0) {
106       dm_disc_mask |= (NFA_DM_DISC_MASK_LF_T3T);
107     }
108     LOG(VERBOSE) << StringPrintf("listen tech will set to 0x%x",
109                                  (dm_disc_mask & NFA_DM_DISC_MASK_LISTEN));
110   }
111 
112   return dm_disc_mask;
113 }
114 
nfa_dm_change_poll_mask(tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,tNFA_TECHNOLOGY_MASK change_poll_mask)115 tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_change_poll_mask(
116     tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
117     tNFA_TECHNOLOGY_MASK change_poll_mask) {
118   if (change_poll_mask & NFA_TECHNOLOGY_MASK_A) {
119     dm_disc_mask |= (NFA_DM_DISC_MASK_PA_T1T | NFA_DM_DISC_MASK_PA_T2T |
120                      NFA_DM_DISC_MASK_PA_ISO_DEP | NFA_DM_DISC_MASK_PA_NFC_DEP |
121                      NFA_DM_DISC_MASK_P_LEGACY);
122   }
123   if (change_poll_mask & NFA_TECHNOLOGY_MASK_B)
124     dm_disc_mask |= NFA_DM_DISC_MASK_PB_ISO_DEP;
125 
126   if (change_poll_mask & NFA_TECHNOLOGY_MASK_F)
127     dm_disc_mask |= (NFA_DM_DISC_MASK_PF_T3T | NFA_DM_DISC_MASK_PF_NFC_DEP);
128 
129   if (change_poll_mask & NFA_TECHNOLOGY_MASK_V)
130     dm_disc_mask |= NFA_DM_DISC_MASK_P_T5T;
131 
132   if (change_poll_mask & NFA_TECHNOLOGY_MASK_B_PRIME)
133     dm_disc_mask |= NFA_DM_DISC_MASK_P_B_PRIME;
134 
135   if (change_poll_mask & NFA_TECHNOLOGY_MASK_KOVIO)
136     dm_disc_mask |= NFA_DM_DISC_MASK_P_KOVIO;
137 
138   LOG(VERBOSE) << StringPrintf("poll tech mask will set to 0x%x",
139                                (dm_disc_mask & NFA_DM_DISC_MASK_POLL));
140 
141   return dm_disc_mask;
142 }
143 
144 /*******************************************************************************
145 **
146 ** Function         nfa_dm_set_rf_field_ntf
147 **
148 ** Description      Update RF_FIELD_INFO_NTF status to NFCC
149 **
150 ** Returns          void
151 **
152 *******************************************************************************/
nfa_dm_set_rf_field_info_ntf(uint8_t val)153 static void nfa_dm_set_rf_field_info_ntf(uint8_t val) {
154   uint8_t params[10], *p;
155 
156   LOG(DEBUG) << StringPrintf("%s; val = 0x%x", __func__, val);
157 
158   p = params;
159 
160   /* for total duration */
161   UINT8_TO_STREAM(p, NFC_PMID_RF_FIELD_INFO);
162   UINT8_TO_STREAM(p, NCI_PARAM_LEN_RF_FIELD_INFO);
163   UINT8_TO_STREAM(p, val);
164 
165   if (p > params) {
166     nfa_dm_check_set_config((uint8_t)(p - params), params, false);
167   }
168 }
169 
170 /*******************************************************************************
171 **
172 ** Function         nfa_dm_get_rf_discover_config
173 **
174 ** Description      Build RF discovery configurations from
175 **                  tNFA_DM_DISC_TECH_PROTO_MASK
176 **
177 ** Returns          number of RF discovery configurations
178 **
179 *******************************************************************************/
nfa_dm_get_rf_discover_config(tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,tNFC_DISCOVER_PARAMS disc_params[],uint8_t max_params)180 static uint8_t nfa_dm_get_rf_discover_config(
181     tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
182     tNFC_DISCOVER_PARAMS disc_params[], uint8_t max_params) {
183   uint8_t num_params = 0;
184   uint8_t rf_field_val;
185 
186   if (nfa_dm_cb.flags & NFA_DM_FLAGS_LISTEN_DISABLED) {
187     LOG(VERBOSE) << StringPrintf("%s; listen disabled, rm listen from 0x%x",
188                                  __func__, dm_disc_mask);
189     dm_disc_mask &= NFA_DM_DISC_MASK_POLL;
190   }
191 
192   if (nfa_dm_cb.flags & NFA_DM_FLAGS_LISTEN_TECH_CHANGED) {
193     dm_disc_mask =
194         nfa_dm_change_listen_mask(dm_disc_mask, nfa_dm_cb.change_listen_mask);
195   } else if (dm_disc_listen_mask_dfl != 0) {
196     LOG(VERBOSE) << StringPrintf("default listen tech 0x%x will be used",
197                                  dm_disc_listen_mask_dfl);
198     dm_disc_mask =
199         nfa_dm_change_listen_mask(dm_disc_mask, dm_disc_listen_mask_dfl);
200   }
201 
202   // RF_FIELD_INFO_NTF needed only if some listen programmed
203   nfa_dm_set_rf_field_info_ntf((dm_disc_mask & NFA_DM_DISC_MASK_LISTEN) ? 0x01
204                                                                         : 0x00);
205 
206   if (nfa_dm_cb.flags & NFA_DM_FLAGS_POLL_TECH_CHANGED) {
207     /* Check polling tech */
208     LOG(VERBOSE) << StringPrintf("poll tech will be changed to 0x%x",
209                                nfa_dm_cb.change_poll_mask);
210     dm_disc_mask &= NFA_DM_DISC_MASK_LISTEN;
211     dm_disc_mask =
212         nfa_dm_change_poll_mask(dm_disc_mask, nfa_dm_cb.change_poll_mask);
213   } else if (dm_disc_poll_mask_dfl != 0) {
214     LOG(VERBOSE) << StringPrintf("default poll tech 0x%x will be used",
215                                  dm_disc_poll_mask_dfl);
216     dm_disc_mask = nfa_dm_change_poll_mask(dm_disc_mask, dm_disc_poll_mask_dfl);
217   }
218 
219   /* Check polling A */
220   if (dm_disc_mask &
221       (NFA_DM_DISC_MASK_PA_T1T | NFA_DM_DISC_MASK_PA_T2T |
222        NFA_DM_DISC_MASK_PA_ISO_DEP | NFA_DM_DISC_MASK_PA_NFC_DEP |
223        NFA_DM_DISC_MASK_P_LEGACY)) {
224     disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_A;
225     disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pa;
226     num_params++;
227 
228     if (num_params >= max_params) return num_params;
229   }
230 
231   /* Check polling B */
232   if (dm_disc_mask & NFA_DM_DISC_MASK_PB_ISO_DEP) {
233     disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_B;
234     disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pb;
235     num_params++;
236 
237     if (num_params >= max_params) return num_params;
238   }
239 
240   /* Check polling F */
241   if (dm_disc_mask & (NFA_DM_DISC_MASK_PF_T3T | NFA_DM_DISC_MASK_PF_NFC_DEP)) {
242     disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_F;
243     disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pf;
244     num_params++;
245 
246     if (num_params >= max_params) return num_params;
247   }
248 
249   /* Check listening A */
250   if (dm_disc_mask & (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T |
251                       NFA_DM_DISC_MASK_LA_ISO_DEP)) {
252     disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_A;
253     disc_params[num_params].frequency = 1;
254     num_params++;
255 
256     if (num_params >= max_params) return num_params;
257   }
258 
259   /* Check listening B */
260   if (dm_disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP) {
261     disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_B;
262     disc_params[num_params].frequency = 1;
263     num_params++;
264 
265     if (num_params >= max_params) return num_params;
266   }
267 
268   /* Check listening F */
269   if (dm_disc_mask & NFA_DM_DISC_MASK_LF_T3T) {
270     disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_F;
271     disc_params[num_params].frequency = 1;
272     num_params++;
273 
274     if (num_params >= max_params) return num_params;
275   }
276 
277   /* Check polling ISO 15693 */
278   if (dm_disc_mask & NFA_DM_DISC_MASK_P_T5T) {
279     disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_V;
280     disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pi93;
281     num_params++;
282 
283     if (num_params >= max_params) return num_params;
284   }
285 
286   /* Check polling B' */
287   if (dm_disc_mask & NFA_DM_DISC_MASK_P_B_PRIME) {
288     if (NFC_DISCOVERY_TYPE_POLL_B_PRIME != NFA_PROTOCOL_INVALID) {
289       disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_B_PRIME;
290       disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pbp;
291       num_params++;
292       if (num_params >= max_params) return num_params;
293     } else {
294       LOG(ERROR) << StringPrintf("Unsupported type POLL_B_PRIME!");
295     }
296   }
297 
298   /* Check polling KOVIO */
299   if (dm_disc_mask & NFA_DM_DISC_MASK_P_KOVIO) {
300     if (NFC_DISCOVERY_TYPE_POLL_KOVIO != NFA_PROTOCOL_INVALID) {
301       disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_KOVIO;
302       disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pk;
303       num_params++;
304       if (num_params >= max_params) return num_params;
305     } else {
306       LOG(ERROR) << StringPrintf("Unsupported type POLL_KOVIO!");
307     }
308   }
309 
310   /* Check listening ISO 15693 */
311   if (dm_disc_mask & NFA_DM_DISC_MASK_L_ISO15693) {
312     disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_ISO15693;
313     disc_params[num_params].frequency = 1;
314     num_params++;
315 
316     if (num_params >= max_params) return num_params;
317   }
318 
319   /* Check listening B' */
320   if (dm_disc_mask & NFA_DM_DISC_MASK_L_B_PRIME) {
321     if (NFC_DISCOVERY_TYPE_LISTEN_B_PRIME != NFA_PROTOCOL_INVALID) {
322       disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_B_PRIME;
323       disc_params[num_params].frequency = 1;
324       num_params++;
325       if (num_params >= max_params) return num_params;
326     } else {
327       LOG(ERROR) << StringPrintf("Unsupported type LISTEN_B_PRIME!");
328     }
329   }
330 
331   return num_params;
332 }
333 
334 /*******************************************************************************
335 **
336 ** Function         nfa_dm_set_rf_listen_mode_config
337 **
338 ** Description      Update listening protocol to NFCC
339 **
340 ** Returns          NFA_STATUS_OK if success
341 **
342 *******************************************************************************/
nfa_dm_set_rf_listen_mode_config(tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask)343 static tNFA_STATUS nfa_dm_set_rf_listen_mode_config(
344     tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask) {
345   uint8_t params[40], *p;
346   uint8_t platform = 0;
347   uint8_t sens_info = 0;
348 
349   LOG(VERBOSE) << StringPrintf("tech_proto_mask = 0x%08X", tech_proto_mask);
350 
351   /*
352   ** T1T listen     LA_PROT 0x80, LA_SENS_RES byte1:0x00 byte2:0x0C
353   ** T2T listen     LA_PROT 0x00
354   ** T3T listen     No bit for T3T in LF_PROT (CE T3T set listen parameters,
355   **                system code, NFCID2, etc.)
356   ** ISO-DEP listen LA_PROT 0x01, LB_PROT 0x01
357   ** NFC-DEP listen LA_PROT 0x02, LF_PROT 0x02
358   */
359 
360   if (tech_proto_mask & NFA_DM_DISC_MASK_LA_T1T) {
361     platform = NCI_PARAM_PLATFORM_T1T;
362   } else if (tech_proto_mask & NFA_DM_DISC_MASK_LA_T2T) {
363     /* platform = 0 and sens_info = 0 */
364   } else {
365     if (tech_proto_mask & NFA_DM_DISC_MASK_LA_ISO_DEP) {
366       sens_info |= NCI_PARAM_SEL_INFO_ISODEP;
367     }
368   }
369 
370   p = params;
371 
372   /*
373    * for Listen A
374    *
375    * Set ATQA 0x0C00 for T1T listen
376    * If the ATQA values are 0x0000, then the FW will use 0x0400
377    * which works for ISODEP, T2T and NFCDEP.
378    *
379    * In mode NFCC allowed to manage RF config (NFCC_CONFIG_CONTROL),
380    * DH will only add RF parameters for itself.
381    * In this case, we must program LA_SEL_INFO for DH techs only
382    */
383     UINT8_TO_STREAM(p, NFC_PMID_LA_BIT_FRAME_SDD);
384     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_BIT_FRAME_SDD);
385     UINT8_TO_STREAM(p, 0x04);
386     UINT8_TO_STREAM(p, NFC_PMID_LA_PLATFORM_CONFIG);
387     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_PLATFORM_CONFIG);
388     UINT8_TO_STREAM(p, platform);
389     UINT8_TO_STREAM(p, NFC_PMID_LA_SEL_INFO);
390     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_SEL_INFO);
391     UINT8_TO_STREAM(p, sens_info);
392 
393   /* for Listen B */
394 
395     UINT8_TO_STREAM(p, NFC_PMID_LB_SENSB_INFO);
396     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_SENSB_INFO);
397     if (tech_proto_mask & NFA_DM_DISC_MASK_LB_ISO_DEP) {
398       UINT8_TO_STREAM(p, NCI_LISTEN_PROTOCOL_ISO_DEP);
399     } else {
400       UINT8_TO_STREAM(p, 0x00);
401     }
402 
403   /* for Listen F */
404     /* NFCC can support T3T listening based on NFCID routing
405      * regardless of NFC-F tech routing */
406     UINT8_TO_STREAM(p, NFC_PMID_LF_PROTOCOL);
407     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_PROTOCOL);
408     UINT8_TO_STREAM(p, 0x00);
409 
410     if (p > params) {
411       nfa_dm_check_set_config((uint8_t)(p - params), params, false);
412     }
413 
414   return NFA_STATUS_OK;
415 }
416 
417 /*******************************************************************************
418 **
419 ** Function         nfa_dm_set_total_duration
420 **
421 ** Description      Update total duration to NFCC
422 **
423 ** Returns          void
424 **
425 *******************************************************************************/
nfa_dm_set_total_duration(void)426 static void nfa_dm_set_total_duration(void) {
427   uint8_t params[10], *p;
428 
429   LOG(VERBOSE) << __func__;
430 
431   p = params;
432 
433   /* for total duration */
434   UINT8_TO_STREAM(p, NFC_PMID_TOTAL_DURATION);
435   UINT8_TO_STREAM(p, NCI_PARAM_LEN_TOTAL_DURATION);
436   UINT16_TO_STREAM(p, nfa_dm_cb.disc_cb.disc_duration);
437 
438   if (p > params) {
439     nfa_dm_check_set_config((uint8_t)(p - params), params, false);
440   }
441 }
442 
443 /*******************************************************************************
444 **
445 ** Function         nfa_dm_set_rf_listen_mode_raw_config
446 **
447 ** Description      Set raw listen parameters
448 **
449 ** Returns          void
450 **
451 *******************************************************************************/
nfa_dm_set_rf_listen_mode_raw_config(tNFA_DM_DISC_TECH_PROTO_MASK * p_disc_mask)452 static void nfa_dm_set_rf_listen_mode_raw_config(
453     tNFA_DM_DISC_TECH_PROTO_MASK* p_disc_mask) {
454   tNFA_DM_DISC_TECH_PROTO_MASK disc_mask = 0;
455   tNFA_LISTEN_CFG* p_cfg = &nfa_dm_cb.disc_cb.excl_listen_config;
456   uint8_t params[250], *p, xx;
457 
458   LOG(VERBOSE) << __func__;
459 
460   /*
461   ** Discovery Configuration Parameters for Listen A
462   */
463   if ((nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A] ==
464        NFA_DM_DISC_HOST_ID_DH) &&
465       (p_cfg->la_enable)) {
466     p = params;
467 
468     UINT8_TO_STREAM(p, NFC_PMID_LA_BIT_FRAME_SDD);
469     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_BIT_FRAME_SDD);
470     UINT8_TO_STREAM(p, p_cfg->la_bit_frame_sdd);
471 
472     UINT8_TO_STREAM(p, NFC_PMID_LA_PLATFORM_CONFIG);
473     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_PLATFORM_CONFIG);
474     UINT8_TO_STREAM(p, p_cfg->la_platform_config);
475 
476     UINT8_TO_STREAM(p, NFC_PMID_LA_SEL_INFO);
477     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_SEL_INFO);
478     UINT8_TO_STREAM(p, p_cfg->la_sel_info);
479 
480     if (p_cfg->la_platform_config == NCI_PARAM_PLATFORM_T1T) {
481       disc_mask |= NFA_DM_DISC_MASK_LA_T1T;
482     } else {
483       /* If T4T or NFCDEP */
484       if (p_cfg->la_sel_info & NCI_PARAM_SEL_INFO_ISODEP) {
485         disc_mask |= NFA_DM_DISC_MASK_LA_ISO_DEP;
486       }
487       /* If neither, T4T nor NFCDEP, then its T2T */
488       if (disc_mask == 0) {
489         disc_mask |= NFA_DM_DISC_MASK_LA_T2T;
490       }
491     }
492 
493     UINT8_TO_STREAM(p, NFC_PMID_LA_NFCID1);
494     UINT8_TO_STREAM(p, p_cfg->la_nfcid1_len);
495     ARRAY_TO_STREAM(p, p_cfg->la_nfcid1, p_cfg->la_nfcid1_len);
496 
497     nfa_dm_check_set_config((uint8_t)(p - params), params, false);
498   }
499 
500   /*
501   ** Discovery Configuration Parameters for Listen B
502   */
503   if ((nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B] ==
504        NFA_DM_DISC_HOST_ID_DH) &&
505       (p_cfg->lb_enable)) {
506     p = params;
507 
508     UINT8_TO_STREAM(p, NFC_PMID_LB_SENSB_INFO);
509     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_SENSB_INFO);
510     UINT8_TO_STREAM(p, p_cfg->lb_sensb_info);
511 
512     UINT8_TO_STREAM(p, NFC_PMID_LB_NFCID0);
513     UINT8_TO_STREAM(p, p_cfg->lb_nfcid0_len);
514     ARRAY_TO_STREAM(p, p_cfg->lb_nfcid0, p_cfg->lb_nfcid0_len);
515 
516     UINT8_TO_STREAM(p, NFC_PMID_LB_APPDATA);
517     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_APPDATA);
518     ARRAY_TO_STREAM(p, p_cfg->lb_app_data, NCI_PARAM_LEN_LB_APPDATA);
519 
520     UINT8_TO_STREAM(p, NFC_PMID_LB_SFGI);
521     UINT8_TO_STREAM(p, 1);
522     UINT8_TO_STREAM(p, p_cfg->lb_adc_fo);
523 
524     UINT8_TO_STREAM(p, NFC_PMID_LB_ADC_FO);
525     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_ADC_FO);
526     UINT8_TO_STREAM(p, p_cfg->lb_adc_fo);
527 
528     nfa_dm_check_set_config((uint8_t)(p - params), params, false);
529 
530     if (p_cfg->lb_sensb_info & NCI_LISTEN_PROTOCOL_ISO_DEP) {
531       disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
532     }
533   }
534 
535   /*
536   ** Discovery Configuration Parameters for Listen F
537   */
538   if ((nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F] ==
539        NFA_DM_DISC_HOST_ID_DH) &&
540       (p_cfg->lf_enable)) {
541     p = params;
542 
543     UINT8_TO_STREAM(p, NFC_PMID_LF_CON_BITR_F);
544     UINT8_TO_STREAM(p, 1);
545     UINT8_TO_STREAM(p, p_cfg->lf_con_bitr_f);
546 
547     UINT8_TO_STREAM(p, NFC_PMID_LF_PROTOCOL);
548     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_PROTOCOL);
549     UINT8_TO_STREAM(p, p_cfg->lf_protocol_type);
550 
551     UINT8_TO_STREAM(p, NFC_PMID_LF_T3T_FLAGS2);
552     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_T3T_FLAGS2);
553     UINT16_TO_STREAM(p, p_cfg->lf_t3t_flags);
554 
555     /* if the bit at position X is set to 0, SC/NFCID2 with index X shall be
556      * ignored */
557     for (xx = 0; xx < NFA_LF_MAX_SC_NFCID2; xx++) {
558       if ((p_cfg->lf_t3t_flags & (0x0001 << xx)) != 0x0000) {
559         UINT8_TO_STREAM(p, NFC_PMID_LF_T3T_ID1 + xx);
560         UINT8_TO_STREAM(p, NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN);
561         ARRAY_TO_STREAM(p, p_cfg->lf_t3t_identifier[xx],
562                         NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN);
563       }
564     }
565 
566     UINT8_TO_STREAM(p, NFC_PMID_LF_T3T_PMM);
567     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_T3T_PMM);
568     ARRAY_TO_STREAM(p, p_cfg->lf_t3t_pmm, NCI_PARAM_LEN_LF_T3T_PMM);
569 
570     nfa_dm_check_set_config((uint8_t)(p - params), params, false);
571 
572     if (p_cfg->lf_t3t_flags != NCI_LF_T3T_FLAGS2_ALL_DISABLED) {
573       disc_mask |= NFA_DM_DISC_MASK_LF_T3T;
574     }
575   }
576 
577   /*
578   ** Discovery Configuration Parameters for Listen ISO-DEP
579   */
580   if ((disc_mask &
581        (NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LB_ISO_DEP)) &&
582       (p_cfg->li_enable)) {
583     p = params;
584 
585     UINT8_TO_STREAM(p, NFC_PMID_FWI);
586     UINT8_TO_STREAM(p, NCI_PARAM_LEN_FWI);
587     UINT8_TO_STREAM(p, p_cfg->li_fwi);
588 
589     if (disc_mask & NFA_DM_DISC_MASK_LA_ISO_DEP) {
590       UINT8_TO_STREAM(p, NFC_PMID_LA_HIST_BY);
591       UINT8_TO_STREAM(p, p_cfg->la_hist_bytes_len);
592       ARRAY_TO_STREAM(p, p_cfg->la_hist_bytes, p_cfg->la_hist_bytes_len);
593     }
594 
595     if (disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP) {
596       UINT8_TO_STREAM(p, NFC_PMID_LB_H_INFO);
597       UINT8_TO_STREAM(p, p_cfg->lb_h_info_resp_len);
598       ARRAY_TO_STREAM(p, p_cfg->lb_h_info_resp, p_cfg->lb_h_info_resp_len);
599     }
600 
601     nfa_dm_check_set_config((uint8_t)(p - params), params, false);
602   }
603 
604   *p_disc_mask = disc_mask;
605 
606   LOG(VERBOSE) << StringPrintf("disc_mask = 0x%x", disc_mask);
607 }
608 
609 /*******************************************************************************
610 **
611 ** Function         nfa_dm_disc_get_disc_mask
612 **
613 ** Description      Convert RF technology, mode and protocol to bit mask
614 **
615 ** Returns          tNFA_DM_DISC_TECH_PROTO_MASK
616 **
617 *******************************************************************************/
nfa_dm_disc_get_disc_mask(tNFC_RF_TECH_N_MODE tech_n_mode,tNFC_PROTOCOL protocol)618 static tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_disc_get_disc_mask(
619     tNFC_RF_TECH_N_MODE tech_n_mode, tNFC_PROTOCOL protocol) {
620   /* Set initial disc_mask to legacy poll or listen */
621   tNFA_DM_DISC_TECH_PROTO_MASK disc_mask =
622       ((tech_n_mode & 0x80) ? NFA_DM_DISC_MASK_L_LEGACY
623                             : NFA_DM_DISC_MASK_P_LEGACY);
624 
625   if (NFC_DISCOVERY_TYPE_POLL_A == tech_n_mode) {
626     switch (protocol) {
627       case NFC_PROTOCOL_T1T:
628         disc_mask = NFA_DM_DISC_MASK_PA_T1T;
629         break;
630       case NFC_PROTOCOL_T2T:
631         disc_mask = NFA_DM_DISC_MASK_PA_T2T;
632         break;
633       case NFC_PROTOCOL_ISO_DEP:
634         disc_mask = NFA_DM_DISC_MASK_PA_ISO_DEP;
635         break;
636       case NFC_PROTOCOL_NFC_DEP:
637         disc_mask = NFA_DM_DISC_MASK_PA_NFC_DEP;
638         break;
639     }
640   } else if (NFC_DISCOVERY_TYPE_POLL_B == tech_n_mode) {
641     if (protocol == NFC_PROTOCOL_ISO_DEP)
642       disc_mask = NFA_DM_DISC_MASK_PB_ISO_DEP;
643     else if (protocol == NCI_PROTOCOL_UNKNOWN) {
644       disc_mask = NFA_DM_DISC_MASK_PB_CI;
645     }
646   } else if (NFC_DISCOVERY_TYPE_POLL_F == tech_n_mode) {
647     if (protocol == NFC_PROTOCOL_T3T)
648       disc_mask = NFA_DM_DISC_MASK_PF_T3T;
649     else if (protocol == NFC_PROTOCOL_NFC_DEP)
650       disc_mask = NFA_DM_DISC_MASK_PF_NFC_DEP;
651   } else if (NFC_DISCOVERY_TYPE_POLL_V == tech_n_mode) {
652     disc_mask = NFA_DM_DISC_MASK_P_T5T;
653   } else if (NFC_DISCOVERY_TYPE_POLL_B_PRIME == tech_n_mode) {
654     disc_mask = NFA_DM_DISC_MASK_P_B_PRIME;
655   } else if (NFC_DISCOVERY_TYPE_POLL_KOVIO == tech_n_mode) {
656     disc_mask = NFA_DM_DISC_MASK_P_KOVIO;
657   } else if (NFC_DISCOVERY_TYPE_LISTEN_A == tech_n_mode) {
658     switch (protocol) {
659       case NFC_PROTOCOL_T1T:
660         disc_mask = NFA_DM_DISC_MASK_LA_T1T;
661         break;
662       case NFC_PROTOCOL_T2T:
663         disc_mask = NFA_DM_DISC_MASK_LA_T2T;
664         break;
665       case NFC_PROTOCOL_ISO_DEP:
666         disc_mask = NFA_DM_DISC_MASK_LA_ISO_DEP;
667         break;
668     }
669   } else if (NFC_DISCOVERY_TYPE_LISTEN_B == tech_n_mode) {
670     if (protocol == NFC_PROTOCOL_ISO_DEP)
671       disc_mask = NFA_DM_DISC_MASK_LB_ISO_DEP;
672   } else if (NFC_DISCOVERY_TYPE_LISTEN_F == tech_n_mode) {
673     if (protocol == NFC_PROTOCOL_T3T) disc_mask = NFA_DM_DISC_MASK_LF_T3T;
674   } else if (NFC_DISCOVERY_TYPE_LISTEN_ISO15693 == tech_n_mode) {
675     disc_mask = NFA_DM_DISC_MASK_L_ISO15693;
676   } else if (NFC_DISCOVERY_TYPE_LISTEN_B_PRIME == tech_n_mode) {
677     disc_mask = NFA_DM_DISC_MASK_L_B_PRIME;
678   }
679 
680   LOG(VERBOSE) << StringPrintf(
681       "tech_n_mode:0x%X, protocol:0x%X, "
682       "disc_mask:0x%X",
683       tech_n_mode, protocol, disc_mask);
684   return (disc_mask);
685 }
686 
687 /*******************************************************************************
688 **
689 ** Function         nfa_dm_disc_discovery_cback
690 **
691 ** Description      Discovery callback event from NFC
692 **
693 ** Returns          void
694 **
695 *******************************************************************************/
nfa_dm_disc_discovery_cback(tNFC_DISCOVER_EVT event,tNFC_DISCOVER * p_data)696 static void nfa_dm_disc_discovery_cback(tNFC_DISCOVER_EVT event,
697                                         tNFC_DISCOVER* p_data) {
698   tNFA_DM_RF_DISC_SM_EVENT dm_disc_event = NFA_DM_DISC_SM_MAX_EVENT;
699 
700   LOG(VERBOSE) << StringPrintf("event:0x%X", event);
701 
702   switch (event) {
703     case NFC_START_DEVT:
704       dm_disc_event = NFA_DM_RF_DISCOVER_RSP;
705       break;
706     case NFC_RESULT_DEVT:
707       dm_disc_event = NFA_DM_RF_DISCOVER_NTF;
708       break;
709     case NFC_SELECT_DEVT:
710       dm_disc_event = NFA_DM_RF_DISCOVER_SELECT_RSP;
711       break;
712     case NFC_ACTIVATE_DEVT:
713       dm_disc_event = NFA_DM_RF_INTF_ACTIVATED_NTF;
714       break;
715     case NFC_DEACTIVATE_DEVT:
716       if (p_data->deactivate.is_ntf) {
717         dm_disc_event = NFA_DM_RF_DEACTIVATE_NTF;
718         if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) ||
719             (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)) {
720           NFC_SetReassemblyFlag(true);
721           nfa_dm_cb.flags &= ~NFA_DM_FLAGS_RAW_FRAME;
722         }
723       } else
724         dm_disc_event = NFA_DM_RF_DEACTIVATE_RSP;
725       break;
726     case NFC_WPT_START_DEVT:
727       dm_disc_event = NFA_DM_WPT_START_RSP;
728       break;
729     case NFC_WPT_RESULT_DEVT:
730       nfa_wlc_cb.flags &= ~NFA_WLC_FLAGS_WPT_NTF_PENDING;
731 
732       tNFA_WLC_EVT_DATA wlc_cback_data;
733       wlc_cback_data.wpt_end_cdt = p_data->wpt_result;
734       nfa_wlc_event_notify(NFA_WLC_CHARGING_RESULT_EVT, &wlc_cback_data);
735       return;
736     default:
737       LOG(ERROR) << StringPrintf("Unexpected event");
738       return;
739   }
740 
741   tNFA_DM_RF_DISC_DATA nfa_dm_rf_disc_data;
742   nfa_dm_rf_disc_data.nfc_discover = *p_data;
743   nfa_dm_disc_sm_execute(dm_disc_event, &nfa_dm_rf_disc_data);
744 }
745 
746 /*******************************************************************************
747 **
748 ** Function         nfa_dm_disc_notify_started
749 **
750 ** Description      Report NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT or
751 **                  NFA_RF_DISCOVERY_STARTED_EVT, if needed
752 **
753 ** Returns          void
754 **
755 *******************************************************************************/
nfa_dm_disc_notify_started(tNFA_STATUS status)756 static void nfa_dm_disc_notify_started(tNFA_STATUS status) {
757   tNFA_CONN_EVT_DATA evt_data;
758 
759   if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY) {
760     nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
761 
762     evt_data.status = status;
763 
764     if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
765       nfa_dm_conn_cback_event_notify(NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT,
766                                      &evt_data);
767     else
768       nfa_dm_conn_cback_event_notify(NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
769   }
770 }
771 
772 /*******************************************************************************
773 **
774 ** Function         nfa_dm_disc_conn_event_notify
775 **
776 ** Description      Notify application of CONN_CBACK event, using appropriate
777 **                  callback
778 **
779 ** Returns          nothing
780 **
781 *******************************************************************************/
nfa_dm_disc_conn_event_notify(uint8_t event,tNFA_STATUS status)782 void nfa_dm_disc_conn_event_notify(uint8_t event, tNFA_STATUS status) {
783   tNFA_CONN_EVT_DATA evt_data;
784 
785   if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY) {
786     nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
787     evt_data.status = status;
788 
789     if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) {
790       /* Use exclusive RF mode callback */
791       if (nfa_dm_cb.p_excl_conn_cback)
792         (*nfa_dm_cb.p_excl_conn_cback)(event, &evt_data);
793     } else {
794       (*nfa_dm_cb.p_conn_cback)(event, &evt_data);
795     }
796   }
797 }
798 
799 /*******************************************************************************
800 **
801 ** Function         nfa_dm_disc_force_to_idle
802 **
803 ** Description      Force NFCC to idle state while waiting for deactivation NTF
804 **
805 ** Returns          tNFC_STATUS
806 **
807 *******************************************************************************/
nfa_dm_disc_force_to_idle(void)808 static tNFC_STATUS nfa_dm_disc_force_to_idle(void) {
809   tNFC_STATUS status = NFC_STATUS_SEMANTIC_ERROR;
810 
811   LOG(VERBOSE) << StringPrintf("disc_flags = 0x%x", nfa_dm_cb.disc_cb.disc_flags);
812 
813   /* do not execute more than one */
814   if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF) {
815     nfa_dm_cb.disc_cb.disc_flags &= ~(NFA_DM_DISC_FLAGS_W4_NTF);
816     nfa_dm_cb.disc_cb.disc_flags |= (NFA_DM_DISC_FLAGS_W4_RSP);
817     nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
818     status = NFC_Deactivate(NFC_DEACTIVATE_TYPE_IDLE);
819   }
820 
821   return (status);
822 }
823 
824 /*******************************************************************************
825 **
826 ** Function         nfa_dm_disc_deact_ntf_timeout_cback
827 **
828 ** Description      Timeout while waiting for deactivation NTF
829 **
830 ** Returns          void
831 **
832 *******************************************************************************/
nfa_dm_disc_deact_ntf_timeout_cback(TIMER_LIST_ENT * p_tle)833 static void nfa_dm_disc_deact_ntf_timeout_cback(__attribute__((unused))
834                                                 TIMER_LIST_ENT* p_tle) {
835   LOG(ERROR) << __func__;
836   if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE) {
837     LOG(ERROR) << "Ignoring deact_ntf_timeout in LISTEN_ACTIVE";
838     tNFA_DM_RF_DISC_DATA p_data;
839     p_data.nfc_discover.deactivate.status = NFC_STATUS_OK;
840     p_data.nfc_discover.deactivate.type = NFC_DEACTIVATE_TYPE_IDLE;
841     p_data.nfc_discover.deactivate.is_ntf = true;
842     p_data.nfc_discover.deactivate.reason = NFC_DEACTIVATE_REASON_DH_REQ;
843     nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_NTF, &p_data);
844     return;
845   }
846   nfa_dm_disc_force_to_idle();
847 }
848 
849 /*******************************************************************************
850 **
851 ** Function         nfa_dm_send_deactivate_cmd
852 **
853 ** Description      Send deactivate command to NFCC, if needed.
854 **
855 ** Returns          NFC_STATUS_OK             - deactivate cmd is sent
856 **                  NCI_STATUS_FAILED         - no buffers
857 **                  NFC_STATUS_SEMANTIC_ERROR - this function does not attempt
858 **                                              to send deactivate cmd
859 **
860 *******************************************************************************/
nfa_dm_send_deactivate_cmd(tNFC_DEACT_TYPE deactivate_type)861 static tNFC_STATUS nfa_dm_send_deactivate_cmd(tNFC_DEACT_TYPE deactivate_type) {
862   tNFC_STATUS status = NFC_STATUS_SEMANTIC_ERROR;
863   tNFA_DM_DISC_FLAGS w4_flags =
864       nfa_dm_cb.disc_cb.disc_flags &
865       (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
866 
867   if (!w4_flags) {
868     /* if deactivate CMD was not sent to NFCC */
869     nfa_dm_cb.disc_cb.disc_flags |=
870         (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
871 
872     status = NFC_Deactivate(deactivate_type);
873 
874     if (!nfa_dm_cb.disc_cb.tle.in_use) {
875       nfa_dm_cb.disc_cb.tle.p_cback =
876           (TIMER_CBACK*)nfa_dm_disc_deact_ntf_timeout_cback;
877       if ((nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE) &&
878           (p_nfa_dm_cfg != nullptr)) {
879         nfa_sys_start_timer(&nfa_dm_cb.disc_cb.tle, 0,
880                             p_nfa_dm_cfg->deact_ntf_listen_active_timeout);
881       } else {
882         nfa_sys_start_timer(&nfa_dm_cb.disc_cb.tle, 0,
883                             NFA_DM_DISC_TIMEOUT_W4_DEACT_NTF);
884       }
885     }
886   } else {
887     if (deactivate_type == NFC_DEACTIVATE_TYPE_SLEEP) {
888       status = NFC_STATUS_SEMANTIC_ERROR;
889     } else if (nfa_dm_cb.disc_cb.tle.in_use) {
890       status = NFC_STATUS_OK;
891     } else {
892       status = nfa_dm_disc_force_to_idle();
893     }
894   }
895 
896   return status;
897 }
898 
899 /*******************************************************************************
900 **
901 ** Function         nfa_dm_start_rf_discover
902 **
903 ** Description      Start RF discovery
904 **
905 ** Returns          void
906 **
907 *******************************************************************************/
nfa_dm_start_rf_discover(void)908 void nfa_dm_start_rf_discover(void) {
909   tNFC_DISCOVER_PARAMS disc_params[NFA_DM_MAX_DISC_PARAMS];
910   tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask = 0, poll_mask, listen_mask;
911   uint8_t config_params[10], *p;
912   uint8_t num_params, xx;
913 
914   LOG(VERBOSE) << __func__;
915   /* Make sure that RF discovery was enabled, or some app has exclusive control
916    */
917   if ((!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED)) &&
918       (nfa_dm_cb.disc_cb.excl_disc_entry.in_use == false)) {
919     return;
920   }
921 
922   /* get listen mode routing table for technology */
923   nfa_ee_get_tech_route(NFA_EE_PWR_STATE_ON, nfa_dm_cb.disc_cb.listen_RT);
924 
925   if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
926     nfa_dm_set_rf_listen_mode_raw_config(&dm_disc_mask);
927     dm_disc_mask |= (nfa_dm_cb.disc_cb.excl_disc_entry.requested_disc_mask &
928                      NFA_DM_DISC_MASK_POLL);
929     nfa_dm_cb.disc_cb.excl_disc_entry.selected_disc_mask = dm_disc_mask;
930   } else {
931     /* Collect RF discovery request from sub-modules */
932     for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
933       if (nfa_dm_cb.disc_cb.entry[xx].in_use) {
934         poll_mask = (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
935                      NFA_DM_DISC_MASK_POLL);
936 
937         /* clear poll mode technolgies and protocols which are already used by
938          * others */
939         poll_mask &= ~(dm_disc_mask & NFA_DM_DISC_MASK_POLL);
940 
941         listen_mask = 0;
942 
943         /*
944         ** add listen mode technolgies and protocols if host ID is
945         ** matched to listen mode routing table
946         */
947 
948         /* NFC-A */
949         if (nfa_dm_cb.disc_cb.entry[xx].host_id ==
950             nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A]) {
951           listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
952                          (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T |
953                           NFA_DM_DISC_MASK_LA_ISO_DEP);
954         }
955       } else {
956         /* host can listen ISO-DEP based on AID routing */
957         listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
958                         NFA_DM_DISC_MASK_LA_ISO_DEP);
959       }
960 
961       /* NFC-B */
962       /* multiple hosts can listen ISO-DEP based on AID routing */
963       listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
964                      NFA_DM_DISC_MASK_LB_ISO_DEP;
965 
966       /* NFC-F */
967       /* NFCC can support NFC-DEP and T3T listening based on NFCID routing
968        * regardless of NFC-F tech routing */
969       listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
970                      NFA_DM_DISC_MASK_LF_T3T;
971       /* NFC-B Prime */
972       if (nfa_dm_cb.disc_cb.entry[xx].host_id ==
973           nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_BP]) {
974         listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
975                        NFA_DM_DISC_MASK_L_B_PRIME;
976       }
977 
978       /*
979       ** clear listen mode technolgies and protocols which are already
980       ** used by others
981       */
982 
983       /* Check if other modules are listening T1T or T2T */
984       if (dm_disc_mask & (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T)) {
985         listen_mask &= ~(NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T |
986                          NFA_DM_DISC_MASK_LA_ISO_DEP);
987       }
988 
989       /* T1T/T2T has priority on NFC-A */
990       if ((dm_disc_mask & NFA_DM_DISC_MASK_LA_ISO_DEP) &&
991           (listen_mask & (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T))) {
992         dm_disc_mask &= ~NFA_DM_DISC_MASK_LA_ISO_DEP;
993       }
994 
995       nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask = poll_mask | listen_mask;
996 
997       LOG(VERBOSE) << StringPrintf(
998           "%s; nfa_dm_cb.disc_cb.entry[%d].selected_disc_mask = 0x%x", __func__,
999           xx, nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask);
1000 
1001       dm_disc_mask |= nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask;
1002     }
1003 
1004     if (NFC_GetNCIVersion() == NCI_VERSION_1_0) {
1005       if (dm_disc_mask & NFA_DM_DISC_MASK_PF_T3T) {
1006         /* According to the NFC Forum Activity spec, controllers must:
1007          * 1) Poll with RC=0 and SC=FFFF to find NFC-DEP targets
1008          * 2) Poll with RC=1 and SC=FFFF to find T3T targets
1009          * Many controllers don't do this yet, and seem to be activating
1010          * NFC-DEP by default.
1011          *
1012          * We can at least fix the scenario where we're not interested
1013          * in NFC-DEP, by setting RC=1 in that case. */
1014         p = config_params;
1015         UINT8_TO_STREAM(p, NFC_PMID_PF_RC);
1016         UINT8_TO_STREAM(p, NCI_PARAM_LEN_PF_RC);
1017         UINT8_TO_STREAM(p, 0x01);  // RC=1
1018         nfa_dm_check_set_config(p - config_params, config_params, false);
1019       }
1020     }
1021   }
1022 
1023   LOG(VERBOSE) << StringPrintf("dm_disc_mask = 0x%x", dm_disc_mask);
1024 
1025   /* Get Discovery Technology parameters */
1026   num_params = nfa_dm_get_rf_discover_config(dm_disc_mask, disc_params,
1027                                              NFA_DM_MAX_DISC_PARAMS);
1028 
1029   if (num_params) {
1030     /*
1031     ** NFCC will abort programming personality slots if not available.
1032     ** NFCC programs the personality slots in the following order of RF
1033     ** technologies: NFC-A, NFC-B, NFC-BP, NFC-I93
1034     */
1035 
1036     /* if this is not for exclusive control */
1037     if (!nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
1038       /* update listening protocols in each NFC technology */
1039       nfa_dm_set_rf_listen_mode_config(dm_disc_mask);
1040     }
1041 
1042     /* Set polling duty cycle */
1043     nfa_dm_set_total_duration();
1044     nfa_dm_cb.disc_cb.dm_disc_mask = dm_disc_mask;
1045 
1046     NFC_DiscoveryStart(num_params, disc_params, nfa_dm_disc_discovery_cback);
1047     /* set flag about waiting for response in IDLE state */
1048     nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1049 
1050     /* register callback to get interface error NTF */
1051     NFC_SetStaticRfCback(nfa_dm_disc_data_cback);
1052   } else {
1053     /* RF discovery is started but there is no valid technology or protocol to
1054      * discover */
1055     nfa_dm_disc_notify_started(NFA_STATUS_OK);
1056   }
1057 
1058   /* if Kovio presence check timer is running, timeout callback will reset the
1059    * activation information */
1060   if ((nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_KOVIO) ||
1061       (!nfa_dm_cb.disc_cb.kovio_tle.in_use)) {
1062     /* reset protocol and hanlde of activated sub-module */
1063     nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
1064     nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
1065   }
1066 }
1067 
1068 /*******************************************************************************
1069 **
1070 ** Function         nfa_dm_notify_discovery
1071 **
1072 ** Description      Send RF discovery notification to upper layer
1073 **
1074 ** Returns          void
1075 **
1076 *******************************************************************************/
nfa_dm_notify_discovery(tNFA_DM_RF_DISC_DATA * p_data)1077 static void nfa_dm_notify_discovery(tNFA_DM_RF_DISC_DATA* p_data) {
1078   tNFA_CONN_EVT_DATA conn_evt;
1079 
1080   /* let application select a device */
1081   conn_evt.disc_result.status = NFA_STATUS_OK;
1082   memcpy(&(conn_evt.disc_result.discovery_ntf), &(p_data->nfc_discover.result),
1083          sizeof(tNFC_RESULT_DEVT));
1084 
1085   nfa_dm_conn_cback_event_notify(NFA_DISC_RESULT_EVT, &conn_evt);
1086 }
1087 
1088 /*******************************************************************************
1089 **
1090 ** Function         nfa_dm_start_wireless_power_transfer
1091 **
1092 ** Description      Send WPT request to NFCC
1093 **
1094 ** Returns          void
1095 **
1096 *******************************************************************************/
nfa_dm_start_wireless_power_transfer(uint8_t power_adj_req,uint8_t wpt_time_int)1097 void nfa_dm_start_wireless_power_transfer(uint8_t power_adj_req,
1098                                           uint8_t wpt_time_int) {
1099   tNFA_DM_DISC_WPT_START_PARAMS start_wpt_params;
1100 
1101   LOG(VERBOSE) << StringPrintf("%s; power_adj_req: 0x%X, wpt_time_int: 0x%X",
1102                              __func__, power_adj_req, wpt_time_int);
1103 
1104   if ((nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) &&
1105       (nfa_dm_cb.flags & NFA_DM_FLAGS_RF_EXT_ACTIVE)) {
1106     /* state is OK: notify the status when the response is received from NFCC */
1107     start_wpt_params.power_adj_req = power_adj_req;
1108     start_wpt_params.wpt_time_int = wpt_time_int;
1109 
1110     nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_NOTIFY;
1111     tNFA_DM_RF_DISC_DATA nfa_dm_wpt_start_data;
1112     nfa_dm_wpt_start_data.start_wpt = start_wpt_params;
1113 
1114     nfa_dm_disc_sm_execute(NFA_DM_WPT_START_CMD, &nfa_dm_wpt_start_data);
1115   } else {
1116     nfa_dm_cb.flags &= ~NFA_DM_FLAGS_ENABLE_WLCP_PEND;
1117 
1118     tNFA_WLC_EVT_DATA wlc_cback_data;
1119     /* Wrong state: notify failed status right away */
1120     wlc_cback_data.status = NFA_STATUS_FAILED;
1121 
1122     LOG(VERBOSE) << StringPrintf("%s; wlc_cback_data.status: 0x%X", __func__,
1123                                wlc_cback_data.status);
1124 
1125     nfa_wlc_event_notify(NFA_WLC_START_WPT_RESULT_EVT, &wlc_cback_data);
1126   }
1127 }
1128 
1129 /*******************************************************************************
1130 **
1131 ** Function         nfa_dm_disc_handle_kovio_activation
1132 **
1133 ** Description      Handle Kovio activation; whether it's new or repeated
1134 **                  activation
1135 **
1136 ** Returns          TRUE if repeated activation. No need to notify activated
1137 **                  event to upper layer
1138 **
1139 *******************************************************************************/
nfa_dm_disc_handle_kovio_activation(tNFC_DISCOVER * p_data,tNFA_DISCOVER_CBACK * p_disc_cback)1140 bool nfa_dm_disc_handle_kovio_activation(tNFC_DISCOVER* p_data,
1141                                          tNFA_DISCOVER_CBACK* p_disc_cback) {
1142   tNFC_DISCOVER disc_data;
1143 
1144   if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
1145     /* if this is new Kovio bar code tag */
1146     if ((nfa_dm_cb.activated_nfcid_len !=
1147          p_data->activate.rf_tech_param.param.pk.uid_len) ||
1148         (memcmp(p_data->activate.rf_tech_param.param.pk.uid,
1149                 nfa_dm_cb.activated_nfcid, nfa_dm_cb.activated_nfcid_len))) {
1150       LOG(VERBOSE) << StringPrintf("new Kovio tag is detected");
1151 
1152       /* notify presence check failure for previous tag, if presence check is
1153        * pending */
1154       nfa_dm_disc_report_kovio_presence_check(NFA_STATUS_FAILED);
1155 
1156       /* notify deactivation of previous activation before notifying new
1157        * activation */
1158       if (p_disc_cback) {
1159         disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
1160         (*(p_disc_cback))(NFA_DM_RF_DISC_DEACTIVATED_EVT, &disc_data);
1161       }
1162 
1163       /* restart timer */
1164       nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
1165                           NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1166     } else {
1167       /* notify presence check ok, if presence check is pending */
1168       nfa_dm_disc_report_kovio_presence_check(NFC_STATUS_OK);
1169 
1170       /* restart timer and do not notify upper layer */
1171       nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
1172                           NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1173       return true;
1174     }
1175   } else {
1176     /* this is the first activation, so start timer and notify upper layer */
1177     nfa_dm_cb.disc_cb.kovio_tle.p_cback =
1178         (TIMER_CBACK*)nfa_dm_disc_kovio_timeout_cback;
1179     nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
1180                         NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1181   }
1182 
1183   return false;
1184 }
1185 
1186 /*******************************************************************************
1187 **
1188 ** Function         nfa_dm_disc_notify_activation
1189 **
1190 ** Description      Send RF activation notification to sub-module
1191 **
1192 ** Returns          NFA_STATUS_OK if success
1193 **
1194 *******************************************************************************/
nfa_dm_disc_notify_activation(tNFC_DISCOVER * p_data)1195 static tNFA_STATUS nfa_dm_disc_notify_activation(tNFC_DISCOVER* p_data) {
1196   uint8_t xx, host_id_in_LRT;
1197   uint8_t iso_dep_t3t__listen = NFA_DM_DISC_NUM_ENTRIES;
1198 
1199   tNFC_RF_TECH_N_MODE tech_n_mode = p_data->activate.rf_tech_param.mode;
1200   tNFC_PROTOCOL protocol = p_data->activate.protocol;
1201 
1202   tNFA_DM_DISC_TECH_PROTO_MASK activated_disc_mask;
1203 
1204   LOG(VERBOSE) << StringPrintf("tech_n_mode:0x%X, proto:0x%X", tech_n_mode,
1205                              protocol);
1206 
1207   if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
1208     nfa_dm_cb.disc_cb.activated_tech_mode = tech_n_mode;
1209     nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
1210     nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
1211     nfa_dm_cb.disc_cb.activated_protocol = protocol;
1212     nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
1213 
1214     if (protocol == NFC_PROTOCOL_KOVIO) {
1215       /* check whether it's new or repeated activation */
1216       if (nfa_dm_disc_handle_kovio_activation(
1217               p_data, nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) {
1218         /* do not notify activation of Kovio to upper layer */
1219         return (NFA_STATUS_OK);
1220       }
1221     }
1222 
1223     if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
1224       (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
1225           NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
1226 
1227     return (NFA_STATUS_OK);
1228   }
1229 
1230   /* if this is NFCEE direct RF interface, notify activation to whoever
1231    * listening UICC */
1232   if (p_data->activate.intf_param.type == NFC_INTERFACE_EE_DIRECT_RF) {
1233     for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
1234       if ((nfa_dm_cb.disc_cb.entry[xx].in_use) &&
1235           (nfa_dm_cb.disc_cb.entry[xx].host_id != NFA_DM_DISC_HOST_ID_DH)) {
1236         nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
1237         nfa_dm_cb.disc_cb.activated_rf_interface =
1238             p_data->activate.intf_param.type;
1239         nfa_dm_cb.disc_cb.activated_protocol = NFC_PROTOCOL_UNKNOWN;
1240         nfa_dm_cb.disc_cb.activated_handle = xx;
1241 
1242         LOG(VERBOSE) << StringPrintf(
1243             "activated_rf_interface:0x%x, activated_handle: 0x%x",
1244             nfa_dm_cb.disc_cb.activated_rf_interface,
1245             nfa_dm_cb.disc_cb.activated_handle);
1246 
1247         if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1248           (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
1249               NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
1250 
1251         return (NFA_STATUS_OK);
1252       }
1253     }
1254     return (NFA_STATUS_FAILED);
1255   }
1256 
1257   /* get bit mask of technolgies/mode and protocol */
1258   activated_disc_mask = nfa_dm_disc_get_disc_mask(tech_n_mode, protocol);
1259 
1260   /* get host ID of technology from listen mode routing table */
1261   if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) {
1262     host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A];
1263   } else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) {
1264     host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B];
1265   } else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) {
1266     host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F];
1267   } else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) {
1268     host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_BP];
1269   } else /* DH only */
1270   {
1271     host_id_in_LRT = NFA_DM_DISC_HOST_ID_DH;
1272   }
1273 
1274   if (protocol == NFC_PROTOCOL_NFC_DEP) {
1275     /* Force NFC-DEP to the host */
1276     host_id_in_LRT = NFA_DM_DISC_HOST_ID_DH;
1277   }
1278 
1279   for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
1280     /* if any matching NFC technology and protocol */
1281     if (nfa_dm_cb.disc_cb.entry[xx].in_use) {
1282       if (nfa_dm_cb.disc_cb.entry[xx].host_id == host_id_in_LRT) {
1283         if (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
1284             activated_disc_mask)
1285           break;
1286       } else {
1287         /* check ISO-DEP listening even if host in LRT is not matched */
1288         if (protocol == NFC_PROTOCOL_ISO_DEP) {
1289           if ((tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) &&
1290               (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
1291                NFA_DM_DISC_MASK_LA_ISO_DEP)) {
1292             iso_dep_t3t__listen = xx;
1293           } else if ((tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) &&
1294                      (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
1295                       NFA_DM_DISC_MASK_LB_ISO_DEP)) {
1296             iso_dep_t3t__listen = xx;
1297           }
1298         }
1299         /* check T3T listening even if host in LRT is not matched */
1300         else if (protocol == NFC_PROTOCOL_T3T) {
1301           if ((tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) &&
1302               (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
1303                NFA_DM_DISC_MASK_LF_T3T)) {
1304             iso_dep_t3t__listen = xx;
1305           }
1306         }
1307       }
1308     }
1309   }
1310 
1311   if (xx >= NFA_DM_DISC_NUM_ENTRIES) {
1312     /* if any ISO-DEP or T3T listening even if host in LRT is not matched */
1313     xx = iso_dep_t3t__listen;
1314   }
1315   if (protocol == NFC_PROTOCOL_NFC_DEP &&
1316       (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A)) {
1317     if (appl_dta_mode_flag == 1 && tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) {
1318       LOG(VERBOSE) << StringPrintf(
1319           "DTA Mode Enabled : NFC-A Passive Listen Mode");
1320     }
1321   }
1322 
1323   if (xx < NFA_DM_DISC_NUM_ENTRIES) {
1324     nfa_dm_cb.disc_cb.activated_tech_mode = tech_n_mode;
1325     nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
1326     nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
1327     nfa_dm_cb.disc_cb.activated_protocol = protocol;
1328     nfa_dm_cb.disc_cb.activated_handle = xx;
1329 
1330     LOG(VERBOSE) << StringPrintf(
1331         "activated_protocol:0x%x, activated_handle: 0x%x",
1332         nfa_dm_cb.disc_cb.activated_protocol,
1333         nfa_dm_cb.disc_cb.activated_handle);
1334 
1335     if (protocol == NFC_PROTOCOL_KOVIO) {
1336       /* check whether it's new or repeated activation */
1337       if (nfa_dm_disc_handle_kovio_activation(
1338               p_data, nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) {
1339         /* do not notify activation of Kovio to upper layer */
1340         return (NFA_STATUS_OK);
1341       }
1342     }
1343 
1344     if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1345       (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
1346           NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
1347 
1348     return (NFA_STATUS_OK);
1349   } else {
1350     nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
1351     nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
1352     return (NFA_STATUS_FAILED);
1353   }
1354 }
1355 
1356 /*******************************************************************************
1357 **
1358 ** Function         nfa_dm_disc_notify_deactivation
1359 **
1360 ** Description      Send deactivation notification to sub-module
1361 **
1362 ** Returns          None
1363 **
1364 *******************************************************************************/
nfa_dm_disc_notify_deactivation(tNFA_DM_RF_DISC_SM_EVENT sm_event,tNFC_DISCOVER * p_data)1365 static void nfa_dm_disc_notify_deactivation(tNFA_DM_RF_DISC_SM_EVENT sm_event,
1366                                             tNFC_DISCOVER* p_data) {
1367   tNFA_HANDLE xx;
1368   tNFA_CONN_EVT_DATA evt_data;
1369   tNFC_DISCOVER disc_data;
1370 
1371   LOG(VERBOSE) << StringPrintf("activated_handle=%d",
1372                              nfa_dm_cb.disc_cb.activated_handle);
1373 
1374   if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING) {
1375     LOG(VERBOSE) << StringPrintf("for sleep wakeup");
1376     return;
1377   }
1378 
1379   if (sm_event == NFA_DM_RF_DEACTIVATE_RSP) {
1380     /*
1381     ** Activation has been aborted by upper layer in
1382     ** NFA_DM_RFST_W4_ALL_DISCOVERIES or NFA_DM_RFST_W4_HOST_SELECT
1383     ** Deactivation by upper layer or RF link loss in
1384     ** NFA_DM_RFST_LISTEN_SLEEP
1385     ** No sub-module is activated at this state.
1386     */
1387 
1388     if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_SLEEP) {
1389       if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
1390         if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback) {
1391           disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
1392           (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
1393               NFA_DM_RF_DISC_DEACTIVATED_EVT, &disc_data);
1394         }
1395       } else {
1396         /* let each sub-module handle deactivation */
1397         for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
1398           if ((nfa_dm_cb.disc_cb.entry[xx].in_use) &&
1399               (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
1400                NFA_DM_DISC_MASK_LISTEN)) {
1401             disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
1402             (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
1403                 NFA_DM_RF_DISC_DEACTIVATED_EVT, &disc_data);
1404           }
1405         }
1406       }
1407     } else if ((!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)) ||
1408                (nfa_dm_cb.disc_cb.deact_notify_pending)) {
1409       xx = nfa_dm_cb.disc_cb.activated_handle;
1410 
1411       /* notify event to activated module if failed while reactivation */
1412       if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
1413         if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback) {
1414           disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
1415           (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
1416               NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
1417         }
1418       } else if ((xx < NFA_DM_DISC_NUM_ENTRIES) &&
1419                  (nfa_dm_cb.disc_cb.entry[xx].in_use) &&
1420                  (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) {
1421         (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
1422             NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
1423       } else {
1424         /* notify deactivation to application if there is no activated module */
1425         evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
1426         nfa_dm_conn_cback_event_notify(NFA_DEACTIVATED_EVT, &evt_data);
1427       }
1428     }
1429   } else {
1430     if (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO) {
1431       if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
1432         /* restart timer and do not notify upper layer */
1433         nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
1434                             NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1435         /* clear activated information */
1436         nfa_dm_cb.disc_cb.activated_tech_mode = 0;
1437         nfa_dm_cb.disc_cb.activated_rf_disc_id = 0;
1438         nfa_dm_cb.disc_cb.activated_rf_interface = 0;
1439         nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
1440         nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
1441         nfa_dm_cb.disc_cb.deact_notify_pending = false;
1442         return;
1443       }
1444       /* Otherwise, upper layer initiated deactivation. */
1445     }
1446 
1447     /* notify event to activated module */
1448     if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
1449       if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback) {
1450         disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
1451         (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
1452             NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
1453       }
1454     } else {
1455       xx = nfa_dm_cb.disc_cb.activated_handle;
1456 
1457       if ((xx < NFA_DM_DISC_NUM_ENTRIES) &&
1458           (nfa_dm_cb.disc_cb.entry[xx].in_use)) {
1459         if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1460           (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
1461               NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
1462       }
1463     }
1464   }
1465 
1466   /* clear activated information */
1467   nfa_dm_cb.disc_cb.activated_tech_mode = 0;
1468   nfa_dm_cb.disc_cb.activated_rf_disc_id = 0;
1469   nfa_dm_cb.disc_cb.activated_rf_interface = 0;
1470   nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
1471   nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
1472   nfa_dm_cb.disc_cb.deact_notify_pending = false;
1473 }
1474 
1475 /*******************************************************************************
1476 **
1477 ** Function         nfa_dm_disc_sleep_wakeup
1478 **
1479 ** Description      Put tag to sleep, then wake it up. Can be used Perform
1480 **                  legacy presence check or to wake up tag that went to HALT
1481 **                  state
1482 **
1483 ** Returns          TRUE if operation started
1484 **
1485 *******************************************************************************/
nfa_dm_disc_sleep_wakeup(void)1486 tNFC_STATUS nfa_dm_disc_sleep_wakeup(void) {
1487   tNFC_STATUS status = NFC_STATUS_FAILED;
1488 
1489   if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) {
1490     /* Deactivate to sleep mode */
1491     status = nfa_dm_send_deactivate_cmd(NFC_DEACTIVATE_TYPE_SLEEP);
1492     if (status == NFC_STATUS_OK) {
1493       /* deactivate to sleep is sent on behalf of sleep wakeup.
1494        * set the sleep wakeup information in control block */
1495       nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_CHECKING;
1496       nfa_dm_cb.disc_cb.deact_pending = false;
1497     }
1498   }
1499 
1500   return (status);
1501 }
1502 
1503 /*******************************************************************************
1504 **
1505 ** Function         nfa_dm_is_raw_frame_session
1506 **
1507 ** Description      If NFA_SendRawFrame is called since RF activation,
1508 **                  this function returns TRUE.
1509 **
1510 ** Returns          TRUE if NFA_SendRawFrame is called
1511 **
1512 *******************************************************************************/
nfa_dm_is_raw_frame_session(void)1513 bool nfa_dm_is_raw_frame_session(void) {
1514   return ((nfa_dm_cb.flags & NFA_DM_FLAGS_RAW_FRAME) ? true : false);
1515 }
1516 
1517 /*******************************************************************************
1518 **
1519 ** Function         nfa_dm_disc_end_sleep_wakeup
1520 **
1521 ** Description      Sleep Wakeup is complete
1522 **
1523 ** Returns          None
1524 **
1525 *******************************************************************************/
nfa_dm_disc_end_sleep_wakeup(tNFC_STATUS status)1526 static void nfa_dm_disc_end_sleep_wakeup(tNFC_STATUS status) {
1527   if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO) &&
1528       (nfa_dm_cb.disc_cb.kovio_tle.in_use)) {
1529     /* ignore it while doing Kovio presence check */
1530     return;
1531   }
1532 
1533   if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING) {
1534     nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_CHECKING;
1535 
1536     /* notify RW module that sleep wakeup is finished */
1537     nfa_rw_handle_sleep_wakeup_rsp(status);
1538 
1539     if (nfa_dm_cb.disc_cb.deact_pending) {
1540       nfa_dm_cb.disc_cb.deact_pending = false;
1541       /* Perform pending deactivate command and on response notfiy deactivation
1542        */
1543       nfa_dm_cb.disc_cb.deact_notify_pending = true;
1544       tNFA_DM_RF_DISC_DATA nfa_dm_rf_disc_data;
1545       nfa_dm_rf_disc_data.deactivate_type =
1546           nfa_dm_cb.disc_cb.pending_deact_type;
1547       nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD, &nfa_dm_rf_disc_data);
1548     }
1549   }
1550 }
1551 
1552 /*******************************************************************************
1553 **
1554 ** Function         nfa_dm_disc_kovio_timeout_cback
1555 **
1556 ** Description      Timeout for Kovio bar code tag presence check
1557 **
1558 ** Returns          void
1559 **
1560 *******************************************************************************/
nfa_dm_disc_kovio_timeout_cback(TIMER_LIST_ENT * p_tle)1561 static void nfa_dm_disc_kovio_timeout_cback(__attribute__((unused))
1562                                             TIMER_LIST_ENT* p_tle) {
1563   LOG(VERBOSE) << __func__;
1564 
1565   /* notify presence check failure, if presence check is pending */
1566   nfa_dm_disc_report_kovio_presence_check(NFC_STATUS_FAILED);
1567 
1568   if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) {
1569     /* restart timer in case that upper layer's presence check interval is too
1570      * long */
1571     nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
1572                         NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1573   } else {
1574     /* notify upper layer deactivated event */
1575     tNFC_DEACTIVATE_DEVT deact;
1576     deact.status = NFC_STATUS_OK;
1577     deact.type = NFC_DEACTIVATE_TYPE_DISCOVERY;
1578     deact.is_ntf = true;
1579     deact.reason = NFC_DEACTIVATE_REASON_DH_REQ;
1580     tNFC_DISCOVER nfc_discover;
1581     nfc_discover.deactivate = deact;
1582     nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF, &nfc_discover);
1583   }
1584 }
1585 
1586 /*******************************************************************************
1587 **
1588 ** Function         nfa_dm_disc_start_kovio_presence_check
1589 **
1590 ** Description      Deactivate to discovery mode and wait for activation
1591 **
1592 ** Returns          TRUE if operation started
1593 **
1594 *******************************************************************************/
nfa_dm_disc_start_kovio_presence_check(void)1595 tNFC_STATUS nfa_dm_disc_start_kovio_presence_check(void) {
1596   tNFC_STATUS status = NFC_STATUS_FAILED;
1597 
1598   LOG(VERBOSE) << __func__;
1599 
1600   if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO) &&
1601       (nfa_dm_cb.disc_cb.kovio_tle.in_use)) {
1602     if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) {
1603       /* restart timer */
1604       nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
1605                           NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1606 
1607       /* Deactivate to discovery mode */
1608       status = nfa_dm_send_deactivate_cmd(NFC_DEACTIVATE_TYPE_DISCOVERY);
1609 
1610       if (status == NFC_STATUS_OK) {
1611         /* deactivate to sleep is sent on behalf of sleep wakeup.
1612          * set the sleep wakeup information in control block */
1613         nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_CHECKING;
1614         nfa_dm_cb.disc_cb.deact_pending = false;
1615       }
1616     } else {
1617       /* wait for next activation */
1618       nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_CHECKING;
1619       nfa_dm_cb.disc_cb.deact_pending = false;
1620       status = NFC_STATUS_OK;
1621     }
1622   }
1623 
1624   return (status);
1625 }
1626 
1627 /*******************************************************************************
1628 **
1629 ** Function         nfa_dm_disc_report_kovio_presence_check
1630 **
1631 ** Description      Report Kovio presence check status
1632 **
1633 ** Returns          None
1634 **
1635 *******************************************************************************/
nfa_dm_disc_report_kovio_presence_check(tNFC_STATUS status)1636 static void nfa_dm_disc_report_kovio_presence_check(tNFC_STATUS status) {
1637   LOG(VERBOSE) << __func__;
1638 
1639   if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING) {
1640     nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_CHECKING;
1641 
1642     /* notify RW module that sleep wakeup is finished */
1643     nfa_rw_handle_presence_check_rsp(status);
1644 
1645     if (nfa_dm_cb.disc_cb.deact_pending) {
1646       nfa_dm_cb.disc_cb.deact_pending = false;
1647       tNFA_DM_RF_DISC_DATA nfa_dm_rf_disc_data;
1648       nfa_dm_rf_disc_data.deactivate_type =
1649           nfa_dm_cb.disc_cb.pending_deact_type;
1650       nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD, &nfa_dm_rf_disc_data);
1651     }
1652   }
1653 }
1654 
1655 /*******************************************************************************
1656 **
1657 ** Function         nfa_dm_disc_data_cback
1658 **
1659 ** Description      Monitoring interface error through data callback
1660 **
1661 ** Returns          void
1662 **
1663 *******************************************************************************/
nfa_dm_disc_data_cback(uint8_t conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)1664 static void nfa_dm_disc_data_cback(__attribute__((unused)) uint8_t conn_id,
1665                                    tNFC_CONN_EVT event, tNFC_CONN* p_data) {
1666   LOG(VERBOSE) << __func__;
1667 
1668   /* if selection failed */
1669   if (event == NFC_ERROR_CEVT) {
1670     nfa_dm_disc_sm_execute(NFA_DM_CORE_INTF_ERROR_NTF, nullptr);
1671   } else if (event == NFC_DATA_CEVT) {
1672     GKI_freebuf(p_data->data.p_data);
1673   }
1674 }
1675 
1676 /*******************************************************************************
1677 **
1678 ** Function         nfa_dm_disc_new_state
1679 **
1680 ** Description      Processing discovery events in NFA_DM_RFST_IDLE state
1681 **
1682 ** Returns          void
1683 **
1684 *******************************************************************************/
nfa_dm_disc_new_state(tNFA_DM_RF_DISC_STATE new_state)1685 void nfa_dm_disc_new_state(tNFA_DM_RF_DISC_STATE new_state) {
1686   tNFA_CONN_EVT_DATA evt_data;
1687   tNFA_DM_RF_DISC_STATE old_state = nfa_dm_cb.disc_cb.disc_state;
1688 
1689   LOG(VERBOSE) << StringPrintf(
1690       "old_state: %s (%d), new_state: %s (%d) "
1691       "disc_flags: 0x%x",
1692       nfa_dm_disc_state_2_str(nfa_dm_cb.disc_cb.disc_state).c_str(),
1693       nfa_dm_cb.disc_cb.disc_state, nfa_dm_disc_state_2_str(new_state).c_str(),
1694       new_state, nfa_dm_cb.disc_cb.disc_flags);
1695 
1696   nfa_dm_cb.disc_cb.disc_state = new_state;
1697 
1698   /* not error recovering */
1699   if ((new_state == NFA_DM_RFST_IDLE) &&
1700       (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))) {
1701     if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING) {
1702       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_STOPPING;
1703 
1704       /* if exclusive RF control is stopping */
1705       if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) {
1706         if (old_state > NFA_DM_RFST_DISCOVERY) {
1707           /* notify deactivation to application */
1708           evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
1709           nfa_dm_conn_cback_event_notify(NFA_DEACTIVATED_EVT, &evt_data);
1710         }
1711 
1712         nfa_dm_rel_excl_rf_control_and_notify();
1713       } else {
1714         evt_data.status = NFA_STATUS_OK;
1715         nfa_dm_conn_cback_event_notify(NFA_RF_DISCOVERY_STOPPED_EVT, &evt_data);
1716       }
1717     }
1718     if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_DISABLING) {
1719       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_DISABLING;
1720       nfa_sys_check_disabled();
1721     }
1722   }
1723 }
1724 
1725 /*******************************************************************************
1726 **
1727 ** Function         nfa_dm_disc_sm_idle
1728 **
1729 ** Description      Processing discovery events in NFA_DM_RFST_IDLE state
1730 **
1731 ** Returns          void
1732 **
1733 *******************************************************************************/
nfa_dm_disc_sm_idle(tNFA_DM_RF_DISC_SM_EVENT event,tNFA_DM_RF_DISC_DATA * p_data)1734 static void nfa_dm_disc_sm_idle(tNFA_DM_RF_DISC_SM_EVENT event,
1735                                 tNFA_DM_RF_DISC_DATA* p_data) {
1736   uint8_t xx;
1737 
1738   switch (event) {
1739     case NFA_DM_RF_DISCOVER_CMD:
1740       nfa_dm_start_rf_discover();
1741       break;
1742 
1743     case NFA_DM_RF_DISCOVER_RSP:
1744       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1745 
1746       if (p_data->nfc_discover.status == NFC_STATUS_OK) {
1747         nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
1748 
1749         /* if RF discovery was stopped while waiting for response */
1750         if (nfa_dm_cb.disc_cb.disc_flags &
1751             (NFA_DM_DISC_FLAGS_STOPPING | NFA_DM_DISC_FLAGS_DISABLING)) {
1752           /* stop discovery */
1753           nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1754           NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
1755           if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_DISABLING) {
1756             break;
1757           }
1758         }
1759 
1760         if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
1761           if (nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags &
1762               NFA_DM_DISC_FLAGS_NOTIFY) {
1763             nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags &=
1764                 ~NFA_DM_DISC_FLAGS_NOTIFY;
1765 
1766             if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
1767               (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
1768                   NFA_DM_RF_DISC_START_EVT, &p_data->nfc_discover);
1769           }
1770         } else {
1771           /* notify event to each module which is waiting for start */
1772           for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
1773             /* if registered module is waiting for starting discovery */
1774             if ((nfa_dm_cb.disc_cb.entry[xx].in_use) &&
1775                 (nfa_dm_cb.disc_cb.dm_disc_mask &
1776                  nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask) &&
1777                 (nfa_dm_cb.disc_cb.entry[xx].disc_flags &
1778                  NFA_DM_DISC_FLAGS_NOTIFY)) {
1779               nfa_dm_cb.disc_cb.entry[xx].disc_flags &=
1780                   ~NFA_DM_DISC_FLAGS_NOTIFY;
1781 
1782               if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1783                 (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
1784                     NFA_DM_RF_DISC_START_EVT, &p_data->nfc_discover);
1785             }
1786           }
1787         }
1788         nfa_dm_disc_notify_started(p_data->nfc_discover.status);
1789       } else {
1790         /* in rare case that the discovery states of NFCC and DH mismatch and
1791          * NFCC rejects Discover Cmd
1792          * deactivate idle and then start disvocery when got deactivate rsp */
1793         nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1794         NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
1795       }
1796       break;
1797 
1798     case NFA_DM_RF_DEACTIVATE_RSP:
1799       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1800 
1801       /* if NFCC goes to idle successfully */
1802       if (p_data->nfc_discover.status == NFC_STATUS_OK) {
1803         /* if DH forced to go idle while waiting for deactivation NTF */
1804         if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
1805           nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
1806                                           &(p_data->nfc_discover));
1807 
1808           /* check any pending flags like NFA_DM_DISC_FLAGS_STOPPING or
1809            * NFA_DM_DISC_FLAGS_DISABLING */
1810           nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
1811           /* check if need to restart discovery after resync discovery state
1812            * with NFCC */
1813           nfa_dm_start_rf_discover();
1814         }
1815         /* Otherwise, deactivating when getting unexpected activation */
1816       }
1817       /* Otherwise, wait for deactivation NTF */
1818       break;
1819 
1820     case NFA_DM_RF_DEACTIVATE_NTF:
1821       /* if NFCC sent this after NFCC had rejected deactivate CMD to idle while
1822        * deactivating */
1823       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
1824         if (p_data->nfc_discover.deactivate.type ==
1825             NFC_DEACTIVATE_TYPE_DISCOVERY) {
1826           /* stop discovery */
1827           nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1828           NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
1829         } else {
1830           nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
1831                                           &(p_data->nfc_discover));
1832           /* check any pending flags like NFA_DM_DISC_FLAGS_STOPPING or
1833            * NFA_DM_DISC_FLAGS_DISABLING */
1834           nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
1835           /* check if need to restart discovery after resync discovery state
1836            * with NFCC */
1837           nfa_dm_start_rf_discover();
1838         }
1839       }
1840       /* Otherwise, deactivated when received unexpected activation in idle
1841        * state */
1842       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
1843       break;
1844 
1845     case NFA_DM_RF_INTF_ACTIVATED_NTF:
1846       /* unexpected activation, deactivate to idle */
1847       nfa_dm_cb.disc_cb.disc_flags |=
1848           (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
1849       NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
1850       break;
1851 
1852     case NFA_DM_LP_LISTEN_CMD:
1853       nfa_dm_disc_new_state(NFA_DM_RFST_LP_LISTEN);
1854       break;
1855 
1856     default:
1857       LOG(ERROR) << StringPrintf("Unexpected discovery event");
1858       break;
1859   }
1860 }
1861 
1862 /*******************************************************************************
1863 **
1864 ** Function         nfa_dm_disc_sm_discovery
1865 **
1866 ** Description      Processing discovery events in NFA_DM_RFST_DISCOVERY state
1867 **
1868 ** Returns          void
1869 **
1870 *******************************************************************************/
nfa_dm_disc_sm_discovery(tNFA_DM_RF_DISC_SM_EVENT event,tNFA_DM_RF_DISC_DATA * p_data)1871 static void nfa_dm_disc_sm_discovery(tNFA_DM_RF_DISC_SM_EVENT event,
1872                                      tNFA_DM_RF_DISC_DATA* p_data) {
1873   switch (event) {
1874     case NFA_DM_RF_DEACTIVATE_CMD:
1875       /* if deactivate CMD was not sent to NFCC */
1876       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
1877         nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1878         NFC_Deactivate(p_data->deactivate_type);
1879       }
1880       break;
1881     case NFA_DM_RF_DEACTIVATE_RSP:
1882       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1883 
1884       /* if it's not race condition between deactivate CMD and activate NTF */
1885       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
1886         /* do not notify deactivated to idle in RF discovery state
1887         ** because it is internal or stopping RF discovery
1888         */
1889 
1890         /* there was no activation while waiting for deactivation RSP */
1891         nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
1892         nfa_dm_start_rf_discover();
1893       }
1894       break;
1895     case NFA_DM_RF_DISCOVER_NTF:
1896       nfa_dm_disc_new_state(NFA_DM_RFST_W4_ALL_DISCOVERIES);
1897       nfa_dm_notify_discovery(p_data);
1898       break;
1899     case NFA_DM_RF_INTF_ACTIVATED_NTF:
1900       if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
1901         LOG(VERBOSE) << StringPrintf(
1902             "RF Activated while waiting for deactivation RSP");
1903         /* it's race condition. DH has to wait for deactivation NTF */
1904         nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_NTF;
1905       } else {
1906         if (p_data->nfc_discover.activate.intf_param.type ==
1907             NFC_INTERFACE_EE_DIRECT_RF) {
1908           nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_ACTIVE);
1909         } else if (p_data->nfc_discover.activate.rf_tech_param.mode & 0x80) {
1910           /* Listen mode */
1911           nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_ACTIVE);
1912         } else {
1913           /* Poll mode */
1914           nfa_dm_disc_new_state(NFA_DM_RFST_POLL_ACTIVE);
1915         }
1916 
1917         if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
1918             NFA_STATUS_FAILED) {
1919           LOG(VERBOSE) << StringPrintf(
1920               "Not matched, restart discovery after receiving "
1921               "deactivate ntf");
1922 
1923           /* after receiving deactivate event, restart discovery */
1924           nfa_dm_cb.disc_cb.disc_flags |=
1925               (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
1926           NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
1927         }
1928       }
1929       break;
1930 
1931     case NFA_DM_RF_DEACTIVATE_NTF:
1932       /* if there was race condition between deactivate CMD and activate NTF */
1933       if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF) {
1934         /* race condition is resolved */
1935         nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
1936 
1937         if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
1938           /* do not notify deactivated to idle in RF discovery state
1939           ** because it is internal or stopping RF discovery
1940           */
1941 
1942           nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
1943           nfa_dm_start_rf_discover();
1944         }
1945       }
1946       break;
1947     case NFA_DM_LP_LISTEN_CMD:
1948       break;
1949     case NFA_DM_CORE_INTF_ERROR_NTF:
1950       break;
1951     default:
1952       LOG(ERROR) << StringPrintf("Unexpected discovery event");
1953       break;
1954   }
1955 }
1956 
1957 /*******************************************************************************
1958 **
1959 ** Function         nfa_dm_disc_sm_w4_all_discoveries
1960 **
1961 ** Description      Processing discovery events in
1962 **                  NFA_DM_RFST_W4_ALL_DISCOVERIES state
1963 **
1964 ** Returns          void
1965 **
1966 *******************************************************************************/
nfa_dm_disc_sm_w4_all_discoveries(tNFA_DM_RF_DISC_SM_EVENT event,tNFA_DM_RF_DISC_DATA * p_data)1967 static void nfa_dm_disc_sm_w4_all_discoveries(tNFA_DM_RF_DISC_SM_EVENT event,
1968                                               tNFA_DM_RF_DISC_DATA* p_data) {
1969   switch (event) {
1970     case NFA_DM_RF_DEACTIVATE_CMD:
1971       /* if deactivate CMD was not sent to NFCC */
1972       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
1973         nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1974         /* only IDLE mode is allowed */
1975         NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
1976       }
1977       break;
1978     case NFA_DM_RF_DEACTIVATE_RSP:
1979       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1980       /* notify exiting from w4 all discoverie state */
1981       nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
1982                                       &(p_data->nfc_discover));
1983 
1984       nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
1985       nfa_dm_start_rf_discover();
1986       break;
1987     case NFA_DM_RF_DISCOVER_NTF:
1988       /* if deactivate CMD is already sent then ignore discover NTF */
1989       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
1990         /* Notification Type = NCI_DISCOVER_NTF_LAST or
1991          * NCI_DISCOVER_NTF_LAST_ABORT */
1992         if (p_data->nfc_discover.result.more != NCI_DISCOVER_NTF_MORE) {
1993           nfa_dm_disc_new_state(NFA_DM_RFST_W4_HOST_SELECT);
1994         }
1995         nfa_dm_notify_discovery(p_data);
1996       }
1997       break;
1998     case NFA_DM_RF_INTF_ACTIVATED_NTF:
1999       /*
2000       ** This is only for ISO15693.
2001       ** FW sends activation NTF when all responses are received from tags
2002       ** without host selecting.
2003       */
2004       nfa_dm_disc_new_state(NFA_DM_RFST_POLL_ACTIVE);
2005 
2006       if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
2007           NFA_STATUS_FAILED) {
2008         LOG(VERBOSE) << StringPrintf(
2009             "Not matched, restart discovery after receiving deactivate ntf");
2010 
2011         /* after receiving deactivate event, restart discovery */
2012         NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
2013       }
2014       break;
2015     default:
2016       LOG(ERROR) << StringPrintf("Unexpected discovery event");
2017       break;
2018   }
2019 }
2020 
2021 /*******************************************************************************
2022 **
2023 ** Function         nfa_dm_disc_sm_w4_host_select
2024 **
2025 ** Description      Processing discovery events in NFA_DM_RFST_W4_HOST_SELECT
2026 **                  state
2027 **
2028 ** Returns          void
2029 **
2030 *******************************************************************************/
nfa_dm_disc_sm_w4_host_select(tNFA_DM_RF_DISC_SM_EVENT event,tNFA_DM_RF_DISC_DATA * p_data)2031 static void nfa_dm_disc_sm_w4_host_select(tNFA_DM_RF_DISC_SM_EVENT event,
2032                                           tNFA_DM_RF_DISC_DATA* p_data) {
2033   tNFA_CONN_EVT_DATA conn_evt;
2034   tNFA_DM_DISC_FLAGS old_sleep_wakeup_flag =
2035       (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING);
2036   bool sleep_wakeup_event = false;
2037   bool sleep_wakeup_event_processed = false;
2038   tNFA_STATUS status;
2039 
2040   switch (event) {
2041     case NFA_DM_RF_DISCOVER_SELECT_CMD:
2042       /* if not waiting to deactivate */
2043       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
2044         NFC_DiscoverySelect(p_data->select.rf_disc_id, p_data->select.protocol,
2045                             p_data->select.rf_interface);
2046       } else {
2047         nfa_dm_disc_conn_event_notify(NFA_SELECT_RESULT_EVT, NFA_STATUS_FAILED);
2048       }
2049       break;
2050 
2051     case NFA_DM_RF_DISCOVER_SELECT_RSP:
2052       sleep_wakeup_event = true;
2053       /* notify application status of selection */
2054       if (p_data->nfc_discover.status == NFC_STATUS_OK) {
2055         sleep_wakeup_event_processed = true;
2056         conn_evt.status = NFA_STATUS_OK;
2057         /* register callback to get interface error NTF */
2058         NFC_SetStaticRfCback(nfa_dm_disc_data_cback);
2059       } else
2060         conn_evt.status = NFA_STATUS_FAILED;
2061 
2062       if (!old_sleep_wakeup_flag) {
2063         nfa_dm_disc_conn_event_notify(NFA_SELECT_RESULT_EVT,
2064                                       p_data->nfc_discover.status);
2065       }
2066       break;
2067     case NFA_DM_RF_INTF_ACTIVATED_NTF:
2068       nfa_dm_disc_new_state(NFA_DM_RFST_POLL_ACTIVE);
2069 
2070       if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
2071         // RF_DEACTIVATE_CMD was sent and INTF_ACTIVATED received before the
2072         // RSP, RFST is changed to POLL_ACTIVE, hence a NTF must be waited too
2073         LOG(DEBUG) << StringPrintf(
2074             "%s; Adding NTF flag because activation was received before RSP",
2075             __func__);
2076         nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_NTF;
2077       }
2078 
2079       /* always call nfa_dm_disc_notify_activation to update protocol/interface
2080        * information in NFA control blocks */
2081       status = nfa_dm_disc_notify_activation(&(p_data->nfc_discover));
2082       if (old_sleep_wakeup_flag) {
2083         /* Handle sleep wakeup success: notify RW module of sleep wakeup of tag;
2084          * if deactivation is pending then deactivate  */
2085         nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_OK);
2086       } else if (status == NFA_STATUS_FAILED) {
2087         LOG(VERBOSE) << StringPrintf(
2088             "Not matched, restart discovery after receiving deactivate ntf");
2089 
2090         /* after receiving deactivate event, restart discovery */
2091         NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
2092       }
2093       break;
2094     case NFA_DM_RF_DEACTIVATE_CMD:
2095       if (old_sleep_wakeup_flag) {
2096         nfa_dm_cb.disc_cb.deact_pending = true;
2097         nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
2098       }
2099       /* if deactivate CMD was not sent to NFCC */
2100       else if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
2101         nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
2102         /* only IDLE mode is allowed */
2103         NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
2104       }
2105       break;
2106     case NFA_DM_RF_DEACTIVATE_RSP:
2107       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
2108       /* notify exiting from host select state */
2109       nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
2110                                       &(p_data->nfc_discover));
2111 
2112       nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2113       nfa_dm_start_rf_discover();
2114       break;
2115 
2116     case NFA_DM_CORE_INTF_ERROR_NTF:
2117       sleep_wakeup_event = true;
2118       if (!old_sleep_wakeup_flag) {
2119         /* target activation failed, upper layer may deactivate or select again
2120          */
2121         conn_evt.status = NFA_STATUS_FAILED;
2122         nfa_dm_conn_cback_event_notify(NFA_SELECT_RESULT_EVT, &conn_evt);
2123       }
2124       break;
2125     default:
2126       LOG(ERROR) << StringPrintf("Unexpected discovery event");
2127       break;
2128   }
2129 
2130   if (old_sleep_wakeup_flag && sleep_wakeup_event &&
2131       !sleep_wakeup_event_processed) {
2132     /* performing sleep wakeup and exception conditions happened
2133      * clear sleep wakeup information and report failure */
2134     nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_FAILED);
2135   }
2136 }
2137 
2138 /*******************************************************************************
2139 **
2140 ** Function         nfa_dm_disc_sm_poll_active
2141 **
2142 ** Description      Processing discovery events in NFA_DM_RFST_POLL_ACTIVE state
2143 **
2144 ** Returns          void
2145 **
2146 *******************************************************************************/
nfa_dm_disc_sm_poll_active(tNFA_DM_RF_DISC_SM_EVENT event,tNFA_DM_RF_DISC_DATA * p_data)2147 static void nfa_dm_disc_sm_poll_active(tNFA_DM_RF_DISC_SM_EVENT event,
2148                                        tNFA_DM_RF_DISC_DATA* p_data) {
2149   tNFA_DM_DISC_FLAGS old_sleep_wakeup_flag =
2150       (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING);
2151   bool sleep_wakeup_event = false;
2152   bool sleep_wakeup_event_processed = false;
2153   tNFA_STATUS status;
2154 
2155   switch (event) {
2156     case NFA_DM_RF_DEACTIVATE_CMD:
2157 
2158       if (nfa_dm_cb.disc_cb.activated_protocol == NCI_PROTOCOL_MIFARE) {
2159         nfa_dm_cb.disc_cb.deact_pending = true;
2160         nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
2161         nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
2162         break;
2163       }
2164 
2165       if (old_sleep_wakeup_flag) {
2166         /* sleep wakeup is already enabled when deactivate cmd is requested,
2167          * keep the information in control block to issue it later */
2168         nfa_dm_cb.disc_cb.deact_pending = true;
2169         nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
2170       } else {
2171         status = nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
2172         if (status != NFA_STATUS_OK) {
2173           LOG(ERROR) << StringPrintf(
2174               "%s; Error calling nfa_dm_send_deactivate_cmd()", __func__);
2175         }
2176       }
2177 
2178       break;
2179     case NFA_DM_RF_DEACTIVATE_RSP:
2180       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
2181       /* register callback to get interface error NTF */
2182       NFC_SetStaticRfCback(nfa_dm_disc_data_cback);
2183 
2184       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
2185         /* it's race condition. received deactivate NTF before receiving RSP */
2186 
2187         tNFC_DEACTIVATE_DEVT deact = tNFC_DEACTIVATE_DEVT();
2188         deact.status = NFC_STATUS_OK;
2189         deact.type = NFC_DEACTIVATE_TYPE_IDLE;
2190         deact.is_ntf = true;
2191         tNFC_DISCOVER nfc_discover;
2192         nfc_discover.deactivate = deact;
2193         nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
2194                                         &nfc_discover);
2195 
2196         /* NFCC is in IDLE state */
2197         nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2198         nfa_dm_start_rf_discover();
2199       }
2200       break;
2201     case NFA_DM_RF_DEACTIVATE_NTF:
2202       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
2203 
2204       nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
2205 
2206       if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
2207         /* it's race condition. received deactivate NTF before receiving RSP */
2208         /* notify deactivation after receiving deactivate RSP */
2209         LOG(VERBOSE) << StringPrintf(
2210             "Rx deactivate NTF while waiting for deactivate RSP");
2211         break;
2212       }
2213       if (p_data->nfc_discover.deactivate.reason !=
2214           NFC_DEACTIVATE_REASON_DH_REQ_FAILED) {
2215         /* count for number of times deactivate cmd sent */
2216         nfa_dm_cb.deactivate_cmd_retry_count = 0;
2217 
2218         sleep_wakeup_event = true;
2219         nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
2220                                         &(p_data->nfc_discover));
2221       }
2222       if ((p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP) ||
2223           (p_data->nfc_discover.deactivate.type ==
2224            NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
2225         if (p_data->nfc_discover.deactivate.reason !=
2226             NFC_DEACTIVATE_REASON_DH_REQ_FAILED) {
2227 
2228           nfa_dm_disc_new_state(NFA_DM_RFST_W4_HOST_SELECT);
2229         }
2230         if (old_sleep_wakeup_flag) {
2231           sleep_wakeup_event_processed = true;
2232           /* process pending deactivate request */
2233           if (nfa_dm_cb.disc_cb.deact_pending) {
2234             /* notify RW module that sleep wakeup is finished */
2235             /* if deactivation is pending then deactivate  */
2236             nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_OK);
2237 
2238             /* Notify NFA RW sub-systems because NFA_DM_RF_DEACTIVATE_RSP will
2239              * not call this function */
2240             nfa_rw_proc_disc_evt(NFA_DM_RF_DISC_DEACTIVATED_EVT, nullptr, true);
2241           } else {
2242             /* Successfully went to sleep mode for sleep wakeup */
2243             /* Now wake up the tag to complete the operation */
2244             NFC_DiscoverySelect(nfa_dm_cb.disc_cb.activated_rf_disc_id,
2245                                 nfa_dm_cb.disc_cb.activated_protocol,
2246                                 nfa_dm_cb.disc_cb.activated_rf_interface);
2247           }
2248         }
2249         if (p_data->nfc_discover.deactivate.reason ==
2250             NFC_DEACTIVATE_REASON_DH_REQ_FAILED) {
2251           /* in case deactivation is not sucessfull, NFCC shall send
2252              RF_DEACTIVATE_NTF with DH Req failed due to error.
2253              MW shall send deactivation cmd again for 3 three times. if
2254              deactivation is not successfull 3 times also,
2255              then MW shall send deacivate cmd with deactivate type is
2256              discovery */
2257           if (nfa_dm_cb.deactivate_cmd_retry_count == 3) {
2258             if ((!old_sleep_wakeup_flag) ||
2259                 (!nfa_dm_cb.disc_cb.deact_pending)) {
2260               nfa_dm_send_deactivate_cmd(NFA_DEACTIVATE_TYPE_DISCOVERY);
2261             }
2262           } else {
2263             nfa_dm_cb.deactivate_cmd_retry_count++;
2264             nfa_dm_send_deactivate_cmd(p_data->nfc_discover.deactivate.type);
2265           }
2266         }
2267         if ((nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING) &&
2268             (!old_sleep_wakeup_flag)) {
2269           LOG(DEBUG) << StringPrintf("%s; Rx DEACT_NTF(SLEEP) while stopping,"
2270               "resending DEACT_CMD(idle) now", __func__);
2271           /* stop discovery */
2272           NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
2273         }
2274       } else if (p_data->nfc_discover.deactivate.type ==
2275                  NFC_DEACTIVATE_TYPE_IDLE) {
2276         nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2277         nfa_dm_start_rf_discover();
2278       } else if (p_data->nfc_discover.deactivate.type ==
2279                  NFC_DEACTIVATE_TYPE_DISCOVERY) {
2280         nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
2281         /* If deactivation type is discovery, reset the counter and notify
2282          * upper layer.
2283          */
2284         nfa_dm_cb.deactivate_cmd_retry_count = 0;
2285         LOG(VERBOSE) << __func__
2286                    << StringPrintf("NFA_DM_RF_DEACTIVATE_NTF to discovery");
2287         if (p_data->nfc_discover.deactivate.reason ==
2288             NFC_DEACTIVATE_REASON_DH_REQ_FAILED) {
2289           // If in pres check and at this point still errors
2290           // Stop pres check, tag will be activated again if still present
2291           if (old_sleep_wakeup_flag) {
2292             nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_FAILED);
2293           }
2294           nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
2295                                           &(p_data->nfc_discover));
2296         }
2297         if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING) {
2298           /* stop discovery */
2299           NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
2300         }
2301       }
2302       break;
2303 
2304     case NFA_DM_CORE_INTF_ERROR_NTF:
2305       sleep_wakeup_event = true;
2306       if ((!old_sleep_wakeup_flag) || (!nfa_dm_cb.disc_cb.deact_pending)) {
2307         nfa_dm_send_deactivate_cmd(NFA_DEACTIVATE_TYPE_DISCOVERY);
2308       }
2309       break;
2310 
2311     case NFA_DM_WPT_START_CMD:
2312       if (nfa_dm_cb.flags & NFA_DM_FLAGS_WLCP_ENABLED) {
2313         if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
2314           if (!(nfa_wlc_cb.flags & NFA_WLC_FLAGS_WPT_NTF_PENDING)) {
2315             /* Prepare NCI message with TLV format */
2316             uint8_t tlvs[NCI_WPT_START_CMD_SIZE];
2317             uint8_t* p = tlvs;
2318 
2319             /* Number of Parameters */
2320             // TODO: add to check SEMANTIC_ERROR (malformed command), increase
2321             // size
2322             // UINT8_TO_STREAM(p, NCI_WPT_START_CMD_PARAM_SIZE);
2323 
2324             /* POWER_ADJ_REQ */
2325             // TODO: field not present (status OK), out of range, bits 1b for
2326             // testing
2327             // TODO: use RFU value for type
2328             UINT8_TO_STREAM(p, NCI_WPT_POWER_ADJ_REQ_TYPE);
2329             UINT8_TO_STREAM(p, 1);
2330             UINT8_TO_STREAM(p, p_data->start_wpt.power_adj_req);
2331 
2332             /* WPT_TIME_INT */
2333             // TODO: field not present (semantic error), out of range, bits 1b
2334             // for testing
2335             // TODO: use RFU value for type
2336             UINT8_TO_STREAM(p, NCI_WPT_TIME_INT_TYPE);
2337             UINT8_TO_STREAM(p, 1);
2338             UINT8_TO_STREAM(p, p_data->start_wpt.wpt_time_int);
2339 
2340             nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_NOTIFY;
2341 
2342             NFC_StartPowerTransfert(tlvs, NCI_WPT_START_CMD_SIZE);
2343             break;
2344           } else {
2345             LOG(ERROR) << StringPrintf(
2346                 "%s; Unexpected WPT_START_CMD, \
2347                 power transfer phase already started",
2348                 __func__);
2349           }
2350         } else {
2351           LOG(VERBOSE) << StringPrintf(
2352               "%s; Unexpected WPT_START_CMD, \
2353               already waiting for RSP of a previous command",
2354               __func__);
2355         }
2356       } else {
2357         LOG(VERBOSE) << StringPrintf(
2358             "%s; Unexpected WPT_START_CMD, \
2359             WLC-P not enabled",
2360             __func__);
2361       }
2362 
2363       nfa_dm_cb.flags &= ~NFA_DM_FLAGS_WLCP_ENABLED;
2364       tNFA_WLC_EVT_DATA wlc_cback_data;
2365       /* Wrong state: notify failed status right away */
2366       wlc_cback_data.status = NFA_STATUS_FAILED;
2367 
2368       nfa_wlc_event_notify(NFA_WLC_START_WPT_RESULT_EVT, &wlc_cback_data);
2369       break;
2370 
2371     case NFA_DM_WPT_START_RSP:
2372       if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY) {
2373         nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
2374 
2375         tNFA_WLC_EVT_DATA wlc_cback_data;
2376         if (p_data->nfc_discover.status == NFC_STATUS_OK) {
2377           wlc_cback_data.status = NFA_STATUS_OK;
2378           nfa_wlc_cb.flags |= NFA_WLC_FLAGS_WPT_NTF_PENDING;
2379           LOG(VERBOSE) << StringPrintf("%s; WPT started", __func__);
2380         } else {
2381           wlc_cback_data.status = NFA_STATUS_FAILED;
2382         }
2383         nfa_wlc_event_notify(NFA_WLC_START_WPT_RESULT_EVT, &wlc_cback_data);
2384       }
2385       LOG(VERBOSE) << StringPrintf(
2386           "%s; nfa_dm_cb.flags=0x%x, \
2387           nfa_wlc_cb.flags=0x%x",
2388           __func__, nfa_dm_cb.flags, nfa_wlc_cb.flags);
2389       break;
2390 
2391     default:
2392       LOG(ERROR) << StringPrintf("Unexpected discovery event");
2393       break;
2394   }
2395 
2396   if (old_sleep_wakeup_flag && sleep_wakeup_event &&
2397       !sleep_wakeup_event_processed) {
2398     /* performing sleep wakeup and exception conditions happened
2399      * clear sleep wakeup information and report failure */
2400     nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_FAILED);
2401   }
2402 }
2403 
2404 /*******************************************************************************
2405 **
2406 ** Function         nfa_dm_disc_sm_listen_active
2407 **
2408 ** Description      Processing discovery events in NFA_DM_RFST_LISTEN_ACTIVE
2409 **                  state
2410 **
2411 ** Returns          void
2412 **
2413 *******************************************************************************/
nfa_dm_disc_sm_listen_active(tNFA_DM_RF_DISC_SM_EVENT event,tNFA_DM_RF_DISC_DATA * p_data)2414 static void nfa_dm_disc_sm_listen_active(tNFA_DM_RF_DISC_SM_EVENT event,
2415                                          tNFA_DM_RF_DISC_DATA* p_data) {
2416   tNFC_DEACTIVATE_DEVT deact = tNFC_DEACTIVATE_DEVT();
2417 
2418   switch (event) {
2419     case NFA_DM_RF_DEACTIVATE_CMD:
2420       nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
2421       nfa_dm_cb.listen_deact_cmd_type = p_data->deactivate_type;
2422       break;
2423     case NFA_DM_RF_DEACTIVATE_RSP:
2424       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
2425       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
2426         /* it's race condition. received deactivate NTF before receiving RSP */
2427 
2428         deact.status = NFC_STATUS_OK;
2429         deact.type = NFC_DEACTIVATE_TYPE_IDLE;
2430         deact.is_ntf = true;
2431         tNFC_DISCOVER nfc_discover;
2432         nfc_discover.deactivate = deact;
2433         nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
2434                                         &nfc_discover);
2435 
2436         /* NFCC is in IDLE state */
2437         nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2438         nfa_dm_start_rf_discover();
2439       }
2440       break;
2441     case NFA_DM_RF_DEACTIVATE_NTF:
2442       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
2443 
2444       nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
2445 
2446       if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
2447         /* it's race condition. received deactivate NTF before receiving RSP */
2448         /* notify deactivation after receiving deactivate RSP */
2449         LOG(DEBUG) << StringPrintf(
2450             "%s; Rx deactivate NTF while waiting for deactivate RSP", __func__);
2451         if ((p_data->nfc_discover.deactivate.type ==
2452              NFC_DEACTIVATE_TYPE_SLEEP) ||
2453             (p_data->nfc_discover.deactivate.type ==
2454              NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
2455           nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_SLEEP);
2456         } else if (p_data->nfc_discover.deactivate.type ==
2457                    NFC_DEACTIVATE_TYPE_DISCOVERY) {
2458           /* Discovery */
2459           if (nfa_dm_cb.pending_power_state != SCREEN_STATE_INVALID) {
2460             NFC_SetPowerSubState(nfa_dm_cb.pending_power_state);
2461             nfa_dm_cb.pending_power_state = SCREEN_STATE_INVALID;
2462           }
2463           nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
2464 
2465           // sent RF_DEACTIVATE_CMD(discovery)
2466           if (nfa_dm_cb.listen_deact_cmd_type ==
2467               NFC_DEACTIVATE_TYPE_DISCOVERY) {
2468             // If receiving DEACT_CMD(disc) while in RFST_DISCOVERY
2469             // then NFCC returns to RFST_IDLE (NCI)
2470             LOG(WARNING) << StringPrintf(
2471                 "%s; Already in RFST_DISCOVERY, new state is RFST_IDLE",
2472                 __func__);
2473             nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2474           }
2475         }
2476       } else {
2477         nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
2478                                         &(p_data->nfc_discover));
2479 
2480         if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) {
2481           nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2482           nfa_dm_start_rf_discover();
2483         } else if ((p_data->nfc_discover.deactivate.type ==
2484                     NFC_DEACTIVATE_TYPE_SLEEP) ||
2485                    (p_data->nfc_discover.deactivate.type ==
2486                     NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
2487           nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_SLEEP);
2488         } else if (p_data->nfc_discover.deactivate.type ==
2489                    NFC_DEACTIVATE_TYPE_DISCOVERY) {
2490           /* Discovery */
2491           if (nfa_dm_cb.pending_power_state != SCREEN_STATE_INVALID) {
2492             NFC_SetPowerSubState(nfa_dm_cb.pending_power_state);
2493             nfa_dm_cb.pending_power_state = SCREEN_STATE_INVALID;
2494           }
2495           nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
2496           if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING) {
2497             /* stop discovery */
2498             NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
2499           }
2500         }
2501       }
2502       break;
2503 
2504     case NFA_DM_CORE_INTF_ERROR_NTF:
2505       break;
2506     default:
2507       LOG(ERROR) << StringPrintf("Unexpected discovery event");
2508       break;
2509   }
2510 }
2511 
2512 /*******************************************************************************
2513 **
2514 ** Function         nfa_dm_disc_sm_listen_sleep
2515 **
2516 ** Description      Processing discovery events in NFA_DM_RFST_LISTEN_SLEEP
2517 **                  state
2518 **
2519 ** Returns          void
2520 **
2521 *******************************************************************************/
nfa_dm_disc_sm_listen_sleep(tNFA_DM_RF_DISC_SM_EVENT event,tNFA_DM_RF_DISC_DATA * p_data)2522 static void nfa_dm_disc_sm_listen_sleep(tNFA_DM_RF_DISC_SM_EVENT event,
2523                                         tNFA_DM_RF_DISC_DATA* p_data) {
2524   switch (event) {
2525     case NFA_DM_RF_DEACTIVATE_CMD:
2526       // When in LISTEN_SLEEP, according to NCI, only deactivate(idle)
2527       // can be sent
2528       nfa_dm_send_deactivate_cmd(NFC_DEACTIVATE_TYPE_IDLE);
2529 
2530       /* NFCC will not sent deactivation NTF */
2531       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
2532       nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
2533       break;
2534     case NFA_DM_RF_DEACTIVATE_RSP:
2535       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
2536       /* if deactivate type in CMD was IDLE */
2537       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
2538         nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
2539                                         &(p_data->nfc_discover));
2540 
2541         nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2542         nfa_dm_start_rf_discover();
2543       }
2544       break;
2545     case NFA_DM_RF_DEACTIVATE_NTF:
2546       /* clear both W4_RSP and W4_NTF because of race condition between
2547        * deactivat CMD and link loss */
2548       nfa_dm_cb.disc_cb.disc_flags &=
2549           ~(NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
2550       nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
2551 
2552       /* there is no active protocol in this state, so broadcast to all by using
2553        * NFA_DM_RF_DEACTIVATE_RSP */
2554       nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
2555                                       &(p_data->nfc_discover));
2556 
2557       if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) {
2558         nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2559         nfa_dm_start_rf_discover();
2560       } else if (p_data->nfc_discover.deactivate.type ==
2561                  NFA_DEACTIVATE_TYPE_DISCOVERY) {
2562         nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
2563       } else {
2564         LOG(ERROR) << StringPrintf("Unexpected deactivation type");
2565         nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2566         nfa_dm_start_rf_discover();
2567       }
2568       break;
2569     case NFA_DM_RF_INTF_ACTIVATED_NTF:
2570       nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_ACTIVE);
2571       if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
2572         /* NFCC will sent deactivation NTF */
2573         nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_NTF;
2574       }
2575       if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
2576           NFA_STATUS_FAILED) {
2577         LOG(VERBOSE) << StringPrintf(
2578             "Not matched, restart discovery after receiving deactivate ntf");
2579 
2580         /* after receiving deactivate event, restart discovery */
2581         NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
2582       }
2583       break;
2584     default:
2585       LOG(ERROR) << StringPrintf("Unexpected discovery event");
2586       break;
2587   }
2588 }
2589 
2590 /*******************************************************************************
2591 **
2592 ** Function         nfa_dm_disc_sm_lp_listen
2593 **
2594 ** Description      Processing discovery events in NFA_DM_RFST_LP_LISTEN state
2595 **
2596 ** Returns          void
2597 **
2598 *******************************************************************************/
nfa_dm_disc_sm_lp_listen(tNFA_DM_RF_DISC_SM_EVENT event,tNFA_DM_RF_DISC_DATA * p_data)2599 static void nfa_dm_disc_sm_lp_listen(tNFA_DM_RF_DISC_SM_EVENT event,
2600                                      tNFA_DM_RF_DISC_DATA* p_data) {
2601   switch (event) {
2602     case NFA_DM_RF_INTF_ACTIVATED_NTF:
2603       nfa_dm_disc_new_state(NFA_DM_RFST_LP_ACTIVE);
2604       if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
2605           NFA_STATUS_FAILED) {
2606         LOG(VERBOSE) << StringPrintf("Not matched, unexpected activation");
2607       }
2608       break;
2609 
2610     default:
2611       LOG(ERROR) << StringPrintf("Unexpected discovery event");
2612       break;
2613   }
2614 }
2615 
2616 /*******************************************************************************
2617 **
2618 ** Function         nfa_dm_disc_sm_lp_active
2619 **
2620 ** Description      Processing discovery events in NFA_DM_RFST_LP_ACTIVE state
2621 **
2622 ** Returns          void
2623 **
2624 *******************************************************************************/
nfa_dm_disc_sm_lp_active(tNFA_DM_RF_DISC_SM_EVENT event,tNFA_DM_RF_DISC_DATA * p_data)2625 static void nfa_dm_disc_sm_lp_active(tNFA_DM_RF_DISC_SM_EVENT event,
2626                                      tNFA_DM_RF_DISC_DATA* p_data) {
2627   switch (event) {
2628     case NFA_DM_RF_DEACTIVATE_NTF:
2629       nfa_dm_disc_new_state(NFA_DM_RFST_LP_LISTEN);
2630       nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
2631                                       &(p_data->nfc_discover));
2632       break;
2633     default:
2634       LOG(ERROR) << StringPrintf("Unexpected discovery event");
2635       break;
2636   }
2637 }
2638 
2639 /*******************************************************************************
2640 **
2641 ** Function         nfa_dm_disc_sm_execute
2642 **
2643 ** Description      Processing discovery related events
2644 **
2645 ** Returns          void
2646 **
2647 *******************************************************************************/
nfa_dm_disc_sm_execute(tNFA_DM_RF_DISC_SM_EVENT event,tNFA_DM_RF_DISC_DATA * p_data)2648 void nfa_dm_disc_sm_execute(tNFA_DM_RF_DISC_SM_EVENT event,
2649                             tNFA_DM_RF_DISC_DATA* p_data) {
2650   LOG(VERBOSE) << StringPrintf(
2651       "state: %s (%d), event: %s(%d) disc_flags: "
2652       "0x%x",
2653       nfa_dm_disc_state_2_str(nfa_dm_cb.disc_cb.disc_state).c_str(),
2654       nfa_dm_cb.disc_cb.disc_state, nfa_dm_disc_event_2_str(event).c_str(),
2655       event, nfa_dm_cb.disc_cb.disc_flags);
2656 
2657   switch (nfa_dm_cb.disc_cb.disc_state) {
2658     /*  RF Discovery State - Idle */
2659     case NFA_DM_RFST_IDLE:
2660       nfa_dm_disc_sm_idle(event, p_data);
2661       break;
2662 
2663     /* RF Discovery State - Discovery */
2664     case NFA_DM_RFST_DISCOVERY:
2665       nfa_dm_disc_sm_discovery(event, p_data);
2666       break;
2667 
2668     /*RF Discovery State - Wait for all discoveries */
2669     case NFA_DM_RFST_W4_ALL_DISCOVERIES:
2670       nfa_dm_disc_sm_w4_all_discoveries(event, p_data);
2671       break;
2672 
2673     /* RF Discovery State - Wait for host selection */
2674     case NFA_DM_RFST_W4_HOST_SELECT:
2675       nfa_dm_disc_sm_w4_host_select(event, p_data);
2676       break;
2677 
2678     /* RF Discovery State - Poll mode activated */
2679     case NFA_DM_RFST_POLL_ACTIVE:
2680       nfa_dm_disc_sm_poll_active(event, p_data);
2681       break;
2682 
2683     /* RF Discovery State - listen mode activated */
2684     case NFA_DM_RFST_LISTEN_ACTIVE:
2685       nfa_dm_disc_sm_listen_active(event, p_data);
2686       break;
2687 
2688     /* RF Discovery State - listen mode sleep */
2689     case NFA_DM_RFST_LISTEN_SLEEP:
2690       nfa_dm_disc_sm_listen_sleep(event, p_data);
2691       break;
2692 
2693     /* Listening in Low Power mode    */
2694     case NFA_DM_RFST_LP_LISTEN:
2695       nfa_dm_disc_sm_lp_listen(event, p_data);
2696       break;
2697 
2698     /* Activated in Low Power mode    */
2699     case NFA_DM_RFST_LP_ACTIVE:
2700       nfa_dm_disc_sm_lp_active(event, p_data);
2701       break;
2702   }
2703   LOG(VERBOSE) << StringPrintf(
2704       "new state: %s (%d), disc_flags: 0x%x",
2705       nfa_dm_disc_state_2_str(nfa_dm_cb.disc_cb.disc_state).c_str(),
2706       nfa_dm_cb.disc_cb.disc_state, nfa_dm_cb.disc_cb.disc_flags);
2707 }
2708 
2709 /*******************************************************************************
2710 **
2711 ** Function         nfa_dm_add_rf_discover
2712 **
2713 ** Description      Add discovery configuration and callback function
2714 **
2715 ** Returns          valid handle if success
2716 **
2717 *******************************************************************************/
nfa_dm_add_rf_discover(tNFA_DM_DISC_TECH_PROTO_MASK disc_mask,tNFA_DM_DISC_HOST_ID host_id,tNFA_DISCOVER_CBACK * p_disc_cback)2718 tNFA_HANDLE nfa_dm_add_rf_discover(tNFA_DM_DISC_TECH_PROTO_MASK disc_mask,
2719                                    tNFA_DM_DISC_HOST_ID host_id,
2720                                    tNFA_DISCOVER_CBACK* p_disc_cback) {
2721   uint8_t xx;
2722 
2723   LOG(VERBOSE) << StringPrintf("disc_mask=0x%x", disc_mask);
2724 
2725   for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
2726     if (!nfa_dm_cb.disc_cb.entry[xx].in_use) {
2727       nfa_dm_cb.disc_cb.entry[xx].in_use = true;
2728       nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask = disc_mask;
2729       nfa_dm_cb.disc_cb.entry[xx].host_id = host_id;
2730       nfa_dm_cb.disc_cb.entry[xx].p_disc_cback = p_disc_cback;
2731       nfa_dm_cb.disc_cb.entry[xx].disc_flags = NFA_DM_DISC_FLAGS_NOTIFY;
2732       return xx;
2733     }
2734   }
2735 
2736   return NFA_HANDLE_INVALID;
2737 }
2738 
2739 /*******************************************************************************
2740 **
2741 ** Function         nfa_dm_start_excl_discovery
2742 **
2743 ** Description      Start exclusive RF discovery
2744 **
2745 ** Returns          void
2746 **
2747 *******************************************************************************/
nfa_dm_start_excl_discovery(tNFA_TECHNOLOGY_MASK poll_tech_mask,tNFA_LISTEN_CFG * p_listen_cfg,tNFA_DISCOVER_CBACK * p_disc_cback)2748 void nfa_dm_start_excl_discovery(tNFA_TECHNOLOGY_MASK poll_tech_mask,
2749                                  tNFA_LISTEN_CFG* p_listen_cfg,
2750                                  tNFA_DISCOVER_CBACK* p_disc_cback) {
2751   tNFA_DM_DISC_TECH_PROTO_MASK poll_disc_mask = 0;
2752 
2753   LOG(VERBOSE) << __func__;
2754 
2755   if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A) {
2756     poll_disc_mask |= NFA_DM_DISC_MASK_PA_T1T;
2757     poll_disc_mask |= NFA_DM_DISC_MASK_PA_T2T;
2758     poll_disc_mask |= NFA_DM_DISC_MASK_PA_ISO_DEP;
2759     poll_disc_mask |= NFA_DM_DISC_MASK_PA_NFC_DEP;
2760     poll_disc_mask |= NFA_DM_DISC_MASK_P_LEGACY;
2761   }
2762   if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B) {
2763     poll_disc_mask |= NFA_DM_DISC_MASK_PB_ISO_DEP;
2764   }
2765   if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F) {
2766     poll_disc_mask |= NFA_DM_DISC_MASK_PF_T3T;
2767     poll_disc_mask |= NFA_DM_DISC_MASK_PF_NFC_DEP;
2768   }
2769   if (poll_tech_mask & NFA_TECHNOLOGY_MASK_V) {
2770     poll_disc_mask |= NFA_DM_DISC_MASK_P_T5T;
2771   }
2772   if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B_PRIME) {
2773     poll_disc_mask |= NFA_DM_DISC_MASK_P_B_PRIME;
2774   }
2775   if (poll_tech_mask & NFA_TECHNOLOGY_MASK_KOVIO) {
2776     poll_disc_mask |= NFA_DM_DISC_MASK_P_KOVIO;
2777   }
2778 
2779   nfa_dm_cb.disc_cb.excl_disc_entry.in_use = true;
2780   nfa_dm_cb.disc_cb.excl_disc_entry.requested_disc_mask = poll_disc_mask;
2781   nfa_dm_cb.disc_cb.excl_disc_entry.host_id = NFA_DM_DISC_HOST_ID_DH;
2782   nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback = p_disc_cback;
2783   nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags = NFA_DM_DISC_FLAGS_NOTIFY;
2784 
2785   memcpy(&nfa_dm_cb.disc_cb.excl_listen_config, p_listen_cfg,
2786          sizeof(tNFA_LISTEN_CFG));
2787 
2788   nfa_dm_disc_sm_execute(NFA_DM_RF_DISCOVER_CMD, nullptr);
2789 }
2790 
2791 /*******************************************************************************
2792 **
2793 ** Function         nfa_dm_stop_excl_discovery
2794 **
2795 ** Description      Stop exclusive RF discovery
2796 **
2797 ** Returns          void
2798 **
2799 *******************************************************************************/
nfa_dm_stop_excl_discovery(void)2800 void nfa_dm_stop_excl_discovery(void) {
2801   LOG(VERBOSE) << __func__;
2802 
2803   nfa_dm_cb.disc_cb.excl_disc_entry.in_use = false;
2804   nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback = nullptr;
2805 }
2806 
2807 /*******************************************************************************
2808 **
2809 ** Function         nfa_dm_delete_rf_discover
2810 **
2811 ** Description      Remove discovery configuration and callback function
2812 **
2813 ** Returns          void
2814 **
2815 *******************************************************************************/
nfa_dm_delete_rf_discover(tNFA_HANDLE handle)2816 void nfa_dm_delete_rf_discover(tNFA_HANDLE handle) {
2817   LOG(VERBOSE) << StringPrintf("handle=0x%x", handle);
2818 
2819   if (handle < NFA_DM_DISC_NUM_ENTRIES) {
2820     nfa_dm_cb.disc_cb.entry[handle].in_use = false;
2821   } else {
2822     LOG(ERROR) << StringPrintf("Invalid discovery handle");
2823   }
2824 }
2825 
2826 /*******************************************************************************
2827 **
2828 ** Function         nfa_dm_rf_discover_select
2829 **
2830 ** Description      Select target, protocol and RF interface
2831 **
2832 ** Returns          void
2833 **
2834 *******************************************************************************/
nfa_dm_rf_discover_select(uint8_t rf_disc_id,tNFA_NFC_PROTOCOL protocol,tNFA_INTF_TYPE rf_interface)2835 void nfa_dm_rf_discover_select(uint8_t rf_disc_id, tNFA_NFC_PROTOCOL protocol,
2836                                tNFA_INTF_TYPE rf_interface) {
2837   tNFA_DM_DISC_SELECT_PARAMS select_params;
2838   tNFA_CONN_EVT_DATA conn_evt;
2839 
2840   LOG(VERBOSE) << StringPrintf(
2841       "rf_disc_id:0x%X, protocol:0x%X, rf_interface:0x%X", rf_disc_id, protocol,
2842       rf_interface);
2843 
2844   if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT) {
2845     /* state is OK: notify the status when the response is received from NFCC */
2846     select_params.rf_disc_id = rf_disc_id;
2847     select_params.protocol = protocol;
2848     select_params.rf_interface = rf_interface;
2849 
2850     nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_NOTIFY;
2851     tNFA_DM_RF_DISC_DATA nfa_dm_rf_disc_data;
2852     nfa_dm_rf_disc_data.select = select_params;
2853     nfa_dm_disc_sm_execute(NFA_DM_RF_DISCOVER_SELECT_CMD, &nfa_dm_rf_disc_data);
2854   } else {
2855     /* Wrong state: notify failed status right away */
2856     conn_evt.status = NFA_STATUS_FAILED;
2857     nfa_dm_conn_cback_event_notify(NFA_SELECT_RESULT_EVT, &conn_evt);
2858   }
2859 }
2860 
2861 /*******************************************************************************
2862 **
2863 ** Function         nfa_dm_rf_deactivate
2864 **
2865 ** Description      Deactivate NFC link
2866 **
2867 ** Returns          NFA_STATUS_OK if success
2868 **
2869 *******************************************************************************/
nfa_dm_rf_deactivate(tNFA_DEACTIVATE_TYPE deactivate_type)2870 tNFA_STATUS nfa_dm_rf_deactivate(tNFA_DEACTIVATE_TYPE deactivate_type) {
2871   LOG(VERBOSE) << StringPrintf("deactivate_type:0x%X", deactivate_type);
2872 
2873   if (deactivate_type == NFA_DEACTIVATE_TYPE_SLEEP) {
2874     if (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_NFC_DEP)
2875       deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP_AF;
2876     else
2877       deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP;
2878   }
2879 
2880   if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE) {
2881     return NFA_STATUS_FAILED;
2882   } else if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_DISCOVERY) {
2883     if (deactivate_type == NFA_DEACTIVATE_TYPE_DISCOVERY) {
2884       if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
2885         nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.kovio_tle);
2886         nfa_dm_disc_kovio_timeout_cback(&nfa_dm_cb.disc_cb.kovio_tle);
2887         return NFA_STATUS_OK;
2888       } else {
2889         /* it could be race condition. */
2890         LOG(VERBOSE) << StringPrintf("already in discovery state");
2891         return NFA_STATUS_FAILED;
2892       }
2893     } else if (deactivate_type == NFA_DEACTIVATE_TYPE_IDLE) {
2894       if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
2895         nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.kovio_tle);
2896         nfa_dm_disc_kovio_timeout_cback(&nfa_dm_cb.disc_cb.kovio_tle);
2897       }
2898       tNFA_DM_RF_DISC_DATA nfa_dm_rf_disc_data;
2899       nfa_dm_rf_disc_data.deactivate_type = deactivate_type;
2900       nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD, &nfa_dm_rf_disc_data);
2901       return NFA_STATUS_OK;
2902     } else {
2903       return NFA_STATUS_FAILED;
2904     }
2905   } else {
2906     tNFA_DM_RF_DISC_DATA nfa_dm_rf_disc_data;
2907     nfa_dm_rf_disc_data.deactivate_type = deactivate_type;
2908     nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD, &nfa_dm_rf_disc_data);
2909     return NFA_STATUS_OK;
2910   }
2911 }
2912 
2913 /*******************************************************************************
2914 **
2915 ** Function         nfa_dm_disc_state_2_str
2916 **
2917 ** Description      convert nfc discovery state to string
2918 **
2919 *******************************************************************************/
nfa_dm_disc_state_2_str(uint8_t state)2920 static std::string nfa_dm_disc_state_2_str(uint8_t state) {
2921   switch (state) {
2922     case NFA_DM_RFST_IDLE:
2923       return "IDLE";
2924 
2925     case NFA_DM_RFST_DISCOVERY:
2926       return "DISCOVERY";
2927 
2928     case NFA_DM_RFST_W4_ALL_DISCOVERIES:
2929       return "W4_ALL_DISCOVERIES";
2930 
2931     case NFA_DM_RFST_W4_HOST_SELECT:
2932       return "W4_HOST_SELECT";
2933 
2934     case NFA_DM_RFST_POLL_ACTIVE:
2935       return "POLL_ACTIVE";
2936 
2937     case NFA_DM_RFST_LISTEN_ACTIVE:
2938       return "LISTEN_ACTIVE";
2939 
2940     case NFA_DM_RFST_LISTEN_SLEEP:
2941       return "LISTEN_SLEEP";
2942 
2943     case NFA_DM_RFST_LP_LISTEN:
2944       return "LP_LISTEN";
2945 
2946     case NFA_DM_RFST_LP_ACTIVE:
2947       return "LP_ACTIVE";
2948   }
2949   return "Unknown";
2950 }
2951 
2952 /*******************************************************************************
2953 **
2954 ** Function         nfa_dm_disc_event_2_str
2955 **
2956 ** Description      convert nfc discovery RSP/NTF to string
2957 **
2958 *******************************************************************************/
nfa_dm_disc_event_2_str(uint8_t event)2959 static std::string nfa_dm_disc_event_2_str(uint8_t event) {
2960   switch (event) {
2961     case NFA_DM_RF_DISCOVER_CMD:
2962       return "DISCOVER_CMD";
2963     case NFA_DM_RF_DISCOVER_RSP:
2964       return "DISCOVER_RSP";
2965     case NFA_DM_RF_DISCOVER_NTF:
2966       return "DISCOVER_NTF";
2967     case NFA_DM_RF_DISCOVER_SELECT_CMD:
2968       return "SELECT_CMD";
2969     case NFA_DM_RF_DISCOVER_SELECT_RSP:
2970       return "SELECT_RSP";
2971     case NFA_DM_RF_INTF_ACTIVATED_NTF:
2972       return "ACTIVATED_NTF";
2973     case NFA_DM_RF_DEACTIVATE_CMD:
2974       return "DEACTIVATE_CMD";
2975     case NFA_DM_RF_DEACTIVATE_RSP:
2976       return "DEACTIVATE_RSP";
2977     case NFA_DM_RF_DEACTIVATE_NTF:
2978       return "DEACTIVATE_NTF";
2979     case NFA_DM_LP_LISTEN_CMD:
2980       return "NFA_DM_LP_LISTEN_CMD";
2981     case NFA_DM_CORE_INTF_ERROR_NTF:
2982       return "INTF_ERROR_NTF";
2983     case NFA_DM_WPT_START_CMD:
2984       return "WPT_START_CMD";
2985     case NFA_DM_WPT_START_RSP:
2986       return "WPT_START_RSP";
2987     default:
2988       return "Unknown";
2989   }
2990 }
2991 
2992 /*******************************************************************************
2993 **
2994 ** Function         nfa_dm_get_tech_route_block
2995 **
2996 ** Description      Retrieves which tech shall be muted
2997 **
2998 ** Returns
2999 **
3000 *******************************************************************************/
nfa_dm_get_tech_route_block(uint8_t * listen_techmask,bool * enable)3001 void nfa_dm_get_tech_route_block(uint8_t* listen_techmask, bool* enable) {
3002   if ((nfa_dm_cb.flags & NFA_DM_FLAGS_LISTEN_TECH_CHANGED)) {
3003     *enable = true;
3004     *listen_techmask = nfa_dm_cb.change_listen_mask;
3005   } else if (dm_disc_listen_mask_dfl != 0) {
3006     *enable = true;
3007     *listen_techmask = dm_disc_listen_mask_dfl;
3008   } else {
3009     *enable = false;
3010     *listen_techmask = 0;
3011   }
3012 
3013   if (*enable) {
3014     LOG(VERBOSE) << StringPrintf("%s; change_listen_mask: 0x%x, ", __func__,
3015                                  *listen_techmask);
3016   }
3017 }
3018 
3019 /*******************************************************************************
3020 **
3021 ** Function         nfa_dm_get_nfc_secure
3022 **
3023 ** Description      Retrieves NFC secure information
3024 **
3025 ** Returns
3026 **
3027 *******************************************************************************/
nfa_dm_get_nfc_secure()3028 bool nfa_dm_get_nfc_secure() {
3029   LOG(INFO) << StringPrintf("%s; status: %d", __func__,
3030                             nfa_dm_cb.is_nfc_secure);
3031   return nfa_dm_cb.is_nfc_secure;
3032 }
3033