Skip to content

Python API

API for controlling blueSPY from Python.

Provides functions for connecting to a moreph and loading existing captures. Also provides a packets object, which behaves like a list and can be used to access the packets in the current file.
len(packets) shows the number of available packets; packets[0] accesses the first packet.
The queries documented in the GUI can be accessed with attribute syntax, e.g. packets[0].summary.

Examples

To connect to a moreph with serial 00010100 and capture CL and LE:

python
import bluespy
from time import sleep

bluespy.connect(0x00010100)
bluespy.capture("example.pcapng", CL=True, LE=True)
sleep(20)
bluespy.stop_capture()
bluespy.disconnect()
print(f"Captured {len(bluespy.packets)} packets")
bluespy.close_file()

To load an existing capture and print the summary strings of all packets:

import bluespy
bluespy.load_file("example.pcapng")

for p in bluespy.packets:
    print(p.summary)

bluespy.close_file()

BluespyError

Bases: RuntimeError

! Exception showing why an operation failed.

Source code in application/bluespy.py
class BluespyError(RuntimeError):
    """! Exception showing why an operation failed."""

    def get_error(self):
        """Return the underlying error object."""
        return self.args[0]

get_error

get_error()

Return the underlying error object.

Source code in application/bluespy.py
def get_error(self):
    """Return the underlying error object."""
    return self.args[0]

Packets

Bases: object

List-like object representing the currently loaded baseband packets.

Source code in application/bluespy.py
class Packets(object):
    """List-like object representing the currently loaded baseband packets."""

    def __len__(self):
        """Current number of baseband packets captured"""
        return _libbluespy.bluespy_packet_count()

    def __getitem__(self, i):
        """!
        Get an event_id for a packet

        :param i: Index of packet, 0 <= i < __len__()
        :return: An event_id
        """
        i = int(i)
        if i < 0 or i >= _libbluespy.bluespy_packet_count():
            raise IndexError()
        return _libbluespy.bluespy_get_baseband(i)

__getitem__

__getitem__(i)

! Get an event_id for a packet

Parameters:

Name Type Description Default
i

Index of packet, 0 <= i < len()

required

Returns:

Type Description

An event_id

Source code in application/bluespy.py
def __getitem__(self, i):
    """!
    Get an event_id for a packet

    :param i: Index of packet, 0 <= i < __len__()
    :return: An event_id
    """
    i = int(i)
    if i < 0 or i >= _libbluespy.bluespy_packet_count():
        raise IndexError()
    return _libbluespy.bluespy_get_baseband(i)

__len__

__len__()

Current number of baseband packets captured

Source code in application/bluespy.py
def __len__(self):
    """Current number of baseband packets captured"""
    return _libbluespy.bluespy_packet_count()

audiopod_options

Bases: object

! Audiopod capture options

Source code in application/bluespy.py
class audiopod_options(object):
    """! Audiopod capture options"""
    def __init__(self,
        channels=audio_channel.STEREO,
        output=audio_connect.NOAUDIO,
        input=audio_connect.NOAUDIO,
        bias=audio_bias.OFF,
        sample_rate=0,
        current_probe=False,
        LA_low_voltage = 0.0,
        LA_high_voltage = 0.0,
        power_supply_V=0.0,
        VIO_dV = 0.0,
        second_I2S_input=False,
        AGC=False,
        DRC=False,
        vol_in_left = 0.0,
        vol_in_right = 0.0,
        vol_out_left = 0.0,
        vol_out_right = 0.0,
    ):
        """
        :param channels: Audiopod Channels
        :param output: Which audiopod port is used for output
        :param input: Which audiopod port is used for intput
        :param bias: Audiopod bias
        :param sample_rate: Audiopod sample rate
            Allowed values are: 8'000, 11'025, 16'000, 22'050, 32'000, 44'100, 48'000, 88'200, 96'000, 176'400, 192'000
        :param current_probe: Enable current probe
        :param LA_low_voltage: Logic Low Voltage. Must be within the [0.0, 3.3] range.
        :param LA_high_voltage: Logic High Voltage. Must be within the [0.0, 3.3] range.
            Allowed values for Audiopod_Logic(Low/High)Voltage are from 0.0 to 3.3
        :param power_supply_V: Power supply in volts
            Allowed values are from 0.6 to 5.0
        :param VIO_dV: VIO in deciVolts
        :param second_I2S_input: Enable a second I2S input, output must be set to BLUESPY_NO_AUDIO
        :param AGC: AGC
        :param DRC: DRC
        :param vol_in_left: Input volume (Left)
        :param vol_in_right: Input volume (Right)
        :param vol_out_left: Output volume (Left)
        :param vol_out_right: Output volume (Right)
        """
        object.__setattr__(self, "p", _libbluespy.bluespy_capture_audiopod_options_alloc())
        self.p.contents.sample_rate = sample_rate
        self.p.contents.channels = channels
        self.p.contents.output = output
        self.p.contents.input = input
        self.p.contents.bias = bias
        self.p.contents.current_probe = current_probe
        self.p.contents.LA_low_voltage = LA_low_voltage
        self.p.contents.LA_high_voltage = LA_high_voltage
        self.p.contents.power_supply_V = power_supply_V
        self.p.contents.VIO_dV = VIO_dV
        self.p.contents.second_I2S_input = second_I2S_input
        self.p.contents.AGC = AGC
        self.p.contents.DRC = DRC
        self.p.contents.vol_in_left = vol_in_left
        self.p.contents.vol_in_right = vol_in_right
        self.p.contents.vol_out_left = vol_out_left
        self.p.contents.vol_out_right = vol_out_right
    def __del__(self):
        _libbluespy.bluespy_delete(self.p)
    def __getattr__(self, name):
        if name == "p":
            return self.__getattribute__("p")
        return getattr(self.p.contents, name)
    def __setattr__(self, name, val):
        self.p.contents.__setattr__(name,val)

__init__

__init__(channels=audio_channel.STEREO, output=audio_connect.NOAUDIO, input=audio_connect.NOAUDIO, bias=audio_bias.OFF, sample_rate=0, current_probe=False, LA_low_voltage=0.0, LA_high_voltage=0.0, power_supply_V=0.0, VIO_dV=0.0, second_I2S_input=False, AGC=False, DRC=False, vol_in_left=0.0, vol_in_right=0.0, vol_out_left=0.0, vol_out_right=0.0)

Parameters:

Name Type Description Default
channels

Audiopod Channels

STEREO
output

Which audiopod port is used for output

NOAUDIO
input

Which audiopod port is used for intput

NOAUDIO
bias

Audiopod bias

OFF
sample_rate

Audiopod sample rate Allowed values are: 8'000, 11'025, 16'000, 22'050, 32'000, 44'100, 48'000, 88'200, 96'000, 176'400, 192'000

0
current_probe

Enable current probe

False
LA_low_voltage

Logic Low Voltage. Must be within the [0.0, 3.3] range.

0.0
LA_high_voltage

Logic High Voltage. Must be within the [0.0, 3.3] range. Allowed values for Audiopod_Logic(Low/High)Voltage are from 0.0 to 3.3

0.0
power_supply_V

Power supply in volts Allowed values are from 0.6 to 5.0

0.0
VIO_dV

VIO in deciVolts

0.0
second_I2S_input

