Ticket #2015: olpc-mesh-0.84.patch
File olpc-mesh-0.84.patch, 33.4 KB (added by erikos, 14 years ago) |
---|
-
extensions/deviceicon/network.py
diff --git a/extensions/deviceicon/network.py b/extensions/deviceicon/network.py index f790c91..bcf0cda 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): 385 398 self._icon.props.pulsing = True 386 399 elif state == network.DEVICE_STATE_ACTIVATED: 387 400 address = self._device_props.Get(_NM_DEVICE_IFACE, 'Ip4Address') 388 self._palette.set_connected (self._frequency, address)401 self._palette.set_connected_with_frequency(self._frequency, address) 389 402 self._icon.props.pulsing = False 390 403 else: 391 404 self._icon.props.badge_name = None … … class WirelessDeviceView(ToolButton): 471 484 def __activate_error_cb(self, err): 472 485 logging.debug('Failed to create network: %s', err) 473 486 487 class OlpcMeshDeviceView(ToolButton): 488 _ICON_NAME = 'network-mesh' 489 FRAME_POSITION_RELATIVE = 302 490 491 def __init__(self, device): 492 ToolButton.__init__(self) 493 494 self._bus = dbus.SystemBus() 495 self._device = device 496 self._device_props = None 497 self._device_state = None 498 self._channel = 0 499 500 self._icon = PulsingIcon(icon_name=self._ICON_NAME) 501 self._icon.props.pulse_color = xocolor.XoColor( \ 502 "%s,%s" % (style.COLOR_BUTTON_GREY.get_svg(), 503 style.COLOR_TRANSPARENT.get_svg())) 504 self._icon.props.base_color = profile.get_color() 505 506 self.set_icon_widget(self._icon) 507 self._icon.show() 508 509 self.set_palette_invoker(FrameWidgetInvoker(self)) 510 self._palette = WirelessPalette(_("Mesh Network")) 511 self._palette.connect('deactivate-connection', 512 self.__deactivate_connection) 513 self.set_palette(self._palette) 514 self._palette.set_group_id('frame') 515 516 self._device_props = dbus.Interface(self._device, 517 'org.freedesktop.DBus.Properties') 518 self._device_props.GetAll(_NM_DEVICE_IFACE, byte_arrays=True, 519 reply_handler=self.__get_device_props_reply_cb, 520 error_handler=self.__get_device_props_error_cb) 521 self._device_props.Get(_NM_OLPC_MESH_IFACE, 'ActiveChannel', 522 reply_handler=self.__get_active_channel_reply_cb, 523 error_handler=self.__get_active_channel_error_cb) 524 525 self._bus.add_signal_receiver(self.__state_changed_cb, 526 signal_name='StateChanged', 527 path=self._device.object_path, 528 dbus_interface=_NM_DEVICE_IFACE) 529 self._bus.add_signal_receiver(self.__wireless_properties_changed_cb, 530 signal_name='PropertiesChanged', 531 path=device.object_path, 532 dbus_interface=_NM_OLPC_MESH_IFACE) 533 534 def disconnect(self): 535 self._bus.remove_signal_receiver(self.__state_changed_cb, 536 signal_name='StateChanged', 537 path=self._device.object_path, 538 dbus_interface=_NM_DEVICE_IFACE) 539 self._bus.remove_signal_receiver(self.__wireless_properties_changed_cb, 540 signal_name='PropertiesChanged', 541 path=self._device.object_path, 542 dbus_interface=_NM_OLPC_MESH_IFACE) 543 544 def __get_device_props_reply_cb(self, properties): 545 if 'State' in properties: 546 self._device_state = properties['State'] 547 self._update() 548 549 def __get_device_props_error_cb(self, err): 550 logging.error('Error getting the device properties: %s', err) 551 552 def __get_active_channel_reply_cb(self, channel): 553 self._channel = channel 554 self._update_text() 555 556 def __get_active_channel_error_cb(self, err): 557 logging.error('Error getting the active channel: %s', err) 558 559 def __state_changed_cb(self, new_state, old_state, reason): 560 self._device_state = new_state 561 self._update() 562 563 def __wireless_properties_changed_cb(self, properties): 564 if 'ActiveChannel' in properties: 565 self._channel = properties['ActiveChannel'] 566 self._update_text() 567 568 def _update_text(self): 569 text = _("Mesh Network") + " " + str(self._channel) 570 self._palette.props.primary_text = text 571 572 def _update(self): 573 state = self._device_state 574 575 if state in [network.DEVICE_STATE_PREPARE, 576 network.DEVICE_STATE_CONFIG, 577 network.DEVICE_STATE_NEED_AUTH, 578 network.DEVICE_STATE_IP_CONFIG]: 579 self._palette.set_connecting() 580 self._icon.props.pulsing = True 581 elif state == network.DEVICE_STATE_ACTIVATED: 582 address = self._device_props.Get(_NM_DEVICE_IFACE, 'Ip4Address') 583 self._palette.set_connected_with_channel(self._channel, address) 584 self._icon.props.pulsing = False 585 586 def __deactivate_connection(self, palette, data=None): 587 obj = self._bus.get_object(_NM_SERVICE, _NM_PATH) 588 netmgr = dbus.Interface(obj, _NM_IFACE) 589 netmgr_props = dbus.Interface(netmgr, 'org.freedesktop.DBus.Properties') 590 active_connections_o = netmgr_props.Get(_NM_IFACE, 591 'ActiveConnections') 592 593 for conn_o in active_connections_o: 594 # The connection path for a mesh connection is the device itself. 595 obj = self._bus.get_object(_NM_IFACE, conn_o) 596 props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties') 597 ap_op = props.Get(_NM_ACTIVE_CONN_IFACE, 'SpecificObject') 598 599 try: 600 obj = self._bus.get_object(_NM_IFACE, ap_op) 601 props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties') 602 type = props.Get(_NM_DEVICE_IFACE, 'DeviceType') 603 if type == network.DEVICE_TYPE_802_11_OLPC_MESH: 604 netmgr.DeactivateConnection(conn_o) 605 break 606 except dbus.exceptions.DBusException: 607 pass 608 474 609 class WiredDeviceView(TrayIcon): 475 610 476 611 _ICON_NAME = 'network-wired' -
src/jarabe/desktop/meshbox.py
diff --git a/src/jarabe/desktop/meshbox.py b/src/jarabe/desktop/meshbox.py index 81363ac..9648b4f 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): 139 143 and self._name[-15] == '#' 140 144 141 145 def _create_palette(self): 142 icon_name = get_icon_state(_ ICON_NAME, self._strength)146 icon_name = get_icon_state(_AP_ICON_NAME, self._strength) 143 147 self._palette_icon = Icon(icon_name=icon_name, 144 148 icon_size=style.STANDARD_ICON_SIZE, 145 149 badge_name=self.props.badge_name) … … class WirelessNetworkView(CanvasPulsingIcon): 216 220 if self._mode == network.NM_802_11_MODE_INFRA: 217 221 connection.set_connected() 218 222 219 icon_name = '%s-connected' % _ ICON_NAME223 icon_name = '%s-connected' % _AP_ICON_NAME 220 224 else: 221 icon_name = _ ICON_NAME225 icon_name = _AP_ICON_NAME 222 226 223 227 icon_name = get_icon_state(icon_name, self._strength) 224 228 if icon_name: … … class WirelessNetworkView(CanvasPulsingIcon): 443 447 return None 444 448 return self._access_points[ap_path] 445 449 450 def is_olpc_mesh(self): 451 return self._mode == network.NM_802_11_MODE_ADHOC \ 452 and self.name == "olpc-mesh" 453 454 def remove_all_aps(self): 455 for ap in self._access_points.values(): 456 ap.disconnect() 457 self._access_points = {} 458 self._active_ap = None 459 self.update_strength() 460 446 461 def disconnect(self): 447 462 self._bus.remove_signal_receiver(self.__device_state_changed_cb, 448 463 signal_name='StateChanged', … … class WirelessNetworkView(CanvasPulsingIcon): 454 469 dbus_interface=_NM_WIRELESS_IFACE) 455 470 456 471 472 class OlpcMeshView(CanvasPulsingIcon): 473 def __init__(self, mesh_mgr, channel): 474 CanvasPulsingIcon.__init__(self, icon_name=_OLPC_MESH_ICON_NAME, 475 size=style.STANDARD_ICON_SIZE, cache=True) 476 self._bus = dbus.SystemBus() 477 self._channel = channel 478 self._mesh_mgr = mesh_mgr 479 self._disconnect_item = None 480 self._connect_item = None 481 self._greyed_out = False 482 self._name = '' 483 self._device_state = None 484 self._connection = None 485 self._active = False 486 device = mesh_mgr.mesh_device 487 488 self.connect('button-release-event', self.__button_release_event_cb) 489 490 interface_props = dbus.Interface(device, 491 'org.freedesktop.DBus.Properties') 492 interface_props.Get(_NM_DEVICE_IFACE, 'State', 493 reply_handler=self.__get_device_state_reply_cb, 494 error_handler=self.__get_device_state_error_cb) 495 interface_props.Get(_NM_OLPC_MESH_IFACE, 'ActiveChannel', 496 reply_handler=self.__get_active_channel_reply_cb, 497 error_handler=self.__get_active_channel_error_cb) 498 499 self._bus.add_signal_receiver(self.__device_state_changed_cb, 500 signal_name='StateChanged', 501 path=device.object_path, 502 dbus_interface=_NM_DEVICE_IFACE) 503 self._bus.add_signal_receiver(self.__wireless_properties_changed_cb, 504 signal_name='PropertiesChanged', 505 path=device.object_path, 506 dbus_interface=_NM_OLPC_MESH_IFACE) 507 508 pulse_color = XoColor('%s,%s' % (style.COLOR_BUTTON_GREY.get_svg(), 509 style.COLOR_TRANSPARENT.get_svg())) 510 self.props.pulse_color = pulse_color 511 self.props.base_color = profile.get_color() 512 self._palette = self._create_palette() 513 self.set_palette(self._palette) 514 515 def _create_palette(self): 516 _palette = palette.Palette(_("Mesh Network %d") % self._channel) 517 518 self._connect_item = MenuItem(_('Connect'), 'dialog-ok') 519 self._connect_item.connect('activate', self.__connect_activate_cb) 520 _palette.menu.append(self._connect_item) 521 522 return _palette 523 524 def __get_device_state_reply_cb(self, state): 525 self._device_state = state 526 self._update() 527 528 def __get_device_state_error_cb(self, err): 529 logging.error('Error getting the device state: %s', err) 530 531 def __device_state_changed_cb(self, new_state, old_state, reason): 532 self._device_state = new_state 533 self._update() 534 535 def __get_active_channel_reply_cb(self, channel): 536 self._active = (channel == self._channel) 537 self._update() 538 539 def __get_active_channel_error_cb(self, err): 540 logging.error('Error getting the active channel: %s', err) 541 542 def __wireless_properties_changed_cb(self, properties): 543 if 'ActiveChannel' in properties: 544 channel = properties['ActiveChannel'] 545 self._active = (channel == self._channel) 546 self._update() 547 548 def _update(self): 549 if self._active: 550 state = self._device_state 551 else: 552 state = network.DEVICE_STATE_UNKNOWN 553 554 if state in [network.DEVICE_STATE_PREPARE, 555 network.DEVICE_STATE_CONFIG, 556 network.DEVICE_STATE_NEED_AUTH, 557 network.DEVICE_STATE_IP_CONFIG]: 558 if self._disconnect_item: 559 self._disconnect_item.show() 560 self._connect_item.hide() 561 self._palette.props.secondary_text = _('Connecting...') 562 self.props.pulsing = True 563 elif state == network.DEVICE_STATE_ACTIVATED: 564 if self._disconnect_item: 565 self._disconnect_item.show() 566 self._connect_item.hide() 567 self._palette.props.secondary_text = _('Connected') 568 self.props.pulsing = False 569 else: 570 if self._disconnect_item: 571 self._disconnect_item.hide() 572 self._connect_item.show() 573 self._palette.props.secondary_text = None 574 self.props.pulsing = False 575 576 def _update_color(self): 577 if self._greyed_out: 578 self.props.base_color = XoColor('#D5D5D5,#D5D5D5') 579 else: 580 self.props.base_color = profile.get_color() 581 582 def __connect_activate_cb(self, icon): 583 self._connect() 584 585 def __button_release_event_cb(self, icon, event): 586 self._connect() 587 588 def _connect(self): 589 self._mesh_mgr.user_activate_channel(self._channel) 590 591 def __activate_reply_cb(self, connection): 592 logging.debug('Connection activated: %s', connection) 593 594 def __activate_error_cb(self, err): 595 logging.error('Failed to activate connection: %s', err) 596 597 def set_filter(self, query): 598 self._greyed_out = (query != '') 599 self._update_color() 600 601 def disconnect(self): 602 self._bus.remove_signal_receiver(self.__device_state_changed_cb, 603 signal_name='StateChanged', 604 path=self._device.object_path, 605 dbus_interface=_NM_DEVICE_IFACE) 606 self._bus.remove_signal_receiver(self.__wireless_properties_changed_cb, 607 signal_name='PropertiesChanged', 608 path=self._device.object_path, 609 dbus_interface=_NM_OLPC_MESH_IFACE) 610 611 457 612 class ActivityView(hippo.CanvasBox): 458 613 def __init__(self, model): 459 614 hippo.CanvasBox.__init__(self) … … class NetworkManagerObserver(object): 752 907 device_type = props.Get(_NM_DEVICE_IFACE, 'DeviceType') 753 908 if device_type == network.DEVICE_TYPE_802_11_WIRELESS: 754 909 self._devices[device_o] = DeviceObserver(self._box, device) 910 elif device_type == network.DEVICE_TYPE_802_11_OLPC_MESH: 911 self._box.enable_olpc_mesh(device) 755 912 756 913 def _get_device_path_error_cb(self, err): 757 914 logging.error('Failed to get device type: %s', err) … … class NetworkManagerObserver(object): 764 921 observer = self._devices[device_o] 765 922 observer.disconnect() 766 923 del self._devices[device_o] 924 return 925 926 device = self._bus.get_object(_NM_SERVICE, device_o) 927 props = dbus.Interface(device, 'org.freedesktop.DBus.Properties') 928 device_type = props.Get(_NM_DEVICE_IFACE, 'DeviceType') 929 if device_type == network.DEVICE_TYPE_802_11_OLPC_MESH: 930 self._box.disable_olpc_mesh(device) 767 931 768 932 769 933 class MeshBox(gtk.VBox): … … class MeshBox(gtk.VBox): 779 943 self._model = neighborhood.get_model() 780 944 self._buddies = {} 781 945 self._activities = {} 782 self._mesh = {}946 self._mesh = [] 783 947 self._buddy_to_activity = {} 784 948 self._suspended = True 785 949 self._query = '' … … class MeshBox(gtk.VBox): 924 1088 del self.wireless_networks[hash] 925 1089 926 1090 def _ap_props_changed_cb(self, ap, old_hash): 1091 # if we have mesh hardware, ignore OLPC mesh networks that appear as 1092 # normal wifi networks 1093 if len(self._mesh) > 0 and ap.mode == network.NM_802_11_MODE_ADHOC \ 1094 and ap.name == "olpc-mesh": 1095 logging.debug("ignoring OLPC mesh IBSS") 1096 ap.disconnect() 1097 return 1098 927 1099 if old_hash is None: # new AP finished initializing 928 1100 self._add_ap_to_network(ap) 929 1101 return … … class MeshBox(gtk.VBox): 958 1130 self._remove_net_if_empty(net, ap.network_hash()) 959 1131 return 960 1132 961 logging.error('Can not remove access point %s', ap_o) 1133 # it's not an error if the AP isn't found, since we might have ignored 1134 # it (e.g. olpc-mesh adhoc network) 1135 logging.debug('Can not remove access point %s' % ap_o) 1136 1137 def _add_olpc_mesh_icon(self, mesh_mgr, channel): 1138 icon = OlpcMeshView(mesh_mgr, channel) 1139 self._layout.add(icon) 1140 self._mesh.append(icon) 1141 1142 def enable_olpc_mesh(self, mesh_device): 1143 mesh_mgr = OlpcMeshManager(mesh_device) 1144 self._add_olpc_mesh_icon(mesh_mgr, 1) 1145 self._add_olpc_mesh_icon(mesh_mgr, 6) 1146 self._add_olpc_mesh_icon(mesh_mgr, 11) 1147 1148 # the OLPC mesh can be recognised as a "normal" wifi network. remove 1149 # any such normal networks if they have been created 1150 for hash, net in self.wireless_networks.iteritems(): 1151 if not net.is_olpc_mesh(): 1152 continue 1153 1154 logging.debug("removing OLPC mesh IBSS") 1155 net.remove_all_aps() 1156 net.disconnect() 1157 self._layout.remove(net) 1158 del self.wireless_networks[hash] 1159 1160 def disable_olpc_mesh(self, mesh_device): 1161 for icon in self._mesh: 1162 icon.disconnect() 1163 self._layout.remove(icon) 1164 self._mesh = [] 962 1165 963 1166 def suspend(self): 964 1167 if not self._suspended: 965 1168 self._suspended = True 966 for net in self.wireless_networks.values() :1169 for net in self.wireless_networks.values() + self._mesh: 967 1170 net.props.paused = True 968 1171 969 1172 def resume(self): 970 1173 if self._suspended: 971 1174 self._suspended = False 972 for net in self.wireless_networks.values() :1175 for net in self.wireless_networks.values() + self._mesh: 973 1176 net.props.paused = False 974 1177 975 1178 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 23b7472..97c5d27 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 class OlpcMesh(object): 126 nm_name = "802-11-olpc-mesh" 127 128 def __init__(self, channel, anycast_addr): 129 self.channel = channel 130 self.anycast_addr = anycast_addr 131 132 def get_dict(self): 133 ret = { 134 "ssid": dbus.ByteArray("olpc-mesh"), 135 "channel": self.channel, 136 } 137 138 if self.anycast_addr: 139 ret["dhcp-anycast-address"] = dbus.ByteArray(self.anycast_addr) 140 return ret 141 122 142 class Connection(object): 123 143 def __init__(self): 124 144 self.id = None … … class IP4Config(object): 147 167 return ip4_config 148 168 149 169 class Settings(object): 150 def __init__(self ):170 def __init__(self, wireless_cfg=None): 151 171 self.connection = Connection() 152 self.wireless = Wireless()153 172 self.ip4_config = None 154 173 self.wireless_security = None 155 174 175 if wireless_cfg is not None: 176 self.wireless = wireless_cfg 177 else: 178 self.wireless = Wireless() 179 156 180 def get_dict(self): 157 181 settings = {} 158 182 settings['connection'] = self.connection.get_dict() 159 settings[ '802-11-wireless'] = self.wireless.get_dict()183 settings[self.wireless.nm_name] = self.wireless.get_dict() 160 184 if self.wireless_security is not None: 161 185 settings['802-11-wireless-security'] = \ 162 186 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..bdf0cec
- + 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_timer() 87 else: 88 self._start_automesh() 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