[Metrics] Add helper data structures to parse metrics messages

Bug: 323508669

Change-Id: Ic4716dd47168481b6aa780f55d9db1208623b61d
This commit is contained in:
Snehal 2024-02-28 18:08:09 +00:00
parent 01d754d672
commit dfd84433dd
2 changed files with 76 additions and 29 deletions

View file

@ -39,14 +39,17 @@
* repository. They must be kept in sync.
*/
#define METRICS_PORT "com.android.trusty.metrics"
#define METRICS_PORT "com.android.trusty.metrics.consumer"
#define UUID_STR_SIZE (37)
/**
* enum metrics_cmd - command identifiers for metrics interface
* @METRICS_CMD_RESP_BIT: message is a response
* @METRICS_CMD_REQ_SHIFT: number of bits used by @METRICS_CMD_RESP_BIT
* @METRICS_CMD_REPORT_EVENT_DROP: report gaps in the event stream
* @METRICS_CMD_REPORT_CRASH: report an app crash event
* @METRICS_CMD_RESP_BIT: message is a response
* @METRICS_CMD_REQ_SHIFT: number of bits used by @METRICS_CMD_RESP_BIT
* @METRICS_CMD_REPORT_EVENT_DROP: report gaps in the event stream
* @METRICS_CMD_REPORT_CRASH: report an app crash event
* @METRICS_CMD_REPORT_STORAGE_ERROR: report trusty storage error
*/
enum metrics_cmd {
METRICS_CMD_RESP_BIT = 1,
@ -54,6 +57,7 @@ enum metrics_cmd {
METRICS_CMD_REPORT_EVENT_DROP = (1 << METRICS_CMD_REQ_SHIFT),
METRICS_CMD_REPORT_CRASH = (2 << METRICS_CMD_REQ_SHIFT),
METRICS_CMD_REPORT_STORAGE_ERROR = (3 << METRICS_CMD_REQ_SHIFT),
};
/**
@ -90,17 +94,70 @@ struct metrics_resp {
/**
* struct metrics_report_crash_req - arguments of %METRICS_CMD_REPORT_CRASH
* requests
* @app_id_len: length of app ID that follows this structure
* @app_id: uuid of the app that crashed
* @crash_reason: architecture-specific code representing the reason for the
* crash
*/
struct metrics_report_crash_req {
uint32_t app_id_len;
char app_id[UUID_STR_SIZE];
uint32_t crash_reason;
} __attribute__((__packed__));
#define METRICS_MAX_APP_ID_LEN 256
enum TrustyStorageErrorType {
TRUSTY_STORAGE_ERROR_UNKNOWN = 0,
TRUSTY_STORAGE_ERROR_SUPERBLOCK_INVALID = 1,
TRUSTY_STORAGE_ERROR_BLOCK_MAC_MISMATCH = 2,
TRUSTY_STORAGE_ERROR_BLOCK_HEADER_INVALID = 3,
TRUSTY_STORAGE_ERROR_RPMB_COUNTER_MISMATCH = 4,
TRUSTY_STORAGE_ERROR_RPMB_COUNTER_MISMATCH_RECOVERED = 5,
TRUSTY_STORAGE_ERROR_RPMB_COUNTER_READ_FAILURE = 6,
TRUSTY_STORAGE_ERROR_RPMB_MAC_MISMATCH = 7,
TRUSTY_STORAGE_ERROR_RPMB_ADDR_MISMATCH = 8,
TRUSTY_STORAGE_ERROR_RPMB_FAILURE_RESPONSE = 9,
TRUSTY_STORAGE_ERROR_RPMB_UNKNOWN = 10,
TRUSTY_STORAGE_ERROR_RPMB_SCSI_ERROR = 11,
TRUSTY_STORAGE_ERROR_IO_ERROR = 12,
TRUSTY_STORAGE_ERROR_PROXY_COMMUNICATION_FAILURE = 13,
};
#define METRICS_MAX_MSG_SIZE \
(sizeof(struct metrics_req) + sizeof(struct metrics_report_crash_req) + \
METRICS_MAX_APP_ID_LEN)
enum TrustyFileSystem {
TRUSTY_FS_UNKNOWN = 0,
TRUSTY_FS_TP = 1,
TRUSTY_FS_TD = 2,
TRUSTY_FS_TDP = 3,
TRUSTY_FS_TDEA = 4,
TRUSTY_FS_NSP = 5,
};
enum TrustyBlockType {
TRUSTY_BLOCKTYPE_UNKNOWN = 0,
TRUSTY_BLOCKTYPE_FILES_ROOT = 1,
TRUSTY_BLOCKTYPE_FREE_ROOT = 2,
TRUSTY_BLOCKTYPE_FILES_INTERNAL = 3,
TRUSTY_BLOCKTYPE_FREE_INTERNAL = 4,
TRUSTY_BLOCKTYPE_FILE_ENTRY = 5,
TRUSTY_BLOCKTYPE_FILE_BLOCK_MAP = 6,
TRUSTY_BLOCKTYPE_FILE_DATA = 7,
TRUSTY_BLOCKTYPE_CHECKPOINT_ROOT = 8,
TRUSTY_BLOCKTYPE_CHECKPOINT_FILES_ROOT = 9,
TRUSTY_BLOCKTYPE_CHECKPOINT_FREE_ROOT = 10,
};
struct metrics_report_storage_error_req {
enum TrustyStorageErrorType error;
char app_id[UUID_STR_SIZE];
char client_app_id[UUID_STR_SIZE];
uint32_t write;
enum TrustyFileSystem file_system;
uint64_t file_path_hash;
enum TrustyBlockType block_type;
uint64_t repair_counter;
} __attribute__((__packed__));
struct metrics_msg {
struct metrics_req req;
union {
struct metrics_report_crash_req crash_args;
struct metrics_report_storage_error_req storage_args;
};
} __attribute__((__packed__));

View file

@ -78,9 +78,8 @@ Result<void> TrustyMetrics::HandleEvent() {
return Error() << "connection to Metrics TA has not been initialized yet";
}
uint8_t msg[METRICS_MAX_MSG_SIZE];
auto rc = read(metrics_fd_, msg, sizeof(msg));
struct metrics_msg metrics_msg;
int rc = read(metrics_fd_, &metrics_msg, sizeof(metrics_msg));
if (rc < 0) {
return ErrnoError() << "failed to read metrics message";
}
@ -89,23 +88,14 @@ Result<void> TrustyMetrics::HandleEvent() {
if (msg_len < sizeof(metrics_req)) {
return Error() << "message too small: " << rc;
}
auto req = reinterpret_cast<metrics_req*>(msg);
size_t offset = sizeof(metrics_req);
uint32_t cmd = metrics_msg.req.cmd;
uint32_t status = METRICS_NO_ERROR;
switch (req->cmd) {
switch (cmd) {
case METRICS_CMD_REPORT_CRASH: {
if (msg_len < offset + sizeof(metrics_report_crash_req)) {
return Error() << "message too small: " << rc;
}
auto crash_args = reinterpret_cast<metrics_report_crash_req*>(msg + offset);
offset += sizeof(metrics_report_crash_req);
if (msg_len < offset + crash_args->app_id_len) {
return Error() << "message too small: " << rc;
}
auto app_id_ptr = reinterpret_cast<char*>(msg + offset);
std::string app_id(app_id_ptr, crash_args->app_id_len);
struct metrics_report_crash_req crash_args = metrics_msg.crash_args;
auto app_id_ptr = crash_args.app_id;
std::string app_id(app_id_ptr, UUID_STR_SIZE);
HandleCrash(app_id);
break;
@ -121,7 +111,7 @@ Result<void> TrustyMetrics::HandleEvent() {
}
metrics_resp resp = {
.cmd = req->cmd | METRICS_CMD_RESP_BIT,
.cmd = cmd | METRICS_CMD_RESP_BIT,
.status = status,
};