Enable a second I2S input, output must be set to BLUESPY_NO_AUDIO

False
AGC

AGC

False
DRC

DRC

False
vol_in_left

Input volume (Left)

0.0
vol_in_right

Input volume (Right)

0.0
vol_out_left

Output volume (Left)

0.0
vol_out_right

Output volume (Right)

0.0
Source code in application/bluespy.py
def __init__(self,
    channels=audio_channel.STEREO,
    output=audio_connect.NOAUDIO,
    input=audio_connect.NOAUDIO,
    bias=audio_bias.OFF,
    sample_rate=0,
    current_probe=False,
    LA_low_voltage = 0.0,
    LA_high_voltage = 0.0,
    power_supply_V=0.0,
    VIO_dV = 0.0,
    second_I2S_input=False,
    AGC=False,
    DRC=False,
    vol_in_left = 0.0,
    vol_in_right = 0.0,
    vol_out_left = 0.0,
    vol_out_right = 0.0,
):
    """
    :param channels: Audiopod Channels
    :param output: Which audiopod port is used for output
    :param input: Which audiopod port is used for intput
    :param bias: Audiopod bias
    :param sample_rate: Audiopod sample rate
        Allowed values are: 8'000, 11'025, 16'000, 22'050, 32'000, 44'100, 48'000, 88'200, 96'000, 176'400, 192'000
    :param current_probe: Enable current probe
    :param LA_low_voltage: Logic Low Voltage. Must be within the [0.0, 3.3] range.
    :param LA_high_voltage: Logic High Voltage. Must be within the [0.0, 3.3] range.
        Allowed values for Audiopod_Logic(Low/High)Voltage are from 0.0 to 3.3
    :param power_supply_V: Power supply in volts
        Allowed values are from 0.6 to 5.0
    :param VIO_dV: VIO in deciVolts
    :param second_I2S_input: Enable a second I2S input, output must be set to BLUESPY_NO_AUDIO
    :param AGC: AGC
    :param DRC: DRC
    :param vol_in_left: Input volume (Left)
    :param vol_in_right: Input volume (Right)
    :param vol_out_left: Output volume (Left)
    :param vol_out_right: Output volume (Right)
    """
    object.__setattr__(self, "p", _libbluespy.bluespy_capture_audiopod_options_alloc())
    self.p.contents.sample_rate = sample_rate
    self.p.contents.channels = channels
    self.p.contents.output = output
    self.p.contents.input = input
    self.p.contents.bias = bias
    self.p.contents.current_probe = current_probe
    self.p.contents.LA_low_voltage = LA_low_voltage
    self.p.contents.LA_high_voltage = LA_high_voltage
    self.p.contents.power_supply_V = power_supply_V
    self.p.contents.VIO_dV = VIO_dV
    self.p.contents.second_I2S_input = second_I2S_input
    self.p.contents.AGC = AGC
    self.p.contents.DRC = DRC
    self.p.contents.vol_in_left = vol_in_left
    self.p.contents.vol_in_right = vol_in_right
    self.p.contents.vol_out_left = vol_out_left
    self.p.contents.vol_out_right = vol_out_right

audiostream_id

Bases: id

! An object referencing a audio stream.

Do not make your own, only get these from the audio stream id functions. Audio Stream IDs are ordered arbitrarily After running close_file(), do not call any methods on any existing audiostream_id objects.

Source code in application/bluespy.py
class audiostream_id(id):
    """!
    An object referencing a audio stream.

    Do not make your own, only get these from the audio stream id functions.
    Audio Stream IDs are ordered arbitrarily
    After running close_file(), do not call any methods on any existing audiostream_id objects.
    """

connection_id

Bases: id

! An object referencing a connection.

Do not make your own, only get these from the connection id functions. Connection IDs are ordered arbitrarily After running close_file(), do not call any methods on any existing connection_id objects.

Source code in application/bluespy.py
class connection_id(id):
    """!
    An object referencing a connection.

    Do not make your own, only get these from the connection id functions.
    Connection IDs are ordered arbitrarily
    After running close_file(), do not call any methods on any existing connection_id objects.
    """
    def get_audio_streams(self):
        """! Get the audio streams
        :return: Array of audio streams IDs"""
        stream_id_span = _libbluespy.bluespy_get_audiostreams(self)
        return [stream_id_span.data[i] for i in range(stream_id_span.size)]

get_audio_streams

get_audio_streams()

! Get the audio streams

Returns:

Type Description

Array of audio streams IDs

Source code in application/bluespy.py
def get_audio_streams(self):
    """! Get the audio streams
    :return: Array of audio streams IDs"""
    stream_id_span = _libbluespy.bluespy_get_audiostreams(self)
    return [stream_id_span.data[i] for i in range(stream_id_span.size)]

device_id

Bases: id

! An object referencing a device.

Do not make your own, only get these from the device id functions. Device IDs are ordered arbitrarily After running close_file(), do not call any methods on any existing device_id objects.

Source code in application/bluespy.py
class device_id(id):
    """!
    An object referencing a device.

    Do not make your own, only get these from the device id functions.
    Device IDs are ordered arbitrarily
    After running close_file(), do not call any methods on any existing device_id objects.
    """
    def get_connections(self):
        """! Get the connections
        :return: Array of connection IDs"""
        conn_id_span = _libbluespy.bluespy_get_connections(self)
        return [conn_id_span.data[i] for i in range(conn_id_span.size)]

    def get_audio_streams(self):
        """! Get the audio streams
        :return: Array of audio streams IDs"""
        stream_id_span = _libbluespy.bluespy_get_audiostreams(self)
        return [stream_id_span.data[i] for i in range(stream_id_span.size)]

get_audio_streams

get_audio_streams()

! Get the audio streams

Returns:

Type Description

Array of audio streams IDs

Source code in application/bluespy.py
def get_audio_streams(self):
    """! Get the audio streams
    :return: Array of audio streams IDs"""
    stream_id_span = _libbluespy.bluespy_get_audiostreams(self)
    return [stream_id_span.data[i] for i in range(stream_id_span.size)]

get_connections

get_connections()

! Get the connections

Returns:

Type Description

Array of connection IDs

Source code in application/bluespy.py
def get_connections(self):
    """! Get the connections
    :return: Array of connection IDs"""
    conn_id_span = _libbluespy.bluespy_get_connections(self)
    return [conn_id_span.data[i] for i in range(conn_id_span.size)]

error

Bases: c_int

! Return type showing why an operation failed.

Evaluates to True if the operation succeeded, else False. str() and repr() give an error string, .value gives an error code.

Source code in application/bluespy.py
class error(_ct.c_int):
    """! Return type showing why an operation failed.

    Evaluates to True if the operation succeeded, else False.
    str() and repr() give an error string, .value gives an error code.
    """

    def __str__(self):
        return _libbluespy.bluespy_error_string(self.value).decode("utf-8")

    def __repr__(self):
        return "{}: {}".format(self.value, self.__str__()) if self.value else ""

    def __bool__(self):
        return self.value == 0     

event_id

Bases: id

! An object referencing a loaded packet.

Do not make your own, only get these from the 'packets' object. After running close_file(), do not call any methods on any existing event_id objects.

Any query (see the documentation or Help->Query List in the GUI) can be accessed as an attribute on this object

