====== std.hardware.bluetooth ======
Nativer Bluetooth-Stack für Linux: von rohen AF_BLUETOOTH-Sockets über BlueZ-D-Bus-Steuerung bis zu vollständigen GATT-Client-/Server-Implementierungen für Bluetooth Low Energy (BLE) und Classic Bluetooth (RFCOMM). Alle neun Units implementieren das Protokoll direkt in Lyx — keine externen Bluetooth-Bibliotheken. Verbindungen werden als Dateideskriptoren (''int64'') verwaltet; jede Funktion nimmt einen ''fd'' entgegen.
→ [[lyx_-_programmiersprache:units|Standard Library]] · [[lyx_-_programmiersprache:units:android|std.android]]
----
===== Architektur =====
Übersicht der internen Schichten und Abhängigkeiten:
┌─────────────────────────────────────────────────────┐
│ AI / Profile-Typen │
│ bluetooth_ai │
├─────────────────────────────────────────────────────┤
│ BLE: GATT-Schicht │
│ bluetooth_gattc · bluetooth_gatts │
├──────────────────────────┬──────────────────────────┤
│ BLE: L2CAP / ATT │ Classic: RFCOMM │
│ bluetooth_l2cap │ bluetooth_rfcomm │
├──────────────────────────┴──────────────────────────┤
│ Erweiterungen (BLE Scanner, Advertising, Mesh) │
│ bluetooth_ext │
├─────────────────────────────────────────────────────┤
│ Steuerungsebene (BlueZ D-Bus) │
│ bluetooth_dbus │
├─────────────────────────────────────────────────────┤
│ Typen & Low-Level Syscalls │
│ bluetooth_types · bluetooth │
└─────────────────────────────────────────────────────┘
----
===== Units =====
^ Unit ^ Beschreibung ^
| [[lyx_-_programmiersprache:units:hardware:bluetooth|std.hardware.bluetooth]] | Low-Level Bluetooth-Socket-Syscalls (AF_BLUETOOTH): BTSocket, BTConnect, BTSend, BTRecv, BTIoctl |
| [[lyx_-_programmiersprache:units:hardware:bluetooth_types|std.hardware.bluetooth_types]] | Adress-Typen und -Hilfsfunktionen: BTAddrFromBytes, BTAddrToStr, BTSockAddrRcCreate, BTSockAddrL2Create |
| [[lyx_-_programmiersprache:units:hardware:bluetooth_dbus|std.hardware.bluetooth_dbus]] | BlueZ D-Bus Steuerungsebene: BlueZOpenConnection, BlueZDiscoverDevices, BlueZConnectDevice |
| [[lyx_-_programmiersprache:units:hardware:bluetooth_rfcomm|std.hardware.bluetooth_rfcomm]] | RFCOMM (Classic Bluetooth Serial): RFCommConnect, RFCommListen, RFCommSend, RFCommRecv |
| [[lyx_-_programmiersprache:units:hardware:bluetooth_l2cap|std.hardware.bluetooth_l2cap]] | L2CAP + ATT-Protokollschicht: L2CapConnect, AttReadChar, AttWriteChar, AttRecvNotification |
| [[lyx_-_programmiersprache:units:hardware:bluetooth_gattc|std.hardware.bluetooth_gattc]] | GATT-Client: GattDiscoverServices, GattDiscoverChars, GattReadChar, GattWriteChar, GattEnableNotification |
| [[lyx_-_programmiersprache:units:hardware:bluetooth_gatts|std.hardware.bluetooth_gatts]] | GATT-Server: GattServerRegister, GattServerHandleNext, GattServerSendNotification |
| [[lyx_-_programmiersprache:units:hardware:bluetooth_ext|std.hardware.bluetooth_ext]] | BLE Scanner, Advertising und Mesh: BleScannerStart, BleAdvertisementRegister, MeshNetworkJoin |
| [[lyx_-_programmiersprache:units:hardware:bluetooth_ai|std.hardware.bluetooth_ai]] | KI-native, typsichere Bluetooth-Profile als Compiler-Typen |
----
===== std.hardware.bluetooth =====
Unterste Schicht: direkte AF_BLUETOOTH-Socket-Syscalls. Wird in der Regel nicht direkt verwendet — ''bluetooth_rfcomm'' und ''bluetooth_l2cap'' bauen darauf auf.
==== Protokoll-Konstanten ====
^ Konstante ^ Wert ^ Beschreibung ^
| ''AF_BLUETOOTH'' | 31 | Socket-Family für Bluetooth |
| ''BTPROTO_L2CAP'' | 0 | L2CAP-Protokoll (BLE und Classic) |
| ''BTPROTO_HCI'' | 1 | Host Controller Interface (raw) |
| ''BTPROTO_RFCOMM'' | 3 | RFCOMM: serielle Emulation (Classic) |
| ''BTPROTO_BNEP'' | 4 | Bluetooth Network Encapsulation |
| ''BTPROTO_SCO'' | 6 | Synchronous Connection-Oriented (Audio) |
| ''BT_PSM_ATT'' | 31 | ATT-Protokoll-PSM (0x001F) |
| ''SOCK_SEQPACKET'' | 5 | Paket-orientierter Socket (L2CAP BLE) |
==== Security-Flags (BT_LM_*) ====
^ Konstante ^ Beschreibung ^
| ''BT_LM_AUTH'' | Authentifizierung erforderlich |
| ''BT_LM_ENCRYPT'' | Verschlüsselung erforderlich |
| ''BT_LM_SECURE'' | Secure Simple Pairing erzwingen |
==== Funktionen ====
^ Signatur ^ Beschreibung ^
| ''BTSocket(socktype: int64, protocol: int64): int64'' | Erzeugt AF_BLUETOOTH-Socket; gibt fd zurück |
| ''BTBind(fd: int64, addrPtr: int64, addrLen: int64): int64'' | Bindet Socket an lokale Adresse |
| ''BTConnect(fd: int64, addrPtr: int64, addrLen: int64): int64'' | Verbindet zum Remote-Gerät |
| ''BTListen(fd: int64, backlog: int64): int64'' | Öffnet Socket als Server |
| ''BTAccept(fd: int64, addrPtr: int64, addrLenPtr: int64): int64'' | Nimmt eingehende Verbindung an |
| ''BTSend(fd: int64, buf: int64, len: int64, flags: int64): int64'' | Sendet Daten |
| ''BTRecv(fd: int64, buf: int64, len: int64, flags: int64): int64'' | Empfängt Daten |
| ''BTGetSockOpt(fd: int64, level: int64, optname: int64, optval: int64, optlen: int64): int64'' | Liest Socket-Option |
| ''BTSetSockOpt(fd: int64, level: int64, optname: int64, optval: int64, optlen: int64): int64'' | Setzt Socket-Option |
| ''BTSocketPoll(fdsPtr: int64, nfds: int64, timeoutMs: int64): int64'' | ''poll()'' über mehrere BT-Sockets |
| ''BTIoctl(fd: int64, request: int64, argPtr: int64): int64'' | HCI-ioctl (HCIDEVUP, HCIGETDEVINFO …) |
| ''BTClose(fd: int64): int64'' | Schließt Socket |
| ''BTPollFdSet(ptr: int64, fd: int64, events: int64)'' | Befüllt pollfd-Eintrag in einem Array |
| ''BTPollFdRevents(ptr: int64): int64'' | Liest revents aus einem pollfd-Eintrag |
----
===== std.hardware.bluetooth_types =====
Adress-Typen und Hilfsfunktionen. Alle Bluetooth-Adressen sind heap-allozierte 6-Byte-Puffer (''int64'' als Zeiger).
==== Größen-Konstanten ====
^ Konstante ^ Wert ^ Beschreibung ^
| ''BT_BDADDR_SIZE'' | 6 | Größe einer Bluetooth-MAC-Adresse in Bytes |
| ''BT_SOCKADDR_RC_SIZE'' | 10 | Größe von ''struct sockaddr_rc'' (RFCOMM) |
| ''BT_SOCKADDR_L2_SIZE'' | 14 | Größe von ''struct sockaddr_l2'' (L2CAP) |
| ''BDADDR_BREDR'' | 0 | Klassisches Bluetooth (BR/EDR) |
| ''BDADDR_LE_PUBLIC'' | 1 | BLE — öffentliche Adresse |
| ''BDADDR_LE_RANDOM'' | 2 | BLE — zufällige Adresse |
==== Funktionen ====
^ Signatur ^ Beschreibung ^
| ''BTAddrFromBytes(b0..b5: int64): int64'' | Erzeugt Adress-Puffer aus 6 einzelnen Bytes; gibt Zeiger zurück |
| ''BTAddrGetByte(addr: int64, byteIdx: int64): int64'' | Liest ein Adress-Byte (Index 0–5) |
| ''BTAddrToUInt64(addr: int64): int64'' | Gibt Adresse als uint64 zurück |
| ''BTAddrToStr(addr: int64, outBuf: int64)'' | Schreibt ''AA:BB:CC:DD:EE:FF''-String nach outBuf (min. 18 Bytes) |
| ''BTStrToAddr(s: int64): int64'' | Parst ''AA:BB:CC:DD:EE:FF''-String; gibt Adress-Zeiger zurück |
| ''BTSockAddrRcCreate(buf: int64, bdaddr: int64, channel: int64)'' | Füllt ''struct sockaddr_rc'' für RFCOMM |
| ''BTSockAddrL2Create(buf: int64, psm: int64, bdaddr: int64, addrType: int64)'' | Füllt ''struct sockaddr_l2'' für L2CAP |
| ''BTSockAddrRcReadAddr(buf: int64): int64'' | Liest bdaddr aus sockaddr_rc |
| ''BTSockAddrRcReadChannel(buf: int64): int64'' | Liest channel aus sockaddr_rc |
import std.hardware.bluetooth_types;
import std.alloc;
var addr := BTStrToAddr("AA:BB:CC:DD:EE:FF");
var outBuf: int64 := alloc(18);
BTAddrToStr(addr, outBuf); // → "AA:BB:CC:DD:EE:FF"
----
===== std.hardware.bluetooth_dbus =====
Steuerungsebene über das BlueZ-D-Bus-Interface. Ermöglicht Gerätesuche, Pairing und Verbindungsaufbau ohne direkten HCI-Zugriff. Erfordert einen laufenden BlueZ-Daemon (''bluetoothd'').
==== Wichtige Konstanten ====
^ Konstante ^ Beschreibung ^
| ''DBUS_TYPE_METHOD_CALL'' | Nachrichtentyp: Methodenaufruf |
| ''DBUS_HDR_PATH'' | Header-Feld: Objekt-Pfad |
| ''DBUS_HDR_INTERFACE'' | Header-Feld: Interface-Name |
| ''DBUS_HDR_MEMBER'' | Header-Feld: Methoden-/Signal-Name |
| ''DBUS_HDR_DESTINATION'' | Header-Feld: Ziel-Bus-Name |
==== Funktionen ====
^ Signatur ^ Beschreibung ^
| ''BlueZOpenConnection(): int64'' | Öffnet Unix-Domain-Socket zum BlueZ-Daemon; gibt fd zurück |
| ''BlueZClose(fd: int64)'' | Schließt D-Bus-Verbindung |
| ''BlueZStartDiscovery(fd: int64, adapterPath: int64, pathLen: int64): int64'' | Startet Gerätescan auf dem Adapter (z. B. ''/org/bluez/hci0'') |
| ''BlueZStopDiscovery(fd: int64, adapterPath: int64, pathLen: int64): int64'' | Stoppt den Scan |
| ''BlueZGetManagedObjects(fd: int64, outBuf: int64, maxLen: int64): int64'' | Liest alle bekannten Geräte und deren Properties |
| ''BlueZFindDeviceAddress(data: int64, dataLen: int64, addrBuf: int64): int64'' | Sucht Geräteadresse in GetManagedObjects-Antwort |
| ''BlueZDiscoverDevices(fd: int64, adapterPath: int64, pathLen: int64, ...): int64'' | Kombinierter Scan-Helfer: startet, wartet, liest Geräteliste |
| ''BlueZPairDevice(fd: int64, devicePath: int64, pathLen: int64): int64'' | Startet Pairing-Prozess mit einem Gerät |
| ''BlueZConnectDevice(fd: int64, devicePath: int64, pathLen: int64): int64'' | Verbindet mit einem bekannten Gerät |
| ''BlueZDisconnectDevice(fd: int64, devicePath: int64, pathLen: int64): int64'' | Trennt Verbindung |
import std.hardware.bluetooth_dbus;
import std.hardware.bluetooth_types;
import std.alloc;
import std.io;
fn ScanDevices(): void {
var fd := BlueZOpenConnection();
var adapterPath: pchar := "/org/bluez/hci0";
var pathLen: int64 := 16;
BlueZStartDiscovery(fd, adapterPath, pathLen);
Sleep(5000);
BlueZStopDiscovery(fd, adapterPath, pathLen);
var buf: int64 := alloc(4096);
BlueZGetManagedObjects(fd, buf, 4096);
var addrBuf: int64 := alloc(18);
BlueZFindDeviceAddress(buf, 4096, addrBuf);
Print(addrBuf);
BlueZClose(fd);
free(buf, 4096);
free(addrBuf, 18);
}
----
===== std.hardware.bluetooth_rfcomm =====
RFCOMM emuliert einen seriellen Port über Bluetooth Classic (BR/EDR). Typische Anwendungen: Verbindung zu Mikrocontrollern (HC-05, HC-06), Barcode-Scannern und Legacy-Geräten.
==== Funktionen ====
^ Signatur ^ Beschreibung ^
| ''RFCommConnect(bdaddr: int64, channel: int64): int64'' | Verbindet als Client; gibt fd zurück |
| ''RFCommListen(channel: int64, backlog: int64): int64'' | Öffnet Server-Socket |
| ''RFCommAccept(listenFd: int64, remoteAddrOut: int64): int64'' | Nimmt Verbindung an; füllt remoteAddrOut |
| ''RFCommSend(fd: int64, buf: int64, len: int64): int64'' | Sendet Daten |
| ''RFCommSendAll(fd: int64, buf: int64, len: int64): int64'' | Sendet alle Daten (loop bis len Bytes gesendet) |
| ''RFCommRecv(fd: int64, buf: int64, len: int64): int64'' | Empfängt Daten |
| ''RFCommSetSecurity(fd: int64, flags: int64): int64'' | Setzt Sicherheitsstufe (BT_LM_AUTH, BT_LM_ENCRYPT …) |
| ''RFCommPoll(fd: int64, timeoutMs: int64): int64'' | Wartet auf eingehende Daten (> 0 = Daten verfügbar) |
| ''RFCommClose(fd: int64): int64'' | Schließt Verbindung |
import std.hardware.bluetooth_rfcomm;
import std.hardware.bluetooth_types;
import std.alloc;
import std.io;
fn ConnectArduino(): void {
var addr := BTStrToAddr("98:D3:31:F5:AB:CD");
var fd := RFCommConnect(addr, 1);
var msg: pchar := "LED:ON\n";
RFCommSendAll(fd, msg, 7);
var buf: int64 := alloc(64);
var n := RFCommRecv(fd, buf, 63);
Print(buf);
RFCommClose(fd);
free(buf, 64);
}
----
===== std.hardware.bluetooth_l2cap =====
L2CAP ist die Transportschicht für BLE-Verbindungen. Diese Unit enthält zusätzlich eine vollständige ATT-Implementierung (Attribute Protocol) — die Grundlage für GATT.
==== L2CAP-Funktionen ====
^ Signatur ^ Beschreibung ^
| ''L2CapConnect(bdaddr: int64, psm: int64, addrType: int64): int64'' | Verbindet L2CAP-Socket; addrType: BDADDR_LE_PUBLIC / BDADDR_LE_RANDOM |
| ''L2CapListen(psm: int64, backlog: int64): int64'' | Öffnet Server-Socket |
| ''L2CapSetMtu(fd: int64, imtu: int64): int64'' | Setzt Input-MTU |
| ''L2CapClose(fd: int64): int64'' | Schließt Verbindung |
| ''L2CapPoll(fd: int64, timeoutMs: int64): int64'' | Wartet auf eingehende Daten |
==== ATT-Funktionen ====
^ Signatur ^ Beschreibung ^
| ''AttExchangeMtu(fd: int64, clientMtu: int64): int64'' | MTU-Verhandlung; gibt Server-MTU zurück |
| ''AttSend(fd: int64, opcode: int64, payload: int64, payloadLen: int64): int64'' | Sendet rohe ATT-PDU |
| ''AttRecv(fd: int64, opcodeOut: int64, dataBuf: int64, bufLen: int64): int64'' | Empfängt ATT-PDU; schreibt Opcode nach opcodeOut |
| ''AttReadChar(fd: int64, handle: int64, dataBuf: int64, bufLen: int64): int64'' | Liest Attribut per Handle (ATT_OP_READ_REQ) |
| ''AttWriteChar(fd: int64, handle: int64, data: int64, dataLen: int64): int64'' | Schreibt Attribut mit Antwort (ATT_OP_WRITE_REQ) |
| ''AttWriteCmd(fd: int64, handle: int64, data: int64, dataLen: int64): int64'' | Schreibt ohne Antwort (ATT_OP_WRITE_CMD, 0x52) |
| ''AttRecvNotification(fd: int64, handleOut: int64, dataBuf: int64, bufLen: int64): int64'' | Empfängt ATT_OP_HANDLE_VALUE_NTF |
==== ATT-Konstanten (Auswahl) ====
^ Konstante ^ Wert ^ Beschreibung ^
| ''ATT_DEFAULT_MTU'' | 23 | Standard BLE ATT MTU |
| ''ATT_MAX_MTU'' | 517 | Maximal verhandelbare MTU |
| ''ATT_OP_READ_REQ'' | 10 | Lese-Request |
| ''ATT_OP_WRITE_REQ'' | 18 | Schreib-Request (mit ACK) |
| ''ATT_OP_WRITE_CMD'' | 82 | Schreib-Command (ohne ACK) |
| ''ATT_OP_HANDLE_VALUE_NTF'' | 27 | Notification (kein ACK) |
| ''ATT_OP_HANDLE_VALUE_IND'' | 29 | Indication (ACK erforderlich) |
----
===== std.hardware.bluetooth_gattc =====
GATT-Client baut auf einem L2CAP/ATT-fd auf. Der fd wird vorher via ''L2CapConnect'' erzeugt. Servicelisten und Characteristic-Listen werden in heap-allokierten Puffern gehalten; Accessor-Funktionen lesen einzelne Felder heraus.
==== Service-Konstanten ====
^ Konstante ^ UUID ^ Beschreibung ^
| ''GATT_SVC_GENERIC_ACCESS'' | 0x1800 | Generic Access Service |
| ''GATT_SVC_GENERIC_ATTRIBUTE'' | 0x1801 | Generic Attribute Service |
| ''GATT_SVC_HEART_RATE'' | 0x180D | Heart Rate Service |
| ''GATT_SVC_BATTERY'' | 0x180F | Battery Service |
| ''GATT_SVC_DEVICE_INFO'' | 0x180A | Device Information Service |
| ''GATT_SVC_CURRENT_TIME'' | 0x1805 | Current Time Service |
==== Characteristic-UUID-Konstanten ====
^ Konstante ^ UUID ^ Beschreibung ^
| ''GATT_UUID_DEVICE_NAME'' | 0x2A00 | Gerätename |
| ''GATT_UUID_HR_MEASUREMENT'' | 0x2A37 | Heart Rate Measurement |
| ''GATT_UUID_HR_BODY_LOCATION'' | 0x2A38 | Body Sensor Location |
| ''GATT_UUID_BATTERY_LEVEL'' | 0x2A19 | Akkustand (0–100 %) |
| ''GATT_UUID_FIRMWARE_REV'' | 0x2A26 | Firmware-Revision |
| ''GATT_UUID_MODEL_NUMBER'' | 0x2A24 | Modellnummer |
| ''GATT_UUID_CCCD'' | 0x2902 | Client Characteristic Configuration (Notification-Enable) |
==== Properties-Bits ====
^ Konstante ^ Beschreibung ^
| ''GATT_PROP_READ'' | Characteristic ist lesbar |
| ''GATT_PROP_WRITE_NO_RSP'' | Schreiben ohne Antwort (Write Command) |
| ''GATT_PROP_WRITE'' | Schreiben mit Antwort (Write Request) |
| ''GATT_PROP_NOTIFY'' | Server kann Notifications senden |
| ''GATT_PROP_INDICATE'' | Server kann Indications senden (mit ACK) |
==== Discovery-Funktionen ====
^ Signatur ^ Beschreibung ^
| ''GattDiscoverServices(fd: int64, outBuf: int64, maxServices: int64): int64'' | Entdeckt alle Primary Services; gibt Anzahl zurück |
| ''GattDiscoverChars(fd: int64, startHandle: int64, endHandle: int64, outBuf: int64, maxChars: int64): int64'' | Entdeckt Characteristics in einem Service-Handle-Bereich |
| ''GattFindServiceByUUID(svcBuf: int64, svcCount: int64, uuid: int64): int64'' | Sucht Service-Index nach UUID; −1 wenn nicht gefunden |
| ''GattFindCharByUUID(charBuf: int64, charCount: int64, uuid: int64): int64'' | Sucht Characteristic-Index nach UUID; −1 wenn nicht gefunden |
==== Puffer-Accessoren ====
Direktzugriff auf den internen Puffer:
^ Signatur ^ Beschreibung ^
| ''GattSvcStart(buf: int64, idx: int64): int64'' | Start-Handle des Services |
| ''GattSvcEnd(buf: int64, idx: int64): int64'' | End-Handle des Services |
| ''GattSvcUUID(buf: int64, idx: int64): int64'' | UUID des Services (16-Bit) |
| ''GattCharDecl(buf: int64, idx: int64): int64'' | Declaration-Handle der Characteristic |
| ''GattCharValue(buf: int64, idx: int64): int64'' | Value-Handle der Characteristic |
| ''GattCharUUID(buf: int64, idx: int64): int64'' | UUID der Characteristic (16-Bit) |
| ''GattCharProps(buf: int64, idx: int64): int64'' | Properties-Bitmask der Characteristic |
==== Read/Write/Notify ====
^ Signatur ^ Beschreibung ^
| ''GattReadChar(fd: int64, valueHandle: int64, dataBuf: int64, bufLen: int64): int64'' | Liest Characteristic-Wert |
| ''GattWriteChar(fd: int64, valueHandle: int64, data: int64, dataLen: int64): int64'' | Schreibt Wert mit Antwort |
| ''GattWriteCmd(fd: int64, valueHandle: int64, data: int64, dataLen: int64): int64'' | Schreibt ohne Antwort |
| ''GattEnableNotification(fd: int64, cccdHandle: int64): int64'' | Aktiviert Notifications (schreibt 0x0001 in CCCD) |
| ''GattDisableNotification(fd: int64, cccdHandle: int64): int64'' | Deaktiviert Notifications |
| ''GattEnableIndication(fd: int64, cccdHandle: int64): int64'' | Aktiviert Indications (schreibt 0x0002 in CCCD) |
| ''GattRecvNotification(fd: int64, handleOut: int64, dataBuf: int64, bufLen: int64): int64'' | Empfängt nächste Notification; schreibt Handle nach handleOut |
| ''GattPoll(fd: int64, timeoutMs: int64): int64'' | Wartet auf Notification/Indication |
| ''ReadHeartRate(fd: int64, hrHandle: int64, ...): int64'' | High-Level-Helfer: liest Herzrate als BPM |
| ''ReadBatteryLevel(fd: int64, battHandle: int64): int64'' | High-Level-Helfer: liest Akkustand (0–100) |
import std.hardware.bluetooth_l2cap;
import std.hardware.bluetooth_gattc;
import std.hardware.bluetooth_types;
import std.alloc;
import std.io;
fn ReadBattery(addrStr: pchar): int64 {
var addr := BTStrToAddr(addrStr);
var fd := L2CapConnect(addr, BT_PSM_ATT, BDADDR_LE_PUBLIC);
AttExchangeMtu(fd, 512);
var svcBuf: int64 := alloc(GATT_SVC_RECORD_SIZE * 16);
var svcCount := GattDiscoverServices(fd, svcBuf, 16);
var idx := GattFindServiceByUUID(svcBuf, svcCount, GATT_SVC_BATTERY);
var charBuf: int64 := alloc(GATT_CHAR_RECORD_SIZE * 8);
GattDiscoverChars(fd, GattSvcStart(svcBuf, idx), GattSvcEnd(svcBuf, idx),
charBuf, 8);
var cidx := GattFindCharByUUID(charBuf, 8, GATT_UUID_BATTERY_LEVEL);
var valBuf: int64 := alloc(4);
GattReadChar(fd, GattCharValue(charBuf, cidx), valBuf, 4);
var level: int64 := peek8(valBuf);
L2CapClose(fd);
free(svcBuf, GATT_SVC_RECORD_SIZE * 16);
free(charBuf, GATT_CHAR_RECORD_SIZE * 8);
free(valBuf, 4);
return level;
}
fn MonitorHeartRate(addrStr: pchar): void {
var addr := BTStrToAddr(addrStr);
var fd := L2CapConnect(addr, BT_PSM_ATT, BDADDR_LE_PUBLIC);
AttExchangeMtu(fd, 512);
var svcBuf: int64 := alloc(GATT_SVC_RECORD_SIZE * 16);
var svcCount := GattDiscoverServices(fd, svcBuf, 16);
var idx := GattFindServiceByUUID(svcBuf, svcCount, GATT_SVC_HEART_RATE);
var charBuf: int64 := alloc(GATT_CHAR_RECORD_SIZE * 8);
GattDiscoverChars(fd, GattSvcStart(svcBuf, idx), GattSvcEnd(svcBuf, idx), charBuf, 8);
var cidx := GattFindCharByUUID(charBuf, 8, GATT_UUID_HR_MEASUREMENT);
GattEnableNotification(fd, GattCharValue(charBuf, cidx) + 1); // CCCD handle
var ntfBuf: int64 := alloc(32);
var handleOut: int64 := alloc(8);
var i: int64 := 0;
while (i < 10) {
GattPoll(fd, 5000);
GattRecvNotification(fd, handleOut, ntfBuf, 32);
Print("BPM: ");
PrintLn(IntToStr(peek8(ntfBuf + 1))); // Byte 0 = Flags, Byte 1 = BPM
i := i + 1;
}
L2CapClose(fd);
}
----
===== std.hardware.bluetooth_gatts =====
GATT-Server registriert Services über D-Bus und macht das Gerät zum BLE-Peripheral. Erfordert eine aktive ''BlueZOpenConnection''.
==== Puffer-Accessoren ====
Direktzugriff auf den internen Puffer:
^ Signatur ^ Beschreibung ^
| ''GattsCharDefUUID(buf: int64, idx: int64): int64'' | UUID der Characteristic-Definition |
| ''GattsCharDefProps(buf: int64, idx: int64): int64'' | Properties-Bits |
| ''GattsCharDefValuePtr(buf: int64, idx: int64): int64'' | Zeiger auf aktuellen Wert |
| ''GattsCharDefValueLen(buf: int64, idx: int64): int64'' | Länge des aktuellen Werts |
| ''GattsCharDefSetValue(buf: int64, idx: int64, ptr: int64, len: int64)'' | Setzt neuen Wert |
==== Server-Funktionen ====
^ Signatur ^ Beschreibung ^
| ''GattServerRegister(dbusFd: int64, ...): int64'' | Registriert Service-Struktur via D-Bus bei BlueZ |
| ''GattServerHandleNext(fd: int64, svcUUID: int64, ...): int64'' | Verarbeitet nächste eingehende Read/Write-Anfrage |
| ''GattServerSendNotification(fd: int64, ...): int64'' | Sendet Notification an verbundene Centrals |
----
===== std.hardware.bluetooth_ext =====
Ergänzungen für aktives BLE-Scanning, Advertising-Pakete und Bluetooth-Mesh.
==== Scan-Puffer-Konstanten ====
^ Konstante ^ Wert ^ Beschreibung ^
| ''BLE_SCAN_RESULT_SIZE'' | 128 | Größe eines einzelnen Scan-Ergebnis-Eintrags |
==== Scan-Ergebnis-Accessoren ====
^ Signatur ^ Beschreibung ^
| ''BleScanResultAddr(buf: int64, idx: int64): int64'' | Zeiger auf Geräteadresse (6 Bytes) |
| ''BleScanResultRSSI(buf: int64, idx: int64): int64'' | Signalstärke in dBm |
| ''BleScanResultIsConnectable(buf: int64, idx: int64): int64'' | 1 wenn Gerät verbindbar |
| ''BleScanResultNameLen(buf: int64, idx: int64): int64'' | Länge des Gerätenamens |
| ''BleScanResultName(buf: int64, idx: int64): int64'' | Zeiger auf Gerätenamen |
| ''BleScanResultAdvLen(buf: int64, idx: int64): int64'' | Länge der Advertising-Daten |
| ''BleScanResultAdvData(buf: int64, idx: int64): int64'' | Zeiger auf rohe Advertising-Daten |
==== Scanner-Funktionen ====
^ Signatur ^ Beschreibung ^
| ''BleScannerStart(fd: int64, adapterPath: int64, pathLen: int64): int64'' | Startet BLE-Scan via BlueZ |
| ''BleScannerStop(fd: int64, adapterPath: int64, pathLen: int64): int64'' | Stoppt Scan |
| ''BleScannerReadNext(fd: int64, result: int64): int64'' | Liest nächstes Scan-Ergebnis in result-Puffer |
| ''BleScan(fd: int64, adapterPath: int64, pathLen: int64, ...): int64'' | Kombiniert Start, Collect und Stop |
==== Advertising-Konstanten ====
^ Konstante ^ Beschreibung ^
| ''BLE_ADV_TYPE_PERIPHERAL'' | Verbindbares Advertising (Peripheral-Rolle) |
| ''BLE_ADV_TYPE_BROADCAST'' | Nicht-verbindbares Advertising (Beacon) |
| ''BLE_ADV_CONFIG_SIZE'' | Größe des Advertising-Konfigurations-Puffers |
==== Advertising-Funktionen ====
^ Signatur ^ Beschreibung ^
| ''BleAdvertisementRegister(fd: int64, advConfig: int64, serial: int64): int64'' | Registriert Advertising-Konfiguration bei BlueZ |
| ''BleAdvertisementHandleGetAll(fd: int64, advConfig: int64, serial: int64): int64'' | Verarbeitet eingehende D-Bus-Nachrichten für Advertising |
| ''BleAdvertisementUnregister(fd: int64, ...): int64'' | Stoppt Advertising |
==== Mesh-Funktionen ====
^ Signatur ^ Beschreibung ^
| ''MeshNetworkJoin(fd: int64, uuid: int64): int64'' | Tritt einem Bluetooth-Mesh-Netzwerk bei |
| ''MeshSend(fd: int64, dst: int64, data: int64, dataLen: int64): int64'' | Sendet Mesh-Nachricht an Adresse |
| ''MeshRecv(fd: int64, srcOut: int64, dataBuf: int64, bufLen: int64): int64'' | Empfängt Mesh-Nachricht; schreibt Quelladresse nach srcOut |
import std.hardware.bluetooth_ext;
import std.hardware.bluetooth_dbus;
import std.hardware.bluetooth_types;
import std.alloc;
import std.io;
fn ScanAndPrint(): void {
var fd := BlueZOpenConnection();
var path: pchar := "/org/bluez/hci0";
var resultBuf: int64 := alloc(BLE_SCAN_RESULT_SIZE * 32);
var count := BleScan(fd, path, 16, resultBuf, 32);
var i: int64 := 0;
while (i < count) {
if (BleScanResultIsConnectable(resultBuf, i) != 0) {
var nameBuf: int64 := alloc(64);
var nameLen := BleScanResultNameLen(resultBuf, i);
// Name-Bytes kopieren …
PrintLn("RSSI: " + IntToStr(BleScanResultRSSI(resultBuf, i)) + " dBm");
free(nameBuf, 64);
}
i := i + 1;
}
BlueZClose(fd);
free(resultBuf, BLE_SCAN_RESULT_SIZE * 32);
}
----
===== std.hardware.bluetooth_ai =====
KI-native Bluetooth-Profile: Definiert Standard-BLE-Profile als typsichere Compiler-Typen, sodass manuelle UUID-Verwaltung und Buffer-Arithmetik entfallen. Wrapper-Schicht über ''bluetooth_gattc''.
import std.hardware.bluetooth_ai;
import std.hardware.bluetooth_types;
var addr := BTStrToAddr("AA:BB:CC:DD:EE:FF");
// Typsichere Profile — Compiler kennt die Semantik
var sensor: BleSensor;
sensor.Connect(addr);
var bpm: HeartRateValue := sensor.Read();
PrintLn(IntToStr(bpm.value) + " bpm");
var batt: BleSensor;
batt.Connect(addr);
PrintLn(IntToStr(batt.Read().percent) + " %");
==== Unterstützte Profile ====
^ Profil-Typ ^ Service-UUID ^ Beschreibung ^
| ''BleSensor'' | 0x180D | Herzrate und Körperkontakt-Erkennung |
| ''BleSensor'' | 0x180F | Akkustand (0–100 %) |
| ''BleSensor'' | 0x1809 | Körper- oder Umgebungstemperatur |
| ''BleSensor'' | 0x1808 | Blutzuckermessung |
| ''BleSensor'' | 0x1810 | Blutdruck (systolisch/diastolisch) |
| ''BleSensor'' | 0x1814 | Schrittanzahl und Distanz |
| ''BleActuator'' | benutzerdefiniert | Generischer LED-Aktor |
| ''BleActuator'' | benutzerdefiniert | Generischer Relais-Aktor |
----
===== Verwandte Units =====
* ''[[lyx_-_programmiersprache:units:thread|std.thread]]'' — Threads für parallele Sensor-Verbindungen
* ''[[lyx_-_programmiersprache:units:signals|std.signals]]'' — Signalbehandlung für sauberes Herunterfahren
* ''[[lyx_-_programmiersprache:units:net:socket|std.net.socket]]'' — TCP/UDP-Netzwerkkommunikation
* ''[[lyx_-_programmiersprache:units:android:ioctl|std.android.ioctl]]'' — ioctl-Nummern für Android-Bluetooth-Treiber
Letzte Aktualisierung: 2026-06-05