power: add read wakeup source function 08/286608/1 tizen_7.0
authorTaeminYeom <taemin.yeom@samsung.com>
Tue, 6 Dec 2022 06:53:42 +0000 (15:53 +0900)
committerTaemin Yeom <taemin.yeom@samsung.com>
Tue, 10 Jan 2023 11:09:49 +0000 (11:09 +0000)
wakeup source: the information of "/sys/kernel/debug/wakeup_sources" node
wakeup reason: defined TIZEN Enum and able to be get by wakeup source

To add getter wakeup reason in device API, it is needed to read kernel
node (/sys/kernel/debug/wakeup_sources)

This node is including information of wakeup, so it is possible to get
the source of wakeup by compare the value of "wakeup_count" value.

Detailed function description
- hal_backend_device_common_read_wakeup_sources (char ***wakeup_source_name, int *wakeup_source_number):
   wakeup_source_name : get the name of wakeup sources with string array.
     each string and wakeup_source_name should be freed after using.
     caller declare a char ** variable and use the pointer of it.
   wakeup_source_number : the number of wakeup sources.
     caller delcare a int vairable and use the pointer of it.
  Exported and can be called by other HAL backend.

Change-Id: I605a5d539addb2cef7684f8e57f4ab3b5d9c65d4
Signed-off-by: TaeminYeom <taemin.yeom@samsung.com>
(cherry picked from commit a027bd191c2407f449de5db34cc9cd5962e3d591)

CMakeLists.txt
include/hal-backend-device-common-power.h [new file with mode: 0644]
src/power/power.c [new file with mode: 0644]

index ac66f46..4459517 100644 (file)
@@ -7,6 +7,7 @@ SET(SRCS
        src/udev/udev.c
        src/input/input.c
        src/hal-backend-device-common-file.c
+       src/power/power.c
 )
 
 INCLUDE(FindPkgConfig)
@@ -33,6 +34,7 @@ INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${HAL_LIB_DIR} COMPONENT RuntimeLibr
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.Apache-2.0 DESTINATION ${HAL_LICENSE_DIR}/${PROJECT_NAME})
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/hal-backend-common.h DESTINATION ${HAL_INCLUDE_DIR}/device)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/hal-backend-common-udev.h DESTINATION ${HAL_INCLUDE_DIR}/device)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/hal-backend-device-common-power.h DESTINATION ${HAL_INCLUDE_DIR}/device)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/hal-backend-device-common-input.h DESTINATION ${HAL_INCLUDE_DIR}/device)
 
 CONFIGURE_FILE(hal-backend-device-common.pc.in hal-backend-device-common.pc @ONLY)
diff --git a/include/hal-backend-device-common-power.h b/include/hal-backend-device-common-power.h
new file mode 100644 (file)
index 0000000..699cad1
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __HAL_BACKEND_DEVICE_COMMON_POWER_H__
+#define __HAL_BACKEND_DEVICE_COMMON_POWER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int hal_backend_device_common_read_wakeup_sources(char ***wakeup_source_name, int *wakeup_source_number);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __HAL_BACKEND_DEVICE_COMMON_POWER_H__ */
diff --git a/src/power/power.c b/src/power/power.c
new file mode 100644 (file)
index 0000000..d5f62dd
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <glib.h>
+#include <string.h>
+
+#include "hal-backend-common.h"
+
+#define WAKEUP_SOURCES_PATH    "/sys/kernel/debug/wakeup_sources"
+
+#define MAX_NAME_LENGTH                50
+#define MAX_NUM_WAKEUP_SOURCES 100
+#define NUM_INFORMATION                10
+
+struct wakeup_source {
+       char name[MAX_NAME_LENGTH + 1];
+       int active_count;
+       int event_count;
+       int wakeup_count;
+       int expire_count;
+       int active_since;
+       int total_time;
+       int max_time;
+       int last_change;
+       int prevent_suspend_time;
+};
+
+static struct wakeup_source source[MAX_NUM_WAKEUP_SOURCES];
+
+static int read_wakeup_sources(char ***wakeup_source_name, int *wakeup_source_number)
+{
+       char **new_wakeup_source_name;
+       char buf[MAX_NAME_LENGTH + 1] = {0, };
+       struct wakeup_source input = {0, };
+       int source_index = 0; /* for iteration of all wakeup sources */
+       int changed_source_number = 0; /* the number of wakeup sources that increase wakeup_count */
+       int ret;
+       FILE *fp;
+
+       if (!wakeup_source_name || !wakeup_source_number)
+               return -EINVAL;
+
+       fp = fopen(WAKEUP_SOURCES_PATH, "r");
+       if (!fp) {
+               _E("There is no node %s", WAKEUP_SOURCES_PATH);
+               return -errno;
+       }
+
+       for (int i = 0; i < NUM_INFORMATION; ++i) {
+               ret = fscanf(fp, "%50s", buf);
+               if (ret < 1)
+                       goto parse_err;
+       }
+
+       new_wakeup_source_name = calloc(MAX_NUM_WAKEUP_SOURCES, sizeof(char*));
+       if (!new_wakeup_source_name) {
+               _E("Failed to allocate memory");
+               return -errno;
+       }
+
+       while (!feof(fp)) {
+               if (source_index >= MAX_NUM_WAKEUP_SOURCES) {
+                       _E("Exceed max wakeup source number");
+                       for (int i = 0; i < changed_source_number; ++i)
+                               free(new_wakeup_source_name[i]);
+                       free(new_wakeup_source_name);
+                       return -EPERM;
+               }
+
+               ret = fscanf(fp, "%50s %d %d %d %d %d %d %d %d %d\n", input.name,
+                       &input.active_count, &input.event_count,
+                       &input.wakeup_count, &input.expire_count,
+                       &input.active_since, &input.total_time,
+                       &input.max_time, &input.last_change,
+                       &input.prevent_suspend_time);
+
+               if (ret < 10)
+                       goto parse_err;
+
+               /* check whether the wakeup count increases */
+               if (source[source_index].wakeup_count < input.wakeup_count) {
+                       new_wakeup_source_name[changed_source_number] =
+                               calloc(MAX_NAME_LENGTH + 1, sizeof(char));
+                       strncpy(new_wakeup_source_name[changed_source_number++],
+                               input.name, MAX_NAME_LENGTH + 1);
+                       _D("%s wakeup source detected", input.name);
+               }
+
+               source[source_index++] = input;
+       }
+
+       fclose(fp);
+       *wakeup_source_number = changed_source_number;
+       *wakeup_source_name = new_wakeup_source_name;
+       return 0;
+
+parse_err:
+       _E("Failed to parse %s", WAKEUP_SOURCES_PATH);
+       for (int i = 0; i < changed_source_number; ++i)
+               free(new_wakeup_source_name[i]);
+       free(new_wakeup_source_name);
+       fclose(fp);
+       return -EINVAL;
+}
+
+EXPORT int hal_backend_device_common_read_wakeup_sources(char ***wakeup_source_name, int *wakeup_source_number)
+{
+       return read_wakeup_sources(wakeup_source_name, wakeup_source_number);
+}