Kablosuz Yığını
TEKNİK REHBER KABLOSUZ YIĞINI BLUETOOTH 2026

BlueZ
linux bluetooth yığını.

D-Bus mimarisi, HCI, bluetoothctl ve Python pydbus API — BR/EDR'den BLE'ye Linux'ta Bluetooth'un tüm katmanları.

00 BlueZ mimarisi — D-Bus, HCI, kernel yığını

BlueZ, Linux'un resmi Bluetooth protokol yığınıdır. Kernel'dan uygulama katmanına kadar tüm Bluetooth işlevlerini kapsar.

  Uygulama (Python, C, bluetoothctl)
         ↓  D-Bus API
  bluetoothd   →  BlueZ daemon (userspace)
         ↓  HCI socket (BTPROTO_HCI)
  Kernel Bluetooth subsystem
         ├── L2CAP   (Logical Link Control)
         ├── RFCOMM  (Serial Port Emulation)
         ├── BNEP    (Bluetooth Network Encapsulation)
         ├── HID     (Human Interface Device)
         └── ATT/GATT (BLE)
         ↓
  HCI driver  →  hci_uart (UART), hci_usb (USB), hci_vhci
         ↓
  Bluetooth donanımı  (BCM43xx, CSR8510, nRF52, CC2642)
    

BlueZ, uygulamalarla D-Bus üzerinden iletişim kurar. bluetoothd daemon'ı, sistem D-Bus üzerinde org.bluez servisini sunar. Tüm Bluetooth nesneleri (adapter, device, GATT service) D-Bus object path'leri ile temsil edilir.

Kurulum

bash
# Debian / Ubuntu / Raspberry Pi OS
apt-get install bluez bluetooth

# Python D-Bus kütüphanesi
pip3 install pydbus PyGObject

# BlueZ versiyon kontrol
bluetoothd --version
# 5.66

# Servis başlat
systemctl start bluetooth

# HCI cihazlarını listele
hciconfig
# hci0:  Type: Primary  Bus: UART
#         BD Address: DC:A6:32:XX:XX:XX  ACL MTU: 1021:8  SCO MTU: 64:1
#         UP RUNNING

01 bluetoothctl — cihaz tarama, eşleştirme, bağlama

bluetoothctl, BlueZ'in interaktif komut satırı aracıdır. D-Bus API'sinin tüm işlevlerine erişim sağlar.

bash — bluetoothctl başlatma
bluetoothctl
# Agent registered
# [bluetooth]#

Temel işlemler

bluetoothctl prompt
# Adapter bilgisi
[bluetooth]# show
Controller DC:A6:32:XX:XX:XX (public)
    Name: raspberrypi
    Alias: raspberrypi
    Class: 0x00200000
    Powered: yes
    Discoverable: no
    DiscoverableTimeout: 0x000000b4
    Pairable: yes
    UUID: Generic Attribute Profile (00001801-...)
    UUID: Generic Access Profile  (00001800-...)
    Modalias: usb:v1D6Bp0246d0537
    Discovering: no

# Adaptörü aç/kapat
[bluetooth]# power on
[bluetooth]# power off

# Taramayı başlat
[bluetooth]# scan on
# Discovery started
# [NEW] Device AA:BB:CC:DD:EE:01 Sıcaklık_Sensörü
# [NEW] Device AA:BB:CC:DD:EE:02 Telefon

# Bulunan cihazları listele
[bluetooth]# devices
# Device AA:BB:CC:DD:EE:01 Sıcaklık_Sensörü
# Device AA:BB:CC:DD:EE:02 Telefon

# Taramayı durdur
[bluetooth]# scan off

# Cihaza bağlan (eşleştirmeden)
[bluetooth]# connect AA:BB:CC:DD:EE:01

# Eşleştir (pair)
[bluetooth]# pair AA:BB:CC:DD:EE:01

# Güvenilir yap (otomatik bağlantı)
[bluetooth]# trust AA:BB:CC:DD:EE:01

# Cihaz bilgisi
[bluetooth]# info AA:BB:CC:DD:EE:01
# Device AA:BB:CC:DD:EE:01 (public)
#     Name: Sıcaklık_Sensörü
#     Alias: Sıcaklık_Sensörü
#     Paired: yes
#     Trusted: yes
#     Connected: yes
#     RSSI: -52

# Bağlantıyı kes
[bluetooth]# disconnect AA:BB:CC:DD:EE:01

# Eşleştirmeyi kaldır
[bluetooth]# remove AA:BB:CC:DD:EE:01

Non-interaktif bluetoothctl

bash — script'ten kullanım
# Tek komut çalıştır
bluetoothctl power on
bluetoothctl show

# Pipe ile komut dizisi
echo -e "power on\nscan on" | bluetoothctl

