Ticket #230: 0001-Implement-mesh-support-again-dsd.patch
File 0001-Implement-mesh-support-again-dsd.patch, 35.4 KB (added by tomeu, 13 years ago) |
---|
-
extensions/deviceicon/network.py
From c4e6fb13fa5255011911d931d9125e2e7467893e Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso <tomeu@sugarlabs.org> Date: Sat, 16 Jan 2010 19:12:30 +0100 Subject: [PATCH] Implement mesh support again (dsd) --- extensions/deviceicon/network.py | 170 ++++++++++++++++++++++++++--- src/jarabe/desktop/meshbox.py | 222 ++++++++++++++++++++++++++++++++++++-- src/jarabe/model/Makefile.am | 1 + src/jarabe/model/network.py | 32 +++++- src/jarabe/model/olpcmesh.py | 214 ++++++++++++++++++++++++++++++++++++ 5 files changed, 612 insertions(+), 27 deletions(-) create mode 100644 src/jarabe/model/olpcmesh.py diff --git a/extensions/deviceicon/network.py b/extensions/deviceicon/network.py index 3f27ec2..e40e196 100644
a b from sugar.graphics.toolbutton import ToolButton 35 35 from sugar.graphics.tray import TrayIcon 36 36 from sugar.graphics import xocolor 37 37 from sugar.util import unique_id 38 from sugar import profile 38 39 39 40 from jarabe.model import network 40 41 from jarabe.model.network import Settings … … _NM_PATH = '/org/freedesktop/NetworkManager' 50 51 _NM_DEVICE_IFACE = 'org.freedesktop.NetworkManager.Device' 51 52 _NM_WIRED_IFACE = 'org.freedesktop.NetworkManager.Device.Wired' 52 53 _NM_WIRELESS_IFACE = 'org.freedesktop.NetworkManager.Device.Wireless' 54 _NM_OLPC_MESH_IFACE = 'org.freedesktop.NetworkManager.Device.OlpcMesh' 53 55 _NM_ACCESSPOINT_IFACE = 'org.freedesktop.NetworkManager.AccessPoint' 54 56 _NM_ACTIVE_CONN_IFACE = 'org.freedesktop.NetworkManager.Connection.Active' 55 57 … … class WirelessPalette(Palette): 81 83 gobject.TYPE_NONE, ([])), 82 84 } 83 85 84 def __init__(self, primary_text ):86 def __init__(self, primary_text, can_create=True): 85 87 Palette.__init__(self, label=primary_text) 86 88 87 89 self._disconnect_item = None … … class WirelessPalette(Palette): 112 114 self._disconnect_item.connect('activate', self.__disconnect_activate_cb) 113 115 self.menu.append(self._disconnect_item) 114 116 115 self._adhoc_item = gtk.MenuItem(_('Create new wireless network')) 116 self._adhoc_item.connect('activate', self.__adhoc_activate_cb) 117 self.menu.append(self._adhoc_item) 118 self._adhoc_item.show() 117 if can_create: 118 self._adhoc_item = gtk.MenuItem(_('Create new wireless network')) 119 self._adhoc_item.connect('activate', self.__adhoc_activate_cb) 120 self.menu.append(self._adhoc_item) 121 self._adhoc_item.show() 119 122 120 123 def set_connecting(self): 121 124 self.props.secondary_text = _('Connecting...') 122 125 123 def set_connected(self, frequency, iaddress):126 def _set_connected(self, iaddress): 124 127 self.set_content(self._info) 125 128 self.props.secondary_text = _('Connected') 126 self._set_channel(frequency)127 129 self._set_ip_address(iaddress) 128 130 self._disconnect_item.show() 129 131 132 def set_connected_with_frequency(self, frequency, iaddress): 133 self._set_connected(iaddress) 134 self._set_frequency(frequency) 135 136 def set_connected_with_channel(self, channel, iaddress): 137 self._set_connected(iaddress) 138 self._set_channel(channel) 139 130 140 def set_disconnected(self): 131 141 self.props.primary_text = '' 132 142 self.props.secondary_text = '' … … class WirelessPalette(Palette): 139 149 def __adhoc_activate_cb(self, menuitem): 140 150 self.emit('create-connection') 141 151 142 def _set_ channel(self, frequency):152 def _set_frequency(self, frequency): 143 153 try: 144 154 channel = frequency_to_channel(frequency) 145 155 except KeyError: 146 156 channel = 0 157 self._set_channel(channel) 158 159 def _set_channel(self, channel): 147 160 self._channel_label.set_text("%s: %d" % (_("Channel"), channel)) 148 161 149 162 def _set_ip_address(self, ip_address): … … class WirelessDeviceView(ToolButton): 386 399 self._icon.props.pulsing = True 387 400 elif state == network.DEVICE_STATE_ACTIVATED: 388 401 address = self._device_props.Get(_NM_DEVICE_IFACE, 'Ip4Address') 389 self._palette.set_connected (self._frequency, address)402 self._palette.set_connected_with_frequency(self._frequency, address) 390 403 self._icon.props.pulsing = False 391 404 else: 392 405 self._icon.props.badge_name = None … … class WirelessDeviceView(ToolButton): 468 481 def __activate_error_cb(self, err): 469 482 logging.debug('Failed to create network: %s', err) 470 483 484 485 class OlpcMeshDeviceView(ToolButton): 486 _ICON_NAME = 'network-mesh' 487 FRAME_POSITION_RELATIVE = 302 488 489 def __init__(self, device): 490 ToolButton.__init__(self) 491 492 self._bus = dbus.SystemBus() 493 self._device = device 494 self._device_props = None 495 self._device_state = None 496 self._channel = 0 497 498 self._icon = PulsingIcon(icon_name=self._ICON_NAME) 499 self._icon.props.pulse_color = xocolor.XoColor( \ 500 "%s,%s" % (style.COLOR_BUTTON_GREY.get_svg(), 501 style.COLOR_TRANSPARENT.get_svg())) 502 self._icon.props.base_color = profile.get_color() 503 504 self.set_icon_widget(self._icon) 505 self._icon.show() 506 507 self.set_palette_invoker(FrameWidgetInvoker(self)) 508 self._palette = WirelessPalette(_("Mesh Network")) 509 self._palette.connect('deactivate-connection', 510 self.__deactivate_connection) 511 self.set_palette(self._palette) 512 self._palette.set_group_id('frame') 513 514 self._device_props = dbus.Interface(self._device, 515 'org.freedesktop.DBus.Properties') 516 self._device_props.GetAll(_NM_DEVICE_IFACE, byte_arrays=True, 517 reply_handler=self.__get_device_props_reply_cb, 518 error_handler=self.__get_device_props_error_cb) 519 self._device_props.Get(_NM_OLPC_MESH_IFACE, 'ActiveChannel', 520 reply_handler=self.__get_active_channel_reply_cb, 521 error_handler=self.__get_active_channel_error_cb) 522 523 self._bus.add_signal_receiver(self.__state_changed_cb, 524 signal_name='StateChanged', 525 path=self._device.object_path, 526 dbus_interface=_NM_DEVICE_IFACE) 527 self._bus.add_signal_receiver(self.__wireless_properties_changed_cb, 528 signal_name='PropertiesChanged', 529 path=device.object_path, 530 dbus_interface=_NM_OLPC_MESH_IFACE) 531 532 def disconnect(self): 533 self._bus.remove_signal_receiver(self.__state_changed_cb, 534 signal_name='StateChanged', 535 path=self._device.object_path, 536 dbus_interface=_NM_DEVICE_IFACE) 537 self._bus.remove_signal_receiver(self.__wireless_properties_changed_cb, 538 signal_name='PropertiesChanged', 539 path=self._device.object_path, 540 dbus_interface=_NM_OLPC_MESH_IFACE) 541 542 def __get_device_props_reply_cb(self, properties): 543 if 'State' in properties: 544 self._device_state = properties['State'] 545 self._update() 546 547 def __get_device_props_error_cb(self, err): 548 logging.error('Error getting the device properties: %s', err) 549 550 def __get_active_channel_reply_cb(self, channel): 551 self._channel = channel 552 self._update_text() 553 554 def __get_active_channel_error_cb(self, err): 555 logging.error('Error getting the active channel: %s', err) 556 557 def __state_changed_cb(self, new_state, old_state, reason): 558 self._device_state = new_state 559 self._update() 560 561 def __wireless_properties_changed_cb(self, properties): 562 if 'ActiveChannel' in properties: 563 self._channel = properties['ActiveChannel'] 564 self._update_text() 565 566 def _update_text(self): 567 text = _("Mesh Network") + " " + str(self._channel) 568 self._palette.props.primary_text = text 569 570 def _update(self): 571 state = self._device_state 572 573 if state in [network.DEVICE_STATE_PREPARE, 574 network.DEVICE_STATE_CONFIG, 575 network.DEVICE_STATE_NEED_AUTH, 576 network.DEVICE_STATE_IP_CONFIG]: 577 self._palette.set_connecting() 578 self._icon.props.pulsing = True 579 elif state == network.DEVICE_STATE_ACTIVATED: 580 address = self._device_props.Get(_NM_DEVICE_IFACE, 'Ip4Address') 581 self._palette.set_connected_with_channel(self._channel, address) 582 self._icon.props.pulsing = False 583 584 def __deactivate_connection(self, palette, data=None): 585 obj = self._bus.get_object(_NM_SERVICE, _NM_PATH) 586 netmgr = dbus.Interface(obj, _NM_IFACE) 587 netmgr_props = dbus.Interface(netmgr, 'org.freedesktop.DBus.Properties') 588 active_connections_o = netmgr_props.Get(_NM_IFACE, 589 'ActiveConnections') 590 591 for conn_o in active_connections_o: 592 # The connection path for a mesh connection is the device itself. 593 obj = self._bus.get_object(_NM_IFACE, conn_o) 594 props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties') 595 ap_op = props.Get(_NM_ACTIVE_CONN_IFACE, 'SpecificObject') 596 597 try: 598 obj = self._bus.get_object(_NM_IFACE, ap_op) 599 props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties') 600 type = props.Get(_NM_DEVICE_IFACE, 'DeviceType') 601 if type == network.DEVICE_TYPE_802_11_OLPC_MESH: 602 netmgr.DeactivateConnection(conn_o) 603 break 604 except dbus.exceptions.DBusException: 605 pass 606 607 471 608 class WiredDeviceView(TrayIcon): 472 609 473 610 _ICON_NAME = 'network-wired' … … class WiredDeviceView(TrayIcon): 487 624 488 625 489 626 class WirelessDeviceObserver(object): 490 def __init__(self, device, tray ):627 def __init__(self, device, tray, device_type): 491 628 self._device = device 492 629 self._device_view = None 493 630 self._tray = tray 494 631 495 self._device_view = WirelessDeviceView(self._device) 632 if device_type == network.DEVICE_TYPE_802_11_WIRELESS: 633 self._device_view = WirelessDeviceView(self._device) 634 elif device_type == network.DEVICE_TYPE_802_11_OLPC_MESH: 635 self._device_view = OlpcMeshDeviceView(self._device) 636 496 637 self._tray.add_device(self._device_view) 497 638 498 639 def disconnect(self): … … class NetworkManagerObserver(object): 590 731 if device_type == network.DEVICE_TYPE_802_3_ETHERNET: 591 732 device = WiredDeviceObserver(nm_device, self._tray) 592 733 self._devices[device_op] = device 593 elif device_type == network.DEVICE_TYPE_802_11_WIRELESS: 594 device = WirelessDeviceObserver(nm_device, self._tray) 734 elif device_type in [network.DEVICE_TYPE_802_11_WIRELESS, 735 network.DEVICE_TYPE_802_11_OLPC_MESH]: 736 device = WirelessDeviceObserver(nm_device, self._tray, device_type) 595 737 self._devices[device_op] = device 596 738 597 739 def __device_added_cb(self, device_op): -
src/jarabe/desktop/meshbox.py
diff --git a/src/jarabe/desktop/meshbox.py b/src/jarabe/desktop/meshbox.py index 7b8e3a7..38f1e71 100644
a b from sugar.graphics.menuitem import MenuItem 36 36 from sugar.activity.activityhandle import ActivityHandle 37 37 from sugar.activity import activityfactory 38 38 from sugar.util import unique_id 39 from sugar import profile 39 40 40 41 from jarabe.model import neighborhood 41 42 from jarabe.view.buddyicon import BuddyIcon … … from jarabe.model.network import Settings 51 52 from jarabe.model.network import IP4Config 52 53 from jarabe.model.network import WirelessSecurity 53 54 from jarabe.model.network import AccessPoint 55 from jarabe.model.network import OlpcMesh as OlpcMeshSettings 56 from jarabe.model.olpcmesh import OlpcMeshManager 54 57 55 58 _NM_SERVICE = 'org.freedesktop.NetworkManager' 56 59 _NM_IFACE = 'org.freedesktop.NetworkManager' 57 60 _NM_PATH = '/org/freedesktop/NetworkManager' 58 61 _NM_DEVICE_IFACE = 'org.freedesktop.NetworkManager.Device' 59 62 _NM_WIRELESS_IFACE = 'org.freedesktop.NetworkManager.Device.Wireless' 63 _NM_OLPC_MESH_IFACE = 'org.freedesktop.NetworkManager.Device.OlpcMesh' 60 64 _NM_ACCESSPOINT_IFACE = 'org.freedesktop.NetworkManager.AccessPoint' 61 65 _NM_ACTIVE_CONN_IFACE = 'org.freedesktop.NetworkManager.Connection.Active' 62 66 63 _ ICON_NAME = 'network-wireless'64 67 _AP_ICON_NAME = 'network-wireless' 68 _OLPC_MESH_ICON_NAME = 'network-mesh' 65 69 66 70 class WirelessNetworkView(CanvasPulsingIcon): 67 71 def __init__(self, initial_ap): … … class WirelessNetworkView(CanvasPulsingIcon): 149 153 and self._name[-15] == '#' 150 154 151 155 def _create_palette(self): 152 icon_name = get_icon_state(_ ICON_NAME, self._strength)156 icon_name = get_icon_state(_AP_ICON_NAME, self._strength) 153 157 self._palette_icon = Icon(icon_name=icon_name, 154 158 icon_size=style.STANDARD_ICON_SIZE, 155 159 badge_name=self.props.badge_name) … … class WirelessNetworkView(CanvasPulsingIcon): 224 228 if self._mode == network.NM_802_11_MODE_INFRA: 225 229 connection.set_connected() 226 230 227 icon_name = '%s-connected' % _ ICON_NAME231 icon_name = '%s-connected' % _AP_ICON_NAME 228 232 else: 229 icon_name = _ ICON_NAME233 icon_name = _AP_ICON_NAME 230 234 231 235 icon_name = get_icon_state(icon_name, self._strength) 232 236 if icon_name: … … class WirelessNetworkView(CanvasPulsingIcon): 419 423 return None 420 424 return self._access_points[ap_path] 421 425 426 def is_olpc_mesh(self): 427 return self._mode == network.NM_802_11_MODE_ADHOC \ 428 and self.name == "olpc-mesh" 429 430 def remove_all_aps(self): 431 for ap in self._access_points.values(): 432 ap.disconnect() 433 self._access_points = {} 434 self._active_ap = None 435 self.update_strength() 436 422 437 def disconnect(self): 423 438 self._bus.remove_signal_receiver(self.__device_state_changed_cb, 424 439 signal_name='StateChanged', … … class WirelessNetworkView(CanvasPulsingIcon): 430 445 dbus_interface=_NM_WIRELESS_IFACE) 431 446 432 447 448 class OlpcMeshView(CanvasPulsingIcon): 449 def __init__(self, mesh_mgr, channel): 450 CanvasPulsingIcon.__init__(self, icon_name=_OLPC_MESH_ICON_NAME, 451 size=style.STANDARD_ICON_SIZE, cache=True) 452 self._bus = dbus.SystemBus() 453 self._channel = channel 454 self._mesh_mgr = mesh_mgr 455 self._disconnect_item = None 456 self._connect_item = None 457 self._greyed_out = False 458 self._name = '' 459 self._device_state = None 460 self._connection = None 461 self._active = False 462 device = mesh_mgr.mesh_device 463 464 self.connect('button-release-event', self.__button_release_event_cb) 465 466 interface_props = dbus.Interface(device, 467 'org.freedesktop.DBus.Properties') 468 interface_props.Get(_NM_DEVICE_IFACE, 'State', 469 reply_handler=self.__get_device_state_reply_cb, 470 error_handler=self.__get_device_state_error_cb) 471 interface_props.Get(_NM_OLPC_MESH_IFACE, 'ActiveChannel', 472 reply_handler=self.__get_active_channel_reply_cb, 473 error_handler=self.__get_active_channel_error_cb) 474 475 self._bus.add_signal_receiver(self.__device_state_changed_cb, 476 signal_name='StateChanged', 477 path=device.object_path, 478 dbus_interface=_NM_DEVICE_IFACE) 479 self._bus.add_signal_receiver(self.__wireless_properties_changed_cb, 480 signal_name='PropertiesChanged', 481 path=device.object_path, 482 dbus_interface=_NM_OLPC_MESH_IFACE) 483 484 pulse_color = XoColor('%s,%s' % (style.COLOR_BUTTON_GREY.get_svg(), 485 style.COLOR_TRANSPARENT.get_svg())) 486 self.props.pulse_color = pulse_color 487 self.props.base_color = profile.get_color() 488 self._palette = self._create_palette() 489 self.set_palette(self._palette) 490 491 def _create_palette(self): 492 _palette = palette.Palette(_("Mesh Network %d") % self._channel) 493 494 self._connect_item = MenuItem(_('Connect'), 'dialog-ok') 495 self._connect_item.connect('activate', self.__connect_activate_cb) 496 _palette.menu.append(self._connect_item) 497 498 return _palette 499 500 def __get_device_state_reply_cb(self, state): 501 self._device_state = state 502 self._update() 503 504 def __get_device_state_error_cb(self, err): 505 logging.error('Error getting the device state: %s', err) 506 507 def __device_state_changed_cb(self, new_state, old_state, reason): 508 self._device_state = new_state 509 self._update() 510 511 def __get_active_channel_reply_cb(self, channel): 512 self._active = (channel == self._channel) 513 self._update() 514 515 def __get_active_channel_error_cb(self, err): 516 logging.error('Error getting the active channel: %s', err) 517 518 def __wireless_properties_changed_cb(self, properties): 519 if 'ActiveChannel' in properties: 520 channel = properties['ActiveChannel'] 521 self._active = (channel == self._channel) 522 self._update() 523 524 def _update(self): 525 if self._active: 526 state = self._device_state 527 else: 528 state = network.DEVICE_STATE_UNKNOWN 529 530 if state in [network.DEVICE_STATE_PREPARE, 531 network.DEVICE_STATE_CONFIG, 532 network.DEVICE_STATE_NEED_AUTH, 533 network.DEVICE_STATE_IP_CONFIG]: 534 if self._disconnect_item: 535 self._disconnect_item.show() 536 self._connect_item.hide() 537 self._palette.props.secondary_text = _('Connecting...') 538 self.props.pulsing = True 539 elif state == network.DEVICE_STATE_ACTIVATED: 540 if self._disconnect_item: 541 self._disconnect_item.show() 542 self._connect_item.hide() 543 self._palette.props.secondary_text = _('Connected') 544 self.props.pulsing = False 545 else: 546 if self._disconnect_item: 547 self._disconnect_item.hide() 548 self._connect_item.show() 549 self._palette.props.secondary_text = None 550 self.props.pulsing = False 551 552 def _update_color(self): 553 if self._greyed_out: 554 self.props.base_color = XoColor('#D5D5D5,#D5D5D5') 555 else: 556 self.props.base_color = profile.get_color() 557 558 def __connect_activate_cb(self, icon): 559 self._connect() 560 561 def __button_release_event_cb(self, icon, event): 562 self._connect() 563 564 def _connect(self): 565 self._mesh_mgr.user_activate_channel(self._channel) 566 567 def __activate_reply_cb(self, connection): 568 logging.debug('Connection activated: %s', connection) 569 570 def __activate_error_cb(self, err): 571 logging.error('Failed to activate connection: %s', err) 572 573 def set_filter(self, query): 574 self._greyed_out = (query != '') 575 self._update_color() 576 577 def disconnect(self): 578 self._bus.remove_signal_receiver(self.__device_state_changed_cb, 579 signal_name='StateChanged', 580 path=self._device.object_path, 581 dbus_interface=_NM_DEVICE_IFACE) 582 self._bus.remove_signal_receiver(self.__wireless_properties_changed_cb, 583 signal_name='PropertiesChanged', 584 path=self._device.object_path, 585 dbus_interface=_NM_OLPC_MESH_IFACE) 586 587 433 588 class ActivityView(hippo.CanvasBox): 434 589 def __init__(self, model): 435 590 hippo.CanvasBox.__init__(self) … … class NetworkManagerObserver(object): 730 885 device_type = props.Get(_NM_DEVICE_IFACE, 'DeviceType') 731 886 if device_type == network.DEVICE_TYPE_802_11_WIRELESS: 732 887 self._devices[device_o] = DeviceObserver(self._box, device) 888 elif device_type == network.DEVICE_TYPE_802_11_OLPC_MESH: 889 self._box.enable_olpc_mesh(device) 733 890 734 891 def _get_device_path_error_cb(self, err): 735 892 logging.error('Failed to get device type: %s', err) … … class NetworkManagerObserver(object): 742 899 observer = self._devices[device_o] 743 900 observer.disconnect() 744 901 del self._devices[device_o] 745 902 return 903 904 device = self._bus.get_object(_NM_SERVICE, device_o) 905 props = dbus.Interface(device, 'org.freedesktop.DBus.Properties') 906 device_type = props.Get(_NM_DEVICE_IFACE, 'DeviceType') 907 if device_type == network.DEVICE_TYPE_802_11_OLPC_MESH: 908 self._box.disable_olpc_mesh(device) 746 909 747 910 class MeshBox(gtk.VBox): 748 911 __gtype_name__ = 'SugarMeshBox' … … class MeshBox(gtk.VBox): 757 920 self._model = neighborhood.get_model() 758 921 self._buddies = {} 759 922 self._activities = {} 760 self._mesh = {}923 self._mesh = [] 761 924 self._buddy_to_activity = {} 762 925 self._suspended = True 763 926 self._query = '' … … class MeshBox(gtk.VBox): 902 1065 del self.wireless_networks[hash] 903 1066 904 1067 def _ap_props_changed_cb(self, ap, old_hash): 1068 # if we have mesh hardware, ignore OLPC mesh networks that appear as 1069 # normal wifi networks 1070 if len(self._mesh) > 0 and ap.mode == network.NM_802_11_MODE_ADHOC \ 1071 and ap.name == "olpc-mesh": 1072 logging.debug("ignoring OLPC mesh IBSS") 1073 ap.disconnect() 1074 return 1075 905 1076 if old_hash is None: # new AP finished initializing 906 1077 self._add_ap_to_network(ap) 907 1078 return … … class MeshBox(gtk.VBox): 936 1107 self._remove_net_if_empty(net, ap.network_hash()) 937 1108 return 938 1109 939 logging.error('Can not remove access point %s', ap_o) 1110 # it's not an error if the AP isn't found, since we might have ignored 1111 # it (e.g. olpc-mesh adhoc network) 1112 logging.debug('Can not remove access point %s' % ap_o) 1113 1114 def _add_olpc_mesh_icon(self, mesh_mgr, channel): 1115 icon = OlpcMeshView(mesh_mgr, channel) 1116 self._layout.add(icon) 1117 self._mesh.append(icon) 1118 1119 def enable_olpc_mesh(self, mesh_device): 1120 mesh_mgr = OlpcMeshManager(mesh_device) 1121 self._add_olpc_mesh_icon(mesh_mgr, 1) 1122 self._add_olpc_mesh_icon(mesh_mgr, 6) 1123 self._add_olpc_mesh_icon(mesh_mgr, 11) 1124 1125 # the OLPC mesh can be recognised as a "normal" wifi network. remove 1126 # any such normal networks if they have been created 1127 for hash, net in self.wireless_networks.iteritems(): 1128 if not net.is_olpc_mesh(): 1129 continue 1130 1131 logging.debug("removing OLPC mesh IBSS") 1132 net.remove_all_aps() 1133 net.disconnect() 1134 self._layout.remove(net) 1135 del self.wireless_networks[hash] 1136 1137 def disable_olpc_mesh(self, mesh_device): 1138 for icon in self._mesh: 1139 icon.disconnect() 1140 self._layout.remove(icon) 1141 self._mesh = [] 940 1142 941 1143 def suspend(self): 942 1144 if not self._suspended: 943 1145 self._suspended = True 944 for net in self.wireless_networks.values() :1146 for net in self.wireless_networks.values() + self._mesh: 945 1147 net.props.paused = True 946 1148 947 1149 def resume(self): 948 1150 if self._suspended: 949 1151 self._suspended = False 950 for net in self.wireless_networks.values() :1152 for net in self.wireless_networks.values() + self._mesh: 951 1153 net.props.paused = False 952 1154 953 1155 def _toolbar_query_changed_cb(self, toolbar, query): -
src/jarabe/model/Makefile.am
diff --git a/src/jarabe/model/Makefile.am b/src/jarabe/model/Makefile.am index 399db65..18d44da 100644
a b sugar_PYTHON = \ 6 6 filetransfer.py \ 7 7 friends.py \ 8 8 invites.py \ 9 olpcmesh.py \ 9 10 owner.py \ 10 11 neighborhood.py \ 11 12 network.py \ -
src/jarabe/model/network.py
diff --git a/src/jarabe/model/network.py b/src/jarabe/model/network.py index 10b73ab..b3c30d9 100644
a b from sugar import env 29 29 30 30 DEVICE_TYPE_802_3_ETHERNET = 1 31 31 DEVICE_TYPE_802_11_WIRELESS = 2 32 DEVICE_TYPE_802_11_OLPC_MESH = 6 32 33 33 34 DEVICE_STATE_UNKNOWN = 0 34 35 DEVICE_STATE_UNMANAGED = 1 … … class WirelessSecurity(object): 103 104 return wireless_security 104 105 105 106 class Wireless(object): 107 nm_name = "802-11-wireless" 108 106 109 def __init__(self): 107 110 self.ssid = None 108 111 self.security = None … … class Wireless(object): 119 122 wireless['band'] = self.band 120 123 return wireless 121 124 125 126 class OlpcMesh(object): 127 nm_name = "802-11-olpc-mesh" 128 129 def __init__(self, channel, anycast_addr): 130 self.channel = channel 131 self.anycast_addr = anycast_addr 132 133 def get_dict(self): 134 ret = { 135 "ssid": dbus.ByteArray("olpc-mesh"), 136 "channel": self.channel, 137 } 138 139 if self.anycast_addr: 140 ret["dhcp-anycast-address"] = dbus.ByteArray(self.anycast_addr) 141 return ret 142 143 122 144 class Connection(object): 123 145 def __init__(self): 124 146 self.id = None … … class IP4Config(object): 147 169 return ip4_config 148 170 149 171 class Settings(object): 150 def __init__(self ):172 def __init__(self, wireless_cfg=None): 151 173 self.connection = Connection() 152 self.wireless = Wireless()153 174 self.ip4_config = None 154 175 self.wireless_security = None 155 176 177 if wireless_cfg is not None: 178 self.wireless = wireless_cfg 179 else: 180 self.wireless = Wireless() 181 156 182 def get_dict(self): 157 183 settings = {} 158 184 settings['connection'] = self.connection.get_dict() 159 settings[ '802-11-wireless'] = self.wireless.get_dict()185 settings[self.wireless.nm_name] = self.wireless.get_dict() 160 186 if self.wireless_security is not None: 161 187 settings['802-11-wireless-security'] = \ 162 188 self.wireless_security.get_dict() -
new file src/jarabe/model/olpcmesh.py
diff --git a/src/jarabe/model/olpcmesh.py b/src/jarabe/model/olpcmesh.py new file mode 100644 index 0000000..cbd7ddd
- + 1 # Copyright (C) 2009 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 jarabe.model.network import OlpcMesh as OlpcMeshSettings 25 from sugar.util import unique_id 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 _XS_ANYCAST = "\xc0\x27\xc0\x27\xc0\x00" 34 35 DEVICE_STATE_UNKNOWN = 0 36 DEVICE_STATE_UNMANAGED = 1 37 DEVICE_STATE_UNAVAILABLE = 2 38 DEVICE_STATE_DISCONNECTED = 3 39 DEVICE_STATE_PREPARE = 4 40 DEVICE_STATE_CONFIG = 5 41 DEVICE_STATE_NEED_AUTH = 6 42 DEVICE_STATE_IP_CONFIG = 7 43 DEVICE_STATE_ACTIVATED = 8 44 DEVICE_STATE_FAILED = 9 45 46 class OlpcMeshManager(object): 47 def __init__(self, mesh_device): 48 self._bus = dbus.SystemBus() 49 50 self.mesh_device = mesh_device 51 self.eth_device = self._get_companion_device() 52 53 self._connection_queue = [] 54 """Stack of connections that we'll iterate through until we find one 55 that works. 56 57 """ 58 59 props = dbus.Interface(self.mesh_device, 60 'org.freedesktop.DBus.Properties') 61 props.Get(_NM_DEVICE_IFACE, 'State', 62 reply_handler=self.__get_mesh_state_reply_cb, 63 error_handler=self.__get_state_error_cb) 64 65 props = dbus.Interface(self.eth_device, 66 'org.freedesktop.DBus.Properties') 67 props.Get(_NM_DEVICE_IFACE, 'State', 68 reply_handler=self.__get_eth_state_reply_cb, 69 error_handler=self.__get_state_error_cb) 70 71 self._bus.add_signal_receiver(self.__eth_device_state_changed_cb, 72 signal_name='StateChanged', 73 path=self.eth_device.object_path, 74 dbus_interface=_NM_DEVICE_IFACE) 75 76 self._bus.add_signal_receiver(self.__mshdev_state_changed_cb, 77 signal_name='StateChanged', 78 path=self.mesh_device.object_path, 79 dbus_interface=_NM_DEVICE_IFACE) 80 81 self._idle_source = 0 82 self._mesh_device_state = DEVICE_STATE_UNKNOWN 83 self._eth_device_state = DEVICE_STATE_UNKNOWN 84 85 if self._have_configured_connections(): 86 self._start_automesh() 87 else: 88 self._start_automesh_timer() 89 90 def _get_companion_device(self): 91 props = dbus.Interface(self.mesh_device, 92 'org.freedesktop.DBus.Properties') 93 eth_device_o = props.Get(_NM_OLPC_MESH_IFACE, 'Companion') 94 return self._bus.get_object(_NM_SERVICE, eth_device_o) 95 96 def _have_configured_connections(self): 97 return len(network.get_settings().connections) > 0 98 99 def _start_automesh_timer(self): 100 """Start our timer system which basically looks for 10 seconds of 101 inactivity on both devices, then starts automesh. 102 103 """ 104 if self._idle_source != 0: 105 gobject.source_remove(self._idle_source) 106 self._idle_source = gobject.timeout_add_seconds(10, self._idle_check) 107 108 def __get_state_error_cb(self, err): 109 logging.debug('Error getting the device state: %s', err) 110 111 def __get_mesh_state_reply_cb(self, state): 112 self._mesh_device_state = state 113 self._maybe_schedule_idle_check() 114 115 def __get_eth_state_reply_cb(self, state): 116 self._eth_device_state = state 117 self._maybe_schedule_idle_check() 118 119 def __eth_device_state_changed_cb(self, new_state, old_state, reason): 120 """If a connection is activated on the eth device, stop trying our 121 automatic connections. 122 123 """ 124 self._eth_device_state = new_state 125 self._maybe_schedule_idle_check() 126 127 if new_state >= DEVICE_STATE_PREPARE \ 128 and new_state <= DEVICE_STATE_ACTIVATED \ 129 and len(self._connection_queue) > 0: 130 self._connection_queue = [] 131 132 def __mshdev_state_changed_cb(self, new_state, old_state, reason): 133 self._mesh_device_state = new_state 134 self._maybe_schedule_idle_check() 135 136 if new_state == DEVICE_STATE_FAILED: 137 self._try_next_connection_from_queue() 138 elif new_state == DEVICE_STATE_ACTIVATED \ 139 and len(self._connection_queue) > 0: 140 self._empty_connection_queue() 141 142 def _maybe_schedule_idle_check(self): 143 if self._mesh_device_state == DEVICE_STATE_DISCONNECTED \ 144 and self._eth_device_state == DEVICE_STATE_DISCONNECTED: 145 self._start_automesh_timer() 146 147 def _idle_check(self): 148 if self._mesh_device_state == DEVICE_STATE_DISCONNECTED \ 149 and self._eth_device_state == DEVICE_STATE_DISCONNECTED: 150 logging.debug("starting automesh due to inactivity") 151 self._start_automesh() 152 return False 153 154 def _make_connection(self, channel, anycast_address=None): 155 wireless_config = OlpcMeshSettings(channel, anycast_address) 156 settings = Settings(wireless_cfg=wireless_config) 157 if not anycast_address: 158 settings.ip4_config = network.IP4Config() 159 settings.ip4_config.method = 'link-local' 160 settings.connection.id = 'olpc-mesh-' + str(channel) 161 settings.connection.uuid = unique_id() 162 settings.connection.type = '802-11-olpc-mesh' 163 connection = network.add_connection(settings.connection.id, settings) 164 return connection 165 166 def __activate_reply_cb(self, connection): 167 logging.debug('Connection activated: %s', connection) 168 169 def __activate_error_cb(self, err): 170 logging.error('Failed to activate connection: %s', err) 171 172 def _activate_connection(self, channel, anycast_address=None): 173 logging.debug("activate channel %d anycast %s", 174 (channel, repr(anycast_address))) 175 proxy = self._bus.get_object(_NM_SERVICE, _NM_PATH) 176 network_manager = dbus.Interface(proxy, _NM_IFACE) 177 connection = self._make_connection(channel, anycast_address) 178 179 network_manager.ActivateConnection(network.SETTINGS_SERVICE, 180 connection.path, 181 self.mesh_device.object_path, 182 self.mesh_device.object_path, 183 reply_handler=self.__activate_reply_cb, 184 error_handler=self.__activate_error_cb) 185 186 def _try_next_connection_from_queue(self): 187 if len(self._connection_queue) == 0: 188 return 189 190 channel, anycast = self._connection_queue.pop() 191 self._activate_connection(channel, anycast) 192 193 def _empty_connection_queue(self): 194 self._connection_queue = [] 195 196 def user_activate_channel(self, channel): 197 """Activate a mesh connection on a user-specified channel. 198 Looks for XS first, then resorts to simple mesh.""" 199 self._empty_connection_queue() 200 self._connection_queue.append((channel, None)) 201 self._connection_queue.append((channel, _XS_ANYCAST)) 202 self._try_next_connection_from_queue() 203 204 def _start_automesh(self): 205 """Start meshing automatically, intended when there are no better 206 networks to connect to. First looks for XS on all channels, then falls 207 back to simple mesh on channel 1.""" 208 self._empty_connection_queue() 209 self._connection_queue.append((1, None)) 210 self._connection_queue.append((11, _XS_ANYCAST)) 211 self._connection_queue.append((6, _XS_ANYCAST)) 212 self._connection_queue.append((1, _XS_ANYCAST)) 213 self._try_next_connection_from_queue() 214