Hücresel Bağlantı
TEKNİK REHBER HÜCRESEL BAĞLANTI MODEMMANAGER 2026

ModemManager
unified modem API.

D-Bus daemon mimarisi, mmcli ile tam modem yönetimi, NetworkManager entegrasyonu ve systemd ile otomatik 4G bağlantısı.

00 ModemManager mimarisi — D-Bus, udev, daemon

ModemManager, Linux'ta USB/seri/PCIe modemleri yöneten birleşik bir D-Bus daemon'ıdır. AT, QMI ve MBIM protokollerini soyutlar.

  Uygulama (nmcli, mmcli, Python GDBus)
        ↓  org.freedesktop.ModemManager1  (D-Bus)
  ModemManager daemon   (modemmanager.service)
        ├── udev kuralları → modem cihaz tespiti
        ├── AT port yönetimi  (/dev/ttyUSBx)
        ├── QMI port yönetimi (/dev/cdc-wdmx)
        └── MBIM port yönetimi
        ↓
  Modem donanımı   (EC25, RM500Q, SIM7600)
        ├── /dev/ttyUSB2  (AT komutları)
        ├── /dev/cdc-wdm0 (QMI/MBIM kontrol)
        └── /dev/wwan0    (data arayüzü)
    

Kurulum

bash — ModemManager kurulum
# Debian / Ubuntu
apt-get install modemmanager libqmi-utils libmbim-utils

# Yocto — meta-oe katmanı gerekli
# IMAGE_INSTALL += "modemmanager"

# Buildroot
# BR2_PACKAGE_MODEMMANAGER=y

# Servis durumunu kontrol et
systemctl status ModemManager
# ● ModemManager.service - Modem Manager
#    Active: active (running) since ...
#    Main PID: 1234 (ModemManager)

# Servis başlat ve etkinleştir
systemctl enable --now ModemManager

# Versiyon
mmcli --version
# mmcli 1.20.6

# Debug log (sorun giderme)
ModemManager --debug 2>&1 | tee /tmp/mm-debug.log
ÖNEMLI

ModemManager çalışırken aynı anda AT portuna (/dev/ttyUSB2) doğrudan yazmayın. ModemManager portu kilitler ve çakışma yaşanır. Modem kontrolü için mmcli veya D-Bus API kullanın.

01 mmcli — modem listele, durum, etkinleştir

mmcli (ModemManager CLI), ModemManager'ın tüm işlevlerine komut satırından erişim sağlar.

bash — mmcli temel kullanım
# Tespit edilen modemleri listele
mmcli -L
# /org/freedesktop/ModemManager1/Modem/0 [Quectel] EC25

# Modem detaylı bilgisi (index 0)
mmcli -m 0
# ----------------------------------
# General  |            dbus path: /org/.../Modem/0
#           |            device id: abc123...
# ----------------------------------
# Hardware |         manufacturer: Quectel
#           |                model: EC25
#           |    firmware revision: EC25EFAR06A12M4G
#           |            supported: gsm-umts, lte
#           |              current: lte
# ----------------------------------
# Status   |               state: registered
#           |         power state: on
#           |    signal quality: 71% (recent)
# ----------------------------------
# Modes    |           supported: allowed: any; preferred: none
# ----------------------------------
# Bands    |           supported: utran-1, eutran-3, eutran-7,...
# ----------------------------------
# IP       |      supported methods: ipv4, ipv6, ipv4v6

# Modemi etkinleştir
mmcli -m 0 --enable
# successfully enabled the modem

# Modemi devre dışı bırak
mmcli -m 0 --disable

# Modemi sıfırla (reset)
mmcli -m 0 --reset

# SIM bilgisi
mmcli -m 0 --sim-status
mmcli -i 0
# -----------------------
# SIM      |  dbus path: /org/.../SIM/0
#           |  iccid: 8990101234567890
#           |  imsi: 286011234567890
#           |  operator code: 28601
#           |  operator name: Turkcell

JSON çıktısı (script entegrasyonu)

