/** * @file mce-hal.c * Hardware Abstraction Layer for MCE *

* Copyright © 2009-2011 Nokia Corporation and/or its subsidiary(-ies). * Copyright (C) 2012-2019 Jolla Ltd. *

* @author David Weinehall * @author Tapio Rantala * @author Santtu Lakkala * @author Simo Piiroinen * * mce is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * mce is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with mce. If not, see . */ #include "mce-hal.h" #include "mce-log.h" #include "mce-lib.h" #include #include #include #include #ifndef SYSINFOD_SERVICE /** SYSINFOD D-Bus service */ #define SYSINFOD_SERVICE "com.nokia.SystemInfo" #endif /* SYSINFOD_SERVICE */ #ifndef SYSINFOD_INTERFACE /** SYSINFOD D-Bus interface */ #define SYSINFOD_INTERFACE "com.nokia.SystemInfo" #endif /* SYSINFOD_INTERFACE */ #ifndef SYSINFOD_PATH /** SYSINFOD D-Bus object path */ #define SYSINFOD_PATH "/com/nokia/SystemInfo" #endif /* SYSINFOD_PATH */ #ifndef SYSINFOD_GET_CONFIG_VALUE /** Query value of a sysinfo key */ #define SYSINFOD_GET_CONFIG_VALUE "GetConfigValue" #endif /* SYSINFOD_GET_CONFIG_VALUE */ /** The sysinfo key to request */ #define PRODUCT_SYSINFO_KEY "/component/product" /** * The product ID of the device */ static product_id_t product_id = PRODUCT_UNSET; /** Get init process environment value * * If mce is started manually, some environment variables are not * inherited from systemd. This function attempts to retrieve them * from the context of init process itself. * * @param key name of environment value * * @return string, or NULL */ static char *getenv_from_init_process(const char *key) { static const char path[] = "/proc/1/environ"; char *res = 0; int file = -1; char *data = 0; int size = 0x2000; if( (file = open(path, O_RDONLY)) == -1 ) { mce_log(LL_WARN, "%s: %m", path); goto EXIT; } if( !(data = malloc(size)) ) goto EXIT; if( (size = read(file, data, size-1)) < 0 ) { mce_log(LL_WARN, "%s: %m", path); goto EXIT; } data[size] = 0; for( char *now = data; now < data + size; ) { char *val = strchr(now, '='); if( !val ) break; *val++ = 0; if( !strcmp(now, key) ) { res = strdup(val); break; } now = strchr(val, 0) + 1; } EXIT: free(data); if( file != -1 ) close(file); mce_log(LL_NOTICE, "key=%s -> val=%s", key, res); return res; } /** * Retrieve a sysinfo value via D-Bus * * Note: The sysinfod service is provided proprietary Nokia component * and is not supported in nemomobile. This function tries to * handle some queries possibly made by mce on legacy Nokia hw * by getting relevant information from environment variables. * * @param key The sysinfo key to retrieve * @param[out] array A newly allocated byte array with the result; * this array should to be freed when no longer used * @param[out] len The length of the newly allocated string * * @return TRUE on success, FALSE on failure */ gboolean get_sysinfo_value(const gchar *const key, guint8 **array, gulong *len) { /* Try to provide some values from environment */ const char *env = 0; const char *val = 0; char *res = 0; gulong cnt = 0; if( !strcmp(key, PRODUCT_SYSINFO_KEY) ) env = "product_name"; if( env ) { if( (val = getenv(env)) ) res = strdup(val); else res = getenv_from_init_process(env); } if( res ) cnt = strlen(res); mce_log(LL_INFO, "key=%s, env=%s, val=%s, len=%d", key, env, res, (int)cnt); return *array = (guint8*)res, *len = cnt, (res != 0); } /** * Get product ID * * @return The product ID */ product_id_t get_product_id(void) { guint8 *tmp = NULL; gulong len = 0; if (product_id != PRODUCT_UNSET) goto EXIT; product_id = PRODUCT_UNKNOWN; if( !get_sysinfo_value(PRODUCT_SYSINFO_KEY, &tmp, &len) ) { // nothing } else if (strmemcmp(tmp, PRODUCT_SU18_STR, len) == TRUE) { product_id = PRODUCT_SU18; } else if (strmemcmp(tmp, PRODUCT_RX34_STR, len) == TRUE) { product_id = PRODUCT_RX34; } else if (strmemcmp(tmp, PRODUCT_RX44_STR, len) == TRUE) { product_id = PRODUCT_RX44; } else if (strmemcmp(tmp, PRODUCT_RX48_STR, len) == TRUE) { product_id = PRODUCT_RX48; } else if (strmemcmp(tmp, PRODUCT_RX51_STR, len) == TRUE) { product_id = PRODUCT_RX51; } else if (strmemcmp(tmp, PRODUCT_RX71_STR, len) == TRUE) { product_id = PRODUCT_RX71; } else if (strmemcmp(tmp, PRODUCT_RM680_STR, len) == TRUE) { product_id = PRODUCT_RM680; } else if (strmemcmp(tmp, PRODUCT_RM690_STR, len) == TRUE) { product_id = PRODUCT_RM690; } else if (strmemcmp(tmp, PRODUCT_RM696_STR, len) == TRUE) { product_id = PRODUCT_RM696; } else if (strmemcmp(tmp, PRODUCT_RM716_STR, len) == TRUE) { product_id = PRODUCT_RM716; } free(tmp); if ( product_id == PRODUCT_UNKNOWN ) { mce_log(LL_NOTICE, "Failed to get the product ID"); } EXIT: return product_id; }