# Expect benzeri yaklaşım (script)
bluetoothctl -- connect AA:BB:CC:DD:EE:01

02 hciconfig ve hcitool (legacy araçlar)

Eski araçlar hâlâ çalışır, ancak BlueZ 5.x'ten itibaren deprecated sayılır. Düşük seviye HCI debug için yararlıdır.

DEPRECATED

hciconfig, hcitool ve hcidump, BlueZ 5.40+ ile deprecated oldu. Yeni kodda bluetoothctl veya D-Bus API kullan. Mevcut sistemlerde debug amaçlı hâlâ işe yarar.

hciconfig — adapter yönetimi

bash — hciconfig
# Tüm HCI cihazlarını listele
hciconfig
# hci0:   Type: Primary  Bus: UART
#          BD Address: DC:A6:32:XX:XX:XX
#          UP RUNNING PSCAN

# hci0'ı aç
hciconfig hci0 up

# Kamuya açık hale getir (discoverable)
hciconfig hci0 piscan

# Cihaz adını değiştir
hciconfig hci0 name "IoT_Sensor"

# Detaylı bilgi
hciconfig hci0 info

# HCI reset
hciconfig hci0 reset

hcitool — cihaz tarama ve bağlantı

bash — hcitool
# BR/EDR cihaz tara
hcitool scan
# Scanning ...
#     AA:BB:CC:DD:EE:01  Kulaklık
#     AA:BB:CC:DD:EE:02  Klavye

# BLE cihaz tara (LE Scan)
hcitool lescan
# LE Scan ...
#     AA:BB:CC:DD:EE:03  BLE_Sensor
#     AA:BB:CC:DD:EE:04  (unknown)

# Sinyal gücü (RSSI)
hcitool rssi AA:BB:CC:DD:EE:01
# RSSI return value: -52

# Bağlı cihazları listele
hcitool con

# hcidump — HCI paketlerini izle
hcidump -i hci0 -X

03 D-Bus Python API — pydbus

pydbus kütüphanesi ile Python'dan BlueZ D-Bus API'sine erişim — tarama, bağlanma ve cihaz yönetimi.

python — pydbus kurulum ve adapter bilgisi
from pydbus import SystemBus
from gi.repository import GLib

bus = SystemBus()

# BlueZ adapter'ı al
adapter = bus.get('org.bluez', '/org/bluez/hci0')

# Adapter özellikleri
print("Adres:", adapter.Address)
print("İsim:", adapter.Name)
print("Güç:", adapter.Powered)

# Adaptörü aç
adapter.Powered = True

BLE Tarama (Python)

python — BLE tarama
from pydbus import SystemBus
from gi.repository import GLib
import threading

bus = SystemBus()
mainloop = GLib.MainLoop()
adapter = bus.get('org.bluez', '/org/bluez/hci0')

bulunan_cihazlar = {}

def cihaz_eklendi(path, interfaces):
    """Yeni BLE cihazı bulunduğunda çağrılır."""
    if 'org.bluez.Device1' not in interfaces:
        return
    props = interfaces['org.bluez.Device1']
    addr = props.get('Address', 'bilinmiyor')
    name = props.get('Name', 'isimsiz')
    rssi = props.get('RSSI', 0)
    print(f"  Bulundu: {addr}  |  {name}  |  RSSI: {rssi} dBm")
    bulunan_cihazlar[addr] = name

# InterfacesAdded sinyaline bağlan
objmanager = bus.get('org.bluez', '/')
objmanager.InterfacesAdded.connect(cihaz_eklendi)

# Taramayı başlat
adapter.StartDiscovery()
print("Tarama başladı — 10 saniye...")

# 10 saniye tarama
def dur():
    adapter.StopDiscovery()
    mainloop.quit()

GLib.timeout_add_seconds(10, dur)
mainloop.run()

print(f"\nToplam {len(bulunan_cihazlar)} cihaz bulundu.")

Cihaza bağlanma (Python)

python — bağlanma
from pydbus import SystemBus
import time

bus = SystemBus()

# Cihaz path'i: MAC adresindeki ':' yerine '_'
device_path = '/org/bluez/hci0/dev_AA_BB_CC_DD_EE_01'
device = bus.get('org.bluez', device_path)

# Bağlan
print("Bağlanılıyor...")
device.Connect()
time.sleep(2)

# Durum kontrol
print("Bağlı:", device.Connected)
print("Eşleşmiş:", device.Paired)
print("RSSI:", device.RSSI)

# GATT servislerini listele
print("UUID'ler:", device.UUIDs)

# Bağlantıyı kes
device.Disconnect()

04 BlueZ D-Bus API: Adapter1, Device1, GATT

BlueZ, Bluetooth nesnelerini D-Bus object hiyerarşisi olarak sunar. Bu hiyerarşiyi anlamak GATT programlama için zorunludur.

