4e9f147e55
Adds pawlethwd, a native C++ system_ext daemon (coredomain) that detects peripherals, checks the hardware update catalog (ota.php?mode=hardware), verifies payloads, and flashes firmware via authorized handler plugins. - daemon/: manifest parse, libcurl HTTP + sha256, sysfs USB detection, catalog client, dlopen handler registry (fixed path + ABI + allowlist), state persistence, orchestration engine, AIDL service, main. - aidl/: IPawletHardwareUpdate (getComponents/getPendingUpdates/checkNow/...). - include/pawlet/hwh_abi.h: stable C plugin ABI. - handlers/usbdfu/: libpawlethwh_usbdfu.so, DFU 1.1 download over libusb. - sepolicy/: pawlethwd domain, pawlet_hw_data_file, service type. - schemas/, etc/supported_hardware.default.json, README design doc. - hwupdate.mk wires packages + ro.pawlet.hardware.manifest + sepolicy dir; inherited from config/common.mk. Trust: a server-named installer handler is honored only if allowlisted in the immutable supported_hardware.json, maps to a fixed dm-verity-protected .so path, is ABI/id-checked, and every payload is sha256-verified before a handler runs.
93 lines
3.2 KiB
C++
93 lines
3.2 KiB
C++
/*
|
|
* Copyright (C) 2026 oxmc / PawletOS
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#include "manifest.h"
|
|
|
|
#include <json/json.h>
|
|
|
|
#include <fstream>
|
|
|
|
#include <android-base/logging.h>
|
|
|
|
namespace pawlet::hwupdate {
|
|
namespace {
|
|
|
|
std::vector<std::string> StrArray(const Json::Value& v) {
|
|
std::vector<std::string> out;
|
|
if (v.isArray()) {
|
|
for (const auto& e : v) {
|
|
if (e.isString()) out.push_back(e.asString());
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
void ReadIdentifiers(const Json::Value& ids, std::string& usbVid, std::string& usbPid,
|
|
std::vector<std::string>& dtCompat) {
|
|
if (!ids.isObject()) return;
|
|
usbVid = ids.get("usb_vendor_id", "").asString();
|
|
usbPid = ids.get("usb_product_id", "").asString();
|
|
dtCompat = StrArray(ids["device_tree_compatible"]);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
std::optional<Manifest> LoadManifest(const std::string& path) {
|
|
std::ifstream in(path, std::ios::binary);
|
|
if (!in) {
|
|
LOG(ERROR) << "hwupdate: cannot open manifest " << path;
|
|
return std::nullopt;
|
|
}
|
|
|
|
Json::Value root;
|
|
Json::CharReaderBuilder b;
|
|
std::string errs;
|
|
if (!Json::parseFromStream(b, in, &root, &errs)) {
|
|
LOG(ERROR) << "hwupdate: manifest parse error: " << errs;
|
|
return std::nullopt;
|
|
}
|
|
|
|
Manifest m;
|
|
m.schemaVersion = root.get("schema_version", 0).asInt();
|
|
if (m.schemaVersion != 1) {
|
|
LOG(ERROR) << "hwupdate: unsupported manifest schema_version " << m.schemaVersion;
|
|
return std::nullopt;
|
|
}
|
|
m.device = root.get("device", "").asString();
|
|
m.buildVersion = root.get("build_version", "").asString();
|
|
|
|
for (const auto& p : root["supported_hardware"]) {
|
|
ManifestProduct prod;
|
|
prod.id = p.get("id", "").asString();
|
|
prod.manufacturer = p.get("manufacturer", "").asString();
|
|
prod.cls = p.get("class", "").asString();
|
|
prod.support = p.get("support", "full").asString();
|
|
prod.supportedRevisions = StrArray(p["supported_revisions"]);
|
|
ReadIdentifiers(p["identifiers"], prod.usbVendorId, prod.usbProductId, prod.dtCompatible);
|
|
|
|
for (const auto& c : p["components"]) {
|
|
ManifestComponent comp;
|
|
comp.id = c.get("id", "").asString();
|
|
comp.cls = c.get("class", "").asString();
|
|
comp.role = c.get("role", "").asString();
|
|
comp.support = c.get("support", "full").asString();
|
|
comp.supportedRevisions = StrArray(c["supported_revisions"]);
|
|
comp.installerHandlers = StrArray(c["installer_handlers"]);
|
|
ReadIdentifiers(c["identifiers"], comp.usbVendorId, comp.usbProductId, comp.dtCompatible);
|
|
// Fall back to the product's identifiers if the component omits them.
|
|
if (comp.usbVendorId.empty()) comp.usbVendorId = prod.usbVendorId;
|
|
if (comp.usbProductId.empty()) comp.usbProductId = prod.usbProductId;
|
|
if (comp.dtCompatible.empty()) comp.dtCompatible = prod.dtCompatible;
|
|
prod.components.push_back(std::move(comp));
|
|
}
|
|
m.products.push_back(std::move(prod));
|
|
}
|
|
|
|
LOG(INFO) << "hwupdate: loaded manifest device=" << m.device
|
|
<< " products=" << m.products.size();
|
|
return m;
|
|
}
|
|
|
|
} // namespace pawlet::hwupdate
|