GCC Code Coverage Report


Directory: src/gate/
File: src/gate/io/platform/gpiodevice_libgpiod.h
Date: 2026-06-15 21:53:51
Exec Total Coverage
Lines: 0 223 0.0%
Functions: 0 5 0.0%
Branches: 0 114 0.0%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright (c) 2018-2026, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #ifndef GATE_IO_PLATFORM_GPIODEVICE_LIBGPIOD_H_INCLUDED
30 #define GATE_IO_PLATFORM_GPIODEVICE_LIBGPIOD_H_INCLUDED
31
32 #include "gate/libraries.h"
33 #include "gate/debugging.h"
34
35
36 enum gpiod_line_value
37 {
38 GPIOD_LINE_VALUE_ERROR = -1,
39 GPIOD_LINE_VALUE_INACTIVE = 0,
40 GPIOD_LINE_VALUE_ACTIVE = 1
41 };
42
43
44 enum gpiod_line_direction
45 {
46 GPIOD_LINE_DIRECTION_AS_IS = 1,
47 GPIOD_LINE_DIRECTION_INPUT = 2,
48 GPIOD_LINE_DIRECTION_OUTPUT = 3
49 };
50
51 typedef struct gpiod_chip gpiod_chip_t;
52 typedef struct gpiod_chip_info gpiod_chip_info_t;
53 typedef struct gpiod_line gpiod_line_t;
54 typedef struct gpiod_line_info gpiod_line_info_t;
55 typedef struct gpiod_line_settings gpiod_line_settings_t;
56 typedef struct gpiod_line_config gpiod_line_config_t;
57 typedef struct gpiod_line_request gpiod_line_request_t;
58 typedef struct gpiod_request_config gpiod_request_config_t;
59
60 typedef enum gpiod_line_direction gpiod_line_direction_t;
61 typedef enum gpiod_line_value gpiod_line_value_t;
62
63 typedef struct gpiod_code
64 {
65 char const* (*version_string) (void);
66
67
68 /* chip access */
69 gpiod_chip_t* (*chip_open) (const char *path);
70 void (*chip_close) (gpiod_chip_t* chip);
71
72
73 /* chip info */
74 const char* (*v1_chip_name) (gpiod_chip_t* chip);
75 const char* (*v1_chip_label) (gpiod_chip_t* chip);
76 unsigned int (*v1_chip_num_lines) (gpiod_chip_t* chip);
77
78 gpiod_chip_info_t* (*v2_chip_get_info) (gpiod_chip_t* chip);
79 void (*v2_chip_info_free) (gpiod_chip_info_t* info);
80 const char* (*v2_chip_info_get_name) (gpiod_chip_info_t* info);
81 const char* (*v2_chip_info_get_label) (gpiod_chip_info_t* info);
82 size_t (*v2_chip_info_get_num_lines) (gpiod_chip_info_t* info);
83
84 /* line info */
85 gpiod_line_t* (*v1_chip_get_line) (gpiod_chip_t* chip, unsigned int offset);
86 void (*v1_line_release) (gpiod_line_t* line);
87 const char * (*v1_line_name) (gpiod_line_t* line);
88 const char * (*v1_line_consumer) (gpiod_line_t* line);
89 int (*v1_line_direction) (gpiod_line_t* line);
90 int (*v1_line_active_state) (gpiod_line_t* line);
91 bool (*v1_line_is_used) (gpiod_line_t* line);
92
93 gpiod_line_info_t* (*v2_chip_get_line_info) (gpiod_chip_t* chip, unsigned int offset);
94 void (*v2_line_info_free) (gpiod_line_info_t *info);
95 const char * (*v2_line_info_get_name) (gpiod_line_info_t *info);
96 const char * (*v2_line_info_get_consumer) (gpiod_line_info_t *info);
97 bool (*v2_line_info_is_used) (gpiod_line_info_t *info);
98 gpiod_line_direction_t (*v2_line_info_get_direction) (gpiod_line_info_t *info);
99
100 /* line read/write access */
101 int (*v1_line_request_input) (gpiod_line_t* line, const char* consumer);
102 int (*v1_line_get_value) (gpiod_line_t* line);
103 int (*v1_line_request_output) (gpiod_line_t* line, const char *consumer, int default_val);
104 int (*v1_line_set_value) (gpiod_line_t* line, int value);
105
106 gpiod_line_settings_t* (*v2_line_settings_new) (void);
107 void (*v2_line_settings_free) (gpiod_line_settings_t* settings);
108 int (*v2_line_settings_set_direction) (gpiod_line_settings_t* settings, gpiod_line_direction_t direction);
109 int (*v2_line_settings_set_output_value)(gpiod_line_settings_t* settings, gpiod_line_value_t value);
110 gpiod_line_direction_t (*v2_line_settings_get_direction) (gpiod_line_settings_t* settings);
111 gpiod_line_config_t* (*v2_line_config_new) (void);
112 void (*v2_line_config_free) (gpiod_line_config_t* config);
113 int (*v2_line_config_add_line_settings) (gpiod_line_config_t* config, const unsigned int* offsets, size_t num_offsets, gpiod_line_settings_t* settings);
114 gpiod_line_request_t* (*v2_chip_request_lines) (gpiod_chip_t* chip, gpiod_request_config_t* req_cfg, gpiod_line_config_t* line_cfg);
115 void (*v2_line_request_release) (gpiod_line_request_t* request);
116 gpiod_line_value_t (*v2_line_request_get_value) (gpiod_line_request_t* request, unsigned int offset);
117 int (*v2_line_request_reconfigure_lines)(gpiod_line_request_t* request, gpiod_line_config_t* config);
118 int (*v2_line_request_set_value) (gpiod_line_request_t* request, unsigned int offset, gpiod_line_value_t value);
119
120 } gpiod_code_t;
121
122
123 ✗ static gpiod_code_t* get_gpiod_functions()
124 {
125 static gpiod_code_t code;
126 static gate_bool_t code_loaded = false;
127 static gate_library_t code_lib;
128
129 ✗ if (!code_loaded)
130 {
131 static gate_string_t const lib_name = GATE_STRING_INIT_STATIC("libgpiod.so");
132 gate_result_t result;
133 ✗ result = gate_library_open(&lib_name, &code_lib, 0);
134 do
135 {
136 ✗ if (GATE_FAILED(result))
137 {
138 ✗ GATE_DEBUG_TRACE("Failed to load libgpiod");
139 ✗ break;
140 }
141
142 ✗ gate_library_get_function_name(code_lib, "gpiod_version_string", &code.version_string);
143 ✗ gate_library_get_function_name(code_lib, "gpiod_chip_open", &code.chip_open);
144 ✗ gate_library_get_function_name(code_lib, "gpiod_chip_close", &code.chip_close);
145
146 ✗ gate_library_get_function_name(code_lib, "gpiod_chip_name", &code.v1_chip_name);
147 ✗ gate_library_get_function_name(code_lib, "gpiod_chip_label", &code.v1_chip_label);
148 ✗ gate_library_get_function_name(code_lib, "gpiod_chip_num_lines", &code.v1_chip_num_lines);
149
150 ✗ gate_library_get_function_name(code_lib, "gpiod_chip_get_info", &code.v2_chip_get_info);
151 ✗ gate_library_get_function_name(code_lib, "gpiod_chip_info_free", &code.v2_chip_info_free);
152 ✗ gate_library_get_function_name(code_lib, "gpiod_chip_info_get_name", &code.v2_chip_info_get_name);
153 ✗ gate_library_get_function_name(code_lib, "gpiod_chip_info_get_label", &code.v2_chip_info_get_label);
154 ✗ gate_library_get_function_name(code_lib, "gpiod_chip_info_get_num_lines", &code.v2_chip_info_get_num_lines);
155
156 ✗ gate_library_get_function_name(code_lib, "gpiod_chip_get_line", &code.v1_chip_get_line);
157 ✗ gate_library_get_function_name(code_lib, "gpiod_line_release", &code.v1_line_release);
158 ✗ gate_library_get_function_name(code_lib, "gpiod_line_name", &code.v1_line_name);
159 ✗ gate_library_get_function_name(code_lib, "gpiod_line_consumer", &code.v1_line_consumer);
160 ✗ gate_library_get_function_name(code_lib, "gpiod_line_direction", &code.v1_line_direction);
161 ✗ gate_library_get_function_name(code_lib, "gpiod_line_active_state", &code.v1_line_active_state);
162 ✗ gate_library_get_function_name(code_lib, "gpiod_line_is_used", &code.v1_line_is_used);
163
164 ✗ gate_library_get_function_name(code_lib, "gpiod_chip_get_line_info", &code.v2_chip_get_line_info);
165 ✗ gate_library_get_function_name(code_lib, "gpiod_line_info_free", &code.v2_line_info_free);
166 ✗ gate_library_get_function_name(code_lib, "gpiod_line_info_get_name", &code.v2_line_info_get_name);
167 ✗ gate_library_get_function_name(code_lib, "gpiod_line_info_get_consumer", &code.v2_line_info_get_consumer);
168 ✗ gate_library_get_function_name(code_lib, "gpiod_line_info_get_direction", &code.v2_line_info_get_direction);
169 ✗ gate_library_get_function_name(code_lib, "gpiod_line_info_is_used", &code.v2_line_info_is_used);
170
171
172
173 ✗ gate_library_get_function_name(code_lib, "gpiod_line_request_input", &code.v1_line_request_input);
174 ✗ gate_library_get_function_name(code_lib, "gpiod_line_get_value", &code.v1_line_get_value);
175 ✗ gate_library_get_function_name(code_lib, "gpiod_line_request_output", &code.v1_line_request_output);
176 ✗ gate_library_get_function_name(code_lib, "gpiod_line_set_value", &code.v1_line_set_value);
177
178 ✗ gate_library_get_function_name(code_lib, "gpiod_line_settings_new", &code.v2_line_settings_new);
179 ✗ gate_library_get_function_name(code_lib, "gpiod_line_settings_free", &code.v2_line_settings_free);
180 ✗ gate_library_get_function_name(code_lib, "gpiod_line_settings_set_direction", &code.v2_line_settings_set_direction);
181 ✗ gate_library_get_function_name(code_lib, "gpiod_line_settings_set_output_value",&code.v2_line_settings_set_output_value);
182 ✗ gate_library_get_function_name(code_lib, "gpiod_line_settings_get_direction", &code.v2_line_settings_get_direction);
183 ✗ gate_library_get_function_name(code_lib, "gpiod_line_config_new", &code.v2_line_config_new);
184 ✗ gate_library_get_function_name(code_lib, "gpiod_line_config_free", &code.v2_line_config_free);
185 ✗ gate_library_get_function_name(code_lib, "gpiod_line_config_add_line_settings", &code.v2_line_config_add_line_settings);
186 ✗ gate_library_get_function_name(code_lib, "gpiod_chip_request_lines", &code.v2_chip_request_lines);
187 ✗ gate_library_get_function_name(code_lib, "gpiod_line_request_release", &code.v2_line_request_release);
188 ✗ gate_library_get_function_name(code_lib, "gpiod_line_request_get_value", &code.v2_line_request_get_value);
189 ✗ gate_library_get_function_name(code_lib, "gpiod_line_request_reconfigure_lines",&code.v2_line_request_reconfigure_lines);
190 ✗ gate_library_get_function_name(code_lib, "gpiod_line_request_set_value", &code.v2_line_request_set_value);
191
192
193 /* success case */
194 ✗ code_loaded = true;
195 } while(0);
196 }
197
198 ✗ return code_loaded ? &code : NULL;
199 }
200
201
202 ✗ static gate_result_t gate_gpiod_get_chip_infos(gpiod_chip_t* chip, gate_string_t* ptr_name, gate_string_t* ptr_label, gate_size_t* ptr_linecount)
203 {
204 ✗ gpiod_code_t* const gpiod = get_gpiod_functions();
205
206 ✗ if (!gpiod)
207 {
208 ✗ return GATE_RESULT_NOTAVAILABLE;
209 }
210
211 ✗ if (gpiod->v2_chip_get_info)
212 {
213 /* v2 implementation*/
214 ✗ gpiod_chip_info_t* ptr_info = gpiod->v2_chip_get_info(chip);
215 ✗ if (!ptr_info)
216 {
217 ✗ return GATE_RESULT_FAILED;
218 }
219 ✗ if (ptr_name)
220 {
221 ✗ char const* name = gpiod->v2_chip_info_get_name(ptr_info);
222 ✗ gate_string_create(ptr_name, name, gate_str_length(name));
223 }
224 ✗ if (ptr_label)
225 {
226 ✗ char const* label = gpiod->v2_chip_info_get_label(ptr_info);
227 ✗ gate_string_create(ptr_label, label, gate_str_length(label));
228 }
229 ✗ if (ptr_linecount)
230 {
231 ✗ *ptr_linecount = gpiod->v2_chip_info_get_num_lines(ptr_info);
232 }
233 ✗ gpiod->v2_chip_info_free(ptr_info);
234 }
235 else
236 {
237 /* v1 implementation*/
238 ✗ if (ptr_name)
239 {
240 ✗ char const* name = gpiod->v1_chip_name(chip);
241 ✗ gate_string_create(ptr_name, name, gate_str_length(name));
242 }
243 ✗ if (ptr_label)
244 {
245 ✗ char const* label = gpiod->v1_chip_label(chip);
246 ✗ gate_string_create(ptr_label, label, gate_str_length(label));
247 }
248 ✗ if (ptr_linecount)
249 {
250 ✗ *ptr_linecount = gpiod->v1_chip_num_lines(chip);
251 }
252 }
253 ✗ return GATE_RESULT_OK;
254 }
255
256 ✗ static gate_result_t gate_gpiod_get_line_infos(gpiod_chip_t* chip, unsigned int line_offset,
257 gate_string_t* ptr_name, gate_string_t* ptr_consumer,
258 int* ptr_direction,
259 bool* ptr_is_used)
260 {
261 ✗ gpiod_code_t* const gpiod = get_gpiod_functions();
262
263 ✗ if (!gpiod)
264 {
265 ✗ return GATE_RESULT_NOTAVAILABLE;
266 }
267
268 ✗ if (gpiod->v2_line_info_free != NULL)
269 {
270 /* v2 implementation */
271 ✗ gpiod_line_info_t* ptr_line = gpiod->v2_chip_get_line_info(chip, line_offset);
272 ✗ if (NULL == ptr_line)
273 {
274 ✗ return GATE_RESULT_FAILED;
275 }
276
277 ✗ if (ptr_name)
278 {
279 ✗ char const* name = gpiod->v2_line_info_get_name(ptr_line);
280 ✗ gate_string_create(ptr_name, name, gate_str_length(name));
281 }
282 ✗ if (ptr_consumer)
283 {
284 ✗ char const* consumer = gpiod->v2_line_info_get_consumer(ptr_line);
285 ✗ gate_string_create(ptr_consumer, consumer, gate_str_length(consumer));
286 }
287
288 ✗ if (ptr_direction)
289 {
290 ✗ *ptr_direction = gpiod->v2_line_info_get_direction(ptr_line);
291 }
292
293 ✗ if (ptr_is_used)
294 {
295 ✗ *ptr_is_used = gpiod->v2_line_info_is_used(ptr_line);
296 }
297
298 ✗ gpiod->v2_line_info_free(ptr_line);
299 }
300 else
301 {
302 /* v1 implementation */
303 ✗ gpiod_line_t* ptr_line = gpiod->v1_chip_get_line(chip, line_offset);
304 ✗ if (NULL == ptr_line)
305 {
306 ✗ return GATE_RESULT_FAILED;
307 }
308
309 ✗ if (ptr_name)
310 {
311 ✗ char const* name = gpiod->v1_line_name(ptr_line);
312 ✗ gate_string_create(ptr_name, name, gate_str_length(name));
313 }
314 ✗ if (ptr_consumer)
315 {
316 ✗ char const* consumer = gpiod->v1_line_consumer(ptr_line);
317 ✗ gate_string_create(ptr_consumer, consumer, gate_str_length(consumer));
318 }
319
320 ✗ if (ptr_direction)
321 {
322 ✗ *ptr_direction = gpiod->v1_line_direction(ptr_line);
323 }
324
325 ✗ if (ptr_is_used)
326 {
327 ✗ *ptr_is_used = gpiod->v1_line_is_used(ptr_line);
328 }
329 }
330 ✗ return GATE_RESULT_OK;
331 }
332
333
334 ✗ static gate_result_t gate_gpiod_read_line_value(gpiod_chip_t* chip, unsigned int line_offset, int* ptr_value)
335 {
336 ✗ gpiod_code_t* const gpiod = get_gpiod_functions();
337
338 ✗ if (!gpiod)
339 {
340 ✗ return GATE_RESULT_NOTAVAILABLE;
341 }
342
343 ✗ if (gpiod->v2_line_settings_new != NULL)
344 {
345 /* v2 implementation */
346 gate_result_t ret;
347 ✗ gpiod_line_settings_t* new_settings = NULL;
348 ✗ gpiod_line_config_t* new_config = NULL;
349 ✗ gpiod_line_request_t* new_request = NULL;
350
351 do
352 {
353 gpiod_line_value_t new_value;
354
355 ✗ new_settings = gpiod->v2_line_settings_new();
356 ✗ if (!new_settings)
357 {
358 ✗ ret = GATE_RESULT_OUTOFMEMORY;
359 ✗ break;
360 }
361
362 ✗ new_config = gpiod->v2_line_config_new();
363 ✗ if (!new_config)
364 {
365 ✗ ret = GATE_RESULT_OUTOFMEMORY;
366 ✗ break;
367 }
368
369 ✗ if (0 != gpiod->v2_line_settings_set_direction(new_settings, GPIOD_LINE_DIRECTION_INPUT))
370 {
371 ✗ ret = GATE_RESULT_FAILED;
372 ✗ break;
373 }
374
375 ✗ if (0 != gpiod->v2_line_config_add_line_settings(new_config, &line_offset, 1, new_settings))
376 {
377 ✗ ret = GATE_RESULT_FAILED;
378 ✗ break;
379 }
380
381 ✗ new_request = gpiod->v2_chip_request_lines(chip, NULL, new_config);
382 ✗ if (NULL == new_request)
383 {
384 ✗ ret = GATE_RESULT_FAILED;
385 ✗ break;
386 }
387
388 ✗ new_value = gpiod->v2_line_request_get_value(new_request, line_offset);
389 ✗ if (new_value == GPIOD_LINE_VALUE_ERROR)
390 {
391 ✗ ret = GATE_RESULT_EXECUTIONFAILED;
392 ✗ break;
393 }
394
395 /* success case */
396 ✗ if (ptr_value)
397 {
398 ✗ *ptr_value = (GPIOD_LINE_VALUE_INACTIVE == new_value) ? 0 : 1;
399 }
400 ✗ ret = GATE_RESULT_OK;
401 } while (0);
402
403 ✗ if (new_request) gpiod->v2_line_request_release(new_request);
404 ✗ if (new_config) gpiod->v2_line_config_free(new_config);
405 ✗ if (new_settings) gpiod->v2_line_settings_free(new_settings);
406
407 ✗ return ret;
408 }
409 else
410 {
411 /* v1 implementation */
412 ✗ gate_result_t ret = GATE_RESULT_OK;
413 ✗ gpiod_line_t* ptr_line = NULL;
414 do
415 {
416 int result;
417 ✗ ptr_line = gpiod->v1_chip_get_line(chip, line_offset);
418 ✗ if (NULL == ptr_line)
419 {
420 ✗ ret = GATE_RESULT_FAILED;
421 ✗ break;
422 }
423
424 ✗ result = gpiod->v1_line_request_input(ptr_line, "gateio-gpiodevice");
425 ✗ if (result < 0)
426 {
427 ✗ ret = GATE_RESULT_FAILED;
428 ✗ break;
429 }
430
431 ✗ result = gpiod->v1_line_get_value(ptr_line);
432 ✗ if (result < 0)
433 {
434 ✗ ret = GATE_RESULT_FAILED;
435 ✗ break;
436 }
437
438 ✗ if (ptr_value)
439 {
440 ✗ *ptr_value = result;
441 }
442 } while (0);
443
444 ✗ if (ptr_line != NULL)
445 {
446 ✗ gpiod->v1_line_release(ptr_line);
447 }
448 ✗ return ret;
449 }
450 return GATE_RESULT_OK;
451 }
452
453
454 ✗ static gate_result_t gate_gpiod_write_line_value(gpiod_chip_t* chip, unsigned int line_offset, int value)
455 {
456 ✗ gpiod_code_t* const gpiod = get_gpiod_functions();
457
458 ✗ if (!gpiod)
459 {
460 ✗ return GATE_RESULT_NOTAVAILABLE;
461 }
462
463 ✗ if (gpiod->v2_line_settings_new != NULL)
464 {
465 /* v2 implementation */
466 gate_result_t ret;
467 ✗ struct gpiod_line_settings* new_settings = NULL;
468 ✗ struct gpiod_line_config* new_config = NULL;
469 ✗ struct gpiod_line_request* new_request = NULL;
470
471 do
472 {
473 int result;
474 ✗ gpiod_line_value_t new_value = (value == 0) ? GPIOD_LINE_VALUE_INACTIVE : GPIOD_LINE_VALUE_ACTIVE;
475
476 ✗ new_settings = gpiod->v2_line_settings_new();
477 ✗ if (!new_settings)
478 {
479 ✗ ret = GATE_RESULT_OUTOFMEMORY;
480 ✗ break;
481 }
482
483 ✗ new_config = gpiod->v2_line_config_new();
484 ✗ if (!new_config)
485 {
486 ✗ ret = GATE_RESULT_OUTOFMEMORY;
487 ✗ break;
488 }
489
490 ✗ result = gpiod->v2_line_settings_set_direction(new_settings, GPIOD_LINE_DIRECTION_OUTPUT);
491 ✗ if (0 != result)
492 {
493 ✗ ret = GATE_RESULT_FAILED;
494 ✗ break;
495 }
496
497 ✗ result = gpiod->v2_line_settings_set_output_value(new_settings, new_value);
498 ✗ if (0 != result)
499 {
500 ✗ ret = GATE_RESULT_FAILED;
501 ✗ break;
502 }
503
504 ✗ result = gpiod->v2_line_config_add_line_settings(new_config, &line_offset, 1, new_settings);
505 ✗ if (0 != result)
506 {
507 ✗ ret = GATE_RESULT_FAILED;
508 ✗ break;
509 }
510
511 ✗ new_request = gpiod->v2_chip_request_lines(chip, NULL, new_config);
512 ✗ if (NULL == new_request)
513 {
514 ✗ ret = GATE_RESULT_FAILED;
515 ✗ break;
516 }
517
518 ✗ result = gpiod->v2_line_request_reconfigure_lines(new_request, new_config);
519 ✗ if(0 != result)
520 {
521 ✗ ret = GATE_RESULT_EXECUTIONFAILED;
522 ✗ break;
523 }
524
525 /* success case */
526 ✗ ret = GATE_RESULT_OK;
527 } while (0);
528
529 ✗ if (new_request) gpiod->v2_line_request_release(new_request);
530 ✗ if (new_config) gpiod->v2_line_config_free(new_config);
531 ✗ if (new_settings) gpiod->v2_line_settings_free(new_settings);
532
533 ✗ return ret;
534
535 }
536 else
537 {
538 /* v1 implementation */
539 ✗ gate_result_t ret = GATE_RESULT_OK;
540 int result;
541 ✗ gpiod_line_t* const ptr_line = gpiod->v1_chip_get_line(chip, line_offset);
542 do
543 {
544 ✗ if (NULL == ptr_line)
545 {
546 ✗ ret = GATE_RESULT_FAILED;
547 ✗ break;
548 }
549
550 ✗ result = gpiod->v1_line_request_output(ptr_line, "gateio-gpiodevice", 0);
551 ✗ if (result < 0)
552 {
553 ✗ ret = GATE_RESULT_FAILED;
554 ✗ break;
555 }
556
557 ✗ result = gpiod->v1_line_set_value(ptr_line, value);
558 ✗ if (result < 0)
559 {
560 ✗ ret = GATE_RESULT_FAILED;
561 ✗ break;
562 }
563
564 /* success case */
565 ✗ ret = GATE_RESULT_OK;
566 } while(0);
567
568 ✗ if (ptr_line)
569 {
570 ✗ gpiod->v1_line_release(ptr_line);
571 }
572 ✗ return ret;
573 }
574 }
575
576 #endif
577