mirror of
https://github.com/google/bumble.git
synced 2026-05-10 04:18:03 +00:00
add basic support for SCO packets over USB
This commit is contained in:
@@ -1423,6 +1423,9 @@ class ScoLink(utils.CompositeEventEmitter):
|
||||
acl_connection: Connection
|
||||
handle: int
|
||||
link_type: int
|
||||
rx_packet_length: int
|
||||
tx_packet_length: int
|
||||
air_mode: hci.CodecID
|
||||
sink: Callable[[hci.HCI_SynchronousDataPacket], Any] | None = None
|
||||
|
||||
EVENT_DISCONNECTION: ClassVar[str] = "disconnection"
|
||||
@@ -5968,7 +5971,7 @@ class Device(utils.CompositeEventEmitter):
|
||||
def on_connection_request(
|
||||
self, bd_addr: hci.Address, class_of_device: int, link_type: int
|
||||
):
|
||||
logger.debug(f'*** Connection request: {bd_addr}')
|
||||
logger.debug(f'*** Connection request: {bd_addr} link_type={link_type}')
|
||||
|
||||
# Handle SCO request.
|
||||
if link_type in (
|
||||
@@ -5978,6 +5981,7 @@ class Device(utils.CompositeEventEmitter):
|
||||
if connection := self.find_connection_by_bd_addr(
|
||||
bd_addr, transport=PhysicalTransport.BR_EDR
|
||||
):
|
||||
connection.emit(self.EVENT_SCO_REQUEST, link_type)
|
||||
self.emit(self.EVENT_SCO_REQUEST, connection, link_type)
|
||||
else:
|
||||
logger.error(f'SCO request from a non-connected device {bd_addr}')
|
||||
@@ -6337,8 +6341,7 @@ class Device(utils.CompositeEventEmitter):
|
||||
logger.warning('peer name is not valid UTF-8')
|
||||
if connection:
|
||||
connection.emit(connection.EVENT_REMOTE_NAME_FAILURE, error)
|
||||
else:
|
||||
self.emit(self.EVENT_REMOTE_NAME_FAILURE, address, error)
|
||||
self.emit(self.EVENT_REMOTE_NAME_FAILURE, address, error)
|
||||
|
||||
# [Classic only]
|
||||
@host_event_handler
|
||||
@@ -6355,7 +6358,13 @@ class Device(utils.CompositeEventEmitter):
|
||||
@with_connection_from_address
|
||||
@utils.experimental('Only for testing.')
|
||||
def on_sco_connection(
|
||||
self, acl_connection: Connection, sco_handle: int, link_type: int
|
||||
self,
|
||||
acl_connection: Connection,
|
||||
sco_handle: int,
|
||||
link_type: int,
|
||||
rx_packet_length: int,
|
||||
tx_packet_length: int,
|
||||
air_mode: int,
|
||||
) -> None:
|
||||
logger.debug(
|
||||
f'*** SCO connected: {acl_connection.peer_address}, '
|
||||
@@ -6367,7 +6376,11 @@ class Device(utils.CompositeEventEmitter):
|
||||
acl_connection=acl_connection,
|
||||
handle=sco_handle,
|
||||
link_type=link_type,
|
||||
rx_packet_length=rx_packet_length,
|
||||
tx_packet_length=tx_packet_length,
|
||||
air_mode=hci.CodecID(air_mode),
|
||||
)
|
||||
acl_connection.emit(self.EVENT_SCO_CONNECTION, sco_link)
|
||||
self.emit(self.EVENT_SCO_CONNECTION, sco_link)
|
||||
|
||||
# [Classic only]
|
||||
@@ -6378,7 +6391,8 @@ class Device(utils.CompositeEventEmitter):
|
||||
self, acl_connection: Connection, status: int
|
||||
) -> None:
|
||||
logger.debug(f'*** SCO connection failure: {acl_connection.peer_address}***')
|
||||
self.emit(self.EVENT_SCO_CONNECTION_FAILURE)
|
||||
acl_connection.emit(self.EVENT_SCO_CONNECTION_FAILURE, status)
|
||||
self.emit(self.EVENT_SCO_CONNECTION_FAILURE, status)
|
||||
|
||||
# [Classic only]
|
||||
@host_event_handler
|
||||
@@ -6841,15 +6855,18 @@ class Device(utils.CompositeEventEmitter):
|
||||
@with_connection_from_address
|
||||
def on_classic_pairing(self, connection: Connection) -> None:
|
||||
connection.emit(connection.EVENT_CLASSIC_PAIRING)
|
||||
self.emit(connection.EVENT_CLASSIC_PAIRING, connection)
|
||||
|
||||
# [Classic only]
|
||||
@host_event_handler
|
||||
@with_connection_from_address
|
||||
def on_classic_pairing_failure(self, connection: Connection, status: int) -> None:
|
||||
connection.emit(connection.EVENT_CLASSIC_PAIRING_FAILURE, status)
|
||||
self.emit(connection.EVENT_CLASSIC_PAIRING_FAILURE, connection, status)
|
||||
|
||||
def on_pairing_start(self, connection: Connection) -> None:
|
||||
connection.emit(connection.EVENT_PAIRING_START)
|
||||
self.emit(connection.EVENT_PAIRING_START, connection)
|
||||
|
||||
def on_pairing(
|
||||
self,
|
||||
|
||||
121
bumble/hci.py
121
bumble/hci.py
@@ -1769,6 +1769,61 @@ class CodingFormat:
|
||||
)
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class VoiceSetting:
|
||||
class AirCodingFormat(enum.IntEnum):
|
||||
CVSD = 0
|
||||
U_LAW = 1
|
||||
A_LAW = 2
|
||||
TRANSPARENT_DATA = 3
|
||||
|
||||
class InputSampleSize(enum.IntEnum):
|
||||
SIZE_8_BITS = 0
|
||||
SIZE_16_BITS = 1
|
||||
|
||||
class InputDataFormat(enum.IntEnum):
|
||||
ONES_COMPLEMENT = 0
|
||||
TWOS_COMPLEMENT = 1
|
||||
SIGN_AND_MAGNITUDE = 2
|
||||
UNSIGNED = 3
|
||||
|
||||
class InputCodingFormat(enum.IntEnum):
|
||||
LINEAR = 0
|
||||
U_LAW = 1
|
||||
A_LAW = 2
|
||||
RESERVED = 3
|
||||
|
||||
air_coding_format: AirCodingFormat = AirCodingFormat.CVSD
|
||||
linear_pcm_bit_position: int = 0
|
||||
input_sample_size: InputSampleSize = InputSampleSize.SIZE_8_BITS
|
||||
input_data_format: InputDataFormat = InputDataFormat.ONES_COMPLEMENT
|
||||
input_coding_format: InputCodingFormat = InputCodingFormat.LINEAR
|
||||
|
||||
@classmethod
|
||||
def from_int(cls, value: int) -> VoiceSetting:
|
||||
air_coding_format = cls.AirCodingFormat(value & 0b11)
|
||||
linear_pcm_bit_position = (value >> 2) & 0b111
|
||||
input_sample_size = cls.InputSampleSize((value >> 5) & 0b1)
|
||||
input_data_format = cls.InputDataFormat((value >> 6) & 0b11)
|
||||
input_coding_format = cls.InputCodingFormat((value >> 8) & 0b11)
|
||||
return cls(
|
||||
air_coding_format=air_coding_format,
|
||||
linear_pcm_bit_position=linear_pcm_bit_position,
|
||||
input_sample_size=input_sample_size,
|
||||
input_data_format=input_data_format,
|
||||
input_coding_format=input_coding_format,
|
||||
)
|
||||
|
||||
def __int__(self) -> int:
|
||||
return (
|
||||
self.air_coding_format
|
||||
| (self.linear_pcm_bit_position << 2)
|
||||
| (self.input_sample_size << 5)
|
||||
| (self.input_data_format << 6)
|
||||
| (self.input_coding_format << 8)
|
||||
)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
class HCI_Constant:
|
||||
@staticmethod
|
||||
@@ -2907,6 +2962,23 @@ class HCI_Read_Clock_Offset_Command(HCI_AsyncCommand):
|
||||
connection_handle: int = field(metadata=metadata(2))
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@HCI_Command.command
|
||||
@dataclasses.dataclass
|
||||
class HCI_Accept_Synchronous_Connection_Request_Command(HCI_AsyncCommand):
|
||||
'''
|
||||
See Bluetooth spec @ 7.1.27 Accept Synchronous Connection Request Command
|
||||
'''
|
||||
|
||||
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
||||
transmit_bandwidth: int = field(metadata=metadata(4))
|
||||
receive_bandwidth: int = field(metadata=metadata(4))
|
||||
max_latency: int = field(metadata=metadata(2))
|
||||
voice_setting: int = field(metadata=metadata(2))
|
||||
retransmission_effort: int = field(metadata=metadata(1))
|
||||
packet_type: int = field(metadata=metadata(2))
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@HCI_Command.command
|
||||
@dataclasses.dataclass
|
||||
@@ -3965,6 +4037,23 @@ class HCI_Read_Local_OOB_Extended_Data_Command(
|
||||
'''
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
||||
@dataclasses.dataclass
|
||||
class HCI_Configure_Data_Path_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
||||
'''
|
||||
See Bluetooth spec @ 7.3.101 Configure Data Path Command
|
||||
'''
|
||||
|
||||
class DataPathDirection(SpecableEnum):
|
||||
INPUT = 0x00
|
||||
OUTPUT = 0x01
|
||||
|
||||
data_path_direction: DataPathDirection = field(metadata=metadata(1))
|
||||
data_path_id: int = field(metadata=metadata(1))
|
||||
vendor_specific_config: bytes = field(metadata=metadata('*'))
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@dataclasses.dataclass
|
||||
class HCI_Read_Local_Version_Information_ReturnParameters(HCI_StatusReturnParameters):
|
||||
@@ -7355,7 +7444,7 @@ class HCI_Connection_Complete_Event(HCI_Event):
|
||||
status: int = field(metadata=metadata(STATUS_SPEC))
|
||||
connection_handle: int = field(metadata=metadata(2))
|
||||
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
||||
link_type: int = field(metadata=LinkType.type_metadata(1))
|
||||
link_type: LinkType = field(metadata=LinkType.type_metadata(1))
|
||||
encryption_enabled: int = field(metadata=metadata(1))
|
||||
|
||||
|
||||
@@ -7751,12 +7840,6 @@ class HCI_Synchronous_Connection_Complete_Event(HCI_Event):
|
||||
SCO = 0x00
|
||||
ESCO = 0x02
|
||||
|
||||
class AirMode(SpecableEnum):
|
||||
U_LAW_LOG = 0x00
|
||||
A_LAW_LOG_AIR_MORE = 0x01
|
||||
CVSD = 0x02
|
||||
TRANSPARENT_DATA = 0x03
|
||||
|
||||
status: int = field(metadata=metadata(STATUS_SPEC))
|
||||
connection_handle: int = field(metadata=metadata(2))
|
||||
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
||||
@@ -7765,7 +7848,7 @@ class HCI_Synchronous_Connection_Complete_Event(HCI_Event):
|
||||
retransmission_window: int = field(metadata=metadata(1))
|
||||
rx_packet_length: int = field(metadata=metadata(2))
|
||||
tx_packet_length: int = field(metadata=metadata(2))
|
||||
air_mode: int = field(metadata=AirMode.type_metadata(1))
|
||||
air_mode: int = field(metadata=CodecID.type_metadata(1))
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@@ -7997,7 +8080,9 @@ class HCI_AclDataPacket(HCI_Packet):
|
||||
bc_flag = (h >> 14) & 3
|
||||
data = packet[5:]
|
||||
if len(data) != data_total_length:
|
||||
raise InvalidPacketError('invalid packet length')
|
||||
raise InvalidPacketError(
|
||||
f'invalid packet length {len(data)} != {data_total_length}'
|
||||
)
|
||||
return cls(
|
||||
connection_handle=connection_handle,
|
||||
pb_flag=pb_flag,
|
||||
@@ -8030,10 +8115,16 @@ class HCI_SynchronousDataPacket(HCI_Packet):
|
||||
See Bluetooth spec @ 5.4.3 HCI SCO Data Packets
|
||||
'''
|
||||
|
||||
class Status(enum.IntEnum):
|
||||
CORRECTLY_RECEIVED_DATA = 0b00
|
||||
POSSIBLY_INVALID_DATA = 0b01
|
||||
NO_DATA = 0b10
|
||||
DATA_PARTIALLY_LOST = 0b11
|
||||
|
||||
hci_packet_type = HCI_SYNCHRONOUS_DATA_PACKET
|
||||
|
||||
connection_handle: int
|
||||
packet_status: int
|
||||
packet_status: Status
|
||||
data_total_length: int
|
||||
data: bytes
|
||||
|
||||
@@ -8042,7 +8133,7 @@ class HCI_SynchronousDataPacket(HCI_Packet):
|
||||
# Read the header
|
||||
h, data_total_length = struct.unpack_from('<HB', packet, 1)
|
||||
connection_handle = h & 0xFFF
|
||||
packet_status = (h >> 12) & 0b11
|
||||
packet_status = cls.Status((h >> 12) & 0b11)
|
||||
data = packet[4:]
|
||||
if len(data) != data_total_length:
|
||||
raise InvalidPacketError(
|
||||
@@ -8066,7 +8157,7 @@ class HCI_SynchronousDataPacket(HCI_Packet):
|
||||
return (
|
||||
f'{color("SCO", "blue")}: '
|
||||
f'handle=0x{self.connection_handle:04x}, '
|
||||
f'ps={self.packet_status}, '
|
||||
f'ps={self.packet_status.name}, '
|
||||
f'data_total_length={self.data_total_length}, '
|
||||
f'data={self.data.hex()}'
|
||||
)
|
||||
@@ -8094,8 +8185,8 @@ class HCI_IsoDataPacket(HCI_Packet):
|
||||
def __post_init__(self) -> None:
|
||||
self.ts_flag = self.time_stamp is not None
|
||||
|
||||
@staticmethod
|
||||
def from_bytes(packet: bytes) -> HCI_IsoDataPacket:
|
||||
@classmethod
|
||||
def from_bytes(cls, packet: bytes) -> HCI_IsoDataPacket:
|
||||
time_stamp: int | None = None
|
||||
packet_sequence_number: int | None = None
|
||||
iso_sdu_length: int | None = None
|
||||
@@ -8124,7 +8215,7 @@ class HCI_IsoDataPacket(HCI_Packet):
|
||||
pos += 4
|
||||
|
||||
iso_sdu_fragment = packet[pos:]
|
||||
return HCI_IsoDataPacket(
|
||||
return cls(
|
||||
connection_handle=connection_handle,
|
||||
pb_flag=pb_flag,
|
||||
ts_flag=ts_flag,
|
||||
|
||||
@@ -166,7 +166,7 @@ class AgFeature(enum.IntFlag):
|
||||
VOICE_RECOGNITION_TEXT = 0x2000
|
||||
|
||||
|
||||
class AudioCodec(enum.IntEnum):
|
||||
class AudioCodec(utils.OpenIntEnum):
|
||||
"""
|
||||
Audio Codec IDs (normative).
|
||||
|
||||
@@ -178,7 +178,7 @@ class AudioCodec(enum.IntEnum):
|
||||
LC3_SWB = 0x03 # Support for LC3-SWB audio codec
|
||||
|
||||
|
||||
class HfIndicator(enum.IntEnum):
|
||||
class HfIndicator(utils.OpenIntEnum):
|
||||
"""
|
||||
HF Indicators (normative).
|
||||
|
||||
@@ -207,7 +207,7 @@ class CallHoldOperation(enum.Enum):
|
||||
)
|
||||
|
||||
|
||||
class ResponseHoldStatus(enum.IntEnum):
|
||||
class ResponseHoldStatus(utils.OpenIntEnum):
|
||||
"""
|
||||
Response Hold status (normative).
|
||||
|
||||
@@ -235,7 +235,7 @@ class AgIndicator(enum.Enum):
|
||||
BATTERY_CHARGE = 'battchg'
|
||||
|
||||
|
||||
class CallSetupAgIndicator(enum.IntEnum):
|
||||
class CallSetupAgIndicator(utils.OpenIntEnum):
|
||||
"""
|
||||
Values for the Call Setup AG indicator (normative).
|
||||
|
||||
@@ -248,7 +248,7 @@ class CallSetupAgIndicator(enum.IntEnum):
|
||||
REMOTE_ALERTED = 3 # Remote party alerted in an outgoing call
|
||||
|
||||
|
||||
class CallHeldAgIndicator(enum.IntEnum):
|
||||
class CallHeldAgIndicator(utils.OpenIntEnum):
|
||||
"""
|
||||
Values for the Call Held AG indicator (normative).
|
||||
|
||||
@@ -262,7 +262,7 @@ class CallHeldAgIndicator(enum.IntEnum):
|
||||
CALL_ON_HOLD_NO_ACTIVE_CALL = 2 # Call on hold, no active call
|
||||
|
||||
|
||||
class CallInfoDirection(enum.IntEnum):
|
||||
class CallInfoDirection(utils.OpenIntEnum):
|
||||
"""
|
||||
Call Info direction (normative).
|
||||
|
||||
@@ -273,7 +273,7 @@ class CallInfoDirection(enum.IntEnum):
|
||||
MOBILE_TERMINATED_CALL = 1
|
||||
|
||||
|
||||
class CallInfoStatus(enum.IntEnum):
|
||||
class CallInfoStatus(utils.OpenIntEnum):
|
||||
"""
|
||||
Call Info status (normative).
|
||||
|
||||
@@ -288,7 +288,7 @@ class CallInfoStatus(enum.IntEnum):
|
||||
WAITING = 5
|
||||
|
||||
|
||||
class CallInfoMode(enum.IntEnum):
|
||||
class CallInfoMode(utils.OpenIntEnum):
|
||||
"""
|
||||
Call Info mode (normative).
|
||||
|
||||
@@ -301,7 +301,7 @@ class CallInfoMode(enum.IntEnum):
|
||||
UNKNOWN = 9
|
||||
|
||||
|
||||
class CallInfoMultiParty(enum.IntEnum):
|
||||
class CallInfoMultiParty(utils.OpenIntEnum):
|
||||
"""
|
||||
Call Info Multi-Party state (normative).
|
||||
|
||||
@@ -388,7 +388,7 @@ class CallLineIdentification:
|
||||
)
|
||||
|
||||
|
||||
class VoiceRecognitionState(enum.IntEnum):
|
||||
class VoiceRecognitionState(utils.OpenIntEnum):
|
||||
"""
|
||||
vrec values provided in AT+BVRA command.
|
||||
|
||||
@@ -401,7 +401,7 @@ class VoiceRecognitionState(enum.IntEnum):
|
||||
ENHANCED_READY = 2
|
||||
|
||||
|
||||
class CmeError(enum.IntEnum):
|
||||
class CmeError(utils.OpenIntEnum):
|
||||
"""
|
||||
CME ERROR codes (partial listed).
|
||||
|
||||
@@ -1624,7 +1624,7 @@ class AgProtocol(utils.EventEmitter):
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
class ProfileVersion(enum.IntEnum):
|
||||
class ProfileVersion(utils.OpenIntEnum):
|
||||
"""
|
||||
Profile version (normative).
|
||||
|
||||
@@ -2076,6 +2076,7 @@ _ESCO_PARAMETERS_MSBC_T1 = EscoParameters(
|
||||
max_latency=0x0008,
|
||||
packet_type=(
|
||||
HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.EV3
|
||||
| HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.NO_2_EV3
|
||||
| HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.NO_3_EV3
|
||||
| HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.NO_2_EV5
|
||||
| HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.NO_3_EV5
|
||||
@@ -2091,7 +2092,6 @@ _ESCO_PARAMETERS_MSBC_T2 = EscoParameters(
|
||||
max_latency=0x000D,
|
||||
packet_type=(
|
||||
HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.EV3
|
||||
| HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.NO_2_EV3
|
||||
| HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.NO_3_EV3
|
||||
| HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.NO_2_EV5
|
||||
| HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.NO_3_EV5
|
||||
|
||||
@@ -686,6 +686,8 @@ class Host(utils.EventEmitter):
|
||||
self.pending_response, timeout=response_timeout
|
||||
)
|
||||
return response
|
||||
except asyncio.TimeoutError:
|
||||
raise
|
||||
except Exception:
|
||||
logger.exception(color("!!! Exception while sending command:", "red"))
|
||||
raise
|
||||
@@ -866,7 +868,7 @@ class Host(utils.EventEmitter):
|
||||
self.send_hci_packet(
|
||||
hci.HCI_SynchronousDataPacket(
|
||||
connection_handle=connection_handle,
|
||||
packet_status=0,
|
||||
packet_status=hci.HCI_SynchronousDataPacket.Status.CORRECTLY_RECEIVED_DATA,
|
||||
data_total_length=len(sdu),
|
||||
data=sdu,
|
||||
)
|
||||
@@ -1177,11 +1179,28 @@ class Host(utils.EventEmitter):
|
||||
def on_hci_connection_complete_event(
|
||||
self, event: hci.HCI_Connection_Complete_Event
|
||||
):
|
||||
if event.link_type == hci.HCI_Connection_Complete_Event.LinkType.SCO:
|
||||
# Pass this on to the synchronous connection handler
|
||||
forwarded_event = hci.HCI_Synchronous_Connection_Complete_Event(
|
||||
status=event.status,
|
||||
connection_handle=event.connection_handle,
|
||||
bd_addr=event.bd_addr,
|
||||
link_type=event.link_type,
|
||||
transmission_interval=0,
|
||||
retransmission_window=0,
|
||||
rx_packet_length=0,
|
||||
tx_packet_length=0,
|
||||
air_mode=0,
|
||||
)
|
||||
self.on_hci_synchronous_connection_complete_event(forwarded_event)
|
||||
return
|
||||
|
||||
if event.status == hci.HCI_SUCCESS:
|
||||
# Create/update the connection
|
||||
logger.debug(
|
||||
f'### BR/EDR CONNECTION: [0x{event.connection_handle:04X}] '
|
||||
f'{event.bd_addr}'
|
||||
f'### BR/EDR ACL CONNECTION: [0x{event.connection_handle:04X}] '
|
||||
f'{event.bd_addr} '
|
||||
f'{event.link_type.name}'
|
||||
)
|
||||
|
||||
connection = self.connections.get(event.connection_handle)
|
||||
@@ -1581,6 +1600,9 @@ class Host(utils.EventEmitter):
|
||||
event.bd_addr,
|
||||
event.connection_handle,
|
||||
event.link_type,
|
||||
event.rx_packet_length,
|
||||
event.tx_packet_length,
|
||||
event.air_mode,
|
||||
)
|
||||
else:
|
||||
logger.debug(f'### SCO CONNECTION FAILED: {event.status}')
|
||||
|
||||
@@ -110,7 +110,7 @@ RFCOMM_DEFAULT_L2CAP_MTU = 2048
|
||||
RFCOMM_DEFAULT_INITIAL_CREDITS = 7
|
||||
RFCOMM_DEFAULT_MAX_CREDITS = 32
|
||||
RFCOMM_DEFAULT_CREDIT_THRESHOLD = RFCOMM_DEFAULT_MAX_CREDITS // 2
|
||||
RFCOMM_DEFAULT_MAX_FRAME_SIZE = 2000
|
||||
RFCOMM_DEFAULT_MAX_FRAME_SIZE = 1000
|
||||
|
||||
RFCOMM_DYNAMIC_CHANNEL_NUMBER_START = 1
|
||||
RFCOMM_DYNAMIC_CHANNEL_NUMBER_END = 30
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user