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.
106 lines
3.1 KiB
C++
106 lines
3.1 KiB
C++
/*
|
|
* Copyright (C) 2026 oxmc / PawletOS
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#include "detect.h"
|
|
|
|
#include <cstdio>
|
|
#include <filesystem>
|
|
#include <map>
|
|
|
|
#include <android-base/file.h>
|
|
#include <android-base/logging.h>
|
|
#include <android-base/strings.h>
|
|
|
|
namespace pawlet::hwupdate {
|
|
namespace {
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
struct UsbDev {
|
|
std::string vid; // lowercase hex, e.g. "1209"
|
|
std::string pid; // lowercase hex
|
|
std::string node; // /dev/bus/usb/BBB/DDD
|
|
};
|
|
|
|
std::string ReadTrimmed(const std::string& path) {
|
|
std::string s;
|
|
if (!android::base::ReadFileToString(path, &s)) return {};
|
|
return android::base::Trim(s);
|
|
}
|
|
|
|
// Enumerate connected USB devices from sysfs.
|
|
std::vector<UsbDev> EnumUsb() {
|
|
std::vector<UsbDev> out;
|
|
const std::string base = "/sys/bus/usb/devices";
|
|
std::error_code ec;
|
|
if (!fs::exists(base, ec)) return out;
|
|
for (const auto& entry : fs::directory_iterator(base, ec)) {
|
|
const std::string dir = entry.path().string();
|
|
std::string vid = ReadTrimmed(dir + "/idVendor");
|
|
std::string pid = ReadTrimmed(dir + "/idProduct");
|
|
if (vid.empty() || pid.empty()) continue; // hubs/interfaces, skip
|
|
|
|
UsbDev d;
|
|
d.vid = android::base::Trim(vid);
|
|
d.pid = android::base::Trim(pid);
|
|
std::string bus = ReadTrimmed(dir + "/busnum");
|
|
std::string dev = ReadTrimmed(dir + "/devnum");
|
|
if (!bus.empty() && !dev.empty()) {
|
|
char node[64];
|
|
snprintf(node, sizeof(node), "/dev/bus/usb/%03d/%03d", atoi(bus.c_str()),
|
|
atoi(dev.c_str()));
|
|
d.node = node;
|
|
}
|
|
out.push_back(std::move(d));
|
|
}
|
|
return out;
|
|
}
|
|
|
|
bool UsbMatch(const std::vector<UsbDev>& devs, const std::string& vid, const std::string& pid,
|
|
std::string* node) {
|
|
for (const auto& d : devs) {
|
|
if (android::base::EqualsIgnoreCase(d.vid, vid) &&
|
|
android::base::EqualsIgnoreCase(d.pid, pid)) {
|
|
if (node) *node = d.node;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
std::vector<DetectedComponent> Detect(const Manifest& manifest) {
|
|
std::vector<UsbDev> usb = EnumUsb();
|
|
std::vector<DetectedComponent> out;
|
|
|
|
for (const auto& prod : manifest.products) {
|
|
for (const auto& comp : prod.components) {
|
|
DetectedComponent dc;
|
|
dc.product = ∏
|
|
dc.comp = ∁
|
|
|
|
if (!comp.usbVendorId.empty() && !comp.usbProductId.empty()) {
|
|
std::string node;
|
|
if (UsbMatch(usb, comp.usbVendorId, comp.usbProductId, &node)) {
|
|
dc.present = true;
|
|
dc.transport = "usb";
|
|
dc.usbVendorId = comp.usbVendorId;
|
|
dc.usbProductId = comp.usbProductId;
|
|
dc.devPath = node;
|
|
}
|
|
}
|
|
// TODO: device-tree / i2c / spi detectors go here.
|
|
|
|
if (dc.present) {
|
|
LOG(INFO) << "hwupdate: detected " << comp.id << " on " << dc.transport;
|
|
}
|
|
out.push_back(std::move(dc));
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
} // namespace pawlet::hwupdate
|