bash — JSON çıktı ve jq ile ayrıştırma
# JSON formatında çıktı al
mmcli -m 0 -J | jq '.'

# Sadece sinyal kalitesini al
mmcli -m 0 -J | jq '.modem.generic["signal-quality"].value'
# 71

# Modem durumunu al
mmcli -m 0 -J | jq -r '.modem.generic.state'
# connected

# IP adresini al
mmcli -m 0 --bearer=0 -J | \
  jq -r '.bearer.ipv4config.address'
# 100.65.45.123

02 mmcli — bağlan ve bağlantıyı kes

mmcli ile data bağlantısı kurma, bearer (taşıyıcı) yönetimi ve bağlantı kesme işlemleri.

bash — bağlantı yönetimi
# Basit bağlantı (APN ile)
mmcli -m 0 --simple-connect="apn=internet"
# successfully connected the modem

# IPv4+IPv6 bağlantısı
mmcli -m 0 --simple-connect="apn=internet,ip-type=ipv4v6"

# PIN ile birlikte bağlantı
mmcli -m 0 --simple-connect="apn=internet,pin=1234"

# Bağlantıyı kes
mmcli -m 0 --simple-disconnect
# successfully disconnected all bearers in the modem

# Bearer (taşıyıcı) listesi
mmcli -m 0 --list-bearers
# /org/freedesktop/ModemManager1/Bearer/0

# Bearer detayları
mmcli -m 0 --bearer=0
# ----------------------------------------
# General    |        dbus path: /org/.../Bearer/0
# ----------------------------------------
# Status     |     connected: yes
#             |  disconnecting: no
#             |       interface: wwan0
#             |      ip timeout: 20
# ----------------------------------------
# Properties |             apn: internet
#             |         roaming: allowed
#             |      ip type: ipv4
# ----------------------------------------
# IPv4 config|         method: dhcp
#             |        address: 100.65.45.123
#             |         prefix: 30
#             |        gateway: 100.65.45.124
#             |            dns: 8.8.8.8, 8.8.4.4

# Bağlantı sonrası DHCP (dhclient veya udhcpc)
udhcpc -i wwan0 -n -q
ip addr show wwan0
# 2: wwan0: ... inet 100.65.45.123/30 ...

# Default route ekle
ip route add default via 100.65.45.124 dev wwan0

03 Connection profile oluşturma ve kalıcı bağlantı

NetworkManager ile kalıcı bağlantı profilleri oluşturma — sistem yeniden başladığında otomatik bağlanmak için.

bash — nmcli ile 4G profil oluşturma
# Mevcut bağlantıları listele
nmcli connection show
# NAME    UUID                   TYPE  DEVICE
# Eth0    abc-123...             eth   eth0

# GSM (LTE) bağlantı profili oluştur
nmcli connection add \
  type gsm \
  con-name "4G-LTE" \
  ifname "*" \
  gsm.apn "internet" \
  gsm.number "*99#" \
  gsm.pin "1234" \
  connection.autoconnect yes

# Profili düzenle (APN değiştir)
nmcli connection modify "4G-LTE" gsm.apn "super"

# PIN kaldır (embedded cihazda PIN olmadan)
nmcli connection modify "4G-LTE" gsm.pin ""

# Bağlantıyı başlat
nmcli connection up "4G-LTE"
# Connection successfully activated

# Bağlantıyı durdur
nmcli connection down "4G-LTE"

# Bağlantı durumu
nmcli device status
# DEVICE   TYPE      STATE        CONNECTION
# wwan0    gsm       connected    4G-LTE
# eth0     ethernet  connected    Eth0
Profil özelliği Değer Açıklama
gsm.apn "internet" Operatör APN adı
gsm.number "*99#" PPP dial numarası
gsm.pin "1234" SIM PIN kodu
gsm.username "" PAP/CHAP kullanıcı adı
gsm.password "" PAP/CHAP şifresi
connection.autoconnect yes Otomatik bağlantı
connection.autoconnect-priority 0 Öncelik (yüksek = önce)

04 NetworkManager entegrasyonu — nmcli ile modem

