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