File bluespy.h¶
Go to the documentation of this file
#ifndef BLUESPY_INCLUDE_GUARD
#define BLUESPY_INCLUDE_GUARD
#ifndef BLUESPY_API
#if defined _WIN32 || defined __CYGWIN__
#define BLUESPY_API __declspec(dllimport)
#else
#define BLUESPY_API __attribute__((visibility("default")))
#endif
#endif
#include "stdbool.h"
#include "stdint.h"
#include <stddef.h>
#ifdef __cplusplus
#include <utility>
extern "C" {
#endif
#if defined(__has_cpp_attribute)
#define BLUESPY_HASATTR(attr) __has_cpp_attribute(attr)
#elif defined(__has_c_attribute)
#define BLUESPY_HASATTR(attr) __has_c_attribute(attr)
#else
#define BLUESPY_HASATTR(attr) (0)
#endif
#if BLUESPY_HASATTR(deprecated)
#define BLUESPY_DEPRECATED_API [[deprecated]] BLUESPY_API
#else
#define BLUESPY_DEPRECATED_API BLUESPY_API
#endif
typedef enum bluespy_error {
BLUESPY_NO_ERROR = 0,
BLUESPY_ERROR_NO_DEVICE,
BLUESPY_ERROR_LICENCE,
BLUESPY_ERROR_NO_FILE,
BLUESPY_ERROR_CAPTURE_NOT_STARTED,
BLUESPY_ERROR_INVALID_PACKET,
BLUESPY_ERROR_INVALID_CAPTURE_OPTIONS,
BLUESPY_ERROR_INVALID_CIS_CONFIG,
BLUESPY_ERROR_AUDIOPOD_DISABLED,
BLUESPY_ERROR_AUDIOPOD_OUTPUT_DISABLED,
BLUESPY_ERROR_INVALID_PARAMETER,
BLUESPY_ERROR_IUT_NOT_CONNECTED,
BLUESPY_ERROR_INVALID_TCID,
BLUESPY_ERROR_TESTCASE_FAILURE,
BLUESPY_ERROR_ABORTED_TESTCASES,
BLUESPY_ERROR_NOT_INITIALIZED,
} bluespy_error;
BLUESPY_API const char* bluespy_error_string(bluespy_error error);
typedef enum bluespy_log_level {
BLUESPY_LOG_PASS = 0x00,
BLUESPY_LOG_WARN = 0x20,
BLUESPY_LOG_INFO = 0x40,
BLUESPY_LOG_DEBUG = 0x60,
BLUESPY_LOG_ERROR = 0x80,
} bluespy_log_level;
BLUESPY_API void bluespy_init();
BLUESPY_API void bluespy_deinit();
BLUESPY_API void bluespy_start_gui();
BLUESPY_API bluespy_error bluespy_connect(uint32_t serial);
BLUESPY_API bluespy_error bluespy_connect_multiple(uint32_t* serial_data, uint64_t serial_size);
BLUESPY_API uint64_t bluespy_morephs_connected(uint32_t** serials);
BLUESPY_API bluespy_error bluespy_disconnect();
BLUESPY_API bluespy_error bluespy_moreph_reboot(uint32_t serial);
typedef int64_t bluespy_time_point;
#define BLUESPY_TIME_INVALID (INT64_MAX)
BLUESPY_API const char* bluespy_print_time(bluespy_time_point ts);
BLUESPY_API bluespy_error bluespy_add_log_message(bluespy_log_level level, const char* message,
bluespy_time_point ts);
typedef enum bluespy_logic_rate {
bluespy_logic_rate_high,
bluespy_logic_rate_mid,
bluespy_logic_rate_low
} bluespy_logic_rate;
typedef struct bluespy_multi_moreph_options {
bool enable_CL;
bool enable_LE;
bool enable_wifi;
} bluespy_multi_moreph_options;
typedef enum bluespy_audio_channel {
BLUESPY_STEREO,
BLUESPY_MONO_L,
BLUESPY_MONO_R
} bluespy_audio_channel;
typedef enum bluespy_audio_connect {
BLUESPY_NOAUDIO,
BLUESPY_LINE,
BLUESPY_JACK,
BLUESPY_HEADSET,
BLUESPY_COAX,
BLUESPY_OPTICAL,
BLUESPY_MIC,
BLUESPY_I2S
} bluespy_audio_connect;
typedef enum bluespy_audio_bias {
BLUESPY_BIAS_OFF,
BLUESPY_BIAS_LOW,
BLUESPY_BIAS_MID,
BLUESPY_BIAS_HIG,
BLUESPY_BIAS_VDD
} bluespy_audio_bias;
typedef struct bluespy_capture_audiopod_options {
uint32_t sample_rate;
bluespy_audio_channel channels;
bluespy_audio_connect output;
bluespy_audio_connect input;
bluespy_audio_bias bias;
bool current_probe;
double LA_low_voltage;
double LA_high_voltage;
double power_supply_V;
double VIO_dV;
bool AGC;
bool DRC;
bool second_I2S_input; // Enable a second I2S input, output must be set to BLUESPY_NO_AUDIO
double vol_in_left;
double vol_in_right;
double vol_out_left;
double vol_out_right;
} bluespy_capture_audiopod_options;
typedef struct bluespy_capture_i2s_options {
uint8_t SCLK_line; // Valid values are [0,15]
uint8_t WS_line; // Valid values are [0,15]
uint8_t SD_line; // Valid values are [0,15]
uint8_t n_channels; // Valid values are [1,16]
uint8_t bits_per_ch; // Valid values are [1,32]
bool sample_on_rising_edge;
bool first_chan_follows_WS_high;
bool one_sample_delay;
bool MSB_first;
bool DSP_mode;
bool master;
} bluespy_capture_i2s_options;
typedef struct bluespy_capture_options {
bool enable_CL;
bool enable_LE;
bool enable_QHS;
bool enable_15_4;
bool enable_wifi;
bool enable_MHDT_CL;
bool enable_MHDT_LE;
bool enable_Dukosi;
bool enable_Varjo;
bool enable_Channel_Sounding;
bool enable_HDT;
uint16_t spectrum_period;
uint32_t logic_mask;
bool logic_use_external_vref;
bluespy_logic_rate logic_rate;
bluespy_multi_moreph_options multi_moreph_opts[32];
bluespy_capture_audiopod_options* audiopod_opts;
bluespy_capture_i2s_options* i2s_opts[2];
bool enable_Proprietary_1;
bool enable_Proprietary_2;
} bluespy_capture_options;
BLUESPY_API bluespy_capture_options* bluespy_capture_options_alloc();
BLUESPY_DEPRECATED_API void bluespy_capture_options_delete(bluespy_capture_options* opts);
BLUESPY_API void bluespy_delete(void* obj);
BLUESPY_API bluespy_capture_audiopod_options* bluespy_capture_audiopod_options_alloc();
BLUESPY_API bluespy_capture_i2s_options* bluespy_capture_i2s_options_alloc();
BLUESPY_API bluespy_error bluespy_capture(const char* filename, bluespy_capture_options* opts);
BLUESPY_API bluespy_error bluespy_stop_capture();
BLUESPY_API bluespy_error bluespy_load_file(const char* filename);
BLUESPY_API bluespy_error bluespy_close_file();
BLUESPY_API uint32_t bluespy_packet_count(void);
typedef uint64_t bluespy_id;
#define BLUESPY_ID_INVALID ((bluespy_id)(-1))
typedef bluespy_id bluespy_event_id;
typedef bluespy_id bluespy_device_id;
typedef bluespy_id bluespy_connection_id;
typedef bluespy_id bluespy_audiostream_id;
BLUESPY_API bluespy_event_id bluespy_get_baseband(uint32_t index);
BLUESPY_API bluespy_event_id bluespy_get_parent(bluespy_event_id event);
BLUESPY_API const bluespy_event_id* bluespy_get_children(bluespy_event_id event, uint32_t* count);
BLUESPY_API const char* bluespy_query(bluespy_id event, const char* query);
BLUESPY_API int64_t bluespy_query_int(bluespy_id event, const char* query);
BLUESPY_API bool bluespy_query_bool(bluespy_id event, const char* query);
BLUESPY_DEPRECATED_API int bluespy_query_auto(bluespy_id event, const char* query, const char** s,
int64_t* i, bool* b);
typedef struct bluespy_bytes {
const uint8_t* data;
size_t len;
} bluespy_bytes;
BLUESPY_API bluespy_bytes bluespy_query_bytes(bluespy_id event, const char* query);
typedef enum bluespy_query_type {
bluespy_query_type_invalid = -1, /* This query can never be used on this kind of ID */
bluespy_query_type_none = 0, /* There is no value on this specific ID */
bluespy_query_type_bool = 1,
bluespy_query_type_int = 2,
bluespy_query_type_string = 3,
bluespy_query_type_bytes = 4,
bluespy_query_type_double = 5,
bluespy_query_type_id = 6,
} bluespy_query_type;
typedef struct bluespy_query_value {
bluespy_query_type type;
union {
bool b;
int64_t i;
const char* s;
bluespy_bytes bytes;
double d;
bluespy_id id;
};
} bluespy_query_value;
BLUESPY_API bluespy_query_value bluespy_query_get(bluespy_id id, const char* query);
typedef int32_t bluespy_filter_file_id;
#define BLUESPY_FILTER_FILE_ID_INVALID ((bluespy_filter_file_id)(-1))
typedef struct bluespy_filter_file_options {
bluespy_time_point range_start;
bool keep_spectrum;
bool keep_logic;
bool keep_uart;
bool keep_i2s_and_audiopod;
} bluespy_filter_file_options;
BLUESPY_API bluespy_filter_file_options* bluespy_filter_file_options_alloc();
BLUESPY_API void bluespy_filter_file_options_delete(bluespy_filter_file_options* opts);
BLUESPY_API const char* bluespy_get_filter_file_name(bluespy_filter_file_id id);
BLUESPY_API bluespy_filter_file_id bluespy_create_filter_file(const char* filename,
bluespy_filter_file_options* opts);
BLUESPY_API bluespy_error bluespy_add_to_filter_file(bluespy_filter_file_id file_id,
bluespy_event_id event_id);
BLUESPY_API bluespy_error bluespy_close_filter_file(bluespy_filter_file_id file_id);
BLUESPY_API uint32_t bluespy_get_logic_at_time(bluespy_time_point ts);
typedef struct bluespy_logic_change {
uint32_t state; // New logic state - 32-bit mask of the new logic state
uint32_t change_mask; // Logic changed - 32-bit mask of lines which changed
bluespy_time_point time; // The time of the logic change
} bluespy_logic_change;
BLUESPY_API bluespy_logic_change bluespy_get_next_logic_change(bluespy_time_point ts,
uint32_t mask);
BLUESPY_API bluespy_logic_change bluespy_wait_until_next_logic_change(uint32_t mask,
int64_t timeout,
bluespy_time_point start_ts);
BLUESPY_API bluespy_error bluespy_add_link_key(const unsigned char* key, uint64_t addr0,
uint64_t addr1);
BLUESPY_API void bluespy_add_IRK(const unsigned char* key, uint64_t* addr, uint64_t n_addresses);
BLUESPY_API bluespy_device_id bluespy_get_device_id(const char* addr);
typedef struct bluespy_connection_id_span {
bluespy_connection_id* data;
uint64_t size;
} bluespy_connection_id_span;
BLUESPY_API bluespy_connection_id_span bluespy_get_connections(bluespy_device_id dev_id);
typedef struct bluespy_audiostream_id_span {
bluespy_audiostream_id* data;
uint64_t size;
} bluespy_audiostream_id_span;
BLUESPY_API bluespy_audiostream_id_span bluespy_get_audiostreams(bluespy_id id);
BLUESPY_API bluespy_device_id bluespy_get_next_device_id(bluespy_device_id id);
inline bluespy_device_id bluespy_get_first_device_id() {
return bluespy_get_next_device_id(BLUESPY_ID_INVALID);
}
BLUESPY_API bluespy_connection_id bluespy_get_next_connection_id(bluespy_connection_id id);
inline bluespy_connection_id bluespy_get_first_connection_id() {
return bluespy_get_next_connection_id(BLUESPY_ID_INVALID);
}
BLUESPY_API bluespy_audiostream_id bluespy_get_next_audiostream_id(bluespy_audiostream_id id);
inline bluespy_audiostream_id bluespy_get_first_audiostream_id() {
return bluespy_get_next_audiostream_id(BLUESPY_ID_INVALID);
}
typedef enum bluespy_event_types {
bluespy_event_bt_baseband,
bluespy_event_custom,
bluespy_event_proprietary_1,
bluespy_event_proprietary_2,
} bluespy_event_types;
BLUESPY_API void bluespy_register_event_callback(bluespy_event_types types,
void (*callback)(bluespy_event_id));
typedef void (*bluespy_cleanup_t)(void*);
BLUESPY_API void* bluespy_allocate(size_t bytes, bluespy_cleanup_t cleanup);
typedef struct bluespy_custom_event {
bluespy_event_id* children;
unsigned int n_children;
bluespy_query_value (*query)(const struct bluespy_custom_event* self, const char* query_str,
bool prefer_string);
} bluespy_custom_event;
BLUESPY_API bluespy_error bluespy_add_event(bluespy_custom_event* event);
typedef enum bluespy_latency_status {
BLUESPY_OK,
BLUESPY_ZEROS,
BLUESPY_NOT_ENOUGH_DATA,
BLUESPY_ENERGY_THRESHOLD,
BLUESPY_AMBIG_PEAK,
BLUESPY_PERIODIC,
BLUESPY_OTHER_ERROR
} bluespy_latency_status;
BLUESPY_API const char* bluespy_latency_status_string(bluespy_latency_status status);
typedef struct bluespy_latency_result {
int64_t time_difference_ns;
int64_t time_difference_min_ns;
int64_t time_difference_max_ns;
bluespy_time_point measurement_time;
bluespy_latency_status status;
double total_energy;
double peak_ratio;
bool three_measurements_expected;
} bluespy_latency_result;
typedef struct bluespy_audio_channel_t {
bluespy_audiostream_id ID;
uint8_t channel_index;
} bluespy_audio_channel_t;
BLUESPY_API bluespy_latency_result bluespy_measure_latency(bluespy_audio_channel_t channel0,
bluespy_audio_channel_t channel1,
bool include_pres_delay,
bluespy_time_point ts);
typedef struct bluespy_cis_lc3_config {
uint64_t codec_frames_per_SDU;
uint64_t presentation_delay_us;
uint32_t octets_per_codec_frame;
uint32_t frame_duration_us;
uint32_t sampling_frequency_Hz;
uint32_t audio_channel_allocation;
} bluespy_cis_lc3_config;
BLUESPY_API bluespy_error bluespy_set_cis_lc3_config(bluespy_audiostream_id id,
bluespy_cis_lc3_config* conf);
BLUESPY_API bluespy_error bluespy_play_to_audiopod_output(const char* filename, bool loop);
BLUESPY_API bluespy_error bluespy_stop_audio();
BLUESPY_API bluespy_error bluespy_mark_key_used(const char* key, size_t len);
typedef struct bluespy_key {
size_t length;
uint8_t* key;
} bluespy_key;
BLUESPY_API bluespy_error bluespy_list_keys(bluespy_key** keys, size_t* count);
BLUESPY_API bluespy_error bluespy_free_keys(bluespy_key* keys, size_t count);
/*------------------------------------------------------------------------------
* Bluespy Codec Interface Definitions
*----------------------------------------------------------------------------*/
#define BLUESPY_AUDIO_API_VERSION 1
typedef struct bluespy_audio_codec_lib_info {
int api_version; // <- Must be set to BLUESPY_AUDIO_API_VERSION
const char* codec_name; // <- Human-readable codec name (e.g., "AAC", "aptX", "LDAC")
} bluespy_audio_codec_lib_info;
typedef bluespy_audio_codec_lib_info (*bluespy_audio_codec_lib_init_t)(void);
typedef enum bluespy_codec_container {
BLUESPY_CODEC_AVDTP,
BLUESPY_CODEC_CIS,
BLUESPY_CODEC_BIS
} bluespy_codec_container;
typedef struct bluespy_audio_codec_info {
bluespy_codec_container container;
const void* config; // <- pointer to container-specific data block
uint32_t config_len; // <- length of container-specific block
} bluespy_audio_codec_info;
typedef enum bluespy_audio_sample_format {
BLUESPY_AUDIO_FORMAT_S16_LE = 0,
} bluespy_audio_sample_format;
typedef struct bluespy_audio_codec_decoded_format {
uint32_t sample_rate; // <- Sample rate in Hz
uint8_t n_channels; // Number of audio channels (1=mono, 2=stereo)
/* Format of the PCM samples. Currently only S16_LE (signed 16-bit, little endian) is supported.
*/
bluespy_audio_sample_format sample_format;
} bluespy_audio_codec_decoded_format;
BLUESPY_API void bluespy_add_audio(const uint8_t* pcm_data, uint32_t pcm_data_len,
bluespy_event_id source_id, uint32_t missing_samples);
typedef void (*bluespy_audio_decode_t)(uintptr_t context, const uint8_t* payload,
const uint32_t payload_len, bluespy_event_id event_id,
uint64_t sequence_number);
typedef void (*bluespy_audio_codec_deinit_t)(uintptr_t context);
typedef struct bluespy_audio_codec_funcs {
bluespy_audio_decode_t decode;
bluespy_audio_codec_deinit_t deinit;
} bluespy_audio_codec_funcs;
typedef struct bluespy_audio_codec_init_ret {
int error; // <- 0 = success; < 0 = failure.
bluespy_audio_codec_decoded_format format;
bluespy_audio_codec_funcs fns;
uintptr_t context_handle;
} bluespy_audio_codec_init_ret;
typedef bluespy_audio_codec_init_ret (*bluespy_audio_codec_init_t)(
bluespy_audiostream_id stream_id, const bluespy_audio_codec_info* info);
#ifdef __cplusplus
}
namespace bluespy {
template <class T, class... Args>
T* allocate(Args&&... args) {
T* p = static_cast<T*>(bluespy_allocate(sizeof(T), [](void* p) { ((T*)p)->~T(); }));
new (p) T(std::forward<Args>(args)...);
return p;
}
inline bluespy_error connect(uint32_t serial = -1) { return bluespy_connect(serial); }
} // namespace bluespy
#endif
#endif