NetworkManager ve ModemManager birlikte çalışır. NM, MM'nin D-Bus API'sini kullanarak modem bağlantılarını yönetir.

bash — nmcli modem yönetimi
# NetworkManager'ın modem cihazını görmesi
nmcli device
# DEVICE   TYPE      STATE         CONNECTION
# wwan0    gsm       disconnected  --

# Modem detayları NM üzerinden
nmcli device show wwan0
# GENERAL.DEVICE:         wwan0
# GENERAL.TYPE:           gsm
# GENERAL.HWADDR:         (unknown)
# GENERAL.MTU:            1500
# GENERAL.STATE:          30 (disconnected)
# GENERAL.UDI:            /sys/devices/.../usb1/.../net/wwan0

# Bağlantı kur
nmcli device connect wwan0

# WiFi ve 4G birlikte — 4G'yi yedek olarak ayarla
nmcli connection modify "4G-LTE" \
  connection.autoconnect-priority -100

# NetworkManager dispatcher — bağlantı olayında script
# /etc/NetworkManager/dispatcher.d/99-lte-up
cat /etc/NetworkManager/dispatcher.d/99-lte-up
# #!/bin/bash
# IFACE=$1
# ACTION=$2
# if [ "$IFACE" = "wwan0" ] && [ "$ACTION" = "up" ]; then
#     logger "4G bağlantısı kuruldu: $IFACE"
#     # DNS ayarla
#     echo "nameserver 8.8.8.8" > /etc/resolv.conf
# fi
chmod +x /etc/NetworkManager/dispatcher.d/99-lte-up

# NM yeniden başlat (config değişikliği sonrası)
systemctl restart NetworkManager

05 D-Bus API ile Python GDBus programatik kontrol

Python'dan ModemManager D-Bus API'sine doğrudan erişim — mmcli olmadan modem yönetimi, bağlantı izleme ve otomasyon.

python — mm_dbus.py
#!/usr/bin/env python3
"""
ModemManager D-Bus API ile Python kontrolü.
Gereksinimler: pip install PyGObject pydbus
"""
from pydbus import SystemBus
from gi.repository import GLib
import time

BUS_NAME = 'org.freedesktop.ModemManager1'
OBJ_PATH = '/org/freedesktop/ModemManager1'


def get_modems(bus):
    """Mevcut modemleri döndür."""
    mm = bus.get(BUS_NAME, OBJ_PATH)
    manager = bus.get(BUS_NAME, OBJ_PATH)[
        'org.freedesktop.DBus.ObjectManager'
    ]
    objects = manager.GetManagedObjects()
    modems = []
    for path, ifaces in objects.items():
        if 'org.freedesktop.ModemManager1.Modem' in ifaces:
            modems.append(path)
    return modems


def get_modem_info(bus, modem_path):
    """Modem bilgilerini al."""
    modem = bus.get(BUS_NAME, modem_path)
    iface = modem['org.freedesktop.ModemManager1.Modem']
    return {
        'manufacturer': iface.Manufacturer,
        'model':        iface.Model,
        'revision':     iface.Revision,
        'imei':         iface.EquipmentIdentifier,
        'state':        iface.State,
        'signal':       iface.SignalQuality,
    }


def get_sim_info(bus, modem_path):
    """SIM bilgisini al."""
    modem = bus.get(BUS_NAME, modem_path)
    iface = modem['org.freedesktop.ModemManager1.Modem']
    sim_path = iface.Sim
    if not sim_path or sim_path == '/':
        return None
    sim = bus.get(BUS_NAME, sim_path)
    sim_iface = sim['org.freedesktop.ModemManager1.Sim']
    return {
        'imsi':          sim_iface.Imsi,
        'iccid':         sim_iface.SimIdentifier,
        'operator_name': sim_iface.OperatorName,
        'operator_id':   sim_iface.OperatorIdentifier,
    }


def simple_connect(bus, modem_path, apn='internet'):
    """Basit data bağlantısı kur."""
    modem = bus.get(BUS_NAME, modem_path)
    simple = modem['org.freedesktop.ModemManager1.Modem.Simple']
    props = {
        'apn': GLib.Variant('s', apn),
        'ip-type': GLib.Variant('u', 1),  # 1=ipv4
    }
    bearer_path = simple.Connect(props)
    return bearer_path


