From e9a73bbb3c14af340999f70146747787785f4fee Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Mon, 19 Dec 2011 18:20:33 +0000 Subject: initial commit --- pybluez/bluezchat/bluezchat.py | 191 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100755 pybluez/bluezchat/bluezchat.py (limited to 'pybluez/bluezchat/bluezchat.py') 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() -- cgit v1.2.3