Source code in application/bluespy.py
class event_id(id):
    """!
    An object referencing a loaded packet.

    Do not make your own, only get these from the 'packets' object.
    After running close_file(), do not call any methods on any existing event_id objects.

    Any query (see the documentation or Help->Query List in the GUI) can be accessed as an attribute on this object
    """

    def parent(self):
        """! Get the a higher layer packet that contains this one.
        e.g. if this is a baseband data packet get the L2CAP packet it is part of.

        :return: event_id"""
        return _libbluespy.bluespy_get_parent(self)

    def children(self):
        """! Get all constituent packets of this packet.
        e.g. if this is an L2CAP packet

        :return: List of event_ids"""
        count = _ct.c_uint32()
        c = _libbluespy.bluespy_get_children(self, _ct.byref(count))
        return (
            list(_ct.cast(c, _ct.POINTER(event_id * count.value)).contents)
            if count.value > 0
            else []
        )

children

children()

! Get all constituent packets of this packet. e.g. if this is an L2CAP packet

Returns:

Type Description

List of event_ids

Source code in application/bluespy.py
def children(self):
    """! Get all constituent packets of this packet.
    e.g. if this is an L2CAP packet

    :return: List of event_ids"""
    count = _ct.c_uint32()
    c = _libbluespy.bluespy_get_children(self, _ct.byref(count))
    return (
        list(_ct.cast(c, _ct.POINTER(event_id * count.value)).contents)
        if count.value > 0
        else []
    )

parent

parent()

! Get the a higher layer packet that contains this one. e.g. if this is a baseband data packet get the L2CAP packet it is part of.

Returns:

Type Description

event_id

Source code in application/bluespy.py
def parent(self):
    """! Get the a higher layer packet that contains this one.
    e.g. if this is a baseband data packet get the L2CAP packet it is part of.

    :return: event_id"""
    return _libbluespy.bluespy_get_parent(self)

file_id

Bases: c_uint64

! An object referencing a loaded file.

Do not make your own, only get these from the 'files' object.

Source code in application/bluespy.py
class file_id(_ct.c_uint64):
    """!
    An object referencing a loaded file.

    Do not make your own, only get these from the 'files' object.
    """

    def __bool__(self):
        """! Returns true if this is a valid packet"""
        return self.value != 0xFFFFFFFFFFFFFFFF

    def __str__(self):
        """! Returns root filename"""
        return _libbluespy.bluespy_get_filter_file_name(self).decode("utf-8")

__bool__

__bool__()

! Returns true if this is a valid packet

Source code in application/bluespy.py
def __bool__(self):
    """! Returns true if this is a valid packet"""
    return self.value != 0xFFFFFFFFFFFFFFFF

__str__

__str__()

! Returns root filename

Source code in application/bluespy.py
def __str__(self):
    """! Returns root filename"""
    return _libbluespy.bluespy_get_filter_file_name(self).decode("utf-8")

i2s_options

Bases: object

! I2S capture options

Source code in application/bluespy.py
class i2s_options(object):
    """! I2S capture options"""
    def __init__(self,
        SCLK_line=0,
        WS_line=0,
        SD_line=0,
        n_channels=0,
        bits_per_ch=0,
        sample_on_rising_edge=False,
        first_chan_follows_WS_high=False,
        one_sample_delay=False,
        MSB_first=False,
        DSP_Mode=False,
        master=False,
    ):   
        """
        :param SCLK_line: SCLK line for each interface. Valid values are [0,15]
        :param WS_line: WS line for each interface. Valid values are [0,15]
        :param SD_line: SD line for each interface. Valid values are [0,15]
        :param n_channels: Number of channels. Valid values are [1,16]
        :param bits_per_ch: Number of bits per channel. Valid values are [1,32]
        :param sample_on_rising_edge: Whether to sample on rising edges
        :param first_chan_follows_WS_high: Whether the first channel follows WS High
        :param one_sample_delay: Whether to delay by one sample
        :param MSB_first: MSB first
        :param DSP_Mode: DSP Mode
        :param master: Master
        """
        object.__setattr__(self, "p", _libbluespy.bluespy_capture_i2s_options_alloc())
        self.p.contents.SCLK_line = SCLK_line
        self.p.contents.WS_line = WS_line
        self.p.contents.SD_line = SD_line
        self.p.contents.n_channels = n_channels
        self.p.contents.bits_per_ch = bits_per_ch
        self.p.contents.sample_on_rising_edge = sample_on_rising_edge
        self.p.contents.first_chan_follows_WS_high = first_chan_follows_WS_high
        self.p.contents.one_sample_delay = one_sample_delay
        self.p.contents.MSB_first = MSB_first
        self.p.contents.DSP_mode = DSP_Mode
        self.p.contents.master = master
    def __del__(self):
        _libbluespy.bluespy_delete(self.p)     
    def __getattr__(self, name):
        if name == "p":
            return self.__getattribute__("p")
        return getattr(self.p.contents, name)
    def __setattr__(self, name, val):
        self.p.contents.__setattr__(name,val)    

__init__

__init__(SCLK_line=0, WS_line=0, SD_line=0, n_channels=0, bits_per_ch=0, sample_on_rising_edge=False, first_chan_follows_WS_high=False, one_sample_delay=False, MSB_first=False, DSP_Mode=False, master=False)

Parameters:

Name Type Description Default
SCLK_line

SCLK line for each interface. Valid values are [0,15]

0
WS_line

WS line for each interface. Valid values are [0,15]

0
SD_line

SD line for each interface. Valid values are [0,15]

0
n_channels

Number of channels. Valid values are [1,16]

0
bits_per_ch

Number of bits per channel. Valid values are [1,32]

0
sample_on_rising_edge

Whether to sample on rising edges

False
first_chan_follows_WS_high

Whether the first channel follows WS High

False
one_sample_delay

Whether to delay by one sample

False
MSB_first

MSB first

False
DSP_Mode

DSP Mode

False
master

Master

False
Source code in application/bluespy.py
def __init__(self,
    SCLK_line=0,
    WS_line=0,
    SD_line=0,
    n_channels=0,
    bits_per_ch=0,
    sample_on_rising_edge=False,
    first_chan_follows_WS_high=False,
    one_sample_delay=False,
    MSB_first=False,
    DSP_Mode=False,
    master=False,
):   
    """
    :param SCLK_line: SCLK line for each interface. Valid values are [0,15]
    :param WS_line: WS line for each interface. Valid values are [0,15]
    :param SD_line: SD line for each interface. Valid values are [0,15]
    :param n_channels: Number of channels. Valid values are [1,16]
    :param bits_per_ch: Number of bits per channel. Valid values are [1,32]
    :param sample_on_rising_edge: Whether to sample on rising edges
    :param first_chan_follows_WS_high: Whether the first channel follows WS High
    :param one_sample_delay: Whether to delay by one sample
    :param MSB_first: MSB first
    :param DSP_Mode: DSP Mode
    :param master: Master
    """
    object.__setattr__(self, "p", _libbluespy.bluespy_capture_i2s_options_alloc())
    self.p.contents.SCLK_line = SCLK_line
    self.p.contents.WS_line = WS_line
    self.p.contents.SD_line = SD_line
    self.p.contents.n_channels = n_channels
    self.p.contents.bits_per_ch = bits_per_ch
    self.p.contents.sample_on_rising_edge = sample_on_rising_edge
    self.p.contents.first_chan_follows_WS_high = first_chan_follows_WS_high
    self.p.contents.one_sample_delay = one_sample_delay
    self.p.contents.MSB_first = MSB_first
    self.p.contents.DSP_mode = DSP_Mode
    self.p.contents.master = master

