Add functions that fetch serial, revision information
authorYoungjae Cho <y0.cho@samsung.com>
Tue, 30 Jul 2019 08:39:54 +0000 (17:39 +0900)
committerYoungjae Cho <y0.cho@samsung.com>
Thu, 1 Aug 2019 05:05:05 +0000 (14:05 +0900)
Change-Id: If15ec537993dc8a909faf21793251dc7f301fc1c
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
hw/board/CMakeLists.txt
hw/board/board.c

index ef3052b..5416ed1 100644 (file)
@@ -4,9 +4,9 @@ PROJECT(board C)
 SET(PREFIX ${CMAKE_INSTALL_PREFIX})
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(usb_gadget_pkgs REQUIRED hwcommon dlog)
+pkg_check_modules(board_pkgs REQUIRED hwcommon dlog)
 
-FOREACH(flag ${usb_gadget_pkgs_CFLAGS})
+FOREACH(flag ${board_pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
 
@@ -14,6 +14,6 @@ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
 
 ADD_LIBRARY(${PROJECT_NAME} MODULE board.c)
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${usb_gadget_pkgs_LDFLAGS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${board_pkgs_LDFLAGS})
 SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "")
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR}/hw COMPONENT RuntimeLibraries)
index 175cb2e..9cac809 100644 (file)
 #include <string.h>
 #include <hw/shared.h>
 
-#define CPUINFO_PATH "/proc/cpuinfo"
-#define SERIAL_TAG "Serial"
+#define DATA_BUFF_MAX  256
+
+#define SERIAL_PATH_NAME       "/csa/imei/serialno.dat"
+#define CPUINFO_PATH           "/proc/cpuinfo"
+#define SERIAL_TAG                     "Serial"
 #define LINE_LEN 64
 
-static int get_device_serial(char **out)
+#define REVISION_TAG           "Revision"
+
+struct board_info {
+       char serial[DATA_BUFF_MAX];
+       int serial_len;
+       int revision;
+};
+
+static struct board_info info;
+
+static int get_serialno_from_dat(void)
+{
+       FILE *fp;
+       char buffer[DATA_BUFF_MAX], *p, *q;
+       int serial_len;
+
+       fp = fopen(SERIAL_PATH_NAME, "r");
+       if (!fp) {
+               _E("Failed to open %s.", SERIAL_PATH_NAME);
+               return -ENOENT;
+       }
+
+       p = fgets(buffer, DATA_BUFF_MAX, fp);
+       if (!p) {
+               _E("Failed to find serial number from dat.");
+               fclose(fp);
+               return -EIO;
+       }
+       q = strchrnul(p, '\n');
+       *q = '\0';
+
+       serial_len = strlen(p);
+       strcpy(info.serial, p);
+       info.serial_len = strlen(p);
+
+       fclose(fp);
+       return 0;
+}
+
+static int get_serialno_from_cpuinfo(void)
 {
        FILE *fp;
        char line[LINE_LEN], *p, *q;
+       int serial_len;
 
        fp = fopen(CPUINFO_PATH, "r");
-       if (!fp)
-               return -1;
+       if (!fp) {
+               _E("Failed to open %s.", CPUINFO_PATH);
+               return -ENOENT;
+       }
 
        while ((p = fgets(line, sizeof(line), fp)) != NULL) {
                p = strchr(p, '\t');
@@ -44,7 +89,6 @@ static int get_device_serial(char **out)
                        continue;
 
                *p = '\0';
-
                if (strncmp(line, SERIAL_TAG, sizeof(line)) != 0)
                        continue;
 
@@ -53,18 +97,90 @@ static int get_device_serial(char **out)
                if (!p)
                        continue;
                p += 2;
+               q = strchrnul(p, '\n');
+               *q = '\0';
+
+               serial_len = strlen(p);
+               strncpy(info.serial, p, serial_len + 1);
+               info.serial_len = strlen(p);
 
+               fclose(fp);
+               return 0;
+       }
+
+       _E("Failed to find serial number from cpuinfo.");
+       fclose(fp);
+       return -EIO;
+}
+
+static int get_device_serial(char **out)
+{
+       int ret;
+       if (info.serial_len > 0 && strlen(info.serial) == info.serial_len) {
+               *out = strdup(info.serial);
+               if (!out) {
+                       _E("Out of memory, strdup failed.");
+                       return -ENOMEM;
+               }
+               return 0;
+       }
+
+       ret = get_serialno_from_dat();
+       if (ret < 0) {
+               ret = get_serialno_from_cpuinfo();
+               if (ret < 0) {
+                       _E("Failed to find serial number.");
+                       return ret;
+               }
+       }
+
+       *out = strdup(info.serial);
+       if (!out)
+               _E("Out of memory, strdup failed.");
+
+       return ret;
+}
+
+static int get_device_revision(int *out)
+{
+       FILE *fp;
+       char line[LINE_LEN], *p, *q;
+       int ret;
+
+       fp = fopen(CPUINFO_PATH, "r");
+       if (!fp) {
+               _E("Failed to open %s.", CPUINFO_PATH);
+               return -ENOENT;
+       }
+
+       while ((p = fgets(line, sizeof(line), fp)) != NULL) {
+               p = strstr(p, REVISION_TAG);
+               if (!p)
+                       continue;
+
+               p = strchr(p, ':');
+               if (!p)
+                       continue;
+               p += 2;
                q = strchrnul(p, '\n');
                *q = '\0';
-               *out = strdup(p);
-               if (!out)
-                       _E("Out of memory, strdup failed");
+
+               errno = 0;
+               ret = strtol(p, NULL, 16);
+               if (ret == 0 && errno != 0) {
+                       _E("Invalid revision value.");
+                       fclose(fp);
+                       return -errno;
+               }
+               info.revision = ret;
+               *out = ret;
                fclose(fp);
                return 0;
        }
 
+       _E("Failed to find revision from cpuinfo.");
        fclose(fp);
-       return -1;
+       return -EIO;
 }
 
 static int board_open(struct hw_info *info,
@@ -75,12 +191,13 @@ static int board_open(struct hw_info *info,
        if (!info || !common)
                return -EINVAL;
 
-       b = calloc(1, sizeof(*b));
+       b = calloc(1, sizeof(struct hw_board));
        if (!b)
                return -ENOMEM;
 
        b->common.info = info;
        b->get_device_serial = get_device_serial;
+       b->get_device_revision = get_device_revision;
 
        *common = &b->common;
        return 0;