summaryrefslogtreecommitdiff
path: root/pybluez
diff options
context:
space:
mode:
Diffstat (limited to 'pybluez')
-rw-r--r--pybluez/advanced/inquiry-with-rssi.py148
-rw-r--r--pybluez/advanced/l2-mtu.py60
-rw-r--r--pybluez/advanced/l2-unreliable-client.py76
-rw-r--r--pybluez/advanced/l2-unreliable-server.py34
-rw-r--r--pybluez/advanced/read-local-bdaddr.py35
-rw-r--r--pybluez/advanced/write-inquiry-scan.py90
-rw-r--r--pybluez/bluezchat/bluezchat.glade138
-rwxr-xr-xpybluez/bluezchat/bluezchat.py191
-rw-r--r--pybluez/simple/asynchronous-inquiry.py65
-rw-r--r--pybluez/simple/inquiry.py17
-rw-r--r--pybluez/simple/l2capclient.py28
-rw-r--r--pybluez/simple/l2capserver.py32
-rw-r--r--pybluez/simple/rfcomm-client.py45
-rw-r--r--pybluez/simple/rfcomm-server.py41
-rw-r--r--pybluez/simple/sdp-browse.py35
15 files changed, 1035 insertions, 0 deletions
diff --git a/pybluez/advanced/inquiry-with-rssi.py b/pybluez/advanced/inquiry-with-rssi.py
new file mode 100644
index 0000000..814f7ed
--- /dev/null
+++ b/pybluez/advanced/inquiry-with-rssi.py
@@ -0,0 +1,148 @@
+# performs a simple device inquiry, followed by a remote name request of each
+# discovered device
+
+import os
+import sys
+import struct
+import bluetooth._bluetooth as bluez
+
+def printpacket(pkt):
+ for c in pkt:
+ sys.stdout.write("%02x " % struct.unpack("B",c)[0])
+ print
+
+
+def read_inquiry_mode(sock):
+ """returns the current mode, or -1 on failure"""
+ # save current filter
+ old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14)
+
+ # Setup socket filter to receive only events related to the
+ # read_inquiry_mode command
+ flt = bluez.hci_filter_new()
+ opcode = bluez.cmd_opcode_pack(bluez.OGF_HOST_CTL,
+ bluez.OCF_READ_INQUIRY_MODE)
+ bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT)
+ bluez.hci_filter_set_event(flt, bluez.EVT_CMD_COMPLETE);
+ bluez.hci_filter_set_opcode(flt, opcode)
+ sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt )
+
+ # first read the current inquiry mode.
+ bluez.hci_send_cmd(sock, bluez.OGF_HOST_CTL,
+ bluez.OCF_READ_INQUIRY_MODE )
+
+ pkt = sock.recv(255)
+
+ status,mode = struct.unpack("xxxxxxBB", pkt)
+ if status != 0: mode = -1
+
+ # restore old filter
+ sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter )
+ return mode
+
+def write_inquiry_mode(sock, mode):
+ """returns 0 on success, -1 on failure"""
+ # save current filter
+ old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14)
+
+ # Setup socket filter to receive only events related to the
+ # write_inquiry_mode command
+ flt = bluez.hci_filter_new()
+ opcode = bluez.cmd_opcode_pack(bluez.OGF_HOST_CTL,
+ bluez.OCF_WRITE_INQUIRY_MODE)
+ bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT)
+ bluez.hci_filter_set_event(flt, bluez.EVT_CMD_COMPLETE);
+ bluez.hci_filter_set_opcode(flt, opcode)
+ sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt )
+
+ # send the command!
+ bluez.hci_send_cmd(sock, bluez.OGF_HOST_CTL,
+ bluez.OCF_WRITE_INQUIRY_MODE, struct.pack("B", mode) )
+
+ pkt = sock.recv(255)
+
+ status = struct.unpack("xxxxxxB", pkt)[0]
+
+ # restore old filter
+ sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter )
+ if status != 0: return -1
+ return 0
+
+def device_inquiry_with_with_rssi(sock):
+ # save current filter
+ old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14)
+
+ # perform a device inquiry on bluetooth device #0
+ # The inquiry should last 8 * 1.28 = 10.24 seconds
+ # before the inquiry is performed, bluez should flush its cache of
+ # previously discovered devices
+ flt = bluez.hci_filter_new()
+ bluez.hci_filter_all_events(flt)
+ bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT)
+ sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt )
+
+ duration = 4
+ max_responses = 255
+ cmd_pkt = struct.pack("BBBBB", 0x33, 0x8b, 0x9e, duration, max_responses)
+ bluez.hci_send_cmd(sock, bluez.OGF_LINK_CTL, bluez.OCF_INQUIRY, cmd_pkt)
+
+ results = []
+
+ done = False
+ while not done:
+ pkt = sock.recv(255)
+ ptype, event, plen = struct.unpack("BBB", pkt[:3])
+ if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI:
+ pkt = pkt[3:]
+ nrsp = struct.unpack("B", pkt[0])[0]
+ for i in range(nrsp):
+ addr = bluez.ba2str( pkt[1+6*i:1+6*i+6] )
+ rssi = struct.unpack("b", pkt[1+13*nrsp+i])[0]
+ results.append( ( addr, rssi ) )
+ print "[%s] RSSI: [%d]" % (addr, rssi)
+ elif event == bluez.EVT_INQUIRY_COMPLETE:
+ done = True
+ elif event == bluez.EVT_CMD_STATUS:
+ status, ncmd, opcode = struct.unpack("BBH", pkt[3:7])
+ if status != 0:
+ print "uh oh..."
+ printpacket(pkt[3:7])
+ done = True
+ else:
+ print "unrecognized packet type 0x%02x" % ptype
+
+
+ # restore old filter
+ sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter )
+
+ return results
+
+dev_id = 0
+try:
+ sock = bluez.hci_open_dev(dev_id)
+except:
+ print "error accessing bluetooth device..."
+ sys.exit(1)
+
+try:
+ mode = read_inquiry_mode(sock)
+except Exception, e:
+ print "error reading inquiry mode. "
+ print "Are you sure this a bluetooth 1.2 device?"
+ print e
+ sys.exit(1)
+print "current inquiry mode is %d" % mode
+
+if mode != 1:
+ print "writing inquiry mode..."
+ try:
+ result = write_inquiry_mode(sock, 1)
+ except Exception, e:
+ print "error writing inquiry mode. Are you sure you're root?"
+ print e
+ sys.exit(1)
+ if result != 0:
+ print "error while setting inquiry mode"
+ print "result: %d" % result
+
+device_inquiry_with_with_rssi(sock)
diff --git a/pybluez/advanced/l2-mtu.py b/pybluez/advanced/l2-mtu.py
new file mode 100644
index 0000000..1ffe04c
--- /dev/null
+++ b/pybluez/advanced/l2-mtu.py
@@ -0,0 +1,60 @@
+import sys
+import struct
+import bluetooth
+
+def usage():
+ print "usage: l2-mtu < server | client > [options]"
+ print ""
+ print "l2-mtu server to start in server mode"
+ print "l2-mtu client <addr> to start in client mode and connect to addr"
+ sys.exit(2)
+
+if len(sys.argv) < 2: usage()
+
+mode = sys.argv[1]
+if mode not in [ "client", "server" ]: usage()
+
+if mode == "server":
+ server_sock=bluetooth.BluetoothSocket( bluetooth.L2CAP )
+ server_sock.bind(("",0x1001))
+ server_sock.listen(1)
+ while True:
+ print "waiting for incoming connection"
+ client_sock,address = server_sock.accept()
+ print "Accepted connection from %s" % str(address)
+
+ bluetooth.set_l2cap_mtu( client_sock, 65535 )
+
+ print "waiting for data"
+ total = 0
+ while True:
+ try:
+ data = client_sock.recv(65535)
+ except bluetooth.BluetoothError, e:
+ break
+ if len(data) == 0: break
+ print "received packet of size %d" % len(data)
+
+ client_sock.close()
+
+ print "connection closed"
+
+ server_sock.close()
+else:
+ sock=bluetooth.BluetoothSocket(bluetooth.L2CAP)
+
+ bt_addr = sys.argv[2]
+ print "trying to connect to %s:1001" % bt_addr
+ port = 0x1001
+ sock.connect((bt_addr, port))
+
+ print "connected. Adjusting link parameters."
+ bluetooth.set_l2cap_mtu( sock, 65535 )
+
+ totalsent = 0
+ for i in range(1, 65535, 100):
+ pkt = "0" * i
+ sent = sock.send(pkt)
+ print "sent packet of size %d (tried %d)" % (sent, len(pkt))
+
+ sock.close()
diff --git a/pybluez/advanced/l2-unreliable-client.py b/pybluez/advanced/l2-unreliable-client.py
new file mode 100644
index 0000000..5b10a48
--- /dev/null
+++ b/pybluez/advanced/l2-unreliable-client.py
@@ -0,0 +1,76 @@
+import sys
+import fcntl
+import struct
+import array
+import bluetooth
+import bluetooth._bluetooth as bt # low level bluetooth wrappers.
+
+def __get_acl_conn_handle(sock, addr):
+ hci_fd = sock.fileno()
+ reqstr = struct.pack( "6sB17s", bt.str2ba(addr), bt.ACL_LINK, "\0" * 17)
+ request = array.array( "c", reqstr )
+ fcntl.ioctl( hci_fd, bt.HCIGETCONNINFO, request, 1 )
+ handle = struct.unpack("8xH14x", request.tostring())[0]
+ return handle
+
+def write_flush_timeout( addr, timeout ):
+ hci_sock = bt.hci_open_dev()
+ # get the ACL connection handle to the remote device
+ handle = __get_acl_conn_handle(hci_sock, addr)
+ pkt = struct.pack("HH", handle, bt.htobs(timeout))
+ response = bt.hci_send_req(hci_sock, bt.OGF_HOST_CTL,
+ 0x0028, bt.EVT_CMD_COMPLETE, 3, pkt)
+ status = struct.unpack("B", response[0])[0]
+ rhandle = struct.unpack("H", response[1:3])[0]
+ assert rhandle == handle
+ assert status == 0
+
+def read_flush_timeout( addr ):
+ hci_sock = bt.hci_open_dev()
+ # get the ACL connection handle to the remote device
+ handle = __get_acl_conn_handle(hci_sock, addr)
+ pkt = struct.pack("H", handle)
+ response = bt.hci_send_req(hci_sock, bt.OGF_HOST_CTL,
+ 0x0027, bt.EVT_CMD_COMPLETE, 5, pkt)
+ status = struct.unpack("B", response[0])[0]
+ rhandle = struct.unpack("H", response[1:3])[0]
+ assert rhandle == handle
+ assert status == 0
+ fto = struct.unpack("H", response[3:5])[0]
+ return fto
+
+# Create the client socket
+sock=bluetooth.BluetoothSocket(bluetooth.L2CAP)
+
+if len(sys.argv) < 4:
+ print "usage: l2capclient.py <addr> <timeout> <num_packets>"
+ print " address - device that l2-unreliable-server is running on"
+ print " timeout - wait timeout * 0.625ms before dropping unACK'd packets"
+ print " num_packets - number of 627-byte packets to send on connect"
+ sys.exit(2)
+
+bt_addr=sys.argv[1]
+timeout = int(sys.argv[2])
+num_packets = int(sys.argv[3])
+
+print "trying to connect to %s:1001" % bt_addr
+port = 0x1001
+sock.connect((bt_addr, port))
+
+print "connected. Adjusting link parameters."
+print "current flush timeout is %d ms" % read_flush_timeout( bt_addr )
+try:
+ write_flush_timeout( bt_addr, timeout )
+except bt.error, e:
+ print "error setting flush timeout. are you sure you're superuser?"
+ print e
+ sys.exit(1)
+print "new flush timeout is %d ms" % read_flush_timeout( bt_addr )
+
+totalsent = 0
+for i in range(num_packets):
+ pkt = "0" * 672
+ totalsent += sock.send(pkt)
+print "sent %d bytes total" % totalsent
+
+sock.close()
diff --git a/pybluez/advanced/l2-unreliable-server.py b/pybluez/advanced/l2-unreliable-server.py
new file mode 100644
index 0000000..d827775
--- /dev/null
+++ b/pybluez/advanced/l2-unreliable-server.py
@@ -0,0 +1,34 @@
+import sys
+import bluetooth
+
+if len(sys.argv) < 2:
+ print "usage: l2-unreliable-server"
+ sys.exit(2)
+
+timeout = int(sys.argv[1])
+assert timeout >= 0
+
+server_sock=bluetooth.BluetoothSocket( bluetooth.L2CAP )
+server_sock.bind(("",0x1001))
+server_sock.listen(1)
+while True:
+ print "waiting for incoming connection"
+ client_sock,address = server_sock.accept()
+ print "Accepted connection from %s" % str(address)
+
+ print "waiting for data"
+ total = 0
+ while True:
+ try:
+ data = client_sock.recv(1024)
+ except bluetooth.BluetoothError, e:
+ break
+ if len(data) == 0: break
+ total += len(data)
+ print "total byte read: %d" % total
+
+ client_sock.close()
+
+ print "connection closed"
+
+server_sock.close()
diff --git a/pybluez/advanced/read-local-bdaddr.py b/pybluez/advanced/read-local-bdaddr.py
new file mode 100644
index 0000000..410a681
--- /dev/null
+++ b/pybluez/advanced/read-local-bdaddr.py
@@ -0,0 +1,35 @@
+import os
+import sys
+import struct
+import bluetooth._bluetooth as _bt
+
+def read_local_bdaddr(hci_sock):
+ old_filter = hci_sock.getsockopt( _bt.SOL_HCI, _bt.HCI_FILTER, 14)
+ flt = _bt.hci_filter_new()
+ opcode = _bt.cmd_opcode_pack(_bt.OGF_INFO_PARAM,
+ _bt.OCF_READ_BD_ADDR)
+ _bt.hci_filter_set_ptype(flt, _bt.HCI_EVENT_PKT)
+ _bt.hci_filter_set_event(flt, _bt.EVT_CMD_COMPLETE);
+ _bt.hci_filter_set_opcode(flt, opcode)
+ hci_sock.setsockopt( _bt.SOL_HCI, _bt.HCI_FILTER, flt )
+
+ _bt.hci_send_cmd(hci_sock, _bt.OGF_INFO_PARAM, _bt.OCF_READ_BD_ADDR )
+
+ pkt = hci_sock.recv(255)
+
+ status,raw_bdaddr = struct.unpack("xxxxxxB6s", pkt)
+ assert status == 0
+
+ t = [ "%X" % ord(b) for b in raw_bdaddr ]
+ t.reverse()
+ bdaddr = ":".join(t)
+
+ # restore old filter
+ hci_sock.setsockopt( _bt.SOL_HCI, _bt.HCI_FILTER, old_filter )
+ return bdaddr
+
+if __name__ == "__main__":
+ dev_id = 0
+ hci_sock = _bt.hci_open_dev(dev_id)
+ bdaddr = read_local_bdaddr(hci_sock)
+ print bdaddr
diff --git a/pybluez/advanced/write-inquiry-scan.py b/pybluez/advanced/write-inquiry-scan.py
new file mode 100644
index 0000000..54793b7
--- /dev/null
+++ b/pybluez/advanced/write-inquiry-scan.py
@@ -0,0 +1,90 @@
+import os
+import sys
+import struct
+import bluetooth._bluetooth as bluez
+
+def read_inquiry_scan_activity(sock):
+ """returns the current inquiry scan interval and window,
+ or -1 on failure"""
+ # save current filter
+ old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14)
+
+ # Setup socket filter to receive only events related to the
+ # read_inquiry_mode command
+ flt = bluez.hci_filter_new()
+ opcode = bluez.cmd_opcode_pack(bluez.OGF_HOST_CTL,
+ bluez.OCF_READ_INQ_ACTIVITY)
+ bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT)
+ bluez.hci_filter_set_event(flt, bluez.EVT_CMD_COMPLETE);
+ bluez.hci_filter_set_opcode(flt, opcode)
+ sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt )
+
+ # first read the current inquiry mode.
+ bluez.hci_send_cmd(sock, bluez.OGF_HOST_CTL,
+ bluez.OCF_READ_INQ_ACTIVITY )
+
+ pkt = sock.recv(255)
+
+ status,interval,window = struct.unpack("!xxxxxxBHH", pkt)
+ interval = bluez.btohs(interval)
+ interval = (interval >> 8) | ( (interval & 0xFF) << 8 )
+ window = (window >> 8) | ( (window & 0xFF) << 8 )
+ if status != 0: mode = -1
+
+ # restore old filter
+ sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter )
+ return interval, window
+
+def write_inquiry_scan_activity(sock, interval, window):
+ """returns 0 on success, -1 on failure"""
+ # save current filter
+ old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14)
+
+ # Setup socket filter to receive only events related to the
+ # write_inquiry_mode command
+ flt = bluez.hci_filter_new()
+ opcode = bluez.cmd_opcode_pack(bluez.OGF_HOST_CTL,
+ bluez.OCF_WRITE_INQ_ACTIVITY)
+ bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT)
+ bluez.hci_filter_set_event(flt, bluez.EVT_CMD_COMPLETE);
+ bluez.hci_filter_set_opcode(flt, opcode)
+ sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt )
+
+ # send the command!
+ bluez.hci_send_cmd(sock, bluez.OGF_HOST_CTL,
+ bluez.OCF_WRITE_INQ_ACTIVITY, struct.pack("HH",
+ interval, window) )
+
+ pkt = sock.recv(255)
+
+ status = struct.unpack("xxxxxxB", pkt)[0]
+
+ # restore old filter
+ sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter )
+ if status != 0: return -1
+ return 0
+
+dev_id = 0
+try:
+ sock = bluez.hci_open_dev(dev_id)
+except:
+ print "error accessing bluetooth device..."
+ sys.exit(1)
+
+try:
+ interval, window = read_inquiry_scan_activity(sock)
+except Exception, e:
+ print "error reading inquiry scan activity. "
+ print e
+ sys.exit(1)
+print "current inquiry scan interval: %d (0x%X) window: %d (0x%X)" % \
+ (interval, interval, window, window)
+
+if len(sys.argv) == 3:
+ interval = int(sys.argv[1])
+ window = int(sys.argv[2])
+ print "target interval: %d window %d" % (interval, window)
+ write_inquiry_scan_activity(sock, interval, window)
+ interval, window = read_inquiry_scan_activity(sock)
+ print "current inquiry scan interval: %d (0x%X) window: %d (0x%X)" % \
+ (interval, interval, window, window)
diff --git a/pybluez/bluezchat/bluezchat.glade b/pybluez/bluezchat/bluezchat.glade
new file mode 100644
index 0000000..b3f37eb
--- /dev/null
+++ b/pybluez/bluezchat/bluezchat.glade
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--*- mode: xml -*-->
+<glade-interface>
+ <widget class="GtkWindow" id="bluezchat_window">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">bluez chat</property>
+ <property name="default_width">240</property>
+ <property name="default_height">320</property>
+ <signal name="delete_event" handler="gtk_main_quit"/>
+ <signal name="destroy_event" handler="gtk_main_quit"/>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <child>
+ <widget class="GtkTreeView" id="devices_tv">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <signal name="cursor_changed" handler="on_devices_tv_cursor_changed"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkButton" id="quit_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_Quit</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="on_quit_button_clicked"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="scan_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">S_can</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="on_scan_button_clicked"/>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="chat_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_Chat</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="on_chat_button_clicked"/>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <child>
+ <widget class="GtkTextView" id="main_text">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">text:</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="input_tb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">*</property>
+ </widget>
+ <packing>
+ <property name="padding">3</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="send_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_Send</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="on_send_button_clicked"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
diff --git a/pybluez/bluezchat/bluezchat.py b/pybluez/bluezchat/bluezchat.py
new file mode 100755
index 0000000..5021eb3
--- /dev/null
+++ b/pybluez/bluezchat/bluezchat.py
@@ -0,0 +1,191 @@
+#!/usr/bin/python
+
+""" A simple graphical chat client to demonstrate the use of pybluez.
+
+Opens a l2cap socket and listens on PSM 0x1001
+
+Provides the ability to scan for nearby bluetooth devices and establish chat
+sessions with them.
+"""
+
+
+import os
+import sys
+import time
+
+import gtk
+import gobject
+import gtk.glade
+
+import bluetooth
+
+GLADEFILE="bluezchat.glade"
+
+# *****************
+
+def alert(text, buttons=gtk.BUTTONS_NONE, type=gtk.MESSAGE_INFO):
+ md = gtk.MessageDialog(buttons=buttons, type=type)
+ md.label.set_text(text)
+ md.run()
+ md.destroy()
+
+class BluezChatGui:
+ def __init__(self):
+ self.main_window_xml = gtk.glade.XML(GLADEFILE, "bluezchat_window")
+
+ # connect our signal handlers
+ dic = { "on_quit_button_clicked" : self.quit_button_clicked,
+ "on_send_button_clicked" : self.send_button_clicked,
+ "on_chat_button_clicked" : self.chat_button_clicked,
+ "on_scan_button_clicked" : self.scan_button_clicked,
+ "on_devices_tv_cursor_changed" : self.devices_tv_cursor_changed
+ }
+
+ self.main_window_xml.signal_autoconnect(dic)
+
+ # prepare the floor listbox
+ self.devices_tv = self.main_window_xml.get_widget("devices_tv")
+ self.discovered = gtk.ListStore(gobject.TYPE_STRING,
+ gobject.TYPE_STRING)
+ self.devices_tv.set_model(self.discovered)
+ renderer = gtk.CellRendererText()
+ column1=gtk.TreeViewColumn("addr", renderer, text=0)
+ column2=gtk.TreeViewColumn("name", renderer, text=1)
+ self.devices_tv.append_column(column1)
+ self.devices_tv.append_column(column2)
+
+ self.quit_button = self.main_window_xml.get_widget("quit_button")
+ self.scan_button = self.main_window_xml.get_widget("scan_button")
+ self.chat_button = self.main_window_xml.get_widget("chat_button")
+ self.send_button = self.main_window_xml.get_widget("send_button")
+ self.main_text = self.main_window_xml.get_widget("main_text")
+ self.text_buffer = self.main_text.get_buffer()
+
+ self.input_tb = self.main_window_xml.get_widget("input_tb")
+
+ self.listed_devs = []
+
+ self.chat_button.set_sensitive(False)
+
+ self.peers = {}
+ self.sources = {}
+ self.addresses = {}
+
+ # the listening sockets
+ self.server_sock = None
+
+# --- gui signal handlers
+
+ def quit_button_clicked(self, widget):
+ gtk.main_quit()
+
+ def scan_button_clicked(self, widget):
+ self.quit_button.set_sensitive(False)
+ self.scan_button.set_sensitive(False)
+# self.chat_button.set_sensitive(False)
+
+ self.discovered.clear()
+ for addr, name in bluetooth.discover_devices (lookup_names = True):
+ self.discovered.append ((addr, name))
+
+ self.quit_button.set_sensitive(True)
+ self.scan_button.set_sensitive(True)
+# self.chat_button.set_sensitive(True)
+
+ def send_button_clicked(self, widget):
+ text = self.input_tb.get_text()
+ if len(text) == 0: return
+
+ for addr, sock in self.peers.items():
+ sock.send(text)
+
+ self.input_tb.set_text("")
+ self.add_text("\nme - %s" % text)
+
+ def chat_button_clicked(self, widget):
+ (model, iter) = self.devices_tv.get_selection().get_selected()
+ if iter is not None:
+ addr = model.get_value(iter, 0)
+ if addr not in self.peers:
+ self.add_text("\nconnecting to %s" % addr)
+ self.connect(addr)
+ else:
+ self.add_text("\nAlready connected to %s!" % addr)
+
+ def devices_tv_cursor_changed(self, widget):
+ (model, iter) = self.devices_tv.get_selection().get_selected()
+ if iter is not None:
+ self.chat_button.set_sensitive(True)
+ else:
+ self.chat_button.set_sensitive(False)
+
+# --- network events
+
+ def incoming_connection(self, source, condition):
+ sock, info = self.server_sock.accept()
+ address, psm = info
+
+ self.add_text("\naccepted connection from %s" % str(address))
+
+ # add new connection to list of peers
+ self.peers[address] = sock
+ self.addresses[sock] = address
+
+ source = gobject.io_add_watch (sock, gobject.IO_IN, self.data_ready)
+ self.sources[address] = source
+ return True
+
+ def data_ready(self, sock, condition):
+ address = self.addresses[sock]
+ data = sock.recv(1024)
+
+ if len(data) == 0:
+ self.add_text("\nlost connection with %s" % address)
+ gobject.source_remove(self.sources[address])
+ del self.sources[address]
+ del self.peers[address]
+ del self.addresses[sock]
+ sock.close()
+ else:
+ self.add_text("\n%s - %s" % (address, str(data)))
+ return True
+
+# --- other stuff
+
+ def cleanup(self):
+ self.hci_sock.close()
+
+ def connect(self, addr):
+ sock = bluetooth.BluetoothSocket (bluetooth.L2CAP)
+ try:
+ sock.connect((addr, 0x1001))
+ except bluez.error, e:
+ self.add_text("\n%s" % str(e))
+ sock.close()
+ return
+
+ self.peers[addr] = sock
+ source = gobject.io_add_watch (sock, gobject.IO_IN, self.data_ready)
+ self.sources[addr] = source
+ self.addresses[sock] = addr
+
+
+ def add_text(self, text):
+ self.text_buffer.insert(self.text_buffer.get_end_iter(), text)
+
+ def start_server(self):
+ self.server_sock = bluetooth.BluetoothSocket (bluetooth.L2CAP)
+ self.server_sock.bind(("",0x1001))
+ self.server_sock.listen(1)
+
+ gobject.io_add_watch(self.server_sock,
+ gobject.IO_IN, self.incoming_connection)
+
+ def run(self):
+ self.text_buffer.insert(self.text_buffer.get_end_iter(), "loading..")
+ self.start_server()
+ gtk.main()
+
+if __name__ == "__main__":
+ gui = BluezChatGui()
+ gui.run()
diff --git a/pybluez/simple/asynchronous-inquiry.py b/pybluez/simple/asynchronous-inquiry.py
new file mode 100644
index 0000000..abbd70c
--- /dev/null
+++ b/pybluez/simple/asynchronous-inquiry.py
@@ -0,0 +1,65 @@
+# file: asynchronous-inquiry.py
+# auth: Albert Huang <albert@csail.mit.edu>
+# desc: demonstration of how to do asynchronous device discovery by subclassing
+# the DeviceDiscoverer class
+# $Id: asynchronous-inquiry.py 405 2006-05-06 00:39:50Z albert $
+#
+# XXX Linux only (5/5/2006)
+
+import bluetooth
+import select
+
+class MyDiscoverer(bluetooth.DeviceDiscoverer):
+
+ def pre_inquiry(self):
+ self.done = False
+
+ def device_discovered(self, address, device_class, name):
+ print "%s - %s" % (address, name)
+
+ # get some information out of the device class and display it.
+ # voodoo magic specified at:
+ #
+ # https://www.bluetooth.org/foundry/assignnumb/document/baseband
+ major_classes = ( "Miscellaneous",
+ "Computer",
+ "Phone",
+ "LAN/Network Access point",
+ "Audio/Video",
+ "Peripheral",
+ "Imaging" )
+ major_class = (device_class >> 8) & 0xf
+ if major_class < 7:
+ print " %s" % major_classes[major_class]
+ else:
+ print " Uncategorized"
+
+ print " services:"
+ service_classes = ( (16, "positioning"),
+ (17, "networking"),
+ (18, "rendering"),
+ (19, "capturing"),
+ (20, "object transfer"),
+ (21, "audio"),
+ (22, "telephony"),
+ (23, "information"))
+
+ for bitpos, classname in service_classes:
+ if device_class & (1 << (bitpos-1)):
+ print " %s" % classname
+
+ def inquiry_complete(self):
+ self.done = True
+
+d = MyDiscoverer()
+d.find_devices(lookup_names = True)
+
+readfiles = [ d, ]
+
+while True:
+ rfds = select.select( readfiles, [], [] )[0]
+
+ if d in rfds:
+ d.process_event()
+
+ if d.done: break
diff --git a/pybluez/simple/inquiry.py b/pybluez/simple/inquiry.py
new file mode 100644
index 0000000..8f77887
--- /dev/null
+++ b/pybluez/simple/inquiry.py
@@ -0,0 +1,17 @@
+# file: inquiry.py
+# auth: Albert Huang <albert@csail.mit.edu>
+# desc: performs a simple device inquiry followed by a remote name request of
+# each discovered device
+# $Id: inquiry.py 401 2006-05-05 19:07:48Z albert $
+#
+
+import bluetooth
+
+print "performing inquiry..."
+
+nearby_devices = bluetooth.discover_devices(lookup_names = True)
+
+print "found %d devices" % len(nearby_devices)
+
+for addr, name in nearby_devices:
+ print " %s - %s" % (addr, name)
diff --git a/pybluez/simple/l2capclient.py b/pybluez/simple/l2capclient.py
new file mode 100644
index 0000000..930e431
--- /dev/null
+++ b/pybluez/simple/l2capclient.py
@@ -0,0 +1,28 @@
+# file: l2capclient.py
+# desc: Demo L2CAP client for bluetooth module.
+# $Id: l2capclient.py 524 2007-08-15 04:04:52Z albert $
+
+import sys
+import bluetooth
+
+sock=bluetooth.BluetoothSocket(bluetooth.L2CAP)
+
+if len(sys.argv) < 2:
+ print "usage: l2capclient.py <addr>"
+ sys.exit(2)
+
+bt_addr=sys.argv[1]
+port = 0x1001
+
+print "trying to connect to %s on PSM 0x%X" % (bt_addr, port)
+
+sock.connect((bt_addr, port))
+
+print "connected. type stuff"
+while True:
+ data = raw_input()
+ if(len(data) == 0): break
+ sock.send(data)
+
+sock.close()
+
diff --git a/pybluez/simple/l2capserver.py b/pybluez/simple/l2capserver.py
new file mode 100644
index 0000000..40ad7d6
--- /dev/null
+++ b/pybluez/simple/l2capserver.py
@@ -0,0 +1,32 @@
+# file: l2capclient.py
+# desc: Demo L2CAP server for pybluez.
+# $Id: l2capserver.py 524 2007-08-15 04:04:52Z albert $
+
+import bluetooth
+
+server_sock=bluetooth.BluetoothSocket( bluetooth.L2CAP )
+
+port = 0x1001
+
+server_sock.bind(("",port))
+server_sock.listen(1)
+
+#uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ef"
+#bluetooth.advertise_service( server_sock, "SampleServerL2CAP",
+# service_id = uuid,
+# service_classes = [ uuid ]
+# )
+
+client_sock,address = server_sock.accept()
+print "Accepted connection from ",address
+
+data = client_sock.recv(1024)
+print "Data received:", data
+
+while data:
+ client_sock.send('Echo =>' + data)
+ data = client_sock.recv(1024)
+ print "Data received:",data
+
+client_sock.close()
+server_sock.close()
diff --git a/pybluez/simple/rfcomm-client.py b/pybluez/simple/rfcomm-client.py
new file mode 100644
index 0000000..4da12af
--- /dev/null
+++ b/pybluez/simple/rfcomm-client.py
@@ -0,0 +1,45 @@
+# file: rfcomm-client.py
+# auth: Albert Huang <albert@csail.mit.edu>
+# desc: simple demonstration of a client application that uses RFCOMM sockets
+# intended for use with rfcomm-server
+#
+# $Id: rfcomm-client.py 424 2006-08-24 03:35:54Z albert $
+
+from bluetooth import *
+import sys
+
+addr = None
+
+if len(sys.argv) < 2:
+ print "no device specified. Searching all nearby bluetooth devices for"
+ print "the SampleServer service"
+else:
+ addr = sys.argv[1]
+ print "Searching for SampleServer on %s" % addr
+
+# search for the SampleServer service
+uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
+service_matches = find_service( uuid = uuid, address = addr )
+
+if len(service_matches) == 0:
+ print "couldn't find the SampleServer 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)
+
+# Create the client socket
+sock=BluetoothSocket( RFCOMM )
+sock.connect((host, port))
+
+print "connected. type stuff"
+while True:
+ data = raw_input()
+ if len(data) == 0: break
+ sock.send(data)
+
+sock.close()
diff --git a/pybluez/simple/rfcomm-server.py b/pybluez/simple/rfcomm-server.py
new file mode 100644
index 0000000..1fb555f
--- /dev/null
+++ b/pybluez/simple/rfcomm-server.py
@@ -0,0 +1,41 @@
+# file: rfcomm-server.py
+# auth: Albert Huang <albert@csail.mit.edu>
+# desc: simple demonstration of a server application that uses RFCOMM sockets
+#
+# $Id: rfcomm-server.py 518 2007-08-10 07:20:07Z albert $
+
+from bluetooth import *
+
+server_sock=BluetoothSocket( RFCOMM )
+server_sock.bind(("",PORT_ANY))
+server_sock.listen(1)
+
+port = server_sock.getsockname()[1]
+
+uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
+
+advertise_service( server_sock, "SampleServer",
+ service_id = uuid,
+ service_classes = [ uuid, SERIAL_PORT_CLASS ],
+ profiles = [ SERIAL_PORT_PROFILE ],
+# protocols = [ OBEX_UUID ]
+ )
+
+print "Waiting for connection on RFCOMM channel %d" % port
+
+client_sock, client_info = server_sock.accept()
+print "Accepted connection from ", client_info
+
+try:
+ while True:
+ data = client_sock.recv(1024)
+ if len(data) == 0: break
+ print "received [%s]" % data
+except IOError:
+ pass
+
+print "disconnected"
+
+client_sock.close()
+server_sock.close()
+print "all done"
diff --git a/pybluez/simple/sdp-browse.py b/pybluez/simple/sdp-browse.py
new file mode 100644
index 0000000..9d24b7a
--- /dev/null
+++ b/pybluez/simple/sdp-browse.py
@@ -0,0 +1,35 @@
+# file: sdp-browse.py
+# auth: Albert Huang <albert@csail.mit.edu>
+# desc: displays services being advertised on a specified bluetooth device
+# $Id: sdp-browse.py 393 2006-02-24 20:30:15Z albert $
+
+import sys
+import bluetooth
+
+if len(sys.argv) < 2:
+ print "usage: sdp-browse <addr>"
+ print " addr can be a bluetooth address, \"localhost\", or \"all\""
+ sys.exit(2)
+
+target = sys.argv[1]
+if target == "all": target = None
+
+services = bluetooth.find_service(address=target)
+
+if len(services) > 0:
+ print "found %d services on %s" % (len(services), sys.argv[1])
+ print
+else:
+ print "no services found"
+
+for svc in services:
+ print "Service Name: %s" % svc["name"]
+ print " Host: %s" % svc["host"]
+ print " Description: %s" % svc["description"]
+ print " Provided By: %s" % svc["provider"]
+ print " Protocol: %s" % svc["protocol"]
+ print " channel/PSM: %s" % svc["port"]
+ print " svc classes: %s "% svc["service-classes"]
+ print " profiles: %s "% svc["profiles"]
+ print " service id: %s "% svc["service-id"]
+ print