id

Bases: c_uint64

! An object referencing a loaded event, device, connection, or audio stream.

Do not make your own, only get these from the bluespy functions. After running close_file(), do not call any methods on any existing event_id objects.

Any query (see the documentation or Help->Query List in the GUI) can be accessed as an attribute on this object

Source code in application/bluespy.py
class id(_ct.c_uint64):
    """!
    An object referencing a loaded event, device, connection, or audio stream.

    Do not make your own, only get these from the bluespy functions.
    After running close_file(), do not call any methods on any existing event_id objects.

    Any query (see the documentation or Help->Query List in the GUI) can be accessed as an attribute on this object
    """
    def __bool__(self):
        """! Returns true if this is a valid ID"""
        return self.value != 0xFFFFFFFFFFFFFFFF

    def query(self, name):
        """!
        Get a query from this object, and return it in its preferred form

        :param name: A query string, e.g. "summary"
        :return: A string, int or bool depending on the query"""
        r = _libbluespy.bluespy_query_get(self.value, name.encode("utf-8"))

        if r.type == query_type.none:
            return None
        if r.type == query_type.bool_:
            return r.b
        if r.type == query_type.int_:
            return r.i
        if r.type == query_type.string:
            return r.s.decode("utf-8")
        if r.type == query_type.bytes_:
            return _ct.string_at(r.bytes.data, r.bytes.size)
        if r.type == query_type.double:
            return r.d
        if r.type == query_type.id:
            return id(r.id)

        raise AttributeError()

    def __getattr__(self, name):
        """Access queries as attributes"""
        return self.query(name)

    def query_str(self, name):
        """!
        Get a query from this object, and return it as a string

        :param name: A query string, e.g. "summary"
        :return: string"""
        return _libbluespy.bluespy_query(self.value, name.encode("utf-8")).decode(
            "utf-8"
        )

    def query_int(self, name):
        """!
        Get a query from this object, and return it as an integer if possible

        :param name: A query string, e.g. "summary"
        :return: int"""
        return _libbluespy.bluespy_query_int(self.value, name.encode("utf-8"))

    def query_bool(self, name):
        """!
        Get a query from this object, and return it as a bool if possible

        :param name: A query string, e.g. "acked"
        :return: bool"""
        return _libbluespy.bluespy_query_bool(self.value, name.encode("utf-8"))

__bool__

__bool__()

! Returns true if this is a valid ID

Source code in application/bluespy.py
def __bool__(self):
    """! Returns true if this is a valid ID"""
    return self.value != 0xFFFFFFFFFFFFFFFF

__getattr__

__getattr__(name)

Access queries as attributes

Source code in application/bluespy.py
def __getattr__(self, name):
    """Access queries as attributes"""
    return self.query(name)

query

query(name)

! Get a query from this object, and return it in its preferred form

Parameters:

Name Type Description Default
name

A query string, e.g. "summary"

required

Returns:

Type Description

A string, int or bool depending on the query

Source code in application/bluespy.py
def query(self, name):
    """!
    Get a query from this object, and return it in its preferred form

    :param name: A query string, e.g. "summary"
    :return: A string, int or bool depending on the query"""
    r = _libbluespy.bluespy_query_get(self.value, name.encode("utf-8"))

    if r.type == query_type.none:
        return None
    if r.type == query_type.bool_:
        return r.b
    if r.type == query_type.int_:
        return r.i
    if r.type == query_type.string:
        return r.s.decode("utf-8")
    if r.type == query_type.bytes_:
        return _ct.string_at(r.bytes.data, r.bytes.size)
    if r.type == query_type.double:
        return r.d
    if r.type == query_type.id:
        return id(r.id)

    raise AttributeError()

query_bool

query_bool(name)

! Get a query from this object, and return it as a bool if possible

Parameters:

Name Type Description Default
name

A query string, e.g. "acked"

required

Returns:

Type Description

bool

Source code in application/bluespy.py
def query_bool(self, name):
    """!
    Get a query from this object, and return it as a bool if possible

    :param name: A query string, e.g. "acked"
    :return: bool"""
    return _libbluespy.bluespy_query_bool(self.value, name.encode("utf-8"))

query_int

query_int(name)

! Get a query from this object, and return it as an integer if possible

Parameters:

Name Type Description Default
name

A query string, e.g. "summary"

required

Returns:

Type Description

int

Source code in application/bluespy.py
def query_int(self, name):
    """!
    Get a query from this object, and return it as an integer if possible

    :param name: A query string, e.g. "summary"
    :return: int"""
    return _libbluespy.bluespy_query_int(self.value, name.encode("utf-8"))

query_str

query_str(name)

! Get a query from this object, and return it as a string

Parameters:

Name Type Description Default
name

A query string, e.g. "summary"

required

Returns:

Type Description

string

Source code in application/bluespy.py
def query_str(self, name):
    """!
    Get a query from this object, and return it as a string

    :param name: A query string, e.g. "summary"
    :return: string"""
    return _libbluespy.bluespy_query(self.value, name.encode("utf-8")).decode(
        "utf-8"
    )

latency_status

Bases: c_int

! Return log level

Source code in application/bluespy.py
class latency_status(_ct.c_int):
    """! Return log level"""
    def __str__(self):

        return _libbluespy.bluespy_latency_status_string(self.value).decode("utf-8")

    def __repr__(self):
        return "{}: {}".format(self.value, self.__str__()) if self.value else ""

    def __bool__(self):
        return self.value == 0

log_level

Bases: c_int

! Return log level

Source code in application/bluespy.py
class log_level(_ct.c_int):
    """! Return log level"""
    PASS = 0x00
    WARN = 0x20
    INFO = 0x40
    DEBUG = 0x60
    ERROR = 0x80

logic_rate

Bases: c_int

! Return logic rate

Source code in application/bluespy.py
class logic_rate(_ct.c_int):
    """! Return logic rate"""
    high = 0
    medium = 1
    rate = 2

time_point

Bases: c_int64

! Represents the time in nanoseconds since epoch 1970/01/01 00:00 UTC

Source code in application/bluespy.py
class time_point(_ct.c_int64):
    """! Represents the time in nanoseconds since epoch 1970/01/01 00:00 UTC"""

    def __init__(self, ts=0x7fffffffffffffff):
        self.value = ts

    def __bool__(self):
        """! Returns if it's a valid time"""
        return self.value != 0x7fffffffffffffff

    def __str__(self):
        """! Returns the string representation of the time"""
        return _libbluespy.bluespy_print_time(self).decode("utf-8")

__bool__

__bool__()

! Returns if it's a valid time

Source code in application/bluespy.py
def __bool__(self):
    """! Returns if it's a valid time"""
    return self.value != 0x7fffffffffffffff

__str__

__str__()

! Returns the string representation of the time

Source code in application/bluespy.py
def __str__(self):
    """! Returns the string representation of the time"""
    return _libbluespy.bluespy_print_time(self).decode("utf-8")