def get_bearer_info(bus, bearer_path):
    """Bearer IP bilgisini al."""
    bearer = bus.get(BUS_NAME, bearer_path)
    b = bearer['org.freedesktop.ModemManager1.Bearer']
    return {
        'connected':  b.Connected,
        'interface':  b.Interface,
        'ipv4':       dict(b.Ip4Config),
    }


def monitor_signal(bus, modem_path, interval=10, count=5):
    """Sinyal kalitesini periyodik olarak ölç."""
    modem = bus.get(BUS_NAME, modem_path)
    sig_iface = modem['org.freedesktop.ModemManager1.Modem.Signal']
    # Sinyal raporlama aralığını ayarla (saniye)
    sig_iface.Setup(interval)
    print(f"Sinyal izleniyor ({count}x, her {interval}s)...")
    for _ in range(count):
        time.sleep(interval)
        try:
            lte = dict(sig_iface.Lte)
            print(f"  RSSI={lte.get('rssi','?')} dBm, "
                  f"RSRP={lte.get('rsrp','?')} dBm, "
                  f"RSRQ={lte.get('rsrq','?')} dB, "
                  f"SINR={lte.get('sinr','?')} dB")
        except Exception as e:
            print(f"  Sinyal okunamadı: {e}")


def main():
    bus = SystemBus()
    modems = get_modems(bus)

    if not modems:
        print("Modem bulunamadı! ModemManager çalışıyor mu?")
        return

    modem_path = modems[0]
    print(f"Modem yolu: {modem_path}")

    info = get_modem_info(bus, modem_path)
    print(f"Üretici : {info['manufacturer']}")
    print(f"Model   : {info['model']}")
    print(f"IMEI    : {info['imei']}")
    print(f"Durum   : {info['state']}")
    print(f"Sinyal  : {info['signal'][0]}%")

    sim = get_sim_info(bus, modem_path)
    if sim:
        print(f"IMSI    : {sim['imsi']}")
        print(f"Operatör: {sim['operator_name']}")

    print("\nBağlantı kuruluyor...")
    try:
        bearer_path = simple_connect(bus, modem_path, apn='internet')
        binfo = get_bearer_info(bus, bearer_path)
        print(f"Arayüz  : {binfo['interface']}")
        print(f"IPv4    : {binfo['ipv4']}")
    except Exception as e:
        print(f"Bağlantı hatası: {e}")


if __name__ == '__main__':
    main()

06 Sinyal kalitesi izleme — RSSI/RSRP/RSRQ/SINR

LTE sinyal metrikleri: RSSI (toplam güç), RSRP (referans sinyal gücü), RSRQ (kalite), SINR (sinyal/gürültü oranı). Her biri farklı bilgi taşır.

Metrik
Açıklama
İyi değer
Kötü değer
RSSI
Toplam alınan sinyal gücü
≥ −70 dBm
≤ −100 dBm
RSRP
Referans sinyal alınan güç
≥ −80 dBm
≤ −110 dBm
RSRQ
Referans sinyal kalitesi
≥ −10 dB
≤ −20 dB
SINR
Sinyal/Gürültü+Parazit oranı
≥ 20 dB
≤ 0 dB
bash — sinyal izleme
# mmcli sinyal kalitesi raporu
mmcli -m 0 --signal-get
# -------------------------
# Signal   |         lte rssi: -71 dBm
#           |         lte rsrq: -10 dB
#           |         lte rsrp: -93 dBm
#           |         lte snr: 12.8 dB

# Sinyal izlemeyi aktifleştir (10 saniyede bir)
mmcli -m 0 --signal-setup=10

# Serving cell bilgisi (AT+QENG Quectel)
mmcli -m 0 --command='AT+QENG="servingcell"'

