Parowanie urządzeń bez nakładek z gnome lub kde
Ktoś Bardzo Mądry wymyślił, że nie ma już potrzeby parowania urządzeń bluetooth w prosty sposób, przez wpisywanie pinu do plików konfiguracyjnych, ani też żadne passkey-agenty nie są potrzebne.
Zainstaluj sobie bluez-gnome albo kbluetooth i paruj. Nie chcesz pół gnome w systemie? To spadaj!
Ale jakbym chciał gnome, to bym po prostu zainstalował. Spróbuję uruchomić transfer plików pomiędzy telefonem a laptopem we fluxboksie.
Zakładam, że mamy już zainstalowany bluez, wystartowany bluetooth, a polecenie:
hcitool scan
wykrywa telefon i podaje jego MAC (dla pewności lepiej na tę chwilę upublicznić telefon).
Jak już pisałem na wstępie, w bluez-utils+bluez-libs albo alternatywnym bluez nie da się dopisać PIN do pliku hcid.conf, bo go po prostu nie ma. Nie ma żadnych pin-helperów. Jest odesłanie do nakładek graficznych z gnome/kde. Ale da się inaczej.
Na forum archa znalazłem rozwiązanie (post #8)
http://bbs.archlinux.org/viewtopic.php?id=66085
Trzeba tylko ukraść skrypt simple-agent z innej paczki bluez :)
Pan Bardzo Mądry musiał mieć w tym jakiś cel...
Pobieramy paczkę ze strony
http://www.kernel.org/pub/linux/bluetooth/bluez-4.32.tar.bz2
i szukamy simple-agenta
(dla leniwych - jest w folderze "test")
Na wszelki wypadek zamieszczam skrypt poniżej:
#!/usr/bin/python
import gobject
import sys
import dbus
import dbus.service
import dbus.mainloop.glib
class Rejected(dbus.DBusException):
_dbus_error_name = "org.bluez.Error.Rejected"
class Agent(dbus.service.Object):
exit_on_release = True
def set_exit_on_release(self, exit_on_release):
self.exit_on_release = exit_on_release
@dbus.service.method("org.bluez.Agent",
in_signature="", out_signature="")
def Release(self):
print "Release"
if self.exit_on_release:
mainloop.quit()
@dbus.service.method("org.bluez.Agent",
in_signature="os", out_signature="")
def Authorize(self, device, uuid):
print "Authorize (%s, %s)" % (device, uuid)
@dbus.service.method("org.bluez.Agent",
in_signature="o", out_signature="s")
def RequestPinCode(self, device):
print "RequestPinCode (%s)" % (device)
return raw_input("Enter PIN Code: ")
@dbus.service.method("org.bluez.Agent",
in_signature="o", out_signature="u")
def RequestPasskey(self, device):
print "RequestPasskey (%s)" % (device)
passkey = raw_input("Enter passkey: ")
return dbus.UInt32(passkey)
@dbus.service.method("org.bluez.Agent",
in_signature="ou", out_signature="")
def DisplayPasskey(self, device, passkey):
print "DisplayPasskey (%s, %d)" % (device, passkey)
@dbus.service.method("org.bluez.Agent",
in_signature="ou", out_signature="")
def RequestConfirmation(self, device, passkey):
print "RequestConfirmation (%s, %d)" % (device, passkey)
confirm = raw_input("Confirm passkey (yes/no): ")
if (confirm == "yes"):
return
raise Rejected("Passkey doesn't match")
@dbus.service.method("org.bluez.Agent",
in_signature="s", out_signature="")
def ConfirmModeChange(self, mode):
print "ConfirmModeChange (%s)" % (mode)
@dbus.service.method("org.bluez.Agent",
in_signature="", out_signature="")
def Cancel(self):
print "Cancel"
def create_device_reply(device):
print "New device (%s)" % (device)
mainloop.quit()
def create_device_error(error):
print "Creating device failed: %s" % (error)
mainloop.quit()
if __name__ == '__main__':
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object("org.bluez", "/"),
"org.bluez.Manager")
if len(sys.argv) > 1:
path = manager.FindAdapter(sys.argv[1])
else:
path = manager.DefaultAdapter()
adapter = dbus.Interface(bus.get_object("org.bluez", path),
"org.bluez.Adapter")
path = "/test/agent"
agent = Agent(bus, path)
mainloop = gobject.MainLoop()
if len(sys.argv) > 2:
if len(sys.argv) > 3:
device = adapter.FindDevice(sys.argv[2])
adapter.RemoveDevice(device)
agent.set_exit_on_release(False)
adapter.CreatePairedDevice(sys.argv[2], path, "DisplayYesNo",
reply_handler=create_device_reply,
error_handler=create_device_error)
else:
adapter.RegisterAgent(path, "DisplayYesNo")
print "Agent registered"
mainloop.run()
#adapter.UnregisterAgent(path)
#print "Agent unregistered"
Uruchamiamy skrypt z poziomu roota i parujemy urządzenia. Telefon zawoła o PIN, wklepujemy, następnie powtarzamy w konsoli. I już.
Przenoszenie plików pomiędzy urządzeniami
Do przerzucania plików z komputera na telefon potrzebny jest obexftp:
Poleceniem:
sdptool browse 00:11:22:33:44:55
przeglądamy telefon i szukamy fragmentu, gdzie występuje "OBEX" w towarzystwie "Protocol Descriptor List", zczytujemy numer "Channel". Przyda się do przerzucania plików.
Np. tak:
Service Name: OBEX File Transfer
Service RecHandle: 0x1001a
Service Class ID List:
"OBEX File Transfer" (0x1106)
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 11
"OBEX" (0x0008)
Language Base Attr List:
code_ISO639: 0x454e
encoding: 0x6a
base_offset: 0x100
Profile Descriptor List:
"OBEX File Transfer" (0x1106)
Version: 0x0100
Jest! Channel: 11
Teraz wystarczy już tylko:
obexftp --nopath --noconn --uuid none --bluetooth 00:11:22:33:44:55 --channel 11 --put <plik>
np.:
obexftp --nopath --noconn --uuid none --bluetooth 00:11:22:33:44:55 --channel 11 --put zajebiaszcza_tapeta.png
Mój komputer jest niewidzialny!
Na wiki archa znalazłem coś do wyszukiwania niewidzialnych urządzeń:
Twój komputer jest niewidzialny (dla telefonu)? Włącz PSCAN i ISCAN:
$ hciconfig hci0 piscan
sprawdź, czy działa:
$ hciconfig hci0: Type: USB BD Address: 00:12:34:56:78:9A ACL MTU: 192:8 SCO MTU: 64:8 UP RUNNING PSCAN ISCAN RX bytes:20425 acl:115 sco:0 events:526 errors:0 TX bytes:5543 acl:84 sco:0 commands:340 errors:0
Uwaga: Sprawdź czasy widoczności (DiscoverableTimeout) i parowalności (PairableTimeout) w /etc/bluetooth/main.conf!
http://wiki.archlinux.org/index.php/Bluetooth#Using_Obex_for_sending_and_receiving_files
Przesyłanie plików
Do przesyłania plików przyda się moduł fuse Tworzymy folder do montowania telefonu, np.:
sudo mkdir /mnt/e50
Montujemy telefon:
mount -t fuse "obexfs#-b00:11:22:33:44:55 -B6" /katalog_docelowy
np.: mount -t fuse "obexfs#-b00:11:22:33:44:55 -B6" /mnt/e50
Dostęp do telefonu uzyskujemy z poziomu roota, zatem:
sudo mc
pozwala przeglądać telefon; nie próbujcie nic kopiować - działa ale długo trwa! (no i root jest właścicielem plików).
Oprócz forum i wiki archlinux korzystałem też ze strony projektu Obex:
http://dev.zuckschwerdt.org/openobex/wiki/ObexFtpExamples
Aktualizacja:
Montowanie za pomocą fuse przestało u mnie działać. Nie wiem jak u Was :) Działa za to sposób:
obexfs -b <mac address telefonu> /katalog docelowy
Potem już normalnie, czyli mc z prawami roota. Odmontowujemy za pomocą komendy:
fusermount -u /punkt montowania
Automatyzacja
Aby zautomatyzować proces montowania i odmontowywania można posłużyć się prostymi skryptami:
montuj_fon
#!/bin/bash
sudo modprobe fuse
sudo sh /home/user/Skrypty/simple-agent
obexfs -b 00:11:22:33:44:55/punkt montowania
Skrypt ten odwołuje się do znanego już nam skryptu simple-agent
, dzięki któremu telefon nie wymaga montowania z prawami roota. Pozwala to na dostęp do pamięci telefonu i/lub karty pamięci z poziomu użytkownika przez dowolny manager plików.
odmontuj_fon
#!/bin/bash
sudo fusermount -u /mnt/e50
sudo modprobe -r fuse
Aktywatory można podczepić do paska narzędzi lub do menu managera okien, np. we fluxboksie:
.fluxbox/menu
...
[submenu] (telefon)
[exec] (montuj) {sh /home/user/Skrypty/montuj_fon}
[exec] (odmontuj) {sh /home/user/Skrypty/odmontuj_fon}
[end]
...