add_link_key(key, addr0=0, addr1=0)

! Add a link key for decryption

Parameters:

Name Type Description Default
key

Link key as a 16-byte bytes object

required
addr0

(Optional) MAC address of central as a 64-bit integer

0
addr1

(Optional) MAC address of peripheral as a 64-bit integer

0
Source code in application/bluespy.py
def add_link_key(key, addr0=0, addr1=0):
    """! Add a link key for decryption

    :param key: Link key as a 16-byte bytes object
    :param addr0: (Optional) MAC address of central as a 64-bit integer
    :param addr1: (Optional) MAC address of peripheral as a 64-bit integer
    """
    _handle_error(_libbluespy.bluespy_add_link_key(key, addr0, addr1))

add_log_message

add_log_message(level, message, ts=9223372036854775807)

! Adds a log message into the running capture

Parameters:

Name Type Description Default
level

The Log Level.

required
message

The log message content.

required
ts

The time of the log message. ts=invalid means the time will be set to the present.

9223372036854775807

Raises:

Type Description
BluespyError

Exception in the bluespy library

Source code in application/bluespy.py
def add_log_message(level, message, ts=0x7fffffffffffffff):
    """! Adds a log message into the running capture

    :param level: The Log Level.
    :param message: The log message content.
    :param ts: The time of the log message. ts=invalid means the time will be set to the present.

    :exception BluespyError: Exception in the bluespy library"""
    _handle_error(_libbluespy.bluespy_add_log_message(level, message.encode("utf-8"), ts))

add_to_filter_file

add_to_filter_file(file_, event_)

! Add an event to a filter file

Parameters:

Name Type Description Default
file_

File ID

required
event_

Event ID

required

Raises:

Type Description
BluespyError

Exception in the bluespy library

Source code in application/bluespy.py
def add_to_filter_file(file_, event_):
    """! Add an event to a filter file

    :param file_: File ID
    :param event_: Event ID

    :exception BluespyError: Exception in the bluespy library"""
    _handle_error(_libbluespy.bluespy_add_to_filter_file(file_, event_))

capture

capture(filename, CL=False, LE=False, QHS=False, _15_4=False, wifi=False, MHDT_CL=False, MHDT_LE=False, Dukosi=False, Varjo=False, CS=False, Audiopod=None, I2S=[None, None], spectrum=0, logic_mask=0, logic_use_external_vref=True, logic_rate=0, HDT=False, Proprietary_1=False, Proprietary_2=False)

! Start a new capture in filename

Parameters:

Name Type Description Default
filename

Path to store capture in

required
CL

Enable Bluetooth Classic capture

False
LE

Enable Bluetooth LE capture

False
QHS

Enable Qualcomm High Speed capture

False
_15_4

Enable 802.15.4 capture

False
wifi

Enable WiFi capture

False
MHDT_CL

Enable MediaTek mHDT Classic capture

False
MHDT_LE

Enable MediaTek mHDT LE capture

False
Dukosi

Enable Dukosi capture

False
Varjo

Enable Varjo capture

False
CS

Enable Channel-Sounding capture

False
Audiopod

Audiopod options. Providing an audiopod_options struct will enable audiopod

None
I2S

I2S options. Providing i2s_options structs will enable I2S

[None, None]
spectrum

Spectrum capture interval in microseconds. 0 means disabled. Allowed values are: 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000.

0
logic_mask

32-bit mask enabling logic lines

0
logic_use_external_vref

Use External or Internal vref

True
logic_rate

Low, Medium, or High logic rate

0
Proprietary_1

Enable Proprietary_1 capture

False
Proprietary_2

Enable Proprietary_2 capture

False

Raises:

Type Description
BluespyError

Exception in the bluespy library

Source code in application/bluespy.py
def capture(
    filename,
    CL=False,
    LE=False,
    QHS=False,
    _15_4=False,
    wifi=False,
    MHDT_CL=False,
    MHDT_LE=False,
    Dukosi=False,
    Varjo=False,
    CS=False,
    Audiopod=None,
    I2S = [None,None],
    spectrum=0,
    logic_mask=0x0000,
    logic_use_external_vref=True,
    logic_rate=0,
    HDT=False,
    Proprietary_1=False,
    Proprietary_2=False,
):
    """! Start a new capture in filename

    :param filename: Path to store capture in
    :param CL: Enable Bluetooth Classic capture
    :param LE: Enable Bluetooth LE capture
    :param QHS: Enable Qualcomm High Speed capture
    :param _15_4: Enable 802.15.4 capture
    :param wifi: Enable WiFi capture
    :param MHDT_CL: Enable MediaTek mHDT Classic capture
    :param MHDT_LE: Enable MediaTek mHDT LE capture
    :param Dukosi: Enable Dukosi capture
    :param Varjo: Enable Varjo capture
    :param CS: Enable Channel-Sounding capture

    :param Audiopod: Audiopod options. Providing an audiopod_options struct will enable audiopod
    :param I2S: I2S options. Providing i2s_options structs will enable I2S

    :param spectrum: Spectrum capture interval in microseconds. 0 means disabled.
        Allowed values are: 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000.
    :param logic_mask: 32-bit mask enabling logic lines
    :param logic_use_external_vref: Use External or Internal vref
    :param logic_rate: Low, Medium, or High logic rate

    :param Proprietary_1: Enable Proprietary_1 capture
    :param Proprietary_2: Enable Proprietary_2 capture

    :exception BluespyError: Exception in the bluespy library"""
    opts = _libbluespy.bluespy_capture_options_alloc()
    opts.contents.enable_CL = CL
    opts.contents.enable_LE = LE
    opts.contents.enable_HDT = HDT
    opts.contents.enable_QHS = QHS
    opts.contents.enable_15_4 = _15_4
    opts.contents.enable_wifi = wifi
    opts.contents.enable_MHDT_CL = MHDT_CL
    opts.contents.enable_MHDT_LE = MHDT_LE
    opts.contents.enable_Dukosi = Dukosi
    opts.contents.enable_Varjo = Varjo
    opts.contents.enable_Channel_Sounding = CS
    opts.contents.spectrum_period = spectrum
    opts.contents.logic_mask = logic_mask
    opts.contents.logic_use_external_vref = logic_use_external_vref
    opts.contents.logic_rate = logic_rate
    opts.contents.enable_Proprietary_1 = Proprietary_1
    opts.contents.enable_Proprietary_2 = Proprietary_2

    if Audiopod != None:
        opts.contents.audiopod_opts = Audiopod.p

    for i in range(2):
        if I2S[i] != None:
            opts.contents.i2s_opts[i] = I2S[i].p

    _handle_error(
        _libbluespy.bluespy_capture(
            filename.encode("utf-8"), opts,
        )
    )
    _libbluespy.bluespy_delete(opts)
    atexit.register(close_file)
    atexit.register(stop_capture)

capture_multiple

capture_multiple(filename, CL=[], LE=[], wifi=[], QHS=False, _15_4=False, MHDT_CL=False, MHDT_LE=False, Dukosi=False, Varjo=False, CS=False, Audiopod=None, I2S=[None, None], spectrum=0, logic_mask=0, logic_use_external_vref=True, logic_rate=0, HDT=[], Proprietary_1=False, Proprietary_2=False)

! Start a new capture in filename

Parameters:

Name Type Description Default
filename