# AT+QCSQ — Quectel sinyal detayları
mmcli -m 0 --command='AT+QCSQ'
# +QCSQ: "LTE",-71,-93,23,-10
# Format: rat, rssi, rsrp, sinr, rsrq

# SIM7600 sinyal detayları
mmcli -m 0 --command='AT+CPSI?'
# +CPSI: LTE,Online,286-01,0xB13,33623809,231,
#   EUTRAN-BAND3,1750,3,3,-121,-1190,-930,13

# Sürekli izleme script'i
watch -n 5 "mmcli -m 0 --signal-get 2>&1"

Python sinyal logger

python — signal_logger.py
#!/usr/bin/env python3
"""mmcli sinyal değerlerini CSV'ye kaydet."""
import subprocess, json, time, csv, sys
from datetime import datetime

def get_signal():
    r = subprocess.run(
        ['mmcli', '-m', '0', '--signal-get', '-J'],
        capture_output=True, text=True, timeout=10
    )
    if r.returncode != 0:
        return None
    data = json.loads(r.stdout)
    lte = data.get('modem', {}).get('signal', {}).get('lte', {})
    return {
        'ts':    datetime.now().isoformat(),
        'rssi':  lte.get('rssi', ''),
        'rsrp':  lte.get('rsrp', ''),
        'rsrq':  lte.get('rsrq', ''),
        'sinr':  lte.get('snr',  ''),
    }

# Sinyal izlemeyi aktifleştir
subprocess.run(['mmcli', '-m', '0', '--signal-setup=10'])

outfile = '/tmp/lte_signal.csv'
with open(outfile, 'w', newline='') as f:
    w = csv.DictWriter(f, fieldnames=['ts','rssi','rsrp','rsrq','sinr'])
    w.writeheader()
    print(f"Sinyal loglanıyor → {outfile} (Ctrl+C ile dur)")
    try:
        while True:
            sig = get_signal()
            if sig:
                w.writerow(sig)
                f.flush()
                print(f"[{sig['ts']}] "
                      f"RSSI={sig['rssi']} RSRP={sig['rsrp']} "
                      f"RSRQ={sig['rsrq']} SINR={sig['sinr']}")
            time.sleep(10)
    except KeyboardInterrupt:
        print("\nDurduruldu.")

07 SMS via ModemManager

ModemManager üzerinden SMS gönderme ve alma — AT port çakışması olmadan güvenli mesajlaşma.

bash — mmcli ile SMS
# SMS oluştur ve gönder
mmcli -m 0 --messaging-create-sms="number='+905001234567',text='Alarm: Sicaklik yuksek!'"
# Successfully created new SMS:
# /org/freedesktop/ModemManager1/SMS/0

# SMS'i gönder
mmcli -m 0 --sms=0 --send
# Successfully sent the SMS

# Gelen SMS'leri listele
mmcli -m 0 --messaging-list-sms
# /org/freedesktop/ModemManager1/SMS/1 (received)

# SMS içeriğini oku
mmcli -m 0 --sms=1
# ---------------------------
# Content  |    number: +905009876543
#           |      text: Test mesaji
# ---------------------------
# Properties |   pdu type: deliver
#             |      state: received
#             |  timestamp: 2026-01-15T10:30:00+03

# SMS sil
mmcli -m 0 --messaging-delete-sms=1

# Yeni SMS bildirimi — D-Bus sinyal izle
dbus-monitor --system \
  "type='signal',interface='org.freedesktop.ModemManager1.Modem.Messaging'"

08 Practical — systemd ile boot'ta otomatik 4G bağlantısı

Sistem açıldığında ModemManager'ın modemleri tespit etmesini ve NetworkManager'ın otomatik bağlanmasını sağlayan tam systemd kurulumu.

bash — 4G autoconnect sistemi
# 1. NetworkManager için 4G profil oluştur
nmcli connection add \
  type gsm \
  con-name "4G-IoT" \
  ifname "*" \
  gsm.apn "internet" \
  gsm.pin "" \
  connection.autoconnect yes \
  connection.autoconnect-priority 100 \
  ipv4.method auto \
  ipv6.method ignore

