blob: 5de4c18ed6c9ae8e8601cc51e758e385e3c8f6aa [file] [log] [blame]
/* SPDX-License-Identifier: LGPL-2.0-or-later */
/*
*
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2022 Google LLC
*
*
*/
#ifndef __STATS_H
#define __STATS_H
#include <errno.h>
#include <stdint.h>
#include <string.h>
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
/* MODE_PACKET is used in cases of "btmon -r" or "btmon -w" */
#define MODE_PACKET 0
/* MODE_ANALYZE is used in case of "btmon -a" */
#define MODE_ANALYZE 1
/* All of the Android BQR subevents are of integer types. */
enum int_types {
INT8,
INT16,
INT32,
UINT8,
UINT16,
UINT32,
/* Total number of integer types. This should be the last entry. */
TOTAL_INT_TYPES
};
/*
* The subevt_stat struct keeps a range of values of a particular subevent
* over which the statistics are calculated.
*
* value: points to a cyclic buffer which holds up to |bqr_buffer_len| entries.
* The buffer type is determined per subevent at run time.
* int_type: the integer type of a subevt, e.g., INT8 or UINT32
*
* The integer types of subevents are defined in bqr_subevt_table.
*/
struct subevt_stat_slot {
void *value;
void *min;
void *max;
double sum;
double mean;
double sd;
};
struct subevt_stat {
enum int_types int_type;
size_t subevt_size;
unsigned char num_slots;
struct subevt_stat_slot *slots;
};
/* This struct keeps all bqr stats data associated with a connection handle. */
struct bqr_stats_data {
uint16_t index;
uint16_t conn_handle;
unsigned int total_count; /* number of total bqr events */
unsigned int num_entries; /* number of valid entries in stats */
unsigned int next;
const uint8_t *bqr_stats_subevt_list; /* statistics are computed over */
/* this list of subevts */
uint8_t subevt_list_count; /* count of subevts in the list above */
struct subevt_stat *stats; /* buffers and statistics for subevents */
struct timeval *tv; /* packet timestamps of stats' value buffers */
const char *(*get_subevt_name)(uint8_t subevent_id);
uint8_t (*get_subevt_num_slots)(uint8_t subevent_id);
size_t (*get_subevt_size)(uint8_t subevent_id);
enum int_types (*get_subevt_int_type)(uint8_t subevent_id);
};
/* The high level meta about a connection. */
struct conn_info_data {
const uint8_t *name;
const uint8_t *bdaddr;
const uint8_t *link_type_str;
const struct timeval *tv_bgn;
const struct timeval *tv_end;
};
/* The high level meta about a packet. */
struct packet_info_data {
uint16_t index;
const struct timeval *tv;
};
struct subevt_info_data {
const char *name;
unsigned char num_slots;
enum int_types int_type;
size_t size;
};
typedef void (*conn_info_fetch_func_t)(uint16_t index,
uint16_t handle, struct conn_info_data *conn_info);
typedef void (*packet_info_fetch_func_t)(struct packet_info_data *packet_info);
typedef void (*conn_alloc_in_middle_func_t)(uint16_t index, uint16_t handle);
typedef void (*subevt_info_fetch_func_t)(uint8_t subevent_id,
struct subevt_info_data *subevt_info);
void set_conn_info_fetch_func(conn_info_fetch_func_t func);
void set_packet_info_fetch_func(packet_info_fetch_func_t func);
void set_conn_alloc_in_middle_func(conn_alloc_in_middle_func_t func);
void set_subevt_info_fetch_func(subevt_info_fetch_func_t func);
void set_bqr_buffer_length(unsigned int len);
FILE *bqr_file_create(const char *filepath);
void bqr_file_close(void);
void set_analyze_mode(void);
bool is_packet_mode(void);
bool is_analyze_mode(void);
void bqr_stats_post(void);
void queue_new_bqr_stats(void);
void queue_destroy_bqr_stats(void);
void set_bqr_stats_current(uint16_t conn_handle,
const uint8_t *bqr_stats_subevt_list, uint8_t subevt_list_count);
void subevt_slot_add(uint8_t subevt_idx, unsigned char slot_i,
const void *value);
void subevt_add(uint8_t subevt_idx, const void *value);
size_t get_int_size(enum int_types int_type);
#endif /* __STATS_H */