Path to store capture in

required
CL

Enable Bluetooth Classic capture, list of bools, one for each Moreph

[]
LE

Enable Bluetooth LE capture, list of bools, one for each Moreph

[]
wifi

Enable WiFi capture, list of bools, one for each Moreph

[]
QHS

Enable Qualcomm High Speed capture

False
_15_4

Enable 802.15.4 capture

False
MHDT_CL

Enable MediaTek mHDT Classic capture

False
MHDT_LE

Enable MediaTek mHDT LE capture

False
Dukosi

Enable Dukosi capture

False
Varjo

Enable Varjo capture

False
CS

Enable Channel-Sounding capture

False
Audiopod

Audiopod options. Providing an audiopod_options struct will enable audiopod

None
I2S

I2S options. Providing i2s_options structs will enable I2S

[None, None]
spectrum

Spectrum capture interval in microseconds. 0 means disabled. Allowed values are: 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000.

0
Proprietary_1

Enable Proprietary_1 capture

False
Proprietary_2

Enable Proprietary_2 capture

False

Raises:

Type Description
BluespyError

Exception in the bluespy library

Source code in application/bluespy.py
def capture_multiple(

    filename,
    CL=[],
    LE=[],
    wifi=[],
    QHS=False,
    _15_4=False,
    MHDT_CL=False,
    MHDT_LE=False,
    Dukosi=False,
    Varjo=False,
    CS=False,
    Audiopod=None,
    I2S = [None,None],
    spectrum=0,
    logic_mask=0x0000,
    logic_use_external_vref=True,
    logic_rate=0,
    HDT=[],
    Proprietary_1=False,
    Proprietary_2=False,
):
    """! Start a new capture in filename

    :param filename: Path to store capture in
    :param CL: Enable Bluetooth Classic capture, list of bools, one for each Moreph
    :param LE: Enable Bluetooth LE capture, list of bools, one for each Moreph
    :param wifi: Enable WiFi capture, list of bools, one for each Moreph
    :param QHS: Enable Qualcomm High Speed capture
    :param _15_4: Enable 802.15.4 capture
    :param MHDT_CL: Enable MediaTek mHDT Classic capture
    :param MHDT_LE: Enable MediaTek mHDT LE capture
    :param Dukosi: Enable Dukosi capture
    :param Varjo: Enable Varjo capture
    :param CS: Enable Channel-Sounding capture

    :param Audiopod: Audiopod options. Providing an audiopod_options struct will enable audiopod
    :param I2S: I2S options. Providing i2s_options structs will enable I2S

    :param spectrum: Spectrum capture interval in microseconds. 0 means disabled.
        Allowed values are: 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000.

    :param Proprietary_1: Enable Proprietary_1 capture
    :param Proprietary_2: Enable Proprietary_2 capture

    :exception BluespyError: Exception in the bluespy library"""

    opts = _libbluespy.bluespy_capture_options_alloc()

    if len(CL) > 0:
        opts.contents.enable_CL = CL[0]
        for i in range(1,min(len(CL),32)):
            opts.contents.multi_moreph_opts[i-1].enable_CL = CL[i]
    if len(LE) > 0:
        opts.contents.enable_LE = LE[0]
        for i in range(1,min(len(LE),32)):
            opts.contents.multi_moreph_opts[i-1].enable_LE = LE[i]
    if len(HDT) > 0:
        opts.contents.enable_HDT = HDT[0]
        for i in range(1,min(len(HDT),hw_count)):
            opts.contents.multi_moreph_opts[i-1].enable_HDT = HDT[i]
    if len(wifi) > 0:
        opts.contents.enable_wifi = wifi[0]
        for i in range(1,min(len(wifi),32)):
            opts.contents.multi_moreph_opts[i-1].enable_wifi = wifi[i]


    opts.contents.enable_QHS = QHS
    opts.contents.enable_15_4 = _15_4
    opts.contents.enable_MHDT_CL = MHDT_CL
    opts.contents.enable_MHDT_LE = MHDT_LE
    opts.contents.enable_Dukosi = Dukosi
    opts.contents.enable_Varjo = Varjo
    opts.contents.enable_Channel_Sounding = CS
    opts.contents.spectrum_period = spectrum
    opts.contents.logic_mask = logic_mask
    opts.contents.logic_use_external_vref = logic_use_external_vref
    opts.contents.logic_rate = logic_rate
    opts.contents.enable_Proprietary_1 = Proprietary_1
    opts.contents.enable_Proprietary_2 = Proprietary_2

    if Audiopod != None:
        opts.contents.audiopod_opts = Audiopod.p

    for i in range(2):
        if I2S[i] != None:
            opts.contents.i2s_opts[i] = I2S[i].p

    _handle_error(
        _libbluespy.bluespy_capture(
            filename.encode("utf-8"), opts,
        )
    )

    _libbluespy.bluespy_delete(opts)
    atexit.register(close_file)
    atexit.register(stop_capture)

close_file

close_file()

! Close an existing capture

Raises:

Type Description
BluespyError

Exception in the bluespy library

Source code in application/bluespy.py
def close_file():
    """! Close an existing capture

    :exception BluespyError: Exception in the bluespy library"""
    atexit.unregister(close_file)
    _handle_error(_libbluespy.bluespy_close_file())

close_filter_file

close_filter_file(file_)

! Close a filter file

Parameters:

Name Type Description Default
file_

File ID

required

Raises:

Type Description
BluespyError

Exception in the bluespy library

Source code in application/bluespy.py
def close_filter_file(file_):
    """! Close a filter file

    :param file_: File ID

    :exception BluespyError: Exception in the bluespy library"""
    _handle_error(_libbluespy.bluespy_close_filter_file(file_))

connect

connect(serial=-1)

! Connect to Moreph hardware via USB or Ethernet.

Parameters:

Name Type Description Default
serial

A serial number as an integer, or -1 to connect to the first device. The serial number shown in the software and on the MiniMoreph is hexadecimal, so should be entered as 0xNNNNNN. There is a serial number on the bottom of some Moreph30s is of the form AYYYY-XXXXX, the XXXXX is the required serial number in decimal.

-1

Raises:

Type Description
BluespyError

Exception in the bluespy library You should run disconnect() later if this is successful.

Source code in application/bluespy.py
def connect(serial=-1):
    """! Connect to Moreph hardware via USB or Ethernet.

    :param serial: A serial number as an integer, or -1 to connect to the first device.
    The serial number shown in the software and on the MiniMoreph is hexadecimal, so should be entered as 0xNNNNNN.
    There is a serial number on the bottom of some Moreph30s is of the form AYYYY-XXXXX, the XXXXX is the required serial number in decimal.

    :exception BluespyError: Exception in the bluespy library

    You should run disconnect() later if this is successful.
    """

    _handle_error(_libbluespy.bluespy_connect(serial))

connect_multiple

connect_multiple(serials)

! Connect to multiple Moreph hardware devices via USB or Ethernet.

Parameters:

Name Type Description Default
serials

An array of serial numbers as integers. The first serial number in the array is considered that of the primary device. The serial numbers shown in the software and on the MiniMoreph are hexadecimal, so should be entered as 0xNNNNNN. There is a serial number on the bottom of some Moreph30s is of the form AYYYY-XXXXX, the XXXXX is the required serial number in decimal.

