到目前為止介紹了如何偵測鄰近的藍芽裝置,且建立兩種傳輸類型的連線,都是用固定的 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 例外。
| 12
 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.py| 12
 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.py| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | import sysimport 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 通訊程式