• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "light_controller.h"
17 #include <fcntl.h>
18 #include <securec.h>
19 #include <stdio.h>
20 #include "osal_mem.h"
21 #include "hdf_base.h"
22 #include "hdf_dlist.h"
23 #include "hdf_io_service_if.h"
24 #include "hdf_log.h"
25 #include "light_dump.h"
26 #include "light_if.h"
27 #include "light_type.h"
28 
29 #define HDF_LOG_TAG           uhdf_light_service
30 #define LIGHT_SERVICE_NAME    "hdf_light"
31 
32 #define MULTI_LIGHT_MAX_NUMBER    48
33 #define LIGHT_ON    1
34 #define LIGHT_OFF   0
35 
36 struct LightEffect g_lightEffect;
37 uint8_t g_lightState[LIGHT_ID_BUTT] = {0};
38 
GetLightDevicePriv(void)39 struct LightDevice *GetLightDevicePriv(void)
40 {
41     static struct LightDevice lightDeviceData = {
42         .initState = false,
43         .lightNum = 0,
44         .ioService = NULL,
45         .lightInfoEntry = NULL,
46     };
47 
48     return &lightDeviceData;
49 }
50 
GetLightEffect(void)51 struct LightEffect *GetLightEffect(void)
52 {
53     return &g_lightEffect;
54 }
55 
GetLightState(void)56 uint8_t *GetLightState(void)
57 {
58     return g_lightState;
59 }
60 
SendLightMsg(uint32_t cmd,struct HdfSBuf * msg,struct HdfSBuf * reply)61 static int32_t SendLightMsg(uint32_t cmd, struct HdfSBuf *msg, struct HdfSBuf *reply)
62 {
63     struct LightDevice *priv = GetLightDevicePriv();
64 
65     if (priv->ioService == NULL || priv->ioService->dispatcher == NULL ||
66         priv->ioService->dispatcher->Dispatch == NULL) {
67         HDF_LOGE("%s: para invalid", __func__);
68         return HDF_FAILURE;
69     }
70 
71     int32_t ret = priv->ioService->dispatcher->Dispatch(&priv->ioService->object, cmd, msg, reply);
72     if (ret != HDF_SUCCESS) {
73         HDF_LOGE("%{public}s: Light dispatch failed", __func__);
74         return ret;
75     }
76 
77     return HDF_SUCCESS;
78 }
79 
ReadLightInfo(struct HdfSBuf * reply,struct LightDevice * priv)80 static int32_t ReadLightInfo(struct HdfSBuf *reply, struct LightDevice *priv)
81 {
82     struct LightInfo *pos = NULL;
83     const char *name = NULL;
84 
85     if (!HdfSbufReadUint32(reply, &priv->lightNum)) {
86         HDF_LOGE("%s: sbuf read lightNum failed", __func__);
87         return HDF_FAILURE;
88     }
89 
90     if (priv->lightInfoEntry != NULL) {
91         OsalMemFree(priv->lightInfoEntry);
92         priv->lightInfoEntry = NULL;
93     }
94 
95     priv->lightInfoEntry = (struct LightInfo *)OsalMemCalloc(sizeof(*priv->lightInfoEntry) * priv->lightNum);
96     if (priv->lightInfoEntry == NULL) {
97         HDF_LOGE("%s: malloc fail", __func__);
98         return HDF_FAILURE;
99     }
100 
101     pos = priv->lightInfoEntry;
102 
103     for (uint32_t i = 0; i < priv->lightNum; ++i) {
104         if (!HdfSbufReadUint32(reply, &pos->lightId)) {
105             HDF_LOGE("%{public}s:read lightId failed!", __func__);
106             return HDF_FAILURE;
107         }
108 
109         name = HdfSbufReadString(reply);
110         if (strcpy_s(pos->lightName, NAME_MAX_LEN, name) != EOK) {
111             HDF_LOGE("%{public}s:copy lightName failed!", __func__);
112             return HDF_FAILURE;
113         }
114 
115         if (!HdfSbufReadUint32(reply, &pos->lightNumber)) {
116             HDF_LOGE("%{public}s:read lightNumber failed!", __func__);
117             return HDF_FAILURE;
118         }
119 
120         if (!HdfSbufReadInt32(reply, &pos->lightType)) {
121             HDF_LOGE("%{public}s:read lightType failed!", __func__);
122             return HDF_FAILURE;
123         }
124         pos++;
125     }
126 
127     return HDF_SUCCESS;
128 }
129 
GetLightInfo(struct LightInfo ** lightInfo,uint32_t * count)130 static int32_t GetLightInfo(struct LightInfo **lightInfo, uint32_t *count)
131 {
132     if ((lightInfo == NULL) || (count == NULL)) {
133         HDF_LOGE("%s:line:%{public}d pointer is null and return ret", __func__, __LINE__);
134         return HDF_FAILURE;
135     }
136 
137     struct LightDevice *priv = GetLightDevicePriv();
138 
139     if (priv->lightNum > 0) {
140         *count = priv->lightNum;
141         *lightInfo = priv->lightInfoEntry;
142         return HDF_SUCCESS;
143     }
144 
145     (void)OsalMutexLock(&priv->mutex);
146     struct HdfSBuf *reply = HdfSbufObtainDefaultSize();
147     if (reply == NULL) {
148         HDF_LOGE("%s: get sbuf failed", __func__);
149         (void)OsalMutexUnlock(&priv->mutex);
150         return HDF_FAILURE;
151     }
152 
153     int32_t ret = SendLightMsg(LIGHT_IO_CMD_GET_INFO_LIST, NULL, reply);
154     if (ret != HDF_SUCCESS) {
155         HDF_LOGE("%{public}s: Light send cmd failed, ret[%{public}d]", __func__, ret);
156         HdfSbufRecycle(reply);
157         (void)OsalMutexUnlock(&priv->mutex);
158         return ret;
159     }
160 
161     if (ReadLightInfo(reply, priv) != HDF_SUCCESS) {
162         HdfSbufRecycle(reply);
163         (void)OsalMutexUnlock(&priv->mutex);
164         return HDF_FAILURE;
165     }
166 
167     HdfSbufRecycle(reply);
168     (void)OsalMutexUnlock(&priv->mutex);
169 
170     *count = priv->lightNum;
171     *lightInfo = priv->lightInfoEntry;
172 
173     return HDF_SUCCESS;
174 }
175 
OnLightValidityJudgment(uint32_t lightId,struct LightEffect * effect)176 static int32_t OnLightValidityJudgment(uint32_t lightId, struct LightEffect *effect)
177 {
178     if (lightId >= LIGHT_ID_BUTT) {
179         HDF_LOGE("%{public}s: id not supported", __func__);
180         return LIGHT_NOT_SUPPORT;
181     }
182 
183     if (effect->flashEffect.flashMode < LIGHT_FLASH_NONE || effect->flashEffect.flashMode > LIGHT_FLASH_BLINK) {
184         HDF_LOGE("%{public}s: flashMode not supported", __func__);
185         return LIGHT_NOT_FLASH;
186     }
187 
188     if ((effect->flashEffect.flashMode == LIGHT_FLASH_BLINK) && (effect->flashEffect.onTime == 0 ||
189         effect->flashEffect.offTime == 0)) {
190         HDF_LOGE("%{public}s: flashMode not supported", __func__);
191         return LIGHT_NOT_FLASH;
192     }
193 
194     return LIGHT_SUCCESS;
195 }
196 
OnLight(uint32_t lightId,struct LightEffect * effect)197 static int32_t OnLight(uint32_t lightId, struct LightEffect *effect)
198 {
199     int32_t ret;
200 
201     if (effect == NULL) {
202         HDF_LOGE("%{public}s: effect is NULL", __func__);
203         return HDF_FAILURE;
204     }
205 
206     ret = OnLightValidityJudgment(lightId, effect);
207     if (ret != HDF_SUCCESS) {
208         HDF_LOGE("%{public}s: effect is false", __func__);
209         return ret;
210     }
211 
212     struct LightDevice *priv = GetLightDevicePriv();
213     (void)OsalMutexLock(&priv->mutex);
214 
215     struct HdfSBuf *msg = HdfSbufObtainDefaultSize();
216     if (msg == NULL) {
217         HDF_LOGE("%{public}s: Failed to obtain sBuf size", __func__);
218         (void)OsalMutexUnlock(&priv->mutex);
219         return HDF_FAILURE;
220     }
221 
222     if (!HdfSbufWriteInt32(msg, lightId)) {
223         HDF_LOGE("%{public}s: Light write id failed", __func__);
224         HdfSbufRecycle(msg);
225         (void)OsalMutexUnlock(&priv->mutex);
226         return HDF_FAILURE;
227     }
228 
229     if (!HdfSbufWriteInt32(msg, LIGHT_OPS_IO_CMD_ENABLE)) {
230         HDF_LOGE("%{public}s: Light write enable failed", __func__);
231         HdfSbufRecycle(msg);
232         (void)OsalMutexUnlock(&priv->mutex);
233         return HDF_FAILURE;
234     }
235 
236     if (!HdfSbufWriteBuffer(msg, effect, sizeof(*effect))) {
237         HDF_LOGE("%{public}s: Light write enable failed", __func__);
238         HdfSbufRecycle(msg);
239         (void)OsalMutexUnlock(&priv->mutex);
240         return HDF_FAILURE;
241     }
242 
243     ret = SendLightMsg(LIGHT_IO_CMD_OPS, msg, NULL);
244     if (ret != HDF_SUCCESS) {
245         HDF_LOGE("%{public}s: Light enable failed, ret[%{public}d]", __func__, ret);
246     }
247     HdfSbufRecycle(msg);
248     (void)OsalMutexUnlock(&priv->mutex);
249 
250     if (memcpy_s(&g_lightEffect, sizeof(g_lightEffect), effect, sizeof(*effect)) != EOK) {
251         HDF_LOGE("%{public}s: Light effect cpy faild", __func__);
252         return HDF_FAILURE;
253     }
254 
255     g_lightState[lightId] = LIGHT_ON;
256 
257     return ret;
258 }
259 
OnMultiLightsValidityJudgment(uint32_t lightId,const struct LightColor * colors,const uint32_t count)260 static int32_t OnMultiLightsValidityJudgment(uint32_t lightId, const struct LightColor *colors, const uint32_t count)
261 {
262     if (lightId >= LIGHT_ID_BUTT) {
263         HDF_LOGE("%{public}s: id not supported", __func__);
264         return HDF_ERR_NOT_SUPPORT;
265     }
266 
267     if (colors == NULL) {
268         HDF_LOGE("%{public}s: colors is nullptr", __func__);
269         return HDF_ERR_INVALID_PARAM;
270     }
271 
272     if (count == 0 || count > MULTI_LIGHT_MAX_NUMBER) {
273         HDF_LOGE("%{public}s: count out of range", __func__);
274         return HDF_ERR_INVALID_PARAM;
275     }
276 
277     return HDF_SUCCESS;
278 }
279 
OnMultiLights(uint32_t lightId,const struct LightColor * colors,const uint32_t count)280 static int32_t OnMultiLights(uint32_t lightId, const struct LightColor *colors, const uint32_t count)
281 {
282     int32_t ret;
283     struct HdfSBuf *sbuf = NULL;
284 
285     ret = OnMultiLightsValidityJudgment(lightId, colors, count);
286     if (ret != HDF_SUCCESS) {
287         HDF_LOGE("%{public}s: effect is false", __func__);
288         return ret;
289     }
290 
291     struct LightDevice *priv = GetLightDevicePriv();
292     (void)OsalMutexLock(&priv->mutex);
293 
294     sbuf = HdfSbufObtain(sizeof(struct LightColor) * count);
295     if (sbuf == NULL) {
296         HDF_LOGE("%{public}s: sbuf malloc failed", __func__);
297         return HDF_DEV_ERR_NO_MEMORY;
298     }
299 
300     if (!HdfSbufWriteInt32(sbuf, lightId)) {
301         HDF_LOGE("%{public}s: light write id failed", __func__);
302         ret = HDF_FAILURE;
303         goto EXIT;
304     }
305 
306     if (!HdfSbufWriteInt32(sbuf, LIGHT_OPS_IO_CMD_ENABLE_MULTI_LIGHTS)) {
307         HDF_LOGE("%{public}s: light write cmd failed", __func__);
308         ret = HDF_FAILURE;
309         goto EXIT;
310     }
311 
312     if (!HdfSbufWriteBuffer(sbuf, colors, sizeof(*colors))) {
313         HDF_LOGE("%{public}s: light write buf failed", __func__);
314         ret = HDF_FAILURE;
315         goto EXIT;
316     }
317 
318     if (!HdfSbufWriteInt32(sbuf, count)) {
319         HDF_LOGE("%{public}s: light write count failed", __func__);
320         ret = HDF_FAILURE;
321         goto EXIT;
322     }
323 
324     ret = SendLightMsg(LIGHT_IO_CMD_OPS, sbuf, NULL);
325     if (ret != HDF_SUCCESS) {
326         HDF_LOGE("%{public}s: light enable failed, ret[%{public}d]", __func__, ret);
327     }
328 
329 EXIT:
330     HdfSbufRecycle(sbuf);
331     (void)OsalMutexUnlock(&priv->mutex);
332 
333     if (memcpy_s(&(g_lightEffect.lightColor), sizeof(g_lightEffect.lightColor),
334         colors, sizeof(*colors)) != EOK) {
335         HDF_LOGE("%{public}s: Light colors cpy faild", __func__);
336         return HDF_FAILURE;
337     }
338 
339     g_lightState[lightId] = LIGHT_ON;
340 
341     return ret;
342 }
343 
OffLight(uint32_t lightId)344 static int32_t OffLight(uint32_t lightId)
345 {
346     if (lightId >= LIGHT_ID_BUTT) {
347         HDF_LOGE("%{public}s: id not supported", __func__);
348         return HDF_FAILURE;
349     }
350 
351     struct LightDevice *priv = GetLightDevicePriv();
352     (void)OsalMutexLock(&priv->mutex);
353 
354     struct HdfSBuf *msg = HdfSbufObtainDefaultSize();
355     if (msg == NULL) {
356         HDF_LOGE("%{public}s: Failed to obtain sBuf", __func__);
357         (void)OsalMutexUnlock(&priv->mutex);
358         return HDF_FAILURE;
359     }
360 
361     if (!HdfSbufWriteInt32(msg, lightId)) {
362         HDF_LOGE("%{public}s: Light write id failed", __func__);
363         HdfSbufRecycle(msg);
364         (void)OsalMutexUnlock(&priv->mutex);
365         return HDF_FAILURE;
366     }
367 
368     if (!HdfSbufWriteInt32(msg, LIGHT_OPS_IO_CMD_DISABLE)) {
369         HDF_LOGE("%{public}s: Light write disable failed", __func__);
370         HdfSbufRecycle(msg);
371         (void)OsalMutexUnlock(&priv->mutex);
372         return HDF_FAILURE;
373     }
374 
375     int32_t ret = SendLightMsg(LIGHT_IO_CMD_OPS, msg, NULL);
376     if (ret != HDF_SUCCESS) {
377         HDF_LOGE("%{public}s: Light disable failed, ret[%{public}d]", __func__, ret);
378     }
379     HdfSbufRecycle(msg);
380     (void)OsalMutexUnlock(&priv->mutex);
381 
382     g_lightState[lightId] = LIGHT_OFF;
383 
384     return ret;
385 }
386 
NewLightInterfaceInstance(void)387 const struct LightInterface *NewLightInterfaceInstance(void)
388 {
389     static struct LightInterface lightDevInstance;
390     struct LightDevice *priv = GetLightDevicePriv();
391 
392     if (priv->initState) {
393         return &lightDevInstance;
394     }
395 
396     OsalMutexInit(&priv->mutex);
397     lightDevInstance.GetLightInfo = GetLightInfo;
398     lightDevInstance.TurnOnLight = OnLight;
399     lightDevInstance.TurnOffLight = OffLight;
400     lightDevInstance.TurnOnMultiLights = OnMultiLights;
401 
402     priv->ioService = HdfIoServiceBind(LIGHT_SERVICE_NAME);
403     if (priv->ioService == NULL) {
404         HDF_LOGE("%s: get light ioService failed", __func__);
405         OsalMutexDestroy(&priv->mutex);
406         return NULL;
407     }
408 
409     priv->initState = true;
410     HDF_LOGI("get light devInstance success");
411 
412     return &lightDevInstance;
413 }
414 
FreeLightInterfaceInstance(void)415 int32_t FreeLightInterfaceInstance(void)
416 {
417     struct LightDevice *priv = GetLightDevicePriv();
418 
419     if (!priv->initState) {
420         HDF_LOGI("%s: light instance had released", __func__);
421         return HDF_SUCCESS;
422     }
423 
424     priv->lightNum = 0;
425 
426     if (priv->ioService != NULL) {
427         HdfIoServiceRecycle(priv->ioService);
428     }
429 
430     if (priv->lightInfoEntry != NULL) {
431         OsalMemFree(priv->lightInfoEntry);
432         priv->lightInfoEntry = NULL;
433     }
434 
435     OsalMutexDestroy(&priv->mutex);
436 
437     return HDF_SUCCESS;
438 }