diff --git a/board-mappings.ini b/board-mappings.ini new file mode 100644 index 0000000..4365374 --- /dev/null +++ b/board-mappings.ini @@ -0,0 +1,70 @@ +### Don't edit this file manually. Update it in git, if there's a good reason to do so ### +# +# This file is used by SSU to find out which device (or device variant) it's +# running on, and use this information to look for device family, and device +# specific adaptation(s). The last two values are used when resolving URLs, +# and therefore change depending on vendor setup. +# +# To avoid quoting in the search strings SSU will do each checks on the +# _value_, and return the key, if successful. The device model returned +# my either be the device model, or a variant. Before resolving the family +# and adaptations variants will be resolved through entries under the +# variants category. +# +# Valid categories for determining the model: +# - file.exists -- checks for existince of a file in the filesystem +# - systeminfo.equals -- compares the model returned by QSystemInfo +# with the value provided +# - cpuinfo.contains -- searches /proc/cpuinfo for a string +# - arch.equals -- compares with zyppers arch (like i586) +# +# Resolve order is: +# file.exists -> systeminfo.equals -> cpuinfo.contains -> arch.equals +# +# The found model (after resolving variants) will be used as category. The +# following keys are valid there: +# - family -- the device family, used for the family specific adaptation +# - adaptations -- list of additional adaptations, shared between families +# +# The value of adaptations gets converted into a QStringList, which uses +# commas as separator. If one of the adaptation names contains a comma it +# needs to be quoted: +# adaptation=foo +# adaptation="foo, bar", baz +# adaptation=foo, bar, baz +# +# The N9x mappings should be solved through sysinfo, but that's currently +# broken on Mer/Nemo + +[file.exists] +SDK=/mer-sdk-chroot + +[systeminfo.equals] + +[cpuinfo.contains] +N900=Nokia RX-51 board +N950=Nokia RM-680 board +N9=Nokia RM-696 board + +[arch.equals] +generic-x86=i586 + +[variants] +N950=N9 + +[N9] +family=n950-n9 +adaptations=n9xx + +[N900] +family=n900 +adaptations=n9xx + +[SDK] + +[generic-x86] +family=x86 +adaptations=x86 + +[UNKNOWN] +family=UNKNOWN diff --git a/constants.h b/constants.h index 082bd20..0b90ac6 100644 --- a/constants.h +++ b/constants.h @@ -16,6 +16,8 @@ #define SSU_REPO_CONFIGURATION "/usr/share/ssu/repos.ini" /// Path to the main SSU configuration file #define SSU_DEFAULT_CONFIGURATION "/usr/share/ssu/ssu-defaults.ini" +/// Path to board / device family mappings file +#define SSU_BOARD_MAPPING_CONFIGURATION "/usr/share/ssu/board-mappings.ini" /// The SSU protocol version used by the ssu client libraries #define SSU_PROTOCOL_VERSION "1" #endif diff --git a/libssu/ssu.cpp b/libssu/ssu.cpp index de73d75..64b7aee 100644 --- a/libssu/ssu.cpp +++ b/libssu/ssu.cpp @@ -31,6 +31,7 @@ Ssu::Ssu(): QObject(){ settings = new QSettings(SSU_CONFIGURATION, QSettings::IniFormat); repoSettings = new QSettings(SSU_REPO_CONFIGURATION, QSettings::IniFormat); + boardMappings = new QSettings(SSU_BOARD_MAPPING_CONFIGURATION, QSettings::IniFormat); QSettings defaultSettings(SSU_DEFAULT_CONFIGURATION, QSettings::IniFormat); int configVersion=0; @@ -136,37 +137,93 @@ QString Ssu::credentialsUrl(QString scope){ QString Ssu::deviceFamily(){ QString model = deviceModel(); - if (model == "N900") - return "n900"; - if (model == "N9" || model == "N950") - return "n950-n9"; + if (!cachedFamily.isEmpty()) + return cachedFamily; - return "UNKNOWN"; + cachedFamily = "UNKNOWN"; + + if (boardMappings->contains("variants/" + model)) + model = boardMappings->value("variants/" + model).toString(); + + if (boardMappings->contains(model + "/family")) + cachedFamily = boardMappings->value(model + "/family").toString(); + + return cachedFamily; } QString Ssu::deviceModel(){ QDir dir; QFile procCpuinfo; + QStringList keys; - if (dir.exists("/mer-sdk-chroot")) - return "SDK"; + if (!cachedModel.isEmpty()) + return cachedModel; - // This part should be handled using QTM::SysInfo, but that's currently broken - // on Nemo for N9/N950 + boardMappings->beginGroup("file.exists"); + keys = boardMappings->allKeys(); + + // check if the device can be identified by testing for a file + foreach (const QString &key, keys){ + QString value = boardMappings->value(key).toString(); + if (dir.exists(value)){ + cachedModel = key; + break; + } + } + boardMappings->endGroup(); + if (!cachedModel.isEmpty()) return cachedModel; + + // check if the QSystemInfo model is useful + QSystemDeviceInfo devInfo; + QString model = devInfo.model(); + boardMappings->beginGroup("systeminfo.equals"); + keys = boardMappings->allKeys(); + foreach (const QString &key, keys){ + QString value = boardMappings->value(key).toString(); + if (model == value){ + cachedModel = key; + break; + } + } + boardMappings->endGroup(); + if (!cachedModel.isEmpty()) return cachedModel; + + // check if the device can be identified by a string in /proc/cpuinfo procCpuinfo.setFileName("/proc/cpuinfo"); procCpuinfo.open(QIODevice::ReadOnly | QIODevice::Text); if (procCpuinfo.isOpen()){ QTextStream in(&procCpuinfo); QString cpuinfo = in.readAll(); - if (cpuinfo.contains("Nokia RX-51 board")) - return "N900"; - if (cpuinfo.contains("Nokia RM-680 board")) - return "N950"; - if (cpuinfo.contains("Nokia RM-696 board")) - return "N9"; + boardMappings->beginGroup("cpuinfo.contains"); + keys = boardMappings->allKeys(); + + foreach (const QString &key, keys){ + QString value = boardMappings->value(key).toString(); + if (cpuinfo.contains(value)){ + cachedModel = key; + break; + } + } + boardMappings->endGroup(); + } + if (!cachedModel.isEmpty()) return cachedModel; + + + // check if there's a match on arch ofr generic fallback. This probably + // only makes sense for x86 + boardMappings->beginGroup("arch.equals"); + keys = boardMappings->allKeys(); + foreach (const QString &key, keys){ + QString value = boardMappings->value(key).toString(); + if (settings->value("arch").toString() == value){ + cachedModel = key; + break; + } } + boardMappings->endGroup(); + if (cachedModel.isEmpty()) cachedModel = "UNKNOWN"; - return "UNKNOWN"; + return cachedModel; } QString Ssu::deviceUid(){ @@ -294,6 +351,7 @@ QString Ssu::repoUrl(QString repoName, bool rndRepo, QHash rep repoParameters.insert("adaptation", settings->value("adaptation").toString()); repoParameters.insert("deviceFamily", deviceFamily()); + repoParameters.insert("deviceModel", deviceModel()); if (settings->contains("repository-urls/" + repoName)) r = settings->value("repository-urls/" + repoName).toString(); diff --git a/libssu/ssu.h b/libssu/ssu.h index 503e4f8..42745f1 100644 --- a/libssu/ssu.h +++ b/libssu/ssu.h @@ -114,9 +114,10 @@ class Ssu: public QObject { private: QString errorString; + QString cachedModel, cachedFamily; bool errorFlag; QNetworkAccessManager *manager; - QSettings *settings, *repoSettings; + QSettings *settings, *repoSettings, *boardMappings; bool registerDevice(QDomDocument *response); bool setCredentials(QDomDocument *response); bool verifyResponse(QDomDocument *response); diff --git a/repos.ini b/repos.ini index 0a8bf94..96b2073 100644 --- a/repos.ini +++ b/repos.ini @@ -3,8 +3,11 @@ # Variables resolved during package build: # %(arch) Package architecture, as in i586 or armv7hl # -# Variables resolved by URL parameters in repository: +# Variables resolved through information gathered on the device: # %(deviceFamily) A device family in adaptation, like mrst or n9xx +# %(deviceModel) A device model, like N9, N950 +# +# Variables resolved by URL parameters in repository: # %(debugSplit) Set to debug if 'debug' parameter is present, to packages otherwise # # Variables resolved from configuration: @@ -21,12 +24,12 @@ # # baseurl=plugin:ssu?repo=non-oss&rnd # baseurl=plugin:ssu?repo=mer-core&rnd&debug -# baseurl=plugin:ssu?repo=non-oss&rnd&deviceFamily=mrst +# baseurl=plugin:ssu?repo=non-oss&rnd&fooBar=baz # # Valid url specifications in repo files for release repositories include: # # baseurl=plugin:ssu?repo=non-oss -# baseurl=plugin:ssu?repo=non-oss&deviceFamily=mrst +# baseurl=plugin:ssu?repo=non-oss&fooBar=baz [all]