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