required

Raises:

Type Description
BluespyError

Exception in the bluespy library You should run disconnect() later if this is successful.

Source code in application/bluespy.py
def connect_multiple(serials):
    """! Connect to multiple Moreph hardware devices via USB or Ethernet.

    :param serials: An array of serial numbers as integers.
    The first serial number in the array is considered that of the primary device.
    The serial numbers shown in the software and on the MiniMoreph are hexadecimal, so should be entered as 0xNNNNNN.
    There is a serial number on the bottom of some Moreph30s is of the form AYYYY-XXXXX, the XXXXX is the required serial number in decimal.

    :exception BluespyError: Exception in the bluespy library

    You should run disconnect() later if this is successful.
    """
    u32list = _ct.c_uint32 * len(serials)
    serial_span = u32list()
    for i in range(len(serials)):
        serial_span[i] = serials[i]
    _handle_error(_libbluespy.bluespy_connect_multiple(serial_span, len(serials)))

connected_morephs

connected_morephs()

! Get the serial numbers of connected moreph devices.

Returns:

Type Description

Array of serial numbers

Source code in application/bluespy.py
def connected_morephs():
    """! Get the serial numbers of connected moreph devices.

    :return: Array of serial numbers
    """
    uint32_ptr = _ct.POINTER(_ct.c_uint32)
    hw_data = uint32_ptr()
    hw_count = _libbluespy.bluespy_morephs_connected(_ct.byref(hw_data))

    return [hw_data[i] for i in range(hw_count)]

create_filter_file

create_filter_file(filename, range_start=-1, keep_spec=True, keep_logic=True, keep_uart=True, keep_i2s_and_audiopod=True)

! Creates a filter file

Parameters:

Name Type Description Default
filename

File name

required
range_start

File name

-1
keep_spec

Enable copying spectrum

True
keep_logic

Enable copying logic

True
keep_uart

Enable copying UART

True
keep_i2s_and_audiopod

Enable copying I2S and Audiopod

True

Returns:

Type Description

file_id of filter file. -1 = invalid

Source code in application/bluespy.py
def create_filter_file(filename, range_start = -1, keep_spec = True, keep_logic = True, keep_uart = True, keep_i2s_and_audiopod = True):
    """! Creates a filter file

    :param filename: File name
    :param range_start: File name
    :param keep_spec: Enable copying spectrum
    :param keep_logic: Enable copying logic
    :param keep_uart: Enable copying UART
    :param keep_i2s_and_audiopod: Enable copying I2S and Audiopod

    :return: file_id of filter file. -1 = invalid"""
    opts = _libbluespy.bluespy_filter_file_options_alloc()
    opts.contents.range_start = range_start
    opts.contents.keep_spectrum = keep_spec
    opts.contents.keep_logic = keep_logic
    opts.contents.keep_uart = keep_uart
    opts.contents.keep_i2s_and_audiopod = keep_i2s_and_audiopod

    id_ = _libbluespy.bluespy_create_filter_file(filename.encode("utf-8"), opts)
    _libbluespy.bluespy_filter_file_options_delete(opts)
    return id_

disconnect

disconnect()

! Disconnect from the connected Morephs

Raises:

Type Description
BluespyError

Exception in the bluespy library

Source code in application/bluespy.py
def disconnect():
    """! Disconnect from the connected Morephs

    :exception BluespyError: Exception in the bluespy library"""
    atexit.unregister(stop_capture)
    atexit.unregister(disconnect)
    _handle_error(_libbluespy.bluespy_disconnect())

get_audiostreams

get_audiostreams(id_=id(18446744073709551615))

! Get the ids of the audio streams from 'id'

If id is device_id: Streams which a device is creating. If id is connection_id: Streams which are part of a connection. If id is BLUESPY_ID_INVALID: Streams not associated with any device, e.g. audiopod streams.

Parameters:

Name Type Description Default
id_

Device ID or Connection ID, or -1 for audiopod streams.

id(18446744073709551615)

Returns:

Type Description

Array of audio stream IDs

Source code in application/bluespy.py
def get_audiostreams(id_ = id(0xFFFFFFFFFFFFFFFF)):
    """! Get the ids of the audio streams from 'id'

    If id is device_id: Streams which a device is creating.
    If id is connection_id: Streams which are part of a connection.
    If id is BLUESPY_ID_INVALID: Streams not associated with any device, e.g. audiopod streams.    

    :param id_: Device ID or Connection ID, or -1 for audiopod streams.
    :return: Array of audio stream IDs"""
    stream_id_span = _libbluespy.bluespy_get_audiostreams(id_)
    return [stream_id_span.data[i] for i in range(stream_id_span.size)]

get_device_id

get_device_id(addr)

! Get the Device ID from an address

Parameters:

Name Type Description Default
addr

Six bytes representing an address

required

Returns:

Type Description

Device ID. -1 = no device

Source code in application/bluespy.py
def get_device_id(addr):
    """! Get the Device ID from an address

    :param addr: Six bytes representing an address
    :return: Device ID. -1 = no device"""
    return _libbluespy.bluespy_get_device_id(addr)

get_logic_at_time

get_logic_at_time(ts)

! Get the logic state at ts

Parameters:

Name Type Description Default
ts

Timestamp

required

Returns:

Type Description

32 bit integer. The i'th bit represents the state of the i'th logic line

Source code in application/bluespy.py
def get_logic_at_time(ts):
    """! Get the logic state at ts

    :param ts: Timestamp

    :return: 32 bit integer. The i'th bit represents the state of the i'th logic line"""
    return _libbluespy.bluespy_get_logic_at_time(ts)

get_next_logic_change

get_next_logic_change(ts, mask)

! Get the next logic state after ts

Parameters:

Name Type Description Default
ts

Timestamp

required
mask

32 integer mask. logic lines corresponding to zero bits are ignored

required

Returns:

Type Description

A struct containing a 32 integer mask representing the next logic state, and the time of transition

Source code in application/bluespy.py
def get_next_logic_change(ts,  mask):
    """! Get the next logic state after ts

    :param ts: Timestamp
    :param mask: 32 integer mask. logic lines corresponding to zero bits are ignored

    :return: A struct containing a 32 integer mask representing the next logic state, and the time of transition"""

    return _libbluespy.bluespy_get_next_logic_change(ts,  mask)

invalid_time

invalid_time()

! Invalid time point

Returns:

Type Description

invalid time point

Source code in application/bluespy.py
def invalid_time():
    """! Invalid time point

    :return: invalid time point"""
    return time_point()

list_keys

list_keys()

! List the keys from the security tab

Returns:

Type Description

Keys

Source code in application/bluespy.py
def list_keys():
    """! List the keys from the security tab

    :return (list(bytes)): Keys
    """
    keys_ptr = _ct.POINTER(_BluespyKey)()
    length = _ct.c_size_t()
    _libbluespy.bluespy_list_keys(_ct.byref(keys_ptr), _ct.byref(length))
    results = []
    for i in range(length.value):
        key = keys_ptr[i]
        key_bytes = _ct.string_at(key.key, key.length)
        results.append(key_bytes)
    _libbluespy.bluespy_free_keys(keys_ptr, length)
    return results

load_file

load_file(filename)

! Load an existing capture

Raises:

Type Description
BluespyError