D-Bus nesne hiyerarşisi

  /org/bluez
      ├── /org/bluez/hci0          (Adapter1)
      │       └── /org/bluez/hci0/dev_AA_BB_CC_DD_EE_01  (Device1)
      │               ├── /org/bluez/hci0/dev_AA_.../service0001 (GattService1)
      │               │       ├── /...service0001/char0002       (GattCharacteristic1)
      │               │       │       └── /...char0002/desc0003  (GattDescriptor1)
      │               │       └── /...service0001/char0004
      │               └── /org/bluez/hci0/dev_AA_.../service0005
    

Adapter1 arayüzü

Address
Bluetooth adaptörünün BD adresi (string).
Name / Alias
Sistem adı ve değiştirilebilir takma ad.
Powered
boolean — adaptörü aç/kapat.
Discoverable
boolean — diğer cihazlar görebilsin mi.
Pairable
boolean — eşleştirme kabul et.
StartDiscovery()
Taramayı başlat.
StopDiscovery()
Taramayı durdur.
SetDiscoveryFilter()
Tarama filtresi — UUID, transport (le/bredr/auto), RSSI eşiği.

Device1 arayüzü

Address
Cihazın BD/BLE adresi.
Name
Cihaz adı (GAP üzerinden okunur).
Connected
boolean — mevcut bağlantı durumu.
Paired
boolean — eşleştirme durumu.
RSSI
Son ölçülen sinyal gücü (dBm).
UUIDs
Cihazın reklam ettiği servis UUID'leri.
Connect()
Bağlan. Gerekirse önce eşleştirme başlatır.
Disconnect()
Bağlantıyı kes.
Pair()
Eşleştir (güvenli bağlantı).

GATT nesneleri (Python ile okuma)

python — GATT characteristic okuma
from pydbus import SystemBus

bus = SystemBus()

# Cihaza bağlı olmalı
device_path = '/org/bluez/hci0/dev_AA_BB_CC_DD_EE_01'

# Tüm nesneleri listele (servisler, karakteristikler)
objmanager = bus.get('org.bluez', '/')
objs = objmanager.GetManagedObjects()

for path, ifaces in objs.items():
    if 'org.bluez.GattCharacteristic1' in ifaces and device_path in path:
        char = ifaces['org.bluez.GattCharacteristic1']
        print(f"  Char: {path}")
        print(f"    UUID:  {char.get('UUID')}")
        print(f"    Flags: {char.get('Flags')}")

# Belirli karakteristiği oku
char_path = device_path + '/service0001/char0002'
char = bus.get('org.bluez', char_path)

# Read (READ flag gerekir)
deger = char.ReadValue({})
print("Değer:", bytes(deger))

# Write
char.WriteValue([0x01, 0x02, 0x03], {})

05 BR/EDR vs BLE farkları

Klasik Bluetooth (BR/EDR) ve Bluetooth Low Energy (BLE/LE) farklı protokol yığınlarıdır. Aynı donanımda birlikte çalışabilirler (Bluetooth 4.0+).

Frekans
İkisi de 2.4 GHz ISM bandı, 79 kanal (BR/EDR) vs 40 kanal (BLE).
Hız
BR/EDR: 1-3 Mbit/s (EDR). BLE: 125 kbit/s - 2 Mbit/s (LE Coded / LE 2M).
Güç
BR/EDR: ~100 mW. BLE: 0.01-0.5 mW (coin battery yıllarca dayanır).
Bağlantı
BR/EDR: sürekli bağlantı (kulaklık, A2DP). BLE: aralıklı, event-driven (sensörler).
Protokol
BR/EDR: RFCOMM, A2DP, HFP, HID. BLE: GATT/ATT (profil tabanlı).
Keşif
BR/EDR: inquiry (aktif). BLE: advertising (pasif dinleme mümkün).

Transport seçimi (bluetoothctl)

bluetoothctl — transport filtresi
[bluetooth]# scan on
# Her iki modu da tarar

# Sadece BLE cihazları tara
[bluetooth]# menu scan
[bluetooth]# transport le
[bluetooth]# back
[bluetooth]# scan on

# Sadece klasik Bluetooth
[bluetooth]# transport bredr

# Python'da transport filtresi
python — BLE-only tarama
from pydbus import SystemBus

bus = SystemBus()
adapter = bus.get('org.bluez', '/org/bluez/hci0')

# Sadece BLE (LE) cihazları tara
adapter.SetDiscoveryFilter({
    'Transport': 'le',
    'RSSI': -80,           # Minimum sinyal eşiği
    'DuplicateData': False
})
adapter.StartDiscovery()

06 rfkill ve BlueZ

rfkill, Bluetooth donanımını yazılımsal olarak açıp kapatmak için kullanılır.

