到目前為止介紹了如何偵測鄰近的藍芽裝置,且建立兩種傳輸類型的連線,都是用固定的 Bluetooth address 和 port numbers,在實務上我們不推薦這麼做。
在 PyBluez 裡, 使用 服務發現協定 Service Discovery Protocol (SDP) 來動態地配置 port number 進行尋找是很簡單的。get_available_port 函式用來查找可用的 L2CAP 或 RFCOMM 的 port。advertise_service 函式用來廣播這個本地端 SDP 伺服器的服務,find_service 函式用來搜尋指定名稱的藍芽裝置。
1
| bluetooth.get_available_port( protocol )
|
get_available_port 回傳指定 protocol 第一個可用的 port number。目前只有支援 RFCOMM 和 L2CAP protocols。get_available_port 只是回傳一個 port number,並沒有實際預定使用任何資源,所以有可能當你要 bind 時,這 port 已經被別人 bind 走了,如果發生的話 bind 會拋出一個BluetoothException 例外。
1 2 3
| bluetooth.advertise_service( sock, name, uuid ) bluetooth.stop_advertising( sock ) bluetooth.find_service( name = None, uuid = None, bdaddr = None )
|
以上這三種函式用來廣撥服務,advertise_service 函式參數分別為 socket, service name 服務名稱, UUID,
這廣撥服務直到呼叫 stop_advertising 函式來關閉該 socket。
find_service可以搜尋單個或者所有附近特定裝置。透過匹配 name 和 UUID 進行 service 尋找(必須至少指定其中一個)。如果 bdaddr 是 None,那麼所有附近的設備都會進行尋找。如果提供了 localhost 作為 bdaddr 參數,那麼會對本地的 SDP 進行尋找。否則,就會指定的 bdaddr 藍芽裝置進行尋找。
server 端程式
rfcomm-server-sdp.py1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import bluetooth
server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
port = bluetooth.get_available_port( bluetooth.RFCOMM ) server_sock.bind(("",port)) server_sock.listen(1) print "listening on port %d" % port
uuid = "1e0ca4ea-299d-4335-93eb-27fcfe7fa848" bluetooth.advertise_service( server_sock, "FooBar Service", uuid )
client_sock,address = server_sock.accept() print "Accepted connection from ",address
data = client_sock.recv(1024) print "received [%s]" % data
client_sock.close() server_sock.close()
|
client 端程式
rfcomm-client-sdp.py1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import sys import bluetooth
uuid = "1e0ca4ea-299d-4335-93eb-27fcfe7fa848" service_matches = bluetooth.find_service( uuid = uuid )
if len(service_matches) == 0: print "couldn't find the FooBar service" sys.exit(0)
first_match = service_matches[0] port = first_match["port"] name = first_match["name"] host = first_match["host"]
print "connecting to \"%s\" on %s" % (name, host)
sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM ) sock.connect((host, port)) sock.send("hello!!") sock.close()
|
參考
https://people.csail.mit.edu/albert/bluez-intro/x290.html
相關主題
Python 的第一支藍芽程式
Python 寫藍芽 RFCOMM 通訊程式
Python 寫藍芽 L2CAP 通訊程式