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  *  NFA interface for NFC wireless charging
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_api.h"
30 #include "nfa_wlc_int.h"
31 
32 using android::base::StringPrintf;
33 
34 /*****************************************************************************
35 **  Constants
36 *****************************************************************************/
37 
38 /*****************************************************************************
39 **  APIs
40 *****************************************************************************/
41 /*******************************************************************************
42 **
43 ** Function         NFA_WlcEnable
44 **
45 ** Description      This function enables WLC module callback. Prior to calling
46 **                  NFA_WlcEnable, WLC module must be enabled by NFA system
47 **                  manager (done when NFA_Enable called).
48 **
49 **                  When the enabling is completed, an NFA_WLC_ENABLE_RESULT_EVT
50 **                  is returned to the application using the tNFA_WLC_CBACK.
51 **
52 **                  p_wlc_cback: callback to notify later NFCC events
53 **
54 ** Returns          NFA_STATUS_OK if successfully initiated
55 **                  NFA_STATUS_FAILED otherwise
56 **
57 *******************************************************************************/
NFA_WlcEnable(tNFA_WLC_CBACK * p_wlc_cback)58 tNFA_STATUS NFA_WlcEnable(tNFA_WLC_CBACK* p_wlc_cback) {
59   tNFA_WLC_MSG* p_msg;
60 
61   LOG(VERBOSE) << __func__;
62 
63   /* Validate parameters */
64   if (!p_wlc_cback) {
65     LOG(ERROR) << StringPrintf("%s; error null callback", __func__);
66     return (NFA_STATUS_FAILED);
67   }
68 
69   p_msg = (tNFA_WLC_MSG*)GKI_getbuf(sizeof(tNFA_WLC_MSG));
70   if (p_msg != nullptr) {
71     p_msg->enable.hdr.event = NFA_WLC_API_ENABLE_EVT;
72     p_msg->enable.p_wlc_cback = p_wlc_cback;
73 
74     nfa_sys_sendmsg(p_msg);
75 
76     return (NFA_STATUS_OK);
77   }
78 
79   return (NFA_STATUS_FAILED);
80 }
81 
82 /*******************************************************************************
83 **
84 ** Function         NFA_WlcStart
85 **
86 ** Description      Perform the WLC start procedure.
87 **
88 **                  Upon successful completion of RF Interface Extension start
89 **                  (according to the NFC Forum NCI2.3 conditions) and upload
90 **                  of WLC Poller parameters (Non-Autonomous mode only),
91 **                  an NFA_WLC_START_RESULT_EVT is returned to the application
92 **                  using the tNFA_WLC_CBACK.
93 **
94 **                  mode: WLC-P Non-Autonomous (0) or Semi-Autonomous mode
95 **
96 ** Returns:
97 **                  NFA_STATUS_OK if successfully started
98 **                  NFA_STATUS_FAILED otherwise
99 **
100 *******************************************************************************/
NFA_WlcStart(tNFA_WLC_MODE mode)101 tNFA_STATUS NFA_WlcStart(tNFA_WLC_MODE mode) {
102   tNFA_WLC_MSG* p_msg;
103 
104   LOG(VERBOSE) << __func__;
105 
106   if (mode) {
107     LOG(ERROR) << StringPrintf("%s; Wireless Charging mode not supported",
108                                __func__);
109     return (NFA_STATUS_INVALID_PARAM);
110   }
111 
112   p_msg = (tNFA_WLC_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_WLC_MSG));
113   if (p_msg != nullptr) {
114     p_msg->start.hdr.event = NFA_WLC_API_START_EVT;
115     p_msg->start.mode = mode;
116 
117     nfa_sys_sendmsg(p_msg);
118 
119     return (NFA_STATUS_OK);
120   }
121 
122   return (NFA_STATUS_FAILED);
123 }
124 
125 /*******************************************************************************
126 **
127 ** Function         NFA_WlcStartWPT
128 **
129 ** Description      Start a wireless power transfer cycle in Non-Autonomous
130 **                  WLCP mode ([WLC2.0] Technical Specifications state 21
131 **                  for negotiated or state 6 for static WLC mode).
132 **
133 **                  Upon successful completion of WPT start,
134 **                  an NFA_WLC_START_WPT_RESULT_EVT is returned to the
135 *application
136 **                  using the tNFA_WLC_CBACK.
137 **
138 **                  When the duration for the power transfer ends or
139 **                  any error/completion condition occurred, NFCC notifies the
140 *DH
141 **                  with an NFA_WLC_CHARGING_RESULT_EVT and end condition value.
142 **
143 **                  power_adj_req: POWER_ADUJUST_REQ as defined in [WLC]
144 **                  wpt_time_int: WPT_INT_TIME as defined in [WLC]
145 **
146 ** Returns:
147 **                  NFA_STATUS_OK if successfully started
148 **                  NFA_STATUS_FAILED otherwise
149 **
150 *******************************************************************************/
NFA_WlcStartWPT(uint8_t power_adj_req,uint8_t wpt_time_int)151 tNFA_STATUS NFA_WlcStartWPT(uint8_t power_adj_req, uint8_t wpt_time_int) {
152   tNFA_WLC_MSG* p_msg;
153 
154   LOG(VERBOSE) << StringPrintf("%s; power_adj_req: %d, wpt_time_int: %d",
155                              __func__, power_adj_req, wpt_time_int);
156 
157   /* POWER_ADJ_REQ is in the range [0x00..0x14] for request to increase power
158    * POWER_ADJ_REQ is in the range [0xF6..0xFF] for request to decrease power
159    */
160   if ((power_adj_req > POWER_ADJ_REQ_INC_MAX) &&
161       (power_adj_req < POWER_ADJ_REQ_DEC_MIN)) {
162     LOG(ERROR) << StringPrintf("%s; Invalid POWER_ADJ_REQ value", __func__);
163     return false;
164   }
165 
166   /* WPT_DURATION_INT is in the range [0x00..0x13]
167    * Bits 6 and 7 must be 0b
168    */
169   if ((wpt_time_int > WPT_DURATION_INT_MAX) ||
170       (wpt_time_int & WPT_DURATION_INT_MASK)) {
171     LOG(ERROR) << StringPrintf("%s; Invalid WPT_DURATIOM_INT value", __func__);
172     return false;
173   }
174 
175   p_msg = (tNFA_WLC_MSG*)GKI_getbuf((uint16_t)(sizeof(tNFA_WLC_MSG)));
176   if (p_msg != nullptr) {
177     p_msg->hdr.event = NFA_WLC_API_NON_AUTO_START_WPT_EVT;
178 
179     p_msg->non_auto_start_wpt.power_adj_req = power_adj_req;
180     p_msg->non_auto_start_wpt.wpt_time_int = wpt_time_int;
181 
182     nfa_sys_sendmsg(p_msg);
183 
184     return (NFA_STATUS_OK);
185   }
186 
187   return (NFA_STATUS_FAILED);
188 }
189