1 /*
2 * Copyright (c) 2021-2023 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 "vibrator_controller.h"
17 #include <securec.h>
18 #include "hdf_base.h"
19 #include "hdf_log.h"
20 #include "osal_mem.h"
21
22 #define HDF_LOG_TAG uhdf_vibrator
23 #define EFFECT_SUN 64
24 #define VIBRATOR_SERVICE_NAME "hdf_misc_vibrator"
25
GetVibratorDevicePriv(void)26 static struct VibratorDevice *GetVibratorDevicePriv(void)
27 {
28 static struct VibratorDevice vibratorDeviceData = {
29 .initState = false,
30 .ioService = NULL,
31 };
32
33 return &vibratorDeviceData;
34 }
35
SendVibratorMsg(uint32_t cmd,struct HdfSBuf * msg,struct HdfSBuf * reply)36 static int32_t SendVibratorMsg(uint32_t cmd, struct HdfSBuf *msg, struct HdfSBuf *reply)
37 {
38 struct VibratorDevice *priv = GetVibratorDevicePriv();
39
40 if (priv->ioService == NULL || priv->ioService->dispatcher == NULL ||
41 priv->ioService->dispatcher->Dispatch == NULL) {
42 HDF_LOGE("%s: para invalid", __func__);
43 return HDF_FAILURE;
44 }
45
46 int32_t ret = priv->ioService->dispatcher->Dispatch(&priv->ioService->object, cmd, msg, reply);
47 if (ret != HDF_SUCCESS) {
48 HDF_LOGE("%{public}s: Vibrator dispatch failed", __func__);
49 return ret;
50 }
51
52 return HDF_SUCCESS;
53 }
54
ReadVibratorInfo(struct HdfSBuf * reply,struct VibratorDevice * priv)55 static int32_t ReadVibratorInfo(struct HdfSBuf *reply, struct VibratorDevice *priv)
56 {
57 uint32_t len;
58 struct VibratorInfo *buf = NULL;
59
60 if (!HdfSbufReadBuffer(reply, (const void **)&buf, &len)) {
61 return HDF_FAILURE;
62 }
63
64 if (buf == NULL || len != sizeof(struct VibratorInfo)) {
65 HDF_LOGE("%{public}s: read size is error, len = %{public}d, size = %{public}zu\n",\
66 __func__, len, sizeof(struct VibratorInfo));
67 HdfSbufRecycle(reply);
68 return HDF_FAILURE;
69 }
70
71 if (memcpy_s(&priv->vibratorInfoEntry, sizeof(priv->vibratorInfoEntry), buf, sizeof(*buf)) != EOK) {
72 HDF_LOGE("%s: Memcpy buf failed", __func__);
73 HdfSbufRecycle(reply);
74 return HDF_FAILURE;
75 }
76
77 return HDF_SUCCESS;
78 }
79
GetVibratorInfo(struct VibratorInfo ** vibratorInfo)80 static int32_t GetVibratorInfo(struct VibratorInfo **vibratorInfo)
81 {
82 int32_t ret;
83 if (vibratorInfo == NULL) {
84 HDF_LOGE("%s:line:%{public}d pointer is null and return ret", __func__, __LINE__);
85 return HDF_FAILURE;
86 }
87 struct VibratorDevice *priv = GetVibratorDevicePriv();
88
89 (void)OsalMutexLock(&priv->mutex);
90 struct HdfSBuf *reply = HdfSbufObtainDefaultSize();
91 if (reply == NULL) {
92 HDF_LOGE("%s: get sbuf failed", __func__);
93 (void)OsalMutexUnlock(&priv->mutex);
94 return HDF_FAILURE;
95 }
96
97 ret = SendVibratorMsg(VIBRATOR_IO_GET_INFO, NULL, reply);
98 if (ret != HDF_SUCCESS) {
99 HDF_LOGE("%{public}s: Vibrator send cmd failed, ret[%{public}d]", __func__, ret);
100 HdfSbufRecycle(reply);
101 (void)OsalMutexUnlock(&priv->mutex);
102 return ret;
103 }
104
105 if (ReadVibratorInfo(reply, priv) != HDF_SUCCESS) {
106 HdfSbufRecycle(reply);
107 (void)OsalMutexUnlock(&priv->mutex);
108 return HDF_FAILURE;
109 }
110
111 HdfSbufRecycle(reply);
112 (void)OsalMutexUnlock(&priv->mutex);
113
114 *vibratorInfo = &priv->vibratorInfoEntry;
115
116 return HDF_SUCCESS;
117 }
118
ValidityJudgment(uint32_t duration,uint16_t intensity,int16_t frequency)119 static int32_t ValidityJudgment(uint32_t duration, uint16_t intensity, int16_t frequency)
120 {
121 struct VibratorDevice *priv = GetVibratorDevicePriv();
122 if (duration == 0) {
123 HDF_LOGE("%s:invalid vibration period", __func__);
124 return VIBRATOR_NOT_PERIOD;
125 }
126
127 if ((priv->vibratorInfoEntry.isSupportIntensity == 0) || (intensity < priv->vibratorInfoEntry.intensityMinValue) ||
128 (intensity > priv->vibratorInfoEntry.intensityMaxValue)) {
129 HDF_LOGE("%s:intensity not supported", __func__);
130 return VIBRATOR_NOT_INTENSITY;
131 }
132
133 if ((priv->vibratorInfoEntry.isSupportFrequency == 0) || (frequency < priv->vibratorInfoEntry.frequencyMinValue) ||
134 (frequency > priv->vibratorInfoEntry.frequencyMaxValue)) {
135 HDF_LOGE("%s:frequency not supported", __func__);
136 return VIBRATOR_NOT_FREQUENCY;
137 }
138
139 return VIBRATOR_SUCCESS;
140 }
141
EnableVibratorModulation(uint32_t duration,uint16_t intensity,int16_t frequency)142 static int32_t EnableVibratorModulation(uint32_t duration, uint16_t intensity, int16_t frequency)
143 {
144 int32_t ret;
145 struct VibratorDevice *priv = GetVibratorDevicePriv();
146
147 ret = ValidityJudgment(duration, intensity, frequency);
148 if (ret != HDF_SUCCESS) {
149 HDF_LOGE("%{public}s: effect is false", __func__);
150 return ret;
151 }
152
153 (void)OsalMutexLock(&priv->mutex);
154 struct HdfSBuf *msg = HdfSbufObtainDefaultSize();
155 if (msg == NULL) {
156 HDF_LOGE("%{public}s: get sbuf failed", __func__);
157 (void)OsalMutexUnlock(&priv->mutex);
158 return HDF_FAILURE;
159 }
160
161 if (!HdfSbufWriteUint32(msg, duration)) {
162 HDF_LOGE("%{public}s: write duration failed.", __func__);
163 HdfSbufRecycle(msg);
164 (void)OsalMutexUnlock(&priv->mutex);
165 return HDF_FAILURE;
166 }
167
168 if (!HdfSbufWriteUint16(msg, intensity)) {
169 HDF_LOGE("%{public}s: write intensity failed.", __func__);
170 HdfSbufRecycle(msg);
171 (void)OsalMutexUnlock(&priv->mutex);
172 return HDF_FAILURE;
173 }
174
175 if (!HdfSbufWriteInt16(msg, frequency)) {
176 HDF_LOGE("%{public}s: write frequency failed.", __func__);
177 HdfSbufRecycle(msg);
178 (void)OsalMutexUnlock(&priv->mutex);
179 return HDF_FAILURE;
180 }
181 ret = SendVibratorMsg(VIBRATOR_IO_ENABLE_MODULATION_PARAMETER, msg, NULL);
182 if (ret != HDF_SUCCESS) {
183 HDF_LOGE("%{public}s: Vibrator send cmd failed, ret[%{public}d]", __func__, ret);
184 }
185 HdfSbufRecycle(msg);
186 (void)OsalMutexUnlock(&priv->mutex);
187
188 return ret;
189 }
190
StartOnce(uint32_t duration)191 static int32_t StartOnce(uint32_t duration)
192 {
193 int32_t ret;
194 struct VibratorDevice *priv = GetVibratorDevicePriv();
195
196 if (duration == 0) {
197 HDF_LOGE("%s:invalid duration para", __func__);
198 return HDF_ERR_INVALID_PARAM;
199 }
200
201 (void)OsalMutexLock(&priv->mutex);
202 struct HdfSBuf *msg = HdfSbufObtainDefaultSize();
203 if (msg == NULL) {
204 HDF_LOGE("%s: get sbuf failed", __func__);
205 (void)OsalMutexUnlock(&priv->mutex);
206 return HDF_FAILURE;
207 }
208
209 if (!HdfSbufWriteUint32(msg, duration)) {
210 HDF_LOGE("%s: write duration failed", __func__);
211 HdfSbufRecycle(msg);
212 (void)OsalMutexUnlock(&priv->mutex);
213 return HDF_FAILURE;
214 }
215
216 ret = SendVibratorMsg(VIBRATOR_IO_START_ONCE, msg, NULL);
217 if (ret != HDF_SUCCESS) {
218 HDF_LOGE("%{public}s: Vibrator send cmd failed, ret[%{public}d]", __func__, ret);
219 }
220 HdfSbufRecycle(msg);
221 (void)OsalMutexUnlock(&priv->mutex);
222
223 return ret;
224 }
225
Start(const char * effect)226 static int32_t Start(const char *effect)
227 {
228 int32_t ret;
229 struct VibratorDevice *priv = GetVibratorDevicePriv();
230
231 if (effect == NULL) {
232 HDF_LOGE("%s: start vibrator effect type invalid", __func__);
233 return HDF_ERR_INVALID_PARAM;
234 }
235
236 (void)OsalMutexLock(&priv->mutex);
237 struct HdfSBuf *msg = HdfSbufObtainDefaultSize();
238 if (msg == NULL) {
239 HDF_LOGE("%s: get sbuf failed", __func__);
240 HdfSbufRecycle(msg);
241 (void)OsalMutexUnlock(&priv->mutex);
242 return HDF_FAILURE;
243 }
244
245 if (!HdfSbufWriteString(msg, effect)) {
246 HDF_LOGE("%s: write effectName failed", __func__);
247 HdfSbufRecycle(msg);
248 (void)OsalMutexUnlock(&priv->mutex);
249 return HDF_FAILURE;
250 }
251
252 ret = SendVibratorMsg(VIBRATOR_IO_START_EFFECT, msg, NULL);
253 if (ret != HDF_SUCCESS) {
254 HDF_LOGE("%{public}s: Vibrator send cmd failed, ret[%{public}d]", __func__, ret);
255 }
256 HdfSbufRecycle(msg);
257 (void)OsalMutexUnlock(&priv->mutex);
258
259 return ret;
260 }
261
Stop(enum VibratorMode mode)262 static int32_t Stop(enum VibratorMode mode)
263 {
264 int32_t ret;
265 struct VibratorDevice *priv = GetVibratorDevicePriv();
266
267 (void)OsalMutexLock(&priv->mutex);
268 struct HdfSBuf *msg = HdfSbufObtainDefaultSize();
269 if (msg == NULL) {
270 HDF_LOGE("%s: get sbuf failed", __func__);
271 (void)OsalMutexUnlock(&priv->mutex);
272 return HDF_FAILURE;
273 }
274
275 if (!HdfSbufWriteInt32(msg, mode)) {
276 HDF_LOGE("%s: write mode failed", __func__);
277 HdfSbufRecycle(msg);
278 (void)OsalMutexUnlock(&priv->mutex);
279 return HDF_FAILURE;
280 }
281
282 ret = SendVibratorMsg(VIBRATOR_IO_STOP, msg, NULL);
283 if (ret != HDF_SUCCESS) {
284 HDF_LOGE("%{public}s: Vibrator send cmd failed, ret[%{public}d]", __func__, ret);
285 }
286 HdfSbufRecycle(msg);
287 (void)OsalMutexUnlock(&priv->mutex);
288
289 return ret;
290 }
291
NewVibratorInterfaceInstance(void)292 const struct VibratorInterface *NewVibratorInterfaceInstance(void)
293 {
294 static struct VibratorInterface vibratorDevInstance;
295 struct VibratorDevice *priv = GetVibratorDevicePriv();
296
297 if (priv->initState) {
298 return &vibratorDevInstance;
299 }
300
301 OsalMutexInit(&priv->mutex);
302 vibratorDevInstance.Start = Start;
303 vibratorDevInstance.StartOnce = StartOnce;
304 vibratorDevInstance.Stop = Stop;
305 vibratorDevInstance.GetVibratorInfo = GetVibratorInfo;
306 vibratorDevInstance.EnableVibratorModulation = EnableVibratorModulation;
307
308 priv->ioService = HdfIoServiceBind(VIBRATOR_SERVICE_NAME);
309 if (priv->ioService == NULL) {
310 HDF_LOGE("%s: get vibrator ioService failed", __func__);
311 OsalMutexDestroy(&priv->mutex);
312 return NULL;
313 }
314
315 priv->initState = true;
316 HDF_LOGD("get vibrator devInstance success");
317 return &vibratorDevInstance;
318 }
319
FreeVibratorInterfaceInstance(void)320 int32_t FreeVibratorInterfaceInstance(void)
321 {
322 struct VibratorDevice *priv = GetVibratorDevicePriv();
323
324 if (!priv->initState) {
325 HDF_LOGD("%s: vibrator instance had released", __func__);
326 return HDF_SUCCESS;
327 }
328
329 if (priv->ioService != NULL) {
330 HdfIoServiceRecycle(priv->ioService);
331 }
332
333 OsalMutexDestroy(&priv->mutex);
334
335 return HDF_SUCCESS;
336 }