Phát GPS qua mạng cục bộ
(evertpot.com)- Sau khi Mozilla ngừng dịch vụ định vị GPS, việc xác định vị trí dựa trên GeoClue trên Linux trở nên kém chính xác;
where-am-idùng GeoIP và xác định gần Toronto với độ chính xác 25km - Tận dụng việc máy chủ gia đình cố định không di chuyển, tác giả cấu hình để phát ra tọa độ GPS mong muốn ngay trong mạng nội bộ
- Trong GeoClue,
network-nmeađược bật mặc định trong/etc/geoclue/geoclue.conf, và nó tìm dịch vụ mDNS_nmea-0183._tcpđể nhận thông tin GPS - nmea-static-gps-server phát các bản tin GPS NMEA 0183 qua TCP mỗi giây một lần, đồng thời đăng ký dịch vụ
_nmea-0183._tcpbằng Avahi - Sau khi khởi động lại GeoClue, máy khách lập tức nhận đúng tọa độ từ máy chủ; kết quả trả về mô tả
GPS GGA+RMCcùng độ chính xác 0 mét, và Gnome Maps hiển thị đúng vị trí ngay lập tức
Cấu hình GeoClue và NMEA
- Sau khi Mozilla ngừng dịch vụ định vị GPS, độ chính xác vị trí trên Linux giảm xuống; trên nhiều hệ thống Linux, GeoClue mà Firefox và Gnome Maps sử dụng đã xác định
where-am-ibằng GeoIP gần Toronto với độ chính xác 25km - Có thể cài bản demo
where-am-ibằng gói tương ứng theo từng bản phân phối# Fedora sudo dnf install geoclue2-demos # Debian family sudo apt install geoclue-2-demo - Tận dụng việc máy chủ gia đình cố định không di chuyển, tác giả cấu hình để phát tọa độ GPS mong muốn ngay trong mạng nội bộ
- Giao thức được dùng là NMEA 0183, một bộ đặc tả dành cho thiết bị điện tử hàng hải; bản tin có thể được gửi qua cổng nối tiếp hoặc socket TCP
- Ví dụ bản tin GPS gồm các dòng
GPRMCvàGPGGA$GPRMC,204049.000,A,5308.3999,N,00601.9266,E,0.000,0.000,030526,,*02 $GPGGA,204049.000,5308.3999,N,00601.9266,E,1,08,1.0,119.0,M,0.0,M,,*6F - Trong
/etc/geoclue/geoclue.conf, network-nmea được bật mặc định# Network NMEA source configuration options [network-nmea] # Fetch location from NMEA sources on local network? enable=true - GeoClue tìm dịch vụ mDNS có tên
_nmea-0183._tcp; khi phát hiện bản ghi, nó kết nối tới địa chỉ đó để nhận thông tin GPS
Triển khai máy chủ và kiểm tra hoạt động
- nmea-static-gps-server là một máy chủ TCP phát thông tin GPS mỗi giây một lần, đồng thời đăng ký dịch vụ
_nmea-0183._tcpbằng Avahi - Avahi là triển khai mDNS tiêu chuẩn trên Linux; trên Mac, Bonjour đảm nhiệm vai trò tương tự, và mDNS cũng được dùng để tìm địa chỉ
.localhoặc phát hiện các thiết bị như máy in và TV trong mạng cục bộ - Kho lưu trữ có kèm cấu hình dịch vụ Avahi như sau
<?xml version="1.0" standalone='no'?> <!DOCTYPE service-group SYSTEM "avahi-service.dtd"> <service-group> <name replace-wildcards="yes">NMEA GPS (%h)</name> <service> <type>_nmea-0183._tcp</type> <port>10110</port> </service> </service-group> - Sau khi chép tệp này vào
/etc/avahi/services/nmea-statis-gpc.service, có thể dùngavahi-browsetrên máy khác để xác nhận dịch vụ đã được công bố$ avahi-browse _nmea-0183._tcp -r -t + wlp192s0 IPv6 NMEA GPS (node05) _nmea-0183._tcp local + wlp192s0 IPv4 NMEA GPS (node05) _nmea-0183._tcp local = wlp192s0 IPv6 NMEA GPS (node05) _nmea-0183._tcp local hostname = [node05.local] address = [fe80::a8c2:15de:9af:19b] port = [10110] txt = [] = wlp192s0 IPv4 NMEA GPS (node05) _nmea-0183._tcp local hostname = [node05.local] address = [192.168.2.205] port = [10110] txt = [] - Khi dịch vụ đang chạy trên
node05.local, cũng có thể dễ dàng kiểm tra chính máy chủ TCP bằngtelnet node05.local 10110 - Sau khi khởi động lại GeoClue trên máy khách, nó lập tức nhận đúng tọa độ từ máy chủ
$ sudo systemctl restart geoclue $ /usr/libexec/geoclue-2.0/demos/where-am-i - Kết quả trả về đúng tọa độ của máy chủ cùng mô tả
GPS GGA+RMC, và độ chính xác được hiển thị là 0 métClient object: /org/freedesktop/GeoClue2/Client/3 New location: Latitude: 43.645758° Longitude: -79.410510° Accuracy: 0 meters Altitude: 119.000000 meters Speed: 0.000000 meters/second Description: GPS GGA+RMC Timestamp: Sun 03 May 2026 04:58:58 PM (1777841938 seconds since the Epoch) - Gnome Maps hiển thị đúng vị trí ngay lập tức, còn Firefox cần khởi động lại
- Trên Apple Maps của Mac, cách này có vẻ cũng hoạt động khi tắt Location Services, nhưng bản đồ không hiển thị điểm chính xác mà chỉ đúng khu vực tương đối
- Cách làm này giúp các máy Linux trong nhà xác định đúng vị trí ngay lập tức mà không phải chờ truy vấn GPS chậm và kém chính xác; nó cũng có thể được dùng để giả vị trí sai cho khách hoặc đồng nghiệp dùng Linux
- https://github.com/evert/nmea-static-gps-server
1 bình luận
Ý kiến trên Lobste.rs
Tôi hoàn toàn không biết là có một dịch vụ mDNS tiêu chuẩn để quảng bá GNSS trên LAN, và nó đã giải quyết ngay một vấn đề mà tôi thỉnh thoảng suy nghĩ suốt khoảng 6 tháng qua
Giả mạo vị trí GPS là một ý tưởng hay, nhưng để triển khai thực tế thì có vẻ vẫn khá nhiều việc
Sẽ thật tuyệt nếu trong phần cài đặt Android hoặc một tiện ích mở rộng Firefox có tùy chọn đơn giản như “dùng vị trí thật / dùng vị trí tùy chỉnh”
Dù vậy, tôi cũng thắc mắc GPS location được ưu tiên đến mức nào khi xung đột với các yếu tố khác như IP hay locale
Nhân tiện, tôi đã hơi giật mình khi thấy ảnh Jeff Geerling ở cuối trang, rồi mới nhận ra là ông ấy chỉ bấm thích chứ không phải tác giả
Nếu có thể thì tôi thường tránh các sản phẩm của ông ấy
Tôi từng dùng bộ thu GNSS của Trimble, không nhớ là qua USB OTG hay BLE, nhưng ứng dụng Trimble có thể làm nguồn Mock Locations để bất kỳ ứng dụng Android nào cũng nhận được tọa độ độ chính xác cao từ cây sào đo đạc, khoảng 2 cm, thay vì độ chính xác tương đối thấp của chính điện thoại
Khá thú vị, nhưng tôi cũng có thể tự triển khai và viết một script để phát thứ này từ thiết bị Android khi ở trong mạng gia đình
Tôi vẫn chưa hoàn toàn chắc mình có thực sự cần nó hay không :p
Tôi mới biết NMEA 0183 là một bộ đặc tả dành cho thiết bị điện tử hàng hải
Tôi chưa từng đủ tò mò để tra xem NMEA nghĩa là gì, nhưng tôi biết tên này thông qua ModemManager và modem Qualcomm