# 2. Modem udev kuralı — cihaz gelince MM'yi tetikle
cat /etc/udev/rules.d/99-quectel.rules
# SUBSYSTEM=="usb", ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125",
#   ACTION=="add", RUN+="/bin/systemctl restart ModemManager"

# 3. ModemManager servis dropin — bağlantı sonrası routing
mkdir -p /etc/systemd/system/ModemManager.service.d
cat > /etc/systemd/system/ModemManager.service.d/override.conf <<'EOF'
[Service]
Environment=MM_LOGGING_LEVEL=INFO
ExecStartPost=/bin/sleep 3
EOF
bash — /usr/local/bin/4g-connect.sh
#!/bin/bash
# 4G bağlantısını güvenli şekilde kur ve doğrula
set -e
LOG="logger -t 4g-connect"

$LOG "4G bağlantı scripti başlıyor..."

# ModemManager başlayana kadar bekle
for i in $(seq 1 30); do
    if mmcli -L 2>/dev/null | grep -q Modem; then
        $LOG "Modem tespit edildi"
        break
    fi
    sleep 2
done

MODEM_IDX=$(mmcli -L 2>/dev/null | grep -oP '/Modem/\K\d+' | head -1)
if [ -z "$MODEM_IDX" ]; then
    $LOG "HATA: Modem bulunamadı"
    exit 1
fi

# LTE kaydı bekle (maksimum 120s)
for i in $(seq 1 60); do
    STATE=$(mmcli -m "$MODEM_IDX" -J 2>/dev/null | \
            python3 -c "import sys,json; \
            d=json.load(sys.stdin); \
            print(d['modem']['generic']['state'])" 2>/dev/null)
    if [ "$STATE" = "registered" ] || [ "$STATE" = "connected" ]; then
        $LOG "LTE kayıt OK (durum: $STATE)"
        break
    fi
    $LOG "Bekleniyor: $STATE ($i/60)"
    sleep 2
done

# Bağlı değilse bağlan
if [ "$STATE" != "connected" ]; then
    $LOG "Bağlantı kuruluyor..."
    mmcli -m "$MODEM_IDX" --simple-connect="apn=internet"
    sleep 5
fi

# DHCP
IFACE=$(mmcli -m "$MODEM_IDX" --bearer=0 -J 2>/dev/null | \
        python3 -c "import sys,json; \
        d=json.load(sys.stdin); \
        print(d['bearer']['status']['interface'])" 2>/dev/null)

if [ -n "$IFACE" ]; then
    $LOG "DHCP: $IFACE"
    udhcpc -i "$IFACE" -n -q -t 10
    IP=$(ip -4 addr show "$IFACE" | grep -oP '(?<=inet )\S+')
    $LOG "IP: $IP"
fi

$LOG "4G bağlantısı hazır"
systemd — /etc/systemd/system/4g-connect.service
[Unit]
Description=4G LTE Otomatik Bağlantı
After=ModemManager.service network.target
Wants=ModemManager.service
# Bağlantı kesintisinde yeniden dene
StartLimitIntervalSec=300
StartLimitBurst=5

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/4g-connect.sh
Restart=on-failure
RestartSec=30
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
bash — servis etkinleştirme ve izleme
# Script'i çalıştırılabilir yap
chmod +x /usr/local/bin/4g-connect.sh

# Servisi etkinleştir
systemctl enable --now 4g-connect.service

# Log izle
journalctl -fu 4g-connect.service

# Bağlantı durumunu kontrol et
mmcli -m 0 -J | python3 -c "
import sys, json
d = json.load(sys.stdin)
m = d['modem']
print('Durum :', m['generic']['state'])
print('Sinyal:', m['generic']['signal-quality']['value'], '%')
"

# İnternet testi
ping -c 3 -I wwan0 8.8.8.8
EMBEDDED İPUCU

NetworkManager olmayan minimal Yocto/Buildroot sistemlerde yukarıdaki script tek başına yeterlidir. ModemManager + mmcli + udhcpc kombinasyonu, NetworkManager'ın %80 işlevselliğini sadece birkaç MB ile sağlar.