bash — rfkill Bluetooth
# Bluetooth durumunu listele
rfkill list bluetooth
# 1: hci0: Bluetooth
#    Soft blocked: no
#    Hard blocked: no

# Bluetooth'u blokla (kapat)
rfkill block bluetooth

# Bluetooth'u aç
rfkill unblock bluetooth

# BlueZ bu değişikliği otomatik algılar
bluetoothctl show | grep Powered
bash — rfkill ile güç yönetimi (embedded)
# Güç tasarrufu: Bluetooth kullanılmadığında kapat
#!/bin/sh

bluetooth_kullan() {
    rfkill unblock bluetooth
    bluetoothctl power on
    # ... bluetooth işlemleri ...
    bluetoothctl power off
    rfkill block bluetooth
}

# Kernel rfkill event'lerini izle
cat /dev/rfkill | hexdump -C

07 systemd bluetooth.service

bluetoothd daemon'ı systemd ile yönet, önyüklemede otomatik başlat.

bash — servis yönetimi
# Servis durumu
systemctl status bluetooth

# Başlat / durdur
systemctl start bluetooth
systemctl stop bluetooth

# Önyüklemede başlasın
systemctl enable bluetooth

# Log izle
journalctl -u bluetooth -f

# bluetoothd'yi debug modda yeniden başlat
systemctl stop bluetooth
bluetoothd -d -n   # -n: daemon olmadan, -d: debug

systemd servis dosyası

/lib/systemd/system/bluetooth.service
[Unit]
Description=Bluetooth service
Documentation=man:bluetoothd(8)
ConditionPathIsDirectory=/sys/class/bluetooth

[Service]
Type=dbus
BusName=org.bluez
ExecStart=/usr/lib/bluetooth/bluetoothd
NotifyAccess=main
#WatchdogSec=10
#Restart=on-failure
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
LimitNOFILE=65536
ProtectHome=true
ProtectSystem=full

[Install]
WantedBy=bluetooth.target
Alias=dbus-org.bluez.service

bluetoothd parametreleri

/etc/bluetooth/main.conf
[Policy]
# Otomatik eşleştirme zaman aşımı (saniye)
AutoEnable=true

[General]
# Cihaz adı
Name = EmbeddedDevice

# ClassicBondedOnly: sadece eşleşmiş cihazlardan gelen bağlantı
ClassicBondedOnly = false

# Privacy: BLE random address kullan
Privacy = device

08 Embedded — bluetoothd minimal ve obexd

Gömülü sistemlerde BlueZ'i hafifletmek için gereksiz plugin'leri devre dışı bırak. obexd ile dosya transferi.

bluetoothd --noplugin ile minimal başlatma

bash — minimal bluetoothd
# Tüm plugin'leri devre dışı bırak
bluetoothd --noplugin=*

# Belirli plugin'leri hariç tut
bluetoothd --noplugin=sap,a2dp,avrcp,hfp,hsp,hid,gap

# Sadece belirli plugin'leri yükle
bluetoothd --plugin=gatt

# Tüm plugin listesi
bluetoothd --list-plugins

systemd override ile minimal config

/etc/systemd/system/bluetooth.service.d/minimal.conf
[Service]
ExecStart=
ExecStart=/usr/lib/bluetooth/bluetoothd --noplugin=sap,a2dp,avrcp,hfp

obexd — Bluetooth Dosya Transferi

bash — obexd
# obexd kurulum
apt-get install obexd

# obexd başlat (OPP: Object Push Profile)
obexd --root=/tmp/bluetooth --opp

# Python ile obex dosya transferi
python — obex dosya gönder
from pydbus import SessionBus
import time

bus = SessionBus()

# obexd session bus üzerinde çalışır
client = bus.get('org.bluez.obex', '/org/bluez/obex')

# Oturum oluştur
session_path, props = client.CreateSession(
    'AA:BB:CC:DD:EE:01',
    {'Target': 'opp'}
)

session = bus.get('org.bluez.obex', session_path)
opp = bus.get('org.bluez.obex', session_path + '/opp')

# Dosya gönder
transfer_path, props = opp.SendFile('/tmp/sensor_data.csv')

# Transfer tamamlanmasını bekle
transfer = bus.get('org.bluez.obex', transfer_path)
while transfer.Status != 'complete':
    time.sleep(0.5)

print("Transfer tamamlandı:", transfer.Transferred, "bayt")

# Oturumu kapat
client.RemoveSession(session_path)
EMBEDDED TAVSİYE

IoT sensör düğümlerinde BlueZ sadece GATT server/client ihtiyacı için kullanılıyorsa --noplugin=* ile başlat. Bu, RAM kullanımını önemli ölçüde azaltır. Buildroot'ta BR2_PACKAGE_BLUEZ5_UTILS=y ve yalnızca gerekli plugin'leri seç.