Większość z kart WWAN ma pewien nieużywany bajer, obsługę GPS. W większości laptopów średnio to przydatne. Skoro jednak jest, to żal nie spróbować, by to uruchomić. Oczywiście postanowiłem to zrobić w Linuxie.
Instalacja karty
Opiszę najpierw mój przypadek. Dysponuję kartą Dell Wireless 5550, kupioną za jakieś 40zł na aliexpress. Jest to rebrandowana karta Ericsson F5521GW. Rebrand polega na zmienionych identyfikatorach VendorId oraz zgłaszanej na porcie USB nazwie urządzenia (tak, karta WWAN miniPCIe siedzi na USB).
Jest to istotne z dwóch powodów – sterowniki są dopasowywane według VendorId, więc jeśli mamy Windowsa, to albo szukamy właściwych sterowników (od tego, kto rebrandował), albo ręcznie modyfikujemy pliki .inf z informacją o sterowniku. Wedle upodobań.
Jest też powód drugi, który mnie dotyczył. Część producentów laptopów stosuje whitelist kart WLAN i WWAN (między innymi Lenovo i HP). Polega to na tym, że jeśli zainstalujemy kartę z niewłaściwym VendorId, to system nie będzie widział tej karty, BIOS na to nie pozwoli (komunikat przy starcie). Skąd wynika ta głupota? Jednym z powodów jest to, że homologacje bezprzewodowe (które ma każdy laptop), są wydawane na zestaw „laptop + konkretna karta bezprzewodowa”. Drugi, to oczywiście sprzedaż kart po zawyżonych cenach 🙂
Zatem, jeśli mamy tego pecha, że karta się nie uruchamia, są trzy drogi. Zmienić VendorId na karcie (zwykle trudne), wyłączyć whitelist poprzez zmianę BIOSu na modowany (łatwe), bądź kupno karty, która pasuje. Oczywiście wybrałem modyfikację BIOSu, znalezienie odpowiedniego to chwila googlowania.
Odpalanie GPSu
Ważna rzecz, do następnych etapów potrzebujemy karty, która działa (będzie odpowiadać na polecenia). Zawsze jest potrzebne, by siedziała w niej karta SIM, może być nieaktywna, ale lepiej, by nie wymagała PINu (mniej roboty).
Moja karta zgłasza się w systemie jako kilka terminali /dev/ttyACM
- /dev/ttyACM0 odpowiada za połączenie GSM – tutaj trzeba w razie potrzeby wstukać PIN
- /dev/ttyACM1 odpowiada za GPS
Teoretycznie, by zaczęło to działać, wystarczy zainicjalizować kartę komendami AT, np. przez wxdial.
cat /etc/wvdial.conf [Dialer Defaults] New PPPD = yes Stupid Mode = 1 Modem Type = USB Modem [Dialer on] Modem = /dev/ttyACM0 Init1 = AT+CFUN=1 [Dialer off] Modem = /dev/ttyACM0 Init1 = AT+CFUN=4 [Dialer gps] Modem = /dev/ttyACM1 Init1 = AT*E2GPSCTL=1,5,1 Init2 = AT*E2GPSNPD
Wystarczy teraz wstukać wxdial gps, a potem odpalić daemona gpsd.
wvdial gps gpsd /dev/ttyACM1
Jakby co, metoda bezczelnie zerżnięta stąd.
Alternatywna metoda dla kart Ericsson
Niestety, nie jest to takie proste. Karta zwykle po paru sekundach zamykała połączenie, a daemon gpsd przerywał pracę. Trochę się pomęczyłem, ale działa to nadwyraz dobrze!
Pierwszy etap, konieczne oprogramowanie. Wxdial można już wywalić. Przyda się za to modemmanager (jeśli jeszcze go nie macie), oraz mbm-gpsd. Ta druga paczka pochodzi stąd, ale jako, że używam archa, to pobrałem ją z AUR.
Potrzebna konfiguracja wygląda tak.
cat /etc/gpsd # Default settings for gpsd. START_DAEMON="true" GPSD_OPTIONS="-b -P /tmp/gpsd.pid" DEVICES="/dev/gps0" USBAUTO="true"
cat /usr/lib/systemd/system/gpsd.service [Unit] Description=GPS (Global Positioning System) Daemon Requires=gpsd.socket # Needed with chrony SOCK refclock After=chronyd.service [Service] EnvironmentFile=-/etc/gpsd EnvironmentFile=-/etc/sysconfig/gpsd ExecStart=/usr/bin/gpsd -N $GPSD_OPTIONS $OPTIONS $DEVICES [Install] WantedBy=multi-user.target Also=gpsd.socket
Jeśli zaś chodzi o mbm-gps, to tutaj wymagana była pewna przeróbka
cat /etc/systemd/system/mbm-gps.service [Unit] Description=DBus system service to communicate with GPS Before=gpsd.service StopWhenUnneeded=true [Service] ExecStartPre=-/etc/modem_switch ACTIVATE ExecStart=/usr/bin/mbm-gpsd -f ExecStopPost=-/etc/modem_switch DEACTIVATE User=root [Install] WantedBy=gpsd.service
Warty odnotowania, StopWhenUnneeded. Jeśli zależności (WantedBy), zostaną dezaktywowane, to ten Service też.
Przed i po uruchomieniu mbm-gps, odpalany jest mały skrypt używający mmcli, czyli konsolowego interfejsu modemmanagera. Garść regexu, żeby wykryć numer modemu w DBUS i by nie wyłączać go, gdy aktywne jest połączenie GSM. Tutaj należy również dopisać wpisywanie PINu, jeśli go potrzebujemy.
cat /etc/modem_switch #!/bin/sh MODEM_NUMBER=`mmcli --list-modems | grep -oP "Modem\/\K\d" | head -1` if [ "$1" = "ACTIVATE" ]; then /usr/bin/mmcli -m $MODEM_NUMBER -e else if [ "$1" = "DEACTIVATE" ]; then MODEM_STATE=`mmcli -m $MODEM_NUMBER --simple-status | grep -oP "state: \'(\K\w+)(?=\')" | head -1` if [ "$MODEM_STATE" != "connected" ]; then /usr/bin/mmcli -m $MODEM_NUMBER -d //disables modem if gsm is not connected fi fi fi
Aktywujemy po kolei usługi w systemd
systemctl enable gpsd.socket systemctl enable mbm-gpsd.service
Zauważcie, że dodałem gpsd.socket, a nie gpsd.service. Dzięki temu, daemon zacznie pracę dopiero, gdy coś zastuka na port. Możemy odpalić dla testu xgps i wyjść z piwnicy na świeże powietrze. W aktywnych procesach powinny się pojawić gpsd i mbm-gpsd. W razie problemów, journalctl -r.
Sleep hook
O ile gpsd może sam się włączyć, to o jego wyłączenie musimy zadbać sami, czyli systemctl stop gpsd.
Kolejnym problemem jest zwiecha mbm-gpsd po uśpieniu. Wiele urządzeń ma problem z zarządzaniem energią w Linuxie. Co zrobić, jak żyć? Ano systemd ułatwił trochę sprawę. Dawno, dawno temu, był sobie pakiet pm-utils, który odpowiadał za zarządzanie energią. Pisało się skrypty, tzw. hooki w katalogu /etc/pm/sleep.d, które były odpalane przy uśpieniu, hibernacji i pobudce. W systemd jest znacznie prościej, możemy po prostu napisać Service, który odpali się po jakimś zdarzeniu.
cat /etc/systemd/system/mbm-gpsd-sleep.service [Unit] Description=Mbm-gpsd sleep hook Before=sleep.target StopWhenUnneeded=yes [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/bin/systemctl stop gpsd [Install] WantedBy=sleep.target
Oczywiście, odpalamy systemctl enable mbm-gpsd-sleep.service
Jeśli wejdziemy w stan uśpienia, systemd najpierw odpali sleep.target, a co za tym idzie też ten Service, który wyłącza gpsd (a ten z kolei wyłącza mbm-gpsd). Przydatne? Jak cholera.