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.
87 lines
2.0 KiB
C++
87 lines
2.0 KiB
C++
/*
|
|
* Copyright (C) 2026 oxmc / PawletOS
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#pragma once
|
|
|
|
#include <atomic>
|
|
#include <condition_variable>
|
|
#include <mutex>
|
|
#include <string>
|
|
#include <thread>
|
|
#include <vector>
|
|
|
|
#include "handlers.h"
|
|
#include "state.h"
|
|
|
|
namespace pawlet::hwupdate {
|
|
|
|
// Thread-safe snapshots exposed to the AIDL layer.
|
|
struct ComponentStatus {
|
|
std::string componentId;
|
|
std::string productId;
|
|
std::string componentClass;
|
|
std::string role;
|
|
std::string transport;
|
|
bool present = false;
|
|
std::string installedVersion;
|
|
std::string hardwareRevision;
|
|
std::string support;
|
|
};
|
|
|
|
struct PendingUpdate {
|
|
std::string componentId;
|
|
bool available = false;
|
|
std::string version;
|
|
int64_t sizeBytes = 0;
|
|
std::string changelogUrl;
|
|
};
|
|
|
|
struct EngineConfig {
|
|
std::string manifestPath;
|
|
std::string serverBaseUrl; // ".../ota.php?mode=hardware"
|
|
std::string stateDir; // e.g. /data/pawlet/hw
|
|
int maxRetries = 3;
|
|
bool autoApply = true;
|
|
};
|
|
|
|
class Engine {
|
|
public:
|
|
explicit Engine(EngineConfig cfg);
|
|
~Engine();
|
|
|
|
void Start(); // spawns worker, runs an initial cycle
|
|
void Stop();
|
|
|
|
// Request an asynchronous detect+check(+apply) cycle.
|
|
void CheckNow();
|
|
|
|
// Snapshots (safe to call from binder threads).
|
|
std::vector<ComponentStatus> Components() const;
|
|
std::vector<PendingUpdate> Pending() const;
|
|
bool IsBusy() const { return busy_.load(); }
|
|
int LastResult() const { return lastResult_.load(); }
|
|
|
|
private:
|
|
void WorkerLoop();
|
|
int RunCycle(); // returns 0 on success
|
|
|
|
EngineConfig cfg_;
|
|
HandlerRegistry handlers_;
|
|
State state_;
|
|
|
|
mutable std::mutex snapMu_;
|
|
std::vector<ComponentStatus> components_;
|
|
std::vector<PendingUpdate> pending_;
|
|
|
|
std::thread worker_;
|
|
std::mutex reqMu_;
|
|
std::condition_variable reqCv_;
|
|
bool requested_ = false;
|
|
bool stop_ = false;
|
|
std::atomic<bool> busy_{false};
|
|
std::atomic<int> lastResult_{0};
|
|
};
|
|
|
|
} // namespace pawlet::hwupdate
|