• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2023 The Android Open Source Project.
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains the action functions the NFA_WLC state machine.
22  *
23  ******************************************************************************/
24 #include <android-base/logging.h>
25 #include <android-base/stringprintf.h>
26 #include <log/log.h>
27 #include <string.h>
28 
29 #include "nfa_dm_int.h"
30 #include "nfa_rw_int.h"
31 #include "nfa_wlc_int.h"
32 #include "nfc_int.h"
33 
34 using android::base::StringPrintf;
35 
36 /*******************************************************************************
37 **
38 ** Function         nfa_wlc_enable
39 **
40 ** Description      Initialize the NFC WLC manager
41 **
42 ** Returns          TRUE (message buffer to be freed by caller)
43 **
44 *******************************************************************************/
nfa_wlc_enable(tNFA_WLC_MSG * p_data)45 bool nfa_wlc_enable(tNFA_WLC_MSG* p_data) {
46   LOG(VERBOSE) << StringPrintf("%s:  nfa_dm_cb.flags=0x%x", __func__,
47                                nfa_dm_cb.flags);
48   tNFA_WLC_EVT_DATA wlc_cback_data;
49 
50   /* Check if NFA is already enabled */
51   if ((nfa_dm_cb.flags & NFA_DM_FLAGS_DM_IS_ACTIVE) &&
52       !((nfa_dm_cb.flags & NFA_DM_FLAGS_ENABLE_EVT_PEND) ||
53         (nfa_dm_cb.flags & NFA_DM_FLAGS_DM_DISABLING_NFC))) {
54     /* Store Enable parameters */
55     nfa_wlc_cb.p_wlc_cback = p_data->enable.p_wlc_cback;
56 
57     wlc_cback_data.status = NFA_STATUS_OK;
58   } else {
59     LOG(VERBOSE) << StringPrintf(
60         "%s:  DM not active or enable event pending or DM disabling NFC ",
61         __func__);
62     wlc_cback_data.status = NFA_STATUS_FAILED;
63   }
64   (*(p_data->enable.p_wlc_cback))(NFA_WLC_ENABLE_RESULT_EVT, &wlc_cback_data);
65 
66   return true;
67 }
68 
69 /*******************************************************************************
70 **
71 ** Function         nfa_wlc_start
72 **
73 ** Description      Start WLC-P Non-Autonomous RF Interface Extension
74 **                  if conditions are met (extension supported by NFCC,
75 **                  NFCC in POLL_ACTIVE, correct protocol for activated tag,
76 **                  DM module in appropriate state...).
77 **
78 ** Returns          TRUE upon successful start else FALSE
79 **
80 *******************************************************************************/
nfa_wlc_start(tNFA_WLC_MSG * p_data)81 bool nfa_wlc_start(tNFA_WLC_MSG* p_data) {
82   LOG(VERBOSE) << StringPrintf("%s:  ", __func__);
83 
84   /* If mode is WLC-P Non-Autonomous mode:
85    * Support for WLC-P Non-Autonomous RF Interface Extension in CORE_INIT_RSP
86    * mandated Non-Autonomous RF Frame Extension shall be in stopped state NFCC
87    * in RFST_POLL_ACTIVE Frame RF or ISO-DEP Interfaces shall be in activated
88    * state EP protocol: T2T, T3T, T5T, ISO-DEP DH not waiting for a response
89    * from the EP
90    */
91 
92   if (p_data->start.mode == NFA_WLC_NON_AUTONOMOUS) {
93     // TODO: check WLC-P Non-Autonomous RF Interface Extension is enabled in
94     // CORE_INIT_RSP
95     /* Reject request if NFCC does not support Removal Detection in Poll Mode */
96     /* Mandated for WLC procedure */
97     if (!(nfc_cb.nci_features & NCI_POLL_REMOVAL_DETECTION)) {
98       LOG(ERROR) << StringPrintf(
99           "%s:  NFCC Feature Removal Detection "
100           "in Poll Mode not supported, can not start WLC procedure",
101           __func__);
102       return false;
103     }
104 
105     if (nfa_wlc_cb.flags & NFA_WLC_FLAGS_NON_AUTO_MODE_ENABLED) {
106       /* Non-Autonomous RF Frame Extension shall be in stopped state */
107       /* return status not stopped to JNI ???*/
108       LOG(ERROR) << StringPrintf(
109           "%s:  WLCP Non-autonomous Extension not "
110           "in stopped state",
111           __func__);
112       return false;
113     }
114 
115     if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_POLL_ACTIVE) {
116       LOG(ERROR) << StringPrintf(
117           "%s:  NFCC not in WLCP "
118           "RFST_POLL_ACTIVE state",
119           __func__);
120       return false;
121     }
122 
123     if (!((nfa_rw_cb.protocol == NFC_PROTOCOL_T2T) ||
124           (nfa_rw_cb.protocol == NFC_PROTOCOL_T3T) ||
125           (nfa_rw_cb.protocol == NFC_PROTOCOL_T5T) ||
126           (nfa_rw_cb.protocol == NFA_PROTOCOL_ISO_DEP))) {
127       LOG(ERROR) << StringPrintf("%s:  Invalid RF protocol activated",
128                                  __func__);
129       return false;
130     }
131 
132     if (nfa_rw_cb.flags & NFA_RW_FL_API_BUSY) {
133       LOG(ERROR) << StringPrintf("%s:  RW API already busy", __func__);
134       /* TODO: pending till RW action completes? */
135       return false;
136     }
137     if (nfa_dm_cb.disc_cb.disc_flags &
138         (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF |
139          NFA_DM_DISC_FLAGS_STOPPING |  /* Stop RF discovery is pending */
140          NFA_DM_DISC_FLAGS_DISABLING)) /* Disable NFA is pending */
141     {
142       // TODO: shall we check other modules busy?
143       return false;
144     }
145 
146     nfa_wlc_cb.wlc_mode = p_data->start.mode;
147 
148     /* Start Parameter shall be 0 */
149     nfa_dm_start_rf_intf_ext(NCI_INTF_EXT_WLCP_NON_AUTO, nullptr, 0);
150     // TODO: remove as only for testing, replace by extension activation
151     // nfa_dm_cb.flags |= NFA_DM_FLAGS_RF_EXT_ACTIVE;
152     // nfa_dm_cb.flags |= NFA_DM_FLAGS_WLCP_ENABLED;
153 
154     // tNFA_WLC_EVT_DATA wlc_cback_data;
155     // wlc_cback_data.status = NFA_STATUS_OK;
156     // nfa_wlc_event_notify(NFA_WLC_START_RESULT_EVT, &wlc_cback_data);
157 
158     return true;
159 
160   } else {
161     LOG(ERROR) << StringPrintf("%s:  Wireless Charging mode not supported",
162                                __func__);
163     return false;
164   }
165 }
166 
167 /*******************************************************************************
168 **
169 ** Function         nfa_wlc_non_auto_start_wpt
170 **
171 ** Description      Stop timer for presence check
172 **
173 ** Returns          Nothing
174 **
175 *******************************************************************************/
nfa_wlc_non_auto_start_wpt(tNFA_WLC_MSG * p_data)176 bool nfa_wlc_non_auto_start_wpt(tNFA_WLC_MSG* p_data) {
177   LOG(VERBOSE) << StringPrintf("%s:  power_adj_req=0x%x, wpt_time_int=0x%x",
178                                __func__,
179                                p_data->non_auto_start_wpt.power_adj_req,
180                                p_data->non_auto_start_wpt.wpt_time_int);
181 
182   nfa_dm_start_wireless_power_transfer(p_data->non_auto_start_wpt.power_adj_req,
183                                        p_data->non_auto_start_wpt.wpt_time_int);
184 
185   return true;
186 }
187