Skip to main content

bleswiftcli-macos-bluetooth

A macOS command-line tool for Bluetooth Low Energy operations—scan, connect, pair, read, write, inspect GATT, and L2CAP channels.

Ir a la instalación

Datos de origen

Repositorio
reason-machines/devtools-skills
Última actividad en el origen
30 de julio de 2026 a las 03:08
Idioma detectado de SKILL.md
inglés
Estrellas
4
Forks
0

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
bleswiftcli-macos-bluetooth
description
A macOS command-line tool for Bluetooth Low Energy operations—scan, connect, pair, read, write, inspect GATT, and L2CAP channels.
triggers
["scan for bluetooth devices on mac","connect to a ble peripheral","read bluetooth characteristic value","write to ble device","inspect gatt services","pair with bluetooth low energy device","set up l2cap channel","bluetooth le command line tool"]
# BLESwiftCLI — macOS Bluetooth LE Command-Line Tool > Skill by [ara.so](https://ara.so) — Devtools Skills collection. `ble` is a macOS command-line tool for Bluetooth Low Energy operations: scanning, connecting, pairing, reading/writing characteristics and descriptors, inspecting GATT databases, and opening L2CAP channels. Built on BLESwift and swift-argument-parser. ## Installation ### Homebrew ```sh brew install kylebrowning/tap/ble ``` ### Mint ```sh mint install kylebrowning/BLESwiftCLI ``` ### From Source ```sh swift build -c release cp .build/release/ble /usr/local/bin/ ``` **Permissions**: On first run, macOS prompts for Bluetooth access. Grant it to your terminal app (Terminal, iTerm, etc.) in *System Settings → Privacy & Security → Bluetooth*. ## Core Concepts - **Peripherals** are identified by UUID or name substring - **Services** and **characteristics** use 16-bit SIG UUIDs (e.g. `180F`, `2A19`) or full 128-bit UUIDs - Connections are held open only while the CLI process runs - Pairing is triggered by accessing encrypted characteristics—no explicit pair API - Output: data (scan results, values, JSON) → **stdout**; status/progress → **stderr** ## Commands ### Scanning for Devices Scan for all nearby BLE devices: ```sh ble scan ``` Scan for specific service (e.g. Heart Rate `180D`) with unlimited time: ```sh ble scan -s 180D --timeout 0 ``` Live RSSI updates with duplicate advertisements: ```sh ble scan --allow-duplicates ``` Filter by minimum signal strength: ```sh ble scan --min-rssi -70 ``` JSON output for scripting: ```sh ble scan --json | jq '.name, .rssi, .uuid' ``` **Output format** (interactive): Live table sorted by signal strength, showing name, RSSI (color-coded green/yellow/red), peripheral UUID, advertised services, manufacturer data. **Output format** (piped/JSON): One line per advertisement event. ### Connecting to a Peripheral Connect by UUID: ```sh ble connect 6E400001-B5A3-F393-E0A9-E50E24DCCA9E ``` Connect by name substring (resolves via scan): ```sh ble connect "Kyle's Sensor" ``` Connect and auto-reconnect on disconnect: ```sh ble connect mydevice -s 180D --reconnect ``` The connection stays open until Ctrl-C or the process exits. Lifecycle events stream to stderr. ### Pairing with a Device CoreBluetooth has no explicit pair API. Pairing is triggered by accessing a characteristic that requires encryption: ```sh ble pair mydevice -s <service-uuid> -c <protected-characteristic-uuid> ``` To trigger pairing via write: ```sh ble pair mydevice -s FFF0 -c FFF1 --write 0x01 ``` This connects, attempts the read/write, and macOS shows the pairing dialog. Approve it to bond the device. **Unpair**: *System Settings → Bluetooth*, click info button on device, select "Forget This Device". ### Inspecting GATT Database Enumerate all services, characteristics, and descriptors: ```sh ble inspect mydevice ``` Include current values of readable characteristics: ```sh ble inspect mydevice --read ``` JSON output: ```sh ble inspect mydevice --json | jq ``` **Example output**: ``` Service 180F — Battery 2A19 — Battery Level [read, notify] = 0x5A (1 byte, uint 90, "Z") Descriptor 2902 — Client Characteristic Configuration ``` ### Reading Characteristics One-time read: ```sh ble read mydevice -s 180F -c 2A19 ``` Subscribe to notifications: ```sh ble read mydevice -s 180F -c 2A19 --notify ``` Read specific number of notifications: ```sh ble read mydevice -s 180F -c 2A19 --notify --count 5 ``` Read a descriptor: ```sh ble read mydevice -s 180F -c 2A19 -d 2901 ``` **Output**: Hex representation plus interpretations (byte count, little-endian uint, UTF-8 string). ### Writing Characteristics Write hex value: ```sh ble write mydevice -s FFF0 -c FFF1 --hex 0x01FF ``` Write string: ```sh ble write mydevice -s FFF0 -c FFF1 --string "hello" ``` Write from payload file (YAML/JSON): ```sh ble write mydevice -p command.yaml ``` Write and wait for notification on another characteristic: ```sh ble write mydevice -p command.yaml --expect-reply-on FFF2 ``` Dry-run (print encoded bytes without writing): ```sh ble write mydevice -p command.yaml --dry-run ``` Write a descriptor: ```sh ble write mydevice -s FFF0 -c FFF1 -d 2901 --string "label" ``` The tool automatically checks characteristic properties and chooses write-with-response or write-without-response. Use `--without-response` to force it. ### Payload Files Structured payloads in YAML or JSON. Fields are encoded in order and concatenated. **Example** (`command.yaml`): ```yaml service: 180F characteristic: 2A19 writeType: withResponse # optional: withResponse | withoutResponse fields: - { type: u8, value: 1 } - { type: u16le, value: 5000 } - { type: i32be, value: -70 } - { type: string, value: "hello" } - { type: hex, value: "DEADBEEF" } - { type: pad, length: 2 } ``` **Supported types**: - Integers: `u8`, `u16`, `u32`, `u64`, `i8`, `i16`, `i32`, `i64` - Endianness: `u16le` (little-endian, default), `u16be` (big-endian) - `string`: UTF-8 encoded - `hex`: raw hex bytes - `pad`: zero-fill N bytes Command-line flags (`-s`, `-c`) override the file's `service`/`characteristic`. ### L2CAP Channels Open a connection-oriented L2CAP channel: ```sh ble l2cap mydevice --psm 0x0080 ``` Send hex data once, then stream incoming: ```sh ble l2cap mydevice --psm 128 --send-hex 0x01FF ``` Raw binary output (for piping): ```sh ble l2cap mydevice --psm 128 --raw > capture.bin ``` The channel stays open until Ctrl-C or the peripheral closes it. ## Common Patterns ### Find and Connect to a Specific Device Type ```sh # Scan for heart-rate monitors ble scan -s 180D --timeout 5 # Connect to one by name ble connect "Polar H10" --reconnect ``` ### Read Battery Level ```sh ble read mydevice -s 180F -c 2A19 ``` ### Monitor Heart Rate Notifications ```sh ble read mydevice -s 180D -c 2A37 --notify ``` ### Send Multi-Field Command Create `command.yaml`: ```yaml service: FFF0 characteristic: FFF1 fields: - { type: u8, value: 0x02 } # Command ID - { type: u16le, value: 1000 } # Parameter ``` Execute: ```sh ble write mydevice -p command.yaml ``` ### Automated Testing / Scripting ```sh #!/bin/bash # Scan for devices, filter by service, connect to first match DEVICE=$(ble scan -s 180D --timeout 5 --json | jq -r '.uuid' | head -n1) ble connect "$DEVICE" & sleep 2 ble read "$DEVICE" -s 180D -c 2A37 --notify --count 10 ``` ### Full GATT Inspection ```sh # Human-readable with values ble inspect mydevice --read # JSON for parsing ble inspect mydevice --json | jq '.services[].characteristics[].uuid' ``` ### Pair and Then Write to Protected Characteristic ```sh # Trigger pairing ble pair mydevice -s FFF0 -c FFF1 --write 0x00 # Subsequent writes succeed without re-pairing ble write mydevice -s FFF0 -c FFF1 --hex 0x0102 ``` ## Troubleshooting ### "Bluetooth access denied" Grant Bluetooth permission to your terminal app in *System Settings → Privacy & Security → Bluetooth*. ### "Peripheral not found" - Ensure the device is powered on and in range - Try `ble scan` first to confirm it's advertising - Use the exact UUID or a unique name substring ### "Characteristic does not support write" The characteristic's properties don't include `write` or `writeWithoutResponse`. Use `ble inspect` to confirm properties. ### "Value exceeds MTU" The payload is larger than the negotiated maximum write length. Split the data or reduce the payload size. The tool warns about this but doesn't auto-split. ### "Connection timeout" - Device may be out of range or turned off - macOS Bluetooth stack may be busy—try toggling Bluetooth off/on in System Settings - Some devices bond to one host at a time—unpair from other devices ### Pairing dialog doesn't appear The characteristic isn't marked as requiring encryption. Check the device's GATT specification or try a different characteristic known to be protected. ### No notifications received - Verify the characteristic supports notify/indicate: `ble inspect mydevice` - Some devices require enabling notifications via the Client Characteristic Configuration Descriptor (CCCD `2902`)—the tool does this automatically ## Integration with Other Tools ### Pipe to `jq` for JSON filtering ```sh ble scan --json | jq 'select(.rssi > -60) | {name, uuid, rssi}' ``` ### Capture raw L2CAP stream ```sh ble l2cap mydevice --psm 128 --raw | xxd ``` ### Log notifications to file ```sh ble read mydevice -s 180D -c 2A37 --notify > heart_rate.log ``` ### Use in scripts with error handling ```sh #!/bin/bash set -e DEVICE="MyDevice" if ! ble connect "$DEVICE" --timeout 5 2>&1 | grep -q "Connected"; then echo "Failed to connect" exit 1 fi ble write "$DEVICE" -p command.yaml ``` ## Environment and Configuration - **NO_COLOR**: Set to disable colored output - Piping automatically disables colors and switches to line-by-line output - Timeout defaults: scan 10s, connect 30s (override with `--timeout`) ## Development and Testing Build from source: ```sh git clone https://github.com/kylebrowning/BLESwiftCLI.git cd BLESwiftCLI swift build .build/debug/ble --help ``` Run tests (no hardware required): ```sh swift test ``` Tests use BLESwift's `FakeCentral` and `FakePeripheral` for logic validation. ## Reference - **Standard BLE Services**: [Bluetooth SIG GATT Services](https://www.bluetooth.com/specifications/gatt/services/) - `180F` = Battery Service - `180D` = Heart Rate - `180A` = Device Information - **Standard Characteristics**: [Bluetooth SIG GATT Characteristics](https://www.bluetooth.com/specifications/gatt/characteristics/) - `2A19` = Battery Level - `2A37` = Heart Rate Measurement - `2902` = Client Characteristic Configuration (CCCD) --- **Key takeaway**: Use `ble scan` to discover, `ble inspect` to explore GATT, `ble read`/`write` for data, and payload files for complex structured writes.
Ver en GitHub