Add BluetoothSDP - #230
Merged
Merged
Conversation
Code Coverage OverviewLanguages: Swift Swift / code-coverage/llvm-covThe overall coverage in commit 6a3b633 in the Show a code coverage summary of the most impacted files.
Updated |
SDP PDUs are network byte order, unlike most Bluetooth wire formats in this package, which are little-endian — so this module reads/writes multi-byte integers explicitly rather than reusing the little-endian-oriented DataConvertible conformances elsewhere.
Every value inside an SDP PDU or service record — attribute values, search patterns, attribute ID lists — is a data element, self- describing via a one-byte type/size-descriptor header. Conforms to this package's DataConvertible, matching how the rest of the Bluetooth package (BluetoothGAP, BluetoothGATT) encodes its own wire formats, rather than a C ABI.
Covers PDU framing (PDU ID, transaction ID, parameter length) plus the data model and record codec. Per-request-type parameter layouts and continuation-state fragmentation belong with a socket-based session layer, not this pure data model, and aren't included here.
Attributes keyed by SDPAttributeID, encoding/decoding to the flat data element sequence the wire format expects (attribute ID followed directly by its value, sorted by ID), plus convenience accessors for the universal attributes (service class list, protocol descriptor list, profile descriptor list, and the language-base-relative name/description/provider strings).
A normal, always-on target like BluetoothGAP/BluetoothGATT/BluetoothHCI — no C, no environment-variable gating, no @c bindings; just an idiomatic Swift module depending only on Bluetooth.
The generic FixedWidthInteger-constrained big-endian helper doesn't compile for UInt128 at this package's macOS 10.15 deployment target, since this package's UInt128 only conforms to FixedWidthInteger under @available(macOS 15, ...) (a hand-rolled struct backs it before the native stdlib type existed). Dedicated, non-generic UInt128 overloads go through the always-available ByteValue tuple accessor instead.
Round-tripping alone can't distinguish correct big-endian byte order from a consistently-reversed implementation, since encode/decode are exact inverses of each other by construction either way. This checks against a known numeric value instead.
Same availability gate as the library fix — UInt128's ExpressibleByIntegerLiteral and BinaryInteger conformances are macOS 15+ only here. Builds the comparison value via the unconditionally-available ByteValue tuple initializer instead.
colemancda
added a commit
that referenced
this pull request
Aug 3, 2026
Rebasing feature/c-abi onto master surfaced a name collision: feature/c-abi's own C-ABI-style sdp_* implementation was declared as a target/product named BluetoothSDP, unaware that master had since gained an unrelated pure-Swift BluetoothSDP target (merged via #230, after the "no C ABI at all" decision for feature/sdp). Both ended up declared in Package.swift and both wrote into Sources/BluetoothSDP/. Folds the C-ABI sdp_* implementation into BluetoothABI instead of giving it a separate module — CMake already links them into a single shared object (bluetooth-util), so this also removes a redundant static-library layer. The 8 source files move to Sources/BluetoothABI/ with an SDP prefix (avoiding a real filename collision on UUID.swift, whose bt_uuid_* and sdp_* implementations are unrelated), and their round-trip tests move into BluetoothABITests. Sources/BluetoothSDP/ now holds only master's pure-Swift implementation, untouched. Updates CMakeLists.txt (drops the separate BluetoothSDP static library), Conformance/compare.sh (sdp_* symbols now live in libBluetoothABI.so, so the differential driver no longer needs a second binary path), and CBluetooth's README.
colemancda
added a commit
that referenced
this pull request
Aug 3, 2026
Rebasing feature/c-abi onto master surfaced a name collision: feature/c-abi's own C-ABI-style sdp_* implementation was declared as a target/product named BluetoothSDP, unaware that master had since gained an unrelated pure-Swift BluetoothSDP target (merged via #230, after the "no C ABI at all" decision for feature/sdp). Both ended up declared in Package.swift and both wrote into Sources/BluetoothSDP/. Folds the C-ABI sdp_* implementation into BluetoothABI instead of giving it a separate module — CMake already links them into a single shared object (bluetooth-util), so this also removes a redundant static-library layer. The 8 source files move to Sources/BluetoothABI/ with an SDP prefix (avoiding a real filename collision on UUID.swift, whose bt_uuid_* and sdp_* implementations are unrelated), and their round-trip tests move into BluetoothABITests. Sources/BluetoothSDP/ now holds only master's pure-Swift implementation, untouched. Updates CMakeLists.txt (drops the separate BluetoothSDP static library), Conformance/compare.sh (sdp_* symbols now live in libBluetoothABI.so, so the differential driver no longer needs a second binary path), and CBluetooth's README.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
BluetoothSDP, an idiomatic pure-Swift implementation of the SDP(Service Discovery Protocol) data model, service record, and PDU
framing — no C, no vendored headers, no
@cABI bindings. A normal,always-on target alongside
BluetoothGAP/BluetoothGATT/BluetoothHCI,built the same way the rest of this package encodes its wire formats
(
DataConvertible, reusingBluetoothUUIDfor SDP's UUID dataelement).
SDPDataElement— the core recursive data model every SDP value(attribute values, search patterns, attribute ID lists) is built
from: null, unsigned/signed integers (8 through 128-bit), UUID,
text, boolean, sequence, alternative, and URL, each self-describing
via a one-byte type/size-descriptor header. Since SDP is big-endian
(unlike most of this package's little-endian wire formats), integer
encode/decode goes through small dedicated big-endian helpers
(
SDPBigEndian.swift) rather than the package's little-endian-oriented integer
DataConvertibleconformances.SDPAttributeID— the universal attribute IDs every service recordshares, plus the language-base-offset scheme the name/description/
provider string attributes are defined relative to.
SDPServiceRecord— a record's attributes keyed bySDPAttributeID,encoding to/decoding from the flat data element sequence the wire
format expects, with convenience accessors for the universal
attributes (service class ID list, protocol descriptor list,
Bluetooth profile descriptor list, service name/description/provider).
SDPPDUHeader— the fixed 5-byte PDU header (PDU ID, transactionID, parameter length) plus the
SDPPDUIDvalues.SDPError— theErrorResponseerror codes.Scope boundary: this covers PDU framing and the data model/record
codec, not the per-request-type parameter layouts (
ServiceSearchRequestand friends) or continuation-state fragmentation/reassembly — those
belong with a socket-based session layer, not this pure data model,
and aren't included here.
Verified
swift build/swift test— full suite (494 tests, 32 suites)passes, no regressions.
128-bit integer, empty string, and a length large enough to force
the 16-bit size descriptor), nested sequences, malformed-input
rejection, service record round-trip (including attribute-sorted
wire order), attribute ID helpers, PDU header round-trip, and error
code description.
Test plan
swift buildswift test --filter SDPTestsswift test(full suite)