1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdint.h>
17 #include <stdlib.h>
18
19 #include <pthread.h>
20 #include <registry.h>
21 #include <samgr_lite.h>
22 #include <securec.h>
23
24 #include "battery_framework.h"
25 #include "battery_info.h"
26 #include "battery_interface.h"
27 #include "ibattery.h"
28
29 #define MAX_DATA_LEN 1024
30
31 typedef struct {
32 INHERIT_IUNKNOWNENTRY(BatteryProxyInterface);
33 } BatteryProxyEntry;
34
BatteryCallbackInt(IOwner owner,int32_t code,IpcIo * reply)35 static int32_t BatteryCallbackInt(IOwner owner, int32_t code, IpcIo *reply)
36 {
37 (void)code;
38 if ((reply == NULL) || (owner == NULL)) {
39 return EC_INVALID;
40 }
41
42 int32_t *ret = (int32_t *)owner;
43 ReadInt32(reply, ret);
44 return EC_SUCCESS;
45 }
46
GetBatSocProxy(IUnknown * iUnknown)47 static int32_t GetBatSocProxy(IUnknown *iUnknown)
48 {
49 IpcIo request;
50 char buffer[MAX_DATA_LEN] = { 0 };
51 IpcIoInit(&request, buffer, MAX_DATA_LEN, 0);
52 int32_t ret = 0;
53
54 if (iUnknown == NULL) {
55 return EC_INVALID;
56 }
57
58 BatteryProxyInterface *proxy = (BatteryProxyInterface *)iUnknown;
59 proxy->Invoke((IClientProxy *)proxy, BATTERY_FUNCID_GETSOC, &request, &ret, BatteryCallbackInt);
60
61 return ret;
62 }
GetChargingStatusProxy(IUnknown * iUnknown)63 static BatteryChargeState GetChargingStatusProxy(IUnknown *iUnknown)
64 {
65 IpcIo request;
66 char buffer[MAX_DATA_LEN] = { 0 };
67 IpcIoInit(&request, buffer, MAX_DATA_LEN, 0);
68 int32_t ret = 0;
69
70 if (iUnknown == NULL) {
71 return EC_INVALID;
72 }
73
74 BatteryProxyInterface *proxy = (BatteryProxyInterface *)iUnknown;
75 proxy->Invoke((IClientProxy *)proxy, BATTERY_FUNCID_GETCHARGING, &request, &ret, BatteryCallbackInt);
76
77 return ret;
78 }
GetHealthStatusProxy(IUnknown * iUnknown)79 static BatteryHealthState GetHealthStatusProxy(IUnknown *iUnknown)
80 {
81 IpcIo request;
82 char buffer[MAX_DATA_LEN] = { 0 };
83 IpcIoInit(&request, buffer, MAX_DATA_LEN, 0);
84 int32_t ret = 0;
85
86 if (iUnknown == NULL) {
87 return EC_INVALID;
88 }
89
90 BatteryProxyInterface *proxy = (BatteryProxyInterface *)iUnknown;
91 proxy->Invoke((IClientProxy *)proxy, BATTERY_FUNCID_GETHEALTH, &request, &ret, BatteryCallbackInt);
92
93 return ret;
94 }
GetPluggedTypeProxy(IUnknown * iUnknown)95 static BatteryPluggedType GetPluggedTypeProxy(IUnknown *iUnknown)
96 {
97 IpcIo request;
98 char buffer[MAX_DATA_LEN] = { 0 };
99 IpcIoInit(&request, buffer, MAX_DATA_LEN, 0);
100 int32_t ret = 0;
101
102 if (iUnknown == NULL) {
103 return EC_INVALID;
104 }
105
106 BatteryProxyInterface *proxy = (BatteryProxyInterface *)iUnknown;
107 proxy->Invoke((IClientProxy *)proxy, BATTERY_FUNCID_GETPLUGTYPE, &request, &ret, BatteryCallbackInt);
108
109 return ret;
110 }
GetBatVoltageProxy(IUnknown * iUnknown)111 static int32_t GetBatVoltageProxy(IUnknown *iUnknown)
112 {
113 IpcIo request;
114 char buffer[MAX_DATA_LEN] = { 0 };
115 IpcIoInit(&request, buffer, MAX_DATA_LEN, 0);
116 int32_t ret = 0;
117
118 if (iUnknown == NULL) {
119 return EC_INVALID;
120 }
121
122 BatteryProxyInterface *proxy = (BatteryProxyInterface *)iUnknown;
123 proxy->Invoke((IClientProxy *)proxy, BATTERY_FUNCID_GETVOLTAGE, &request, &ret, BatteryCallbackInt);
124
125 return ret;
126 }
127
BatteryCallbackBuff(IOwner owner,int32_t code,IpcIo * reply)128 static int32_t BatteryCallbackBuff(IOwner owner, int32_t code, IpcIo *reply)
129 {
130 size_t len = 0;
131 (void)code;
132 if ((reply == NULL) || (owner == NULL)) {
133 return EC_INVALID;
134 }
135
136 char **strBuff = (char **)owner;
137 *strBuff = (char *)ReadString(reply, &len);
138 if (*strBuff == NULL || len == 0) {
139 return EC_INVALID;
140 }
141
142 return EC_SUCCESS;
143 }
144
GetBatTechnologyProxy(IUnknown * iUnknown)145 static char *GetBatTechnologyProxy(IUnknown *iUnknown)
146 {
147 IpcIo request;
148 char buffer[MAX_DATA_LEN] = { 0 };
149 IpcIoInit(&request, buffer, MAX_DATA_LEN, 0);
150 char *string = NULL;
151
152 if (iUnknown == NULL) {
153 return string;
154 }
155
156 BatteryProxyInterface *proxy = (BatteryProxyInterface *)iUnknown;
157 proxy->Invoke((IClientProxy *)proxy, BATTERY_FUNCID_GETTECHNOLONY, &request, &string, BatteryCallbackBuff);
158 return string;
159 }
160
GetBatTemperatureProxy(IUnknown * iUnknown)161 static int32_t GetBatTemperatureProxy(IUnknown *iUnknown)
162 {
163 IpcIo request;
164 char buffer[MAX_DATA_LEN] = { 0 };
165 IpcIoInit(&request, buffer, MAX_DATA_LEN, 0);
166 int32_t ret = 0;
167
168 if (iUnknown == NULL) {
169 return EC_INVALID;
170 }
171
172 BatteryProxyInterface *proxy = (BatteryProxyInterface *)iUnknown;
173 proxy->Invoke((IClientProxy *)proxy, BATTERY_FUNCID_GETTEMPERATURE, &request, &ret, BatteryCallbackInt);
174
175 return ret;
176 }
177
CreatClient(const char * service,const char * feature,uint32_t size)178 static void *CreatClient(const char *service, const char *feature, uint32_t size)
179 {
180 (void)service;
181 (void)feature;
182 uint32_t len = size + sizeof(BatteryProxyEntry);
183 uint8_t *client = (uint8_t *)malloc(len);
184 if (client == NULL) {
185 return NULL;
186 }
187
188 (void)memset_s(client, len, 0, len);
189 BatteryProxyEntry *entry = (BatteryProxyEntry *)&client[size];
190 entry->ver = ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION);
191 entry->ref = 1;
192 entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
193 entry->iUnknown.AddRef = IUNKNOWN_AddRef;
194 entry->iUnknown.Release = IUNKNOWN_Release;
195 entry->iUnknown.Invoke = NULL;
196 entry->iUnknown.GetBatSocFunc = GetBatSocProxy;
197 entry->iUnknown.GetChargingStatusFunc = GetChargingStatusProxy;
198 entry->iUnknown.GetHealthStatusFunc = GetHealthStatusProxy;
199 entry->iUnknown.GetPluggedTypeFunc = GetPluggedTypeProxy;
200 entry->iUnknown.GetBatVoltageFunc = GetBatVoltageProxy;
201 entry->iUnknown.GetBatTechnologyFunc = GetBatTechnologyProxy;
202 entry->iUnknown.GetBatTemperatureFunc = GetBatTemperatureProxy;
203 return client;
204 }
205
DestroyClient(const char * service,const char * feature,void * iproxy)206 static void DestroyClient(const char *service, const char *feature, void *iproxy)
207 {
208 (void)service;
209 (void)feature;
210 if (iproxy != NULL) {
211 free(iproxy);
212 }
213 }
214
GetBatteryInterface(void)215 static BatteryProxyInterface *GetBatteryInterface(void)
216 {
217 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
218 static BatteryProxyInterface *g_intf = NULL;
219
220 pthread_mutex_lock(&g_mutex);
221 if (g_intf != NULL) {
222 pthread_mutex_unlock(&g_mutex);
223 return g_intf;
224 }
225 SAMGR_RegisterFactory(BATTERY_SERVICE, BATTERY_INNER, CreatClient, DestroyClient);
226
227 IUnknown *iUnknown = GetBatteryIUnknown();
228 if (iUnknown == NULL) {
229 pthread_mutex_unlock(&g_mutex);
230 return NULL;
231 }
232
233 int ret = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&g_intf);
234 if ((ret != EC_SUCCESS) || (g_intf == NULL)) {
235 pthread_mutex_unlock(&g_mutex);
236 return NULL;
237 }
238 pthread_mutex_unlock(&g_mutex);
239
240 return g_intf;
241 }
242
GetBatSoc(void)243 int32_t GetBatSoc(void)
244 {
245 int32_t ret = EC_FAILURE;
246 BatteryProxyInterface *intf = GetBatteryInterface();
247
248 if ((intf != NULL) && (intf->GetBatSocFunc != NULL)) {
249 ret = intf->GetBatSocFunc((IUnknown *)intf);
250 }
251 return ret;
252 }
253
GetChargingStatus(void)254 BatteryChargeState GetChargingStatus(void)
255 {
256 BatteryChargeState state = CHARGE_STATE_NONE;
257 BatteryProxyInterface *intf = GetBatteryInterface();
258 if ((intf != NULL) && (intf->GetBatSocFunc != NULL)) {
259 state = intf->GetChargingStatusFunc((IUnknown *)intf);
260 }
261 return state;
262 }
263
GetHealthStatus(void)264 BatteryHealthState GetHealthStatus(void)
265 {
266 BatteryHealthState state = HEALTH_STATE_UNKNOWN;
267 BatteryProxyInterface *intf = GetBatteryInterface();
268 if ((intf != NULL) && (intf->GetBatSocFunc != NULL)) {
269 state = intf->GetHealthStatusFunc((IUnknown *)intf);
270 }
271 return state;
272 }
273
GetPluggedType(void)274 BatteryPluggedType GetPluggedType(void)
275 {
276 BatteryPluggedType state = PLUGGED_TYPE_NONE;
277 BatteryProxyInterface *intf = GetBatteryInterface();
278 if ((intf != NULL) && (intf->GetBatSocFunc != NULL)) {
279 state = intf->GetPluggedTypeFunc((IUnknown *)intf);
280 }
281 return state;
282 }
283
GetBatVoltage(void)284 int32_t GetBatVoltage(void)
285 {
286 int32_t ret = EC_FAILURE;
287 BatteryProxyInterface *intf = GetBatteryInterface();
288 if ((intf != NULL) && (intf->GetBatSocFunc != NULL)) {
289 ret = intf->GetBatVoltageFunc((IUnknown *)intf);
290 }
291 return ret;
292 }
293
GetBatTechnology(void)294 char *GetBatTechnology(void)
295 {
296 char *strBuff = NULL;
297 BatteryProxyInterface *intf = GetBatteryInterface();
298 if ((intf != NULL) && (intf->GetBatSocFunc != NULL)) {
299 strBuff = intf->GetBatTechnologyFunc((IUnknown *)intf);
300 }
301 return strBuff;
302 }
303
GetBatTemperature(void)304 int32_t GetBatTemperature(void)
305 {
306 int32_t ret = EC_FAILURE;
307 BatteryProxyInterface *intf = GetBatteryInterface();
308 if ((intf != NULL) && (intf->GetBatSocFunc != NULL)) {
309 ret = intf->GetBatTemperatureFunc((IUnknown *)intf);
310 }
311 return ret;
312 }
313