Ticket #1610: 0001-Add-default-Ad-hoc-networks-1610.patch
File 0001-Add-default-Ad-hoc-networks-1610.patch, 38.9 KB (added by erikos, 14 years ago) |
---|
-
extensions/deviceicon/network.py
From aa328066d79eed324b179f2eb840d8b3afecf372 Mon Sep 17 00:00:00 2001 From: Simon Schampijer <simon@schampijer.de> Date: Thu, 5 Aug 2010 10:29:40 +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 | 332 ++++++++++++++++++++++++++++++++++---- src/jarabe/model/Makefile.am | 1 + src/jarabe/model/adhoc.py | 196 ++++++++++++++++++++++ src/jarabe/model/network.py | 21 +++- 5 files changed, 546 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..454c767 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 = True 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 active_connections_o = netmgr_props.Get(_NM_IFACE, 'ActiveConnections') 532 533 for conn_o in active_connections_o: 534 obj = self._bus.get_object(_NM_IFACE, conn_o) 535 props = dbus.Interface(obj, dbus.PROPERTIES_IFACE) 536 state = props.Get(_NM_ACTIVE_CONN_IFACE, 'State') 537 if state == network.NM_ACTIVE_CONNECTION_STATE_ACTIVATED: 538 ap_o = props.Get(_NM_ACTIVE_CONN_IFACE, 'SpecificObject') 539 if ap_o != '/': 540 netmgr.DeactivateConnection(conn_o) 541 542 def __get_device_state_reply_cb(self, state): 543 self._device_state = state 544 self._update() 545 546 def __get_device_state_error_cb(self, err): 547 logging.error('Error getting the device state: %s', err) 548 549 def __device_state_changed_cb(self, new_state, old_state, reason): 550 self._device_state = new_state 551 self._update() 552 553 def __wireless_properties_changed_cb(self, properties): 554 if 'ActiveAccessPoint' in properties and \ 555 properties['ActiveAccessPoint'] != '/': 556 active_ap = self._bus.get_object(_NM_SERVICE, 557 properties['ActiveAccessPoint']) 558 props = dbus.Interface(active_ap, dbus.PROPERTIES_IFACE) 559 props.GetAll(_NM_ACCESSPOINT_IFACE, byte_arrays=True, 560 reply_handler=self.__get_all_ap_props_reply_cb, 561 error_handler=self.__get_all_ap_props_error_cb) 562 563 def __get_all_ap_props_reply_cb(self, properties): 564 if properties['Mode'] == network.NM_802_11_MODE_ADHOC: 565 if 'Frequency' in properties: 566 try: 567 frequency = properties['Frequency'] 568 channel = network.frequency_to_channel(frequency) 569 if self._channel == channel: 570 self._active = True 571 else: 572 self._active = False 573 except KeyError: 574 logging.debug("Error getting the Frequency.") 575 else: 576 self._active = False 577 self._update() 578 579 def __get_all_ap_props_error_cb(self, err): 580 logging.error('Error getting the access point properties: %s', err) 581 582 def _update(self): 583 if self._active: 584 state = self._device_state 585 else: 586 state = network.DEVICE_STATE_UNKNOWN 587 588 if state == network.DEVICE_STATE_ACTIVATED: 589 icon_name = '%s-connected' % self._icon_name 590 else: 591 icon_name = self._icon_name 592 593 self.props.base_color = self._state_color 594 self._palette_icon.props.xo_color = self._state_color 595 596 if icon_name is not None: 597 self.props.icon_name = icon_name 598 icon = self._palette.props.icon 599 icon.props.icon_name = icon_name 600 601 if state in [network.DEVICE_STATE_PREPARE, 602 network.DEVICE_STATE_CONFIG, 603 network.DEVICE_STATE_NEED_AUTH, 604 network.DEVICE_STATE_IP_CONFIG]: 605 if self._disconnect_item: 606 self._disconnect_item.show() 607 self._connect_item.hide() 608 self._palette.props.secondary_text = _('Connecting...') 609 self.props.pulsing = True 610 elif state == network.DEVICE_STATE_ACTIVATED: 611 if self._disconnect_item: 612 self._disconnect_item.show() 613 self._connect_item.hide() 614 self._palette.props.secondary_text = _('Connected') 615 self.props.pulsing = False 616 else: 617 if self._disconnect_item: 618 self._disconnect_item.hide() 619 self._connect_item.show() 620 self._palette.props.secondary_text = None 621 self.props.pulsing = False 622 623 def _update_color(self): 624 if self._greyed_out: 625 self.props.base_color = XoColor('#D5D5D5,#D5D5D5') 626 else: 627 self.props.base_color = self._state_color 628 629 def indicate_population(self, state): 630 if state == True: 631 self._state_color = profile.get_color() 632 self.props.base_color = self._state_color 633 self._palette_icon.props.xo_color = self._state_color 634 else: 635 color = '%s,%s' % (profile.get_color().get_stroke_color(), 636 style.COLOR_TRANSPARENT.get_svg()) 637 self._state_color = XoColor(color) 638 self.props.base_color = self._state_color 639 self._palette_icon.props.xo_color = self._state_color 640 641 def set_filter(self, query): 642 self._greyed_out = self._name.lower().find(query) == -1 643 self._update_color() 644 645 def disconnect(self): 646 self._bus.remove_signal_receiver(self.__device_state_changed_cb, 647 signal_name='StateChanged', 648 path=self._device.object_path, 649 dbus_interface=_NM_DEVICE_IFACE) 650 self._bus.remove_signal_receiver(self.__wireless_properties_changed_cb, 651 signal_name='PropertiesChanged', 652 path=self._device.object_path, 653 dbus_interface=_NM_WIRELESS_IFACE) 654 446 655 447 656 class OlpcMeshView(CanvasPulsingIcon): 448 657 def __init__(self, mesh_mgr, channel): … … class NetworkManagerObserver(object): 814 1023 self._devices = {} 815 1024 self._netmgr = None 816 1025 self._olpc_mesh_device_o = None 1026 self._has_mesh_device = False 1027 self._check_mesh_source = 0 817 1028 818 1029 def listen(self): 819 1030 try: … … class NetworkManagerObserver(object): 833 1044 self._bus.add_signal_receiver(self.__device_removed_cb, 834 1045 signal_name='DeviceRemoved', 835 1046 dbus_interface=_NM_IFACE) 1047 self._bus.add_signal_receiver(self.__properties_changed_cb, 1048 signal_name='PropertiesChanged', 1049 dbus_interface=_NM_IFACE) 836 1050 837 1051 settings = network.get_settings() 838 1052 if settings is not None: … … class NetworkManagerObserver(object): 877 1091 device_type = props.Get(_NM_DEVICE_IFACE, 'DeviceType') 878 1092 if device_type == network.DEVICE_TYPE_802_11_WIRELESS: 879 1093 self._devices[device_o] = DeviceObserver(self._box, device) 1094 if self._check_mesh_source != 0: 1095 gobject.source_remove(self._check_mesh_source) 1096 self._check_mesh_source = gobject.timeout_add( \ 1097 5, self._add_adhoc_networks, device) 880 1098 elif device_type == network.DEVICE_TYPE_802_11_OLPC_MESH: 1099 self._has_mesh_device = True 881 1100 self._olpc_mesh_device_o = device_o 882 1101 self._box.enable_olpc_mesh(device) 883 1102 … … class NetworkManagerObserver(object): 892 1111 observer = self._devices[device_o] 893 1112 observer.disconnect() 894 1113 del self._devices[device_o] 1114 if self._has_mesh_device == False: 1115 self._box.remove_adhoc_networks() 895 1116 return 896 1117 897 1118 if self._olpc_mesh_device_o == device_o: 898 1119 self._box.disable_olpc_mesh(device_o) 899 1120 1121 def _add_adhoc_networks(self, device): 1122 """If we do not find mesh hardware we create Ad-hoc networks.""" 1123 if self._has_mesh_device == False: 1124 self._box.add_adhoc_networks(device) 1125 return False 1126 1127 def __properties_changed_cb(self, properties): 1128 if 'WirelessHardwareEnabled' in properties: 1129 if properties['WirelessHardwareEnabled'] == False: 1130 if self._has_mesh_device == False: 1131 self._box.remove_adhoc_networks() 1132 if properties['WirelessHardwareEnabled'] == True: 1133 for device in self._devices: 1134 if self._has_mesh_device == False: 1135 self._box.add_adhoc_networks(device) 1136 1137 900 1138 class MeshBox(gtk.VBox): 901 1139 __gtype_name__ = 'SugarMeshBox' 902 1140 … … class MeshBox(gtk.VBox): 906 1144 gobject.GObject.__init__(self) 907 1145 908 1146 self.wireless_networks = {} 1147 self._adhoc_manager = None 909 1148 910 1149 self._model = neighborhood.get_model() 911 1150 self._buddies = {} … … class MeshBox(gtk.VBox): 1063 1302 ap.disconnect() 1064 1303 return 1065 1304 1305 if self._adhoc_manager != None and \ 1306 ap.name.startswith('Ad-hoc Network') and \ 1307 ap.mode == network.NM_802_11_MODE_ADHOC: 1308 1309 if old_hash is None: # new Ad-hoc network finished initializing 1310 self._adhoc_manager.add_access_point(ap) 1311 # we are called as well in other cases but we do not need to 1312 # act here as we don't display signal strength for Ad-hoc networks 1313 return 1314 1066 1315 if old_hash is None: # new AP finished initializing 1067 1316 self._add_ap_to_network(ap) 1068 1317 return … … class MeshBox(gtk.VBox): 1085 1334 ap.initialize() 1086 1335 1087 1336 def remove_access_point(self, ap_o): 1337 if self._adhoc_manager is not None: 1338 if self._adhoc_manager.remove_access_point(ap_o) == True: 1339 return 1340 1088 1341 # we don't keep an index of ap object path to network, but since 1089 1342 # we'll only ever have a handful of networks, just try them all... 1090 1343 for net in self.wireless_networks.values(): … … class MeshBox(gtk.VBox): 1101 1354 # it (e.g. olpc-mesh adhoc network) 1102 1355 logging.debug('Can not remove access point %s' % ap_o) 1103 1356 1357 def add_adhoc_networks(self, device): 1358 if self._adhoc_manager is None: 1359 self._adhoc_manager = AdHocManager(device) 1360 for channel in self._adhoc_manager.channels: 1361 self._add_adhoc_network_icon(self._adhoc_manager, channel) 1362 self._adhoc_manager.autoconnect() 1363 1364 def remove_adhoc_networks(self): 1365 for channel in self._adhoc_manger.channels: 1366 icon = self._adhoc_manager.remove_network(channel) 1367 if icon is not None: 1368 icon.disconnect() 1369 self._layout.remove(icon) 1370 1371 def _add_adhoc_network_icon(self, adhoc_manager, channel): 1372 icon = AdHocView(adhoc_manager, channel) 1373 self._layout.add(icon) 1374 self._adhoc_manager.add_network(channel, icon) 1375 1104 1376 def _add_olpc_mesh_icon(self, mesh_mgr, channel): 1105 1377 icon = OlpcMeshView(mesh_mgr, channel) 1106 1378 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..783d474
- + 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 = 'shared' 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