Ticket #1610: 0001-Add-default-Ad-hoc-networks-1610.2.patch
File 0001-Add-default-Ad-hoc-networks-1610.2.patch, 39.4 KB (added by erikos, 14 years ago) |
---|
-
extensions/deviceicon/network.py
From edfe8baf0c19c16d751a2bd0daa97336c937eda0 Mon Sep 17 00:00:00 2001 From: Simon Schampijer <simon@schampijer.de> Date: Mon, 9 Aug 2010 16:10:33 +0200 Subject: [PATCH] Add default Ad-hoc networks #1610 This patch adds three default Ad-hoc networks, for channel 1, 6 and 11. They are represented with designated icons in the neighborhood view. This will mimic the mesh behavior on devices where mesh hardware is not available and make the "under a tree"-scenario possible in those cases. If Sugar sees no "known" network when it starts, it does autoconnect to an Ad-hoc network. --- extensions/deviceicon/network.py | 116 +++---------- src/jarabe/desktop/meshbox.py | 341 ++++++++++++++++++++++++++++++++++---- src/jarabe/model/Makefile.am | 1 + src/jarabe/model/adhoc.py | 196 ++++++++++++++++++++++ src/jarabe/model/network.py | 21 +++- 5 files changed, 555 insertions(+), 120 deletions(-) create mode 100644 src/jarabe/model/adhoc.py diff --git a/extensions/deviceicon/network.py b/extensions/deviceicon/network.py index 227ba46..a8c3124 100644
a b _GSM_STATE_CONNECTING = 2 67 67 _GSM_STATE_CONNECTED = 3 68 68 _GSM_STATE_NEED_AUTH = 4 69 69 70 def frequency_to_channel(frequency):71 ftoc = { 2412: 1, 2417: 2, 2422: 3, 2427: 4,72 2432: 5, 2437: 6, 2442: 7, 2447: 8,73 2452: 9, 2457: 10, 2462: 11, 2467: 12,74 2472: 13}75 return ftoc[frequency]76 70 77 71 class WirelessPalette(Palette): 78 72 __gtype_name__ = 'SugarWirelessPalette' 79 73 80 74 __gsignals__ = { 81 75 'deactivate-connection' : (gobject.SIGNAL_RUN_FIRST, 82 gobject.TYPE_NONE, ([])), 83 'create-connection' : (gobject.SIGNAL_RUN_FIRST, 84 gobject.TYPE_NONE, ([])), 76 gobject.TYPE_NONE, ([])) 85 77 } 86 78 87 def __init__(self, primary_text , can_create=True):79 def __init__(self, primary_text): 88 80 Palette.__init__(self, label=primary_text) 89 81 90 82 self._disconnect_item = None … … class WirelessPalette(Palette): 117 109 self._disconnect_item.connect('activate', self.__disconnect_activate_cb) 118 110 self.menu.append(self._disconnect_item) 119 111 120 if can_create:121 self._adhoc_item = gtk.MenuItem(_('Create new wireless network'))122 self._adhoc_item.connect('activate', self.__adhoc_activate_cb)123 self.menu.append(self._adhoc_item)124 self._adhoc_item.show()125 126 112 def set_connecting(self): 127 113 self.props.secondary_text = _('Connecting...') 128 114 … … class WirelessPalette(Palette): 149 135 def __disconnect_activate_cb(self, menuitem): 150 136 self.emit('deactivate-connection') 151 137 152 def __adhoc_activate_cb(self, menuitem):153 self.emit('create-connection')154 155 138 def _set_frequency(self, frequency): 156 139 try: 157 channel = frequency_to_channel(frequency)140 channel = network.frequency_to_channel(frequency) 158 141 except KeyError: 159 142 channel = 0 160 143 self._set_channel(channel) … … class GsmPalette(Palette): 318 301 319 302 class WirelessDeviceView(ToolButton): 320 303 321 _ICON_NAME = 'network-wireless'322 304 FRAME_POSITION_RELATIVE = 302 323 305 324 306 def __init__(self, device): … … class WirelessDeviceView(ToolButton): 337 319 self._active_ap_op = None 338 320 339 321 self._icon = PulsingIcon() 340 self._icon.props.icon_name = get_icon_state( self._ICON_NAME, 0)322 self._icon.props.icon_name = get_icon_state('network-wireless', 0) 341 323 self._inactive_color = xocolor.XoColor( \ 342 324 "%s,%s" % (style.COLOR_BUTTON_GREY.get_svg(), 343 325 style.COLOR_TRANSPARENT.get_svg())) … … class WirelessDeviceView(ToolButton): 351 333 self._palette = WirelessPalette(self._name) 352 334 self._palette.connect('deactivate-connection', 353 335 self.__deactivate_connection_cb) 354 self._palette.connect('create-connection',355 self.__create_connection_cb)356 336 self.set_palette(self._palette) 357 337 self._palette.set_group_id('frame') 358 338 … … class WirelessDeviceView(ToolButton): 422 402 def __ap_properties_changed_cb(self, properties): 423 403 self._update_properties(properties) 424 404 425 def _name_encodes_colors(self):426 """Match #XXXXXX,#YYYYYY at the end of the network name"""427 return self._name[-7] == '#' and self._name[-8] == ',' \428 and self._name[-15] == '#'429 430 405 def _update_properties(self, properties): 431 406 if 'Mode' in properties: 432 407 self._mode = properties['Mode'] … … class WirelessDeviceView(ToolButton): 442 417 self._frequency = properties['Frequency'] 443 418 444 419 if self._color == None: 445 if self._mode == network.NM_802_11_MODE_ADHOC \ 446 and self._name_encodes_colors(): 447 encoded_color = self._name.split("#", 1) 448 if len(encoded_color) == 2: 449 self._color = xocolor.XoColor('#' + encoded_color[1]) 420 if self._mode == network.NM_802_11_MODE_ADHOC and \ 421 self._name.startswith('Ad-hoc Network'): 422 self._color = profile.get_color() 450 423 else: 451 424 sha_hash = hashlib.sha1() 452 425 data = self._name + hex(self._flags) … … class WirelessDeviceView(ToolButton): 482 455 else: 483 456 state = network.DEVICE_STATE_UNKNOWN 484 457 485 if state == network.DEVICE_STATE_ACTIVATED: 486 icon_name = '%s-connected' % self._ICON_NAME 487 else: 488 icon_name = self._ICON_NAME 458 if self._mode != network.NM_802_11_MODE_ADHOC and \ 459 self._name.startswith('Ad-hoc Network') == False: 460 if state == network.DEVICE_STATE_ACTIVATED: 461 icon_name = '%s-connected' % 'network-wireless' 462 else: 463 icon_name = 'network-wireless' 489 464 490 icon_name = get_icon_state(icon_name, self._strength) 491 if icon_name: 492 self._icon.props.icon_name = icon_name 465 icon_name = get_icon_state(icon_name, self._strength) 466 if icon_name: 467 self._icon.props.icon_name = icon_name 468 else: 469 try: 470 channel = network.frequency_to_channel(self._frequency) 471 except KeyError: 472 channel = 1 473 if state == network.DEVICE_STATE_ACTIVATED: 474 self._icon.props.icon_name = 'network-adhoc-%s-connected' \ 475 % channel 476 else: 477 self._icon.props.icon_name = 'network-adhoc-%s' % channel 478 self._icon.props.base_color = profile.get_color() 493 479 494 480 if state == network.DEVICE_STATE_PREPARE or \ 495 481 state == network.DEVICE_STATE_CONFIG or \ … … class WirelessDeviceView(ToolButton): 528 514 netmgr.DeactivateConnection(conn_o) 529 515 break 530 516 531 def __create_connection_cb(self, palette, data=None):532 """Create an 802.11 IBSS network.533 534 The user's color is encoded at the end of the network name. The network535 name is truncated so that it does not exceed the 32 byte SSID limit.536 """537 client = gconf.client_get_default()538 nick = client.get_string('/desktop/sugar/user/nick').decode('utf-8')539 color = client.get_string('/desktop/sugar/user/color')540 color_suffix = ' %s' % color541 542 format = _('%s\'s network').encode('utf-8')543 extra_length = (len(format) - len('%s')) + len(color_suffix)544 name_limit = 32 - extra_length545 546 # truncate the nick and use a regex to drop any partial characters547 # at the end548 nick = nick.encode('utf-8')[:name_limit]549 pattern = "([\xf6-\xf7][\x80-\xbf]{0,2}|[\xe0-\xef][\x80-\xbf]{0,1}|[\xc0-\xdf])$"550 nick = re.sub(pattern, '', nick)551 552 connection_name = format % nick553 connection_name += color_suffix554 555 connection = network.find_connection_by_ssid(connection_name)556 if connection is None:557 settings = Settings()558 settings.connection.id = 'Auto ' + connection_name559 uuid = settings.connection.uuid = unique_id()560 settings.connection.type = '802-11-wireless'561 settings.wireless.ssid = dbus.ByteArray(connection_name)562 settings.wireless.band = 'bg'563 settings.wireless.mode = 'adhoc'564 settings.ip4_config = IP4Config()565 settings.ip4_config.method = 'link-local'566 567 connection = network.add_connection(uuid, settings)568 569 obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)570 netmgr = dbus.Interface(obj, _NM_IFACE)571 572 netmgr.ActivateConnection(network.SETTINGS_SERVICE,573 connection.path,574 self._device.object_path,575 '/',576 reply_handler=self.__activate_reply_cb,577 error_handler=self.__activate_error_cb)578 579 517 def __activate_reply_cb(self, connection): 580 518 logging.debug('Network created: %s', connection) 581 519 -
src/jarabe/desktop/meshbox.py
diff --git a/src/jarabe/desktop/meshbox.py b/src/jarabe/desktop/meshbox.py index e5ef720..c3812d5 100644
a b 1 1 # Copyright (C) 2006-2007 Red Hat, Inc. 2 2 # Copyright (C) 2009 Tomeu Vizoso, Simon Schampijer 3 # Copyright (C) 2009 One Laptop per Child3 # Copyright (C) 2009-2010 One Laptop per Child 4 4 # 5 5 # This program is free software; you can redistribute it and/or modify 6 6 # it under the terms of the GNU General Public License as published by … … from jarabe.model.network import IP4Config 52 52 from jarabe.model.network import WirelessSecurity 53 53 from jarabe.model.network import AccessPoint 54 54 from jarabe.model.olpcmesh import OlpcMeshManager 55 from jarabe.model.adhoc import AdHocManager 55 56 from jarabe.journal import misc 56 57 57 58 _NM_SERVICE = 'org.freedesktop.NetworkManager' … … class WirelessNetworkView(CanvasPulsingIcon): 89 90 self._connection = None 90 91 self._color = None 91 92 92 if self._mode == network.NM_802_11_MODE_ADHOC \ 93 and self._name_encodes_colors(): 94 encoded_color = self._name.split("#", 1) 95 if len(encoded_color) == 2: 96 self._color = xocolor.XoColor('#' + encoded_color[1]) 93 if self._mode == network.NM_802_11_MODE_ADHOC and \ 94 self._name.startswith('Ad-hoc Network'): 95 self._color = profile.get_color() 97 96 else: 98 97 sha_hash = hashlib.sha1() 99 98 data = self._name + hex(self._flags) … … class WirelessNetworkView(CanvasPulsingIcon): 115 114 self.set_palette(self._palette) 116 115 self._palette_icon.props.xo_color = self._color 117 116 118 if network.find_connection_by_ssid(self._name) is not None: 119 self.props.badge_name = "emblem-favorite" 120 self._palette_icon.props.badge_name = "emblem-favorite" 121 elif initial_ap.flags == network.NM_802_11_AP_FLAGS_PRIVACY: 122 self.props.badge_name = "emblem-locked" 123 self._palette_icon.props.badge_name = "emblem-locked" 117 if self._mode != network.NM_802_11_MODE_ADHOC: 118 if network.find_connection_by_ssid(self._name) is not None: 119 self.props.badge_name = "emblem-favorite" 120 self._palette_icon.props.badge_name = "emblem-favorite" 121 elif self._flags == network.NM_802_11_AP_FLAGS_PRIVACY: 122 self.props.badge_name = "emblem-locked" 123 self._palette_icon.props.badge_name = "emblem-locked" 124 else: 125 self.props.badge_name = None 126 self._palette_icon.props.badge_name = None 124 127 else: 125 128 self.props.badge_name = None 126 129 self._palette_icon.props.badge_name = None … … class WirelessNetworkView(CanvasPulsingIcon): 146 149 path=self._device.object_path, 147 150 dbus_interface=_NM_WIRELESS_IFACE) 148 151 149 def _name_encodes_colors(self):150 """Match #XXXXXX,#YYYYYY at the end of the network name"""151 return self._name[-7] == '#' and self._name[-8] == ',' \152 and self._name[-15] == '#'153 154 152 def _create_palette(self): 155 153 icon_name = get_icon_state(_AP_ICON_NAME, self._strength) 156 154 self._palette_icon = Icon(icon_name=icon_name, … … class WirelessNetworkView(CanvasPulsingIcon): 221 219 else: 222 220 state = network.DEVICE_STATE_UNKNOWN 223 221 224 if state == network.DEVICE_STATE_ACTIVATED: 225 connection = network.find_connection_by_ssid(self._name) 226 if connection: 227 if self._mode == network.NM_802_11_MODE_INFRA: 228 connection.set_connected() 229 230 icon_name = '%s-connected' % _AP_ICON_NAME 231 else: 232 icon_name = _AP_ICON_NAME 233 234 icon_name = get_icon_state(icon_name, self._strength) 235 if icon_name: 222 if self._mode == network.NM_802_11_MODE_ADHOC and \ 223 self._name.startswith('Ad-hoc Network'): 224 channel = max([1] + [ap.channel for ap in 225 self._access_points.values()]) 226 if state == network.DEVICE_STATE_ACTIVATED: 227 icon_name = 'network-adhoc-%s-connected' % channel 228 else: 229 icon_name = 'network-adhoc-%s' % channel 236 230 self.props.icon_name = icon_name 237 231 icon = self._palette.props.icon 238 232 icon.props.icon_name = icon_name 233 else: 234 if state == network.DEVICE_STATE_ACTIVATED: 235 connection = network.find_connection_by_ssid(self._name) 236 if connection: 237 if self._mode == network.NM_802_11_MODE_INFRA: 238 connection.set_connected() 239 icon_name = '%s-connected' % _AP_ICON_NAME 240 else: 241 icon_name = _AP_ICON_NAME 242 243 icon_name = get_icon_state(icon_name, self._strength) 244 if icon_name: 245 self.props.icon_name = icon_name 246 icon = self._palette.props.icon 247 icon.props.icon_name = icon_name 239 248 240 249 if state == network.DEVICE_STATE_PREPARE or \ 241 250 state == network.DEVICE_STATE_CONFIG or \ … … class WirelessNetworkView(CanvasPulsingIcon): 353 362 settings.wireless.mode = 'adhoc' 354 363 settings.wireless.band = 'bg' 355 364 settings.ip4_config = IP4Config() 356 settings.ip4_config.method = ' link-local'365 settings.ip4_config.method = 'shared' 357 366 358 367 wireless_security = self._get_security() 359 368 settings.wireless_security = wireless_security … … class WirelessNetworkView(CanvasPulsingIcon): 443 452 path=self._device.object_path, 444 453 dbus_interface=_NM_WIRELESS_IFACE) 445 454 455 class AdHocView(CanvasPulsingIcon): 456 def __init__(self, manager, channel): 457 CanvasPulsingIcon.__init__(self, 458 icon_name='network-adhoc-%s' % channel, 459 size=style.STANDARD_ICON_SIZE, cache=True) 460 self._bus = dbus.SystemBus() 461 self._manager = manager 462 self._device = manager.device 463 self._channel = channel 464 self._icon_name = 'network-adhoc-%s' % self._channel 465 self._disconnect_item = None 466 self._connect_item = None 467 self._palette_icon = None 468 self._greyed_out = False 469 self._name = "Ad-hoc Network %d" % channel 470 self._device_state = None 471 self._connection = None 472 self._active = False 473 474 self.connect('button-release-event', self.__button_release_event_cb) 475 476 interface_props = dbus.Interface(self._device, 477 'org.freedesktop.DBus.Properties') 478 interface_props.Get(_NM_DEVICE_IFACE, 'State', 479 reply_handler=self.__get_device_state_reply_cb, 480 error_handler=self.__get_device_state_error_cb) 481 482 self._bus.add_signal_receiver(self.__device_state_changed_cb, 483 signal_name='StateChanged', 484 path=self._device.object_path, 485 dbus_interface=_NM_DEVICE_IFACE) 486 self._bus.add_signal_receiver(self.__wireless_properties_changed_cb, 487 signal_name='PropertiesChanged', 488 path=self._device.object_path, 489 dbus_interface=_NM_WIRELESS_IFACE) 490 491 pulse_color = XoColor('%s,%s' % (style.COLOR_BUTTON_GREY.get_svg(), 492 style.COLOR_TRANSPARENT.get_svg())) 493 self.props.pulse_color = pulse_color 494 self._state_color = XoColor('%s,%s' % \ 495 (profile.get_color().get_stroke_color(), 496 style.COLOR_TRANSPARENT.get_svg())) 497 self.props.base_color = self._state_color 498 self._palette = self._create_palette() 499 self.set_palette(self._palette) 500 self._palette_icon.props.xo_color = self._state_color 501 502 def _create_palette(self): 503 self._palette_icon = Icon(icon_name=self._icon_name, 504 icon_size=style.STANDARD_ICON_SIZE) 505 506 _palette = palette.Palette(_("Ad-hoc Network %d") % self._channel, 507 icon=self._palette_icon) 508 509 self._connect_item = MenuItem(_('Connect'), 'dialog-ok') 510 self._connect_item.connect('activate', self.__connect_activate_cb) 511 _palette.menu.append(self._connect_item) 512 513 self._disconnect_item = MenuItem(_('Disconnect'), 'media-eject') 514 self._disconnect_item.connect('activate', 515 self.__disconnect_activate_cb) 516 _palette.menu.append(self._disconnect_item) 517 518 return _palette 519 520 def __button_release_event_cb(self, icon, event): 521 self._manager.activate_channel(self._channel) 522 523 def __connect_activate_cb(self, icon): 524 self._manager.activate_channel(self._channel) 525 526 def __disconnect_activate_cb(self, icon): 527 obj = self._bus.get_object(_NM_SERVICE, _NM_PATH) 528 netmgr = dbus.Interface(obj, _NM_IFACE) 529 530 netmgr_props = dbus.Interface(netmgr, dbus.PROPERTIES_IFACE) 531 netmgr_props.Get(_NM_IFACE, 'ActiveConnections', \ 532 reply_handler=self.__get_active_connections_reply_cb, 533 error_handler=self.__get_active_connections_error_cb) 534 535 def __get_active_connections_reply_cb(self, active_connections_o): 536 for connection_o in active_connections_o: 537 obj = self._bus.get_object(_NM_IFACE, connection_o) 538 props = dbus.Interface(obj, dbus.PROPERTIES_IFACE) 539 state = props.Get(_NM_ACTIVE_CONN_IFACE, 'State') 540 if state == network.NM_ACTIVE_CONNECTION_STATE_ACTIVATED: 541 access_point_o = props.Get(_NM_ACTIVE_CONN_IFACE, 542 'SpecificObject') 543 if access_point_o != '/': 544 obj = self._bus.get_object(_NM_SERVICE, _NM_PATH) 545 netmgr = dbus.Interface(obj, _NM_IFACE) 546 netmgr.DeactivateConnection(connection_o) 547 548 def __get_active_connections_error_cb(self, err): 549 logging.error('Error getting the active connections: %s', err) 550 551 def __get_device_state_reply_cb(self, state): 552 self._device_state = state 553 self._update() 554 555 def __get_device_state_error_cb(self, err): 556 logging.error('Error getting the device state: %s', err) 557 558 def __device_state_changed_cb(self, new_state, old_state, reason): 559 self._device_state = new_state 560 self._update() 561 562 def __wireless_properties_changed_cb(self, properties): 563 if 'ActiveAccessPoint' in properties and \ 564 properties['ActiveAccessPoint'] != '/': 565 active_ap = self._bus.get_object(_NM_SERVICE, 566 properties['ActiveAccessPoint']) 567 props = dbus.Interface(active_ap, dbus.PROPERTIES_IFACE) 568 props.GetAll(_NM_ACCESSPOINT_IFACE, byte_arrays=True, 569 reply_handler=self.__get_all_ap_props_reply_cb, 570 error_handler=self.__get_all_ap_props_error_cb) 571 572 def __get_all_ap_props_reply_cb(self, properties): 573 if properties['Mode'] == network.NM_802_11_MODE_ADHOC: 574 if 'Frequency' in properties: 575 try: 576 frequency = properties['Frequency'] 577 channel = network.frequency_to_channel(frequency) 578 if self._channel == channel: 579 self._active = True 580 else: 581 self._active = False 582 except KeyError: 583 logging.debug("Error getting the Frequency.") 584 else: 585 self._active = False 586 self._update() 587 588 def __get_all_ap_props_error_cb(self, err): 589 logging.error('Error getting the access point properties: %s', err) 590 591 def _update(self): 592 if self._active: 593 state = self._device_state 594 else: 595 state = network.DEVICE_STATE_UNKNOWN 596 597 if state == network.DEVICE_STATE_ACTIVATED: 598 icon_name = '%s-connected' % self._icon_name 599 else: 600 icon_name = self._icon_name 601 602 self.props.base_color = self._state_color 603 self._palette_icon.props.xo_color = self._state_color 604 605 if icon_name is not None: 606 self.props.icon_name = icon_name 607 icon = self._palette.props.icon 608 icon.props.icon_name = icon_name 609 610 if state in [network.DEVICE_STATE_PREPARE, 611 network.DEVICE_STATE_CONFIG, 612 network.DEVICE_STATE_NEED_AUTH, 613 network.DEVICE_STATE_IP_CONFIG]: 614 if self._disconnect_item: 615 self._disconnect_item.show() 616 self._connect_item.hide() 617 self._palette.props.secondary_text = _('Connecting...') 618 self.props.pulsing = True 619 elif state == network.DEVICE_STATE_ACTIVATED: 620 if self._disconnect_item: 621 self._disconnect_item.show() 622 self._connect_item.hide() 623 self._palette.props.secondary_text = _('Connected') 624 self.props.pulsing = False 625 else: 626 if self._disconnect_item: 627 self._disconnect_item.hide() 628 self._connect_item.show() 629 self._palette.props.secondary_text = None 630 self.props.pulsing = False 631 632 def _update_color(self): 633 if self._greyed_out: 634 self.props.base_color = XoColor('#D5D5D5,#D5D5D5') 635 else: 636 self.props.base_color = self._state_color 637 638 def indicate_population(self, state): 639 if state == True: 640 self._state_color = profile.get_color() 641 self.props.base_color = self._state_color 642 self._palette_icon.props.xo_color = self._state_color 643 else: 644 color = '%s,%s' % (profile.get_color().get_stroke_color(), 645 style.COLOR_TRANSPARENT.get_svg()) 646 self._state_color = XoColor(color) 647 self.props.base_color = self._state_color 648 self._palette_icon.props.xo_color = self._state_color 649 650 def set_filter(self, query): 651 self._greyed_out = self._name.lower().find(query) == -1 652 self._update_color() 653 654 def disconnect(self): 655 self._bus.remove_signal_receiver(self.__device_state_changed_cb, 656 signal_name='StateChanged', 657 path=self._device.object_path, 658 dbus_interface=_NM_DEVICE_IFACE) 659 self._bus.remove_signal_receiver(self.__wireless_properties_changed_cb, 660 signal_name='PropertiesChanged', 661 path=self._device.object_path, 662 dbus_interface=_NM_WIRELESS_IFACE) 663 446 664 447 665 class OlpcMeshView(CanvasPulsingIcon): 448 666 def __init__(self, mesh_mgr, channel): … … class NetworkManagerObserver(object): 814 1032 self._devices = {} 815 1033 self._netmgr = None 816 1034 self._olpc_mesh_device_o = None 1035 self._has_mesh_device = False 1036 self._check_mesh_source = 0 817 1037 818 1038 def listen(self): 819 1039 try: … … class NetworkManagerObserver(object): 833 1053 self._bus.add_signal_receiver(self.__device_removed_cb, 834 1054 signal_name='DeviceRemoved', 835 1055 dbus_interface=_NM_IFACE) 1056 self._bus.add_signal_receiver(self.__properties_changed_cb, 1057 signal_name='PropertiesChanged', 1058 dbus_interface=_NM_IFACE) 836 1059 837 1060 settings = network.get_settings() 838 1061 if settings is not None: … … class NetworkManagerObserver(object): 877 1100 device_type = props.Get(_NM_DEVICE_IFACE, 'DeviceType') 878 1101 if device_type == network.DEVICE_TYPE_802_11_WIRELESS: 879 1102 self._devices[device_o] = DeviceObserver(self._box, device) 1103 if self._check_mesh_source != 0: 1104 gobject.source_remove(self._check_mesh_source) 1105 self._check_mesh_source = gobject.timeout_add( \ 1106 5, self._add_adhoc_networks, device) 880 1107 elif device_type == network.DEVICE_TYPE_802_11_OLPC_MESH: 1108 self._has_mesh_device = True 881 1109 self._olpc_mesh_device_o = device_o 882 1110 self._box.enable_olpc_mesh(device) 883 1111 … … class NetworkManagerObserver(object): 892 1120 observer = self._devices[device_o] 893 1121 observer.disconnect() 894 1122 del self._devices[device_o] 1123 if self._has_mesh_device == False: 1124 self._box.remove_adhoc_networks() 895 1125 return 896 1126 897 1127 if self._olpc_mesh_device_o == device_o: 898 1128 self._box.disable_olpc_mesh(device_o) 899 1129 1130 def _add_adhoc_networks(self, device): 1131 """If we do not find mesh hardware we create Ad-hoc networks.""" 1132 if self._has_mesh_device == False: 1133 self._box.add_adhoc_networks(device) 1134 return False 1135 1136 def __properties_changed_cb(self, properties): 1137 if 'WirelessHardwareEnabled' in properties: 1138 if properties['WirelessHardwareEnabled'] == False: 1139 if self._has_mesh_device == False: 1140 self._box.remove_adhoc_networks() 1141 if properties['WirelessHardwareEnabled'] == True: 1142 for device in self._devices: 1143 if self._has_mesh_device == False: 1144 self._box.add_adhoc_networks(device) 1145 1146 900 1147 class MeshBox(gtk.VBox): 901 1148 __gtype_name__ = 'SugarMeshBox' 902 1149 … … class MeshBox(gtk.VBox): 906 1153 gobject.GObject.__init__(self) 907 1154 908 1155 self.wireless_networks = {} 1156 self._adhoc_manager = None 909 1157 910 1158 self._model = neighborhood.get_model() 911 1159 self._buddies = {} … … class MeshBox(gtk.VBox): 1063 1311 ap.disconnect() 1064 1312 return 1065 1313 1314 if self._adhoc_manager != None and \ 1315 ap.name.startswith('Ad-hoc Network') and \ 1316 ap.mode == network.NM_802_11_MODE_ADHOC: 1317 1318 if old_hash is None: # new Ad-hoc network finished initializing 1319 self._adhoc_manager.add_access_point(ap) 1320 # we are called as well in other cases but we do not need to 1321 # act here as we don't display signal strength for Ad-hoc networks 1322 return 1323 1066 1324 if old_hash is None: # new AP finished initializing 1067 1325 self._add_ap_to_network(ap) 1068 1326 return … … class MeshBox(gtk.VBox): 1085 1343 ap.initialize() 1086 1344 1087 1345 def remove_access_point(self, ap_o): 1346 if self._adhoc_manager is not None: 1347 if self._adhoc_manager.remove_access_point(ap_o) == True: 1348 return 1349 1088 1350 # we don't keep an index of ap object path to network, but since 1089 1351 # we'll only ever have a handful of networks, just try them all... 1090 1352 for net in self.wireless_networks.values(): … … class MeshBox(gtk.VBox): 1101 1363 # it (e.g. olpc-mesh adhoc network) 1102 1364 logging.debug('Can not remove access point %s' % ap_o) 1103 1365 1366 def add_adhoc_networks(self, device): 1367 if self._adhoc_manager is None: 1368 self._adhoc_manager = AdHocManager(device) 1369 for channel in self._adhoc_manager.channels: 1370 self._add_adhoc_network_icon(self._adhoc_manager, channel) 1371 self._adhoc_manager.autoconnect() 1372 1373 def remove_adhoc_networks(self): 1374 for channel in self._adhoc_manger.channels: 1375 icon = self._adhoc_manager.remove_network(channel) 1376 if icon is not None: 1377 icon.disconnect() 1378 self._layout.remove(icon) 1379 1380 def _add_adhoc_network_icon(self, adhoc_manager, channel): 1381 icon = AdHocView(adhoc_manager, channel) 1382 self._layout.add(icon) 1383 self._adhoc_manager.add_network(channel, icon) 1384 1104 1385 def _add_olpc_mesh_icon(self, mesh_mgr, channel): 1105 1386 icon = OlpcMeshView(mesh_mgr, channel) 1106 1387 self._layout.add(icon) -
src/jarabe/model/Makefile.am
diff --git a/src/jarabe/model/Makefile.am b/src/jarabe/model/Makefile.am index e9f0700..4650c3b 100644
a b 1 1 sugardir = $(pythondir)/jarabe/model 2 2 sugar_PYTHON = \ 3 adhoc.py \ 3 4 __init__.py \ 4 5 buddy.py \ 5 6 bundleregistry.py \ -
new file src/jarabe/model/adhoc.py
diff --git a/src/jarabe/model/adhoc.py b/src/jarabe/model/adhoc.py new file mode 100644 index 0000000..828451e
- + 1 # Copyright (C) 2010 One Laptop per Child 2 # 3 # This program is free software; you can redistribute it and/or modify 4 # it under the terms of the GNU General Public License as published by 5 # the Free Software Foundation; either version 2 of the License, or 6 # (at your option) any later version. 7 # 8 # This program is distributed in the hope that it will be useful, 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 # GNU General Public License for more details. 12 # 13 # You should have received a copy of the GNU General Public License 14 # along with this program; if not, write to the Free Software 15 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 17 import logging 18 19 import dbus 20 import gobject 21 22 from jarabe.model import network 23 from jarabe.model.network import Settings 24 from sugar.util import unique_id 25 from jarabe.model.network import IP4Config 26 27 _NM_SERVICE = 'org.freedesktop.NetworkManager' 28 _NM_IFACE = 'org.freedesktop.NetworkManager' 29 _NM_PATH = '/org/freedesktop/NetworkManager' 30 _NM_DEVICE_IFACE = 'org.freedesktop.NetworkManager.Device' 31 _NM_OLPC_MESH_IFACE = 'org.freedesktop.NetworkManager.Device.OlpcMesh' 32 33 34 class Network(object): 35 """Representation of an Ad-hoc network""" 36 37 def __init__(self, icon, access_point): 38 self.icon = icon 39 self.access_point = access_point 40 41 42 class AdHocManager(object): 43 """To mimic the mesh behavior on devices where mesh hardware is 44 not available we support the creation of an Ad-hoc network on 45 three channels 1, 6, 11. If Sugar sees no "known" network when it 46 starts, it does autoconnect to an Ad-hoc network. 47 48 """ 49 50 timeout = 30 51 52 def __init__(self, device): 53 self._bus = dbus.SystemBus() 54 55 self.device = device 56 self._idle_source = 0 57 self._device_state = network.DEVICE_STATE_UNKNOWN 58 59 self.channels = [1, 6, 11] 60 self._networks = {} 61 62 props = dbus.Interface(device, 63 'org.freedesktop.DBus.Properties') 64 props.Get(_NM_DEVICE_IFACE, 'State', 65 reply_handler=self.__get_device_state_reply_cb, 66 error_handler=self.__get_state_error_cb) 67 68 self._bus.add_signal_receiver(self.__device_state_changed_cb, 69 signal_name='StateChanged', 70 path=self.device.object_path, 71 dbus_interface=_NM_DEVICE_IFACE) 72 73 def _have_configured_connections(self): 74 return len(network.get_settings().connections) > 0 75 76 def autoconnect(self): 77 """Autoconnect to an Ad-hoc network""" 78 if self._have_configured_connections(): 79 self._autoconnect_adhoc_timer() 80 else: 81 self._autoconnect_adhoc() 82 83 def __get_state_error_cb(self, err): 84 logging.debug('Error getting the device state: %s', err) 85 86 def __get_device_state_reply_cb(self, state): 87 self._device_state = state 88 89 def __device_state_changed_cb(self, new_state, old_state, reason): 90 self._device_state = new_state 91 92 def _autoconnect_adhoc_timer(self): 93 """Start a timer which basically looks for 30 seconds of inactivity 94 on the device, then does autoconnect to an Ad-hoc network. 95 96 """ 97 if self._idle_source != 0: 98 gobject.source_remove(self._idle_source) 99 self._idle_source = gobject.timeout_add_seconds(self.timeout, 100 self._idle_check) 101 102 def _autoconnect_adhoc(self): 103 """First we try if there is an Ad-hoc network that is used by other 104 learners in the area, if not we default to channel 1. 105 106 """ 107 if self._networks[1].access_point is not None: 108 self._connect(1) 109 elif self._networks[6].access_point is not None: 110 self._connect(6) 111 elif self._networks[11].access_point is not None: 112 self._connect(11) 113 else: 114 self._connect(1) 115 116 def _idle_check(self): 117 if self._device_state == network.DEVICE_STATE_DISCONNECTED: 118 logging.debug("Connect to Ad-hoc network due to inactivity.") 119 self._autoconnect_adhoc() 120 return False 121 122 def activate_channel(self, channel): 123 self._connect(channel) 124 125 def _connect(self, channel): 126 name = "Ad-hoc Network %d" % channel 127 connection = network.find_connection_by_ssid(name) 128 if connection is None: 129 settings = Settings() 130 settings.connection.id = name 131 settings.connection.uuid = unique_id() 132 settings.connection.type = '802-11-wireless' 133 settings.wireless.ssid = dbus.ByteArray(name) 134 settings.wireless.band = 'bg' 135 settings.wireless.channel = channel 136 settings.wireless.mode = 'adhoc' 137 settings.ip4_config = IP4Config() 138 settings.ip4_config.method = 'link-local' 139 140 connection = network.add_connection(name, settings) 141 142 obj = self._bus.get_object(_NM_SERVICE, _NM_PATH) 143 netmgr = dbus.Interface(obj, _NM_IFACE) 144 145 netmgr.ActivateConnection(network.SETTINGS_SERVICE, 146 connection.path, 147 self.device.object_path, 148 '/', 149 reply_handler=self.__activate_reply_cb, 150 error_handler=self.__activate_error_cb) 151 152 def __activate_reply_cb(self, connection): 153 logging.debug('Ad-hoc network created: %s', connection) 154 155 def __activate_error_cb(self, err): 156 logging.debug('Failed to create Ad-hoc network: %s', err) 157 158 def add_network(self, channel, icon): 159 if channel not in self._networks: 160 self._networks[channel] = Network(icon, None) 161 162 def remove_network(self, channel): 163 if channel in self._networks: 164 net = self._networks.pop(channel) 165 return net.icon 166 return None 167 168 def add_access_point(self, access_point): 169 """If a new adhoc network is announcd that is named like an Ad-hoc 170 network we take this as an indication that other learners are 171 using the network an indicate this. 172 173 """ 174 if ' 1' == access_point.name[-2:]: 175 self._networks[1].icon.indicate_population(True) 176 self._networks[1].access_point = access_point 177 elif '6' == access_point.name[-1]: 178 self._networks[6].icon.indicate_population(True) 179 self._networks[6].access_point = access_point 180 elif '11' == access_point.name[-2:]: 181 self._networks[11].icon.indicate_population(True) 182 self._networks[11].access_point = access_point 183 184 def remove_access_point(self, ap_object_path): 185 """When the last user of the network goes away we remove 186 the access point and indicate this. 187 188 """ 189 for net in self._networks.values(): 190 if net.access_point is not None: 191 if net.access_point.model.object_path == ap_object_path: 192 net.icon.indicate_population(False) 193 net.access_point.disconnect() 194 net.access_point = None 195 return True 196 return False -
src/jarabe/model/network.py
diff --git a/src/jarabe/model/network.py b/src/jarabe/model/network.py index 47db43f..f53b924 100644
a b 1 1 # Copyright (C) 2008 Red Hat, Inc. 2 2 # Copyright (C) 2009 Tomeu Vizoso, Simon Schampijer 3 # Copyright (C) 2009 One Laptop per Child3 # Copyright (C) 2009-2010 One Laptop per Child 4 4 # Copyright (C) 2009 Paraguay Educa, Martin Abente 5 5 # Copyright (C) 2010 Plan Ceibal, Daniel Castelo 6 6 # … … GSM_PUK_PATH = '/desktop/sugar/network/gsm/puk' 100 100 _nm_settings = None 101 101 _conn_counter = 0 102 102 103 104 def frequency_to_channel(frequency): 105 ftoc = {2412: 1, 2417: 2, 2422: 3, 2427: 4, 106 2432: 5, 2437: 6, 2442: 7, 2447: 8, 107 2452: 9, 2457: 10, 2462: 11, 2467: 12, 108 2472: 13} 109 return ftoc[frequency] 110 111 103 112 class WirelessSecurity(object): 104 113 def __init__(self): 105 114 self.key_mgmt = None … … class Wireless(object): 127 136 self.security = None 128 137 self.mode = None 129 138 self.band = None 139 self.channel = None 130 140 131 141 def get_dict(self): 132 142 wireless = {'ssid': self.ssid} … … class Wireless(object): 136 146 wireless['mode'] = self.mode 137 147 if self.band: 138 148 wireless['band'] = self.band 149 if self.channel: 150 wireless['channel'] = self.channel 139 151 return wireless 140 152 141 153 … … class AccessPoint(gobject.GObject): 476 488 self.wpa_flags = 0 477 489 self.rsn_flags = 0 478 490 self.mode = 0 491 self.channel = 0 479 492 480 493 def initialize(self): 481 494 model_props = dbus.Interface(self.model, … … class AccessPoint(gobject.GObject): 545 558 self.rsn_flags = properties['RsnFlags'] 546 559 if 'Mode' in properties: 547 560 self.mode = properties['Mode'] 561 if 'Frequency' in properties: 562 try: 563 self.channel = frequency_to_channel(properties['Frequency']) 564 except KeyError: 565 self.channel = 1 566 548 567 self._initialized = True 549 568 self.emit('props-changed', old_hash) 550 569