// Dispatches command |cmd|. Fulfills request in |in_buf|, and writes response // to |out_buf|. Returns a Trusty error code if there is a problem serializing // the response or deserializing the request. Avb specific errors are put in // |error|. staticint ProcessRequest(uint32_t cmd, const uint8_t* in_buf,
uint32_t in_size,
UniquePtr<uint8_t[]>* out_buf,
uint32_t* out_size,
AvbError* error) { if (boot_state_locked) { switch (cmd) { case WRITE_ROLLBACK_INDEX: case WRITE_PERMANENT_ATTRIBUTES: case WRITE_LOCK_STATE:
*out_size = 0;
*error = AvbError::kInvalid; return NO_ERROR;
}
} switch (cmd) { case READ_ROLLBACK_INDEX: return ExecuteCommand(&AvbManager::ReadRollbackIndex, in_buf, in_size,
out_buf, out_size, error); case WRITE_ROLLBACK_INDEX: return ExecuteCommand(&AvbManager::WriteRollbackIndex, in_buf, in_size,
out_buf, out_size, error); case AVB_GET_VERSION: return ExecuteCommand(&AvbManager::GetVersion, in_buf, in_size, out_buf,
out_size, error); case READ_PERMANENT_ATTRIBUTES: return ExecuteCommand(&AvbManager::ReadPermanentAttributes, in_buf,
in_size, out_buf, out_size, error); case WRITE_PERMANENT_ATTRIBUTES: return ExecuteCommand(&AvbManager::WritePermanentAttributes, in_buf,
in_size, out_buf, out_size, error); case READ_LOCK_STATE: return ExecuteCommand(&AvbManager::ReadLockState, in_buf, in_size,
out_buf, out_size, error); case WRITE_LOCK_STATE: return ExecuteCommand(&AvbManager::WriteLockState, in_buf, in_size,
out_buf, out_size, error); case LOCK_BOOT_STATE:
*out_size = 0;
*error = AvbError::kNone;
boot_state_locked = true; return NO_ERROR;
default: return ERR_NOT_VALID;
}
}
// Reads the message described by |msg_info| from channel and processes it. // Writes the response message back to |channel|. Returns a Trusty error code if // there is any I/O problem. staticint ProcessOneMessage(handle_t channel, const ipc_msg_info_t& msg_info) { if (msg_info.len > kAvbServiceBufSize) {
TLOGE("Message too large on channel %x: %zu", channel, msg_info.len); return ERR_TOO_BIG;
}
UniquePtr<uint8_t[]> msg_buf(new uint8_t[msg_info.len]);
struct iovec request_iov = {msg_buf.get(), msg_info.len};
ipc_msg_t request_msg = { 1, // number of iovecs
&request_iov, // iovecs pointer 0, // number of handles
nullptr // handles pointer
};
int rc = read_msg(channel, msg_info.id, 0, &request_msg);
if (rc < 0) {
TLOGE("Failed to read msg for channel %x: %d\n", channel, rc); return rc;
}
if (((size_t)rc) < sizeof(avb_message)) {
TLOGE("Invalid message of size %zu for channel %x\n", (size_t)rc,
channel); return ERR_NOT_VALID;
}
// Send response message back to caller
avb_message avb_response_header = {
.cmd = avb_request_header->cmd | AVB_RESP_BIT,
.result = error,
.payload = {},
}; struct iovec response_iov[2] = {
{&avb_response_header, sizeof(avb_response_header)},
{out_buf.get(), out_size},
};
ipc_msg_t response_msg = { 2, // number of iovecs
response_iov, // iovecs pointer 0, // number of handles
nullptr // handles pointer
};
rc = send_msg(channel, &response_msg); if (rc < 0) {
TLOGE("Failed to send_msg on channel %x: %d\n", channel, rc); return rc;
} return NO_ERROR;
}
// Receives all pending messages from |channel| and processes them, sending // responses as appropriate. Returns a Trusty error code if there is a // problem with message processing or I/O. staticint ProcessMessages(handle_t channel) { while (true) {
ipc_msg_info_t msg_info; int rc = get_msg(channel, &msg_info); if (rc == ERR_NO_MSG) { break;
}
if (rc != NO_ERROR) {
TLOGE("Failed to get_msg on channel %x: %d\n", channel, rc); return rc;
}
rc = put_msg(channel, msg_info.id); if (rc != NO_ERROR) {
TLOGE("Failed to put_msg on channel %x: %d\n", rc, channel); return rc;
}
}
return NO_ERROR;
}
// Handles an |event| on a channel. If it is an incoming message, it is // processed. Otherwise, the event indicates a channel hangup or error, so // the channel is closed. staticvoid HandleChannelEvent(const uevent_t& event) { if ((event.event & IPC_HANDLE_POLL_ERROR) ||
(event.event & IPC_HANDLE_POLL_READY)) { // close it as it is in an error state
TLOGE("Error event on channel %x: 0x%x\n", event.event, event.handle);
close(event.handle);
}
if (event.event & IPC_HANDLE_POLL_HUP) { // closed by peer
close(event.handle); return;
}
if (event.event & IPC_HANDLE_POLL_MSG) { if (ProcessMessages(event.handle) != NO_ERROR) {
close(event.handle);
}
}
}
// Handles an |event| on a port. If it is an incoming connection event, // the connection is accepted. Any other event is unexpected. staticvoid HandlePortEvent(const uevent_t& event) { if (event.event & IPC_HANDLE_POLL_READY) { // incoming connection: accept it
uuid_t peer_uuid; int rc = accept(event.handle, &peer_uuid); if (rc < 0) {
TLOGE("Failed to accept on port %d: %d\n", event.handle, rc);
}
} else {
TLOGE("Unexpected event on port %d: 0x%x\n", event.handle, event.event);
}
}
} // namespace avb
int main(void) {
avb::AvbManager avb_manager(new avb::SecureStorage);
g_avb_manager = &avb_manager;
TLOGD("Initializing AVB App\n");
int rc = port_create(kAvbServiceName, kAvbServiceNumBufs,
kAvbServiceBufSize, kAvbServiceFlags); if (rc < 0) {
TLOGE("Failed to initialize AVB app: %d", rc); return rc;
}
handle_t port = static_cast<handle_t>(rc);
// enter main event loop while (true) {
uevent_t event;
event.handle = INVALID_IPC_HANDLE;
event.event = 0;
event.cookie = nullptr;
rc = wait_any(&event, INFINITE_TIME);
if (rc == NO_ERROR) { // got an event if (event.handle == port) {
avb::HandlePortEvent(event);
} else {
avb::HandleChannelEvent(event);
}
} else {
TLOGE("wait_any failed: %d\n", rc);
}
}
g_avb_manager = nullptr; return0;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-26)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.