summaryrefslogtreecommitdiff
path: root/pybluez/bluezchat/bluezchat.py
diff options
context:
space:
mode:
authorTim Redfern <tim@eclectronics.org>2011-12-19 18:20:33 +0000
committerTim Redfern <tim@eclectronics.org>2011-12-19 18:20:33 +0000
commite9a73bbb3c14af340999f70146747787785f4fee (patch)
treea125452f7d641673286542497da051b810427880 /pybluez/bluezchat/bluezchat.py
initial commit
Diffstat (limited to 'pybluez/bluezchat/bluezchat.py')
-rwxr-xr-xpybluez/bluezchat/bluezchat.py191
1 files changed, 191 insertions, 0 deletions
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()