Exception in the bluespy library

Source code in application/bluespy.py
def load_file(filename):
    """! Load an existing capture

    :exception BluespyError: Exception in the bluespy library"""
    _handle_error(_libbluespy.bluespy_load_file(filename.encode("utf-8")))
    atexit.register(close_file)

mark_key_used

mark_key_used(key)

! Marks an encryption key as used

Parameters:

Name Type Description Default
key bytes

Encryption key as bytes object

required
Source code in application/bluespy.py
def mark_key_used(key: bytes):
    """! Marks an encryption key as used

    :param key: Encryption key as bytes object
    """
    _handle_error(
        _libbluespy.bluespy_mark_key_used(key, len(key))
    )

measure_latency

measure_latency(channel0, channel1, include_pres_delay, ts)

! Measures the latency between two audio streams

Parameters:

Name Type Description Default
channel0

Audio channel 0

required
channel1

Audio channel 1

required
include_pres_delay

Include presentation delay

required
ts

Timestamp

required

Returns:

Type Description

Array of latency results

Source code in application/bluespy.py
def measure_latency(channel0, channel1, include_pres_delay, ts):
    """! Measures the latency between two audio streams

    :param channel0: Audio channel 0
    :param channel1: Audio channel 1
    :param include_pres_delay: Include presentation delay
    :param ts: Timestamp

    :return: Array of latency results
    """
    res_data = _libbluespy.bluespy_measure_latency(channel0,channel1,include_pres_delay,ts)
    return res_data

play_to_audiopod_output

play_to_audiopod_output(filename, loop=False)

! Playback audio file to audiopod

Parameters:

Name Type Description Default
filename

Audio file

required
loop

Loop audio

False
Source code in application/bluespy.py
def play_to_audiopod_output(filename, loop = False):
    """! Playback audio file to audiopod

    :param filename: Audio file
    :param loop: Loop audio"""
    _handle_error(
        _libbluespy.bluespy_play_to_audiopod_output(filename.encode("utf-8"), loop)
    )

reboot_moreph

reboot_moreph(serial=-1)

! Reboot Moreph hardware via USB or Ethernet.

Parameters:

Name Type Description Default
serial

A serial number as an integer, or -1 to connect to the first device. The serial number shown in the software and on the MiniMoreph is hexadecimal, so should be entered as 0xNNNNNN. There is a serial number on the bottom of some Moreph30s is of the form AYYYY-XXXXX, the XXXXX is the required serial number in decimal.

-1

Raises:

Type Description
BluespyError

Exception in the bluespy library This function will cause the specified Moreph to disconnect - bluespy.connect(serial) needs to be called afterwards to talk to the Moreph again

Source code in application/bluespy.py
def reboot_moreph(serial=-1):
    """! Reboot Moreph hardware via USB or Ethernet.

    :param serial: A serial number as an integer, or -1 to connect to the first device.
    The serial number shown in the software and on the MiniMoreph is hexadecimal, so should be entered as 0xNNNNNN.
    There is a serial number on the bottom of some Moreph30s is of the form AYYYY-XXXXX, the XXXXX is the required serial number in decimal.

    :exception BluespyError: Exception in the bluespy library

    This function will cause the specified Moreph to disconnect - bluespy.connect(serial) needs to be called
    afterwards to talk to the Moreph again
    """
    _handle_error(_libbluespy.bluespy_moreph_reboot(serial))

set_cis_lc3_config

set_cis_lc3_config(audio_id, codec_frames_per_SDU=1, presentation_delay_us=40000, octets_per_codec_frame=120, frame_duration_us=10000, sampling_frequency_Hz=48000, audio_channel_allocation=256)

! Set the config of a CIS stream

Parameters:

Name Type Description Default
audio_id

CIS stream ID

required
codec_frames_per_SDU

Codec Frames per SDU

1
presentation_delay_us

Presentation Delay in μs

40000
octets_per_codec_frame

Octets per Codec Frame

120
frame_duration_us

Frame Duration in μs

10000
sampling_frequency_Hz

Sample Rate in Hz

48000
audio_channel_allocation

Audio Channel Allocation mask

256

Returns:

Type Description

Array of serial numbers

Source code in application/bluespy.py
def set_cis_lc3_config(
        audio_id, 
        codec_frames_per_SDU=1, 
        presentation_delay_us = 40000, 
        octets_per_codec_frame = 120, 
        frame_duration_us = 10000, 
        sampling_frequency_Hz = 48000, 
        audio_channel_allocation = 0x100
        ):
    """! Set the config of a CIS stream

    :param audio_id: CIS stream ID
    :param codec_frames_per_SDU: Codec Frames per SDU
    :param presentation_delay_us: Presentation Delay in μs
    :param octets_per_codec_frame: Octets per Codec Frame
    :param frame_duration_us: Frame Duration in μs
    :param sampling_frequency_Hz: Sample Rate in Hz
    :param audio_channel_allocation: Audio Channel Allocation mask
    :return: Array of serial numbers"""
    conf = _cis_lc3_config()
    conf.codec_frames_per_SDU = codec_frames_per_SDU
    conf.presentation_delay_us = presentation_delay_us
    conf.octets_per_codec_frame = octets_per_codec_frame
    conf.frame_duration_us = frame_duration_us
    conf.sampling_frequency_Hz = sampling_frequency_Hz
    conf.audio_channel_allocation = audio_channel_allocation
    _handle_error(
        _libbluespy.bluespy_set_cis_lc3_config(audio_id, _ct.byref(conf))
    )

start_gui

start_gui()

! Spawn an instance of the user interface

Source code in application/bluespy.py
def start_gui():
    """! Spawn an instance of the user interface"""
    _libbluespy.bluespy_start_gui()

stop_audio

stop_audio()

! Stop file in playback

Source code in application/bluespy.py
def stop_audio():
    """! Stop file in playback"""
    _handle_error(
        _libbluespy.bluespy_stop_audio()
    )

stop_capture

stop_capture()

! Stop the current capture

Raises:

Type Description
BluespyError

Exception in the bluespy library

Source code in application/bluespy.py
def stop_capture():
    """! Stop the current capture

    :exception BluespyError: Exception in the bluespy library"""
    atexit.unregister(stop_capture)
    _handle_error(_libbluespy.bluespy_stop_capture()) 

wait_until_next_logic_change

wait_until_next_logic_change(mask, timeout, ts)

! Waits until a logic line in the specified mask changes or until the given timeout period passes

Parameters:

Name Type Description Default
mask

32 integer mask. logic lines corresponding to zero bits are ignored

required
timeout

Timeout

required
ts

Time to wait from

required

Returns:

Type Description

A struct containing the new state, the line which switched, the time of the switch, and whether the logic state changed or the function timed out. True = Logic changed. False = Timeout

Source code in application/bluespy.py
def wait_until_next_logic_change(mask, timeout, ts):
    """! Waits until a logic line in the specified mask changes or until the given timeout period passes

    :param mask: 32 integer mask. logic lines corresponding to zero bits are ignored
    :param timeout: Timeout
    :param ts: Time to wait from

    :return: A struct containing the new state, the line which switched, the time of the switch, and whether the logic state changed or the function timed out. True = Logic changed. False = Timeout"""

    return _libbluespy.bluespy_wait_until_next_logic_change(mask, timeout, ts)