/[soft]/drakx-net/trunk/lib/network/connection_manager.pm
ViewVC logotype

Contents of /drakx-net/trunk/lib/network/connection_manager.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 636 - (show annotations) (download)
Sun Mar 6 11:05:43 2011 UTC (13 years, 1 month ago) by dmorgan
File size: 22959 byte(s)
Remove wrong commit 
1 package network::connection_manager;
2
3 use strict;
4
5 use common;
6 use run_program;
7 use detect_devices;
8 use interactive;
9 use mygtk2;
10 use ugtk2 qw(:create :helpers :wrappers);
11 use Gtk2::SimpleList;
12 use network::signal_strength;
13 use network::network;
14 use network::tools;
15 use network::connection;
16 use modules;
17 use locale; # for cmp
18
19 sub create_pixbufs() {
20 {
21 state => { map { $_ => gtkcreate_pixbuf($_) } qw(connected disconnected refresh) },
22 link_level => { map {
23 $_ => gtkcreate_pixbuf('wifi-' . sprintf('%03d', $_))->scale_simple(24, 24, 'hyper');
24 } qw(20 40 60 80 100) },
25 encryption => { map {
26 $_ => gtkcreate_pixbuf("encryption-$_-24");
27 } qw(open weak strong) },
28 };
29 }
30
31 sub new {
32 my ($class, $in, $net, $w, $pixbufs) = @_;
33 bless {
34 in => $in, net => $net, gui => { w => $w, pixbufs => $pixbufs },
35 }, $class;
36 }
37
38 sub set_connection {
39 my ($cmanager, $connection) = @_;
40 $cmanager->{connection} = $connection;
41 $cmanager->{wait_message_timeout} = 20*1000 if ref($connection) eq 'network::connection::wireless';
42 }
43
44 sub check_setup {
45 my ($cmanager) = @_;
46 $cmanager->{connection}{passed_setup} =
47 (!$cmanager->{connection}->can("check_device") ||
48 $cmanager->{connection}->check_device) &&
49 (!$cmanager->{connection}->can("check_hardware") ||
50 !$cmanager->{connection}->check_hardware_is_slow && $cmanager->{connection}->check_hardware)
51 if !defined $cmanager->{connection}{passed_setup};
52 $cmanager->{connection}{passed_setup};
53 }
54
55 sub setup_connection {
56 my ($cmanager) = @_;
57
58 $cmanager->load_settings;
59
60 my @packages = $cmanager->{connection}->can('get_packages') ? $cmanager->{connection}->get_packages : ();
61 if (@packages && !$cmanager->{in}->do_pkgs->install(@packages)) {
62 $cmanager->{in}->ask_warn(N("Error"), N("Could not install the packages (%s)!", join(', ', @packages)));
63 return;
64 }
65 $cmanager->{connection}->prepare_device;
66 $cmanager->{connection}->setup_thirdparty($cmanager->{in}) or return;
67 if ($cmanager->{connection}->can("check_device") && !$cmanager->{connection}->check_device) {
68 $cmanager->{in}->ask_warn(N("Error"), $cmanager->{connection}{device}{error});
69 return;
70 }
71 my $device_ready = 1;
72 if ($cmanager->{connection}->can('check_hardware')) {
73 #- FIXME: change message to "Checking device..." in cooker
74 my $_wait = $cmanager->{in}->wait_message(N("Please wait"), N("Configuring device..."));
75 $device_ready = $cmanager->{connection}->check_hardware;
76 }
77 if ($cmanager->{connection}->can('get_hardware_settings') && !$device_ready) {
78 $cmanager->{in}->ask_from_({
79 title => N("Network settings"),
80 messages => N("Please enter settings for network"),
81 auto_window_size => 1,
82 }, $cmanager->{connection}->get_hardware_settings) or return;
83 if ($cmanager->{connection}->can("check_hardware_settings") && !$cmanager->{connection}->check_hardware_settings) {
84 $cmanager->{in}->ask_warn(N("Error"), $cmanager->{connection}->{hardware}{error});
85 return;
86 }
87 }
88 if ($cmanager->{connection}->can('configure_hardware') && !$device_ready) {
89 my $wait = $cmanager->{in}->wait_message(N("Please wait"), N("Configuring device..."));
90 if (!$cmanager->{connection}->configure_hardware) {
91 undef $wait;
92 $cmanager->{in}->ask_warn(N("Error"), $cmanager->{connection}{hardware}{error}) if $cmanager->{connection}{hardware}{error};
93 return;
94 }
95 }
96 $cmanager->write_settings;
97 $cmanager->{connection}{passed_setup} = 1;
98 }
99
100 sub load_settings {
101 my ($cmanager) = @_;
102
103 $cmanager->{connection}->load_interface_settings;
104 $cmanager->{connection}->guess_hardware_settings if $cmanager->{connection}->can('guess_hardware_settings');
105 $cmanager->{connection}->guess_network_access_settings if $cmanager->{connection}->can('guess_network_access_settings');
106 if ($cmanager->{connection}->can('get_providers')) {
107 $cmanager->{connection}->guess_provider_settings;
108 $cmanager->{connection}->set_provider;
109 }
110 $cmanager->{connection}->guess_protocol($cmanager->{net}) if $cmanager->{connection}->can('guess_protocol');
111 $cmanager->{connection}->guess_access_settings if $cmanager->{connection}->can('guess_access_settings');
112 $cmanager->{connection}->guess_address_settings if $cmanager->{connection}->can('guess_address_settings');
113 $cmanager->{connection}->guess_hostname_settings if $cmanager->{connection}->can('guess_hostname_settings');
114 $cmanager->{connection}->guess_network_control_settings if $cmanager->{connection}->can('guess_network_control_settings');
115 $cmanager->{connection}->guess_control_settings;
116 }
117
118 sub write_settings {
119 my ($cmanager) = @_;
120
121 my $modules_conf = modules::any_conf->read;
122 $cmanager->{connection}->write_settings($cmanager->{net}, $modules_conf);
123 $modules_conf->write;
124 }
125
126 sub configure_connection {
127 my ($cmanager) = @_;
128
129 if (!$cmanager->check_setup) {
130 $cmanager->setup_connection or return;
131 $cmanager->update_networks if $cmanager->{connection}->can('get_networks');
132 $cmanager->update_on_status_change;
133 return;
134 }
135
136 $cmanager->load_settings;
137 my $system_file = '/etc/sysconfig/drakx-net';
138 my %global_settings = getVarsFromSh($system_file);
139
140 my $error;
141 do {
142 undef $error;
143 $cmanager->{in}->ask_from_({
144 title => N("Network settings"),
145 messages => N("Please enter settings for network"),
146 icon => $cmanager->{connection}->get_type_icon(48),
147 banner_title => $cmanager->{connection}->get_description,
148 },
149 [
150 $cmanager->{connection}->can('get_network_access_settings') ? (
151 { label => $cmanager->{connection}->get_network_access_settings_label, title => 1, advanced => 1 },
152 @{$cmanager->{connection}->get_network_access_settings},
153 ) : (),
154 $cmanager->{connection}->can('get_providers') ? (
155 @{$cmanager->{connection}->get_provider_settings($cmanager->{net})}
156 ) : (),
157 $cmanager->{connection}->can('get_protocols') ? (
158 @{$cmanager->{connection}->get_protocol_settings},
159 ) : (),
160 $cmanager->{connection}->can('get_access_settings') ? (
161 { label => $cmanager->{connection}->get_access_settings_label, title => 1, advanced => 1 },
162 @{$cmanager->{connection}->get_access_settings}
163 ) : (),
164 $cmanager->{connection}->can('get_address_settings') && !text2bool($global_settings{AUTOMATIC_ADDRESS}) ? (
165 { label => $cmanager->{connection}->get_address_settings_label, title => 1, advanced => 1 },
166 @{$cmanager->{connection}->get_address_settings('show_all')}
167 ) : (),
168 $cmanager->{connection}->can('get_network_control_settings') ? (
169 @{$cmanager->{connection}->get_network_control_settings}
170 ) : (),
171 $cmanager->{connection}->can('get_control_settings') ? (
172 @{$cmanager->{connection}->get_control_settings}
173 ) : (),
174 ],
175 ) or return;
176 if ($cmanager->{connection}->can('check_network_access_settings') && !$cmanager->{connection}->check_network_access_settings) {
177 $cmanager->{in}->ask_warn(N("Error"), $cmanager->{connection}{network_access}{error}{message});
178 $error = 1;
179 }
180 if ($cmanager->{connection}->can('check_address_settings') && !$cmanager->{connection}->check_address_settings($cmanager->{net})) {
181 $cmanager->{in}->ask_warn(N("Error"), $cmanager->{connection}{address}{error}{message});
182 $error = 1;
183 }
184 } while $error;
185
186 $cmanager->{connection}->install_packages($cmanager->{in}) if $cmanager->{connection}->can('install_packages');
187 $cmanager->{connection}->unload_connection if $cmanager->{connection}->can('unload_connection');
188
189 $cmanager->write_settings;
190
191 1;
192 }
193
194 sub start_connection {
195 my ($cmanager) = @_;
196
197 $cmanager->{connection} or return;
198 if ($cmanager->{connection}->can('get_networks')) {
199 $cmanager->{connection}{network} &&
200 ($cmanager->{connection}->selected_network_is_configured ||
201 $cmanager->configure_connection)
202 or return;
203 }
204
205 gtkset_mousecursor_wait($cmanager->{gui}{w}{window}->window);
206 my $wait = $cmanager->{in}->wait_message(N("Please wait"), N("Connecting..."));
207 if ($cmanager->{connection}->can('apply_network_selection')) {
208 $cmanager->load_settings;
209 $cmanager->{connection}->apply_network_selection($cmanager);
210 }
211 $cmanager->{connection}->prepare_connection if $cmanager->{connection}->can('prepare_connection');
212 $cmanager->{connection}->disconnect;
213 $cmanager->{connection}->connect($cmanager->{in}, $cmanager->{net});
214 gtkset_mousecursor_normal($cmanager->{gui}{w}{window}->window);
215
216 $cmanager->update_on_status_change;
217 if ($cmanager->{wait_message_timeout}) {
218 $cmanager->{wait_message} = $wait;
219 Glib::Timeout->add($cmanager->{wait_message_timeout},
220 sub {
221 if ($cmanager->{wait_message}) {
222 undef $cmanager->{wait_message};
223 $cmanager->{in}->ask_warn(N("Error"), N("Connection failed."))
224 if !$cmanager->{connection}->get_status;
225 }
226 undef;
227 });
228 };
229 }
230
231 sub stop_connection {
232 my ($cmanager) = @_;
233
234 gtkset_mousecursor_wait($cmanager->{gui}{w}{window}->window);
235 my $_wait = $cmanager->{in}->wait_message(N("Please wait"), N("Disconnecting..."));
236 $cmanager->{connection}->disconnect;
237 gtkset_mousecursor_normal($cmanager->{gui}{w}{window}->window);
238
239 $cmanager->update_on_status_change;
240 }
241
242 sub monitor_connection {
243 my ($cmanager) = @_;
244 my $interface = $cmanager->{connection} && $cmanager->{connection}->get_interface or return;
245 run_program::raw({ detach => 1 }, '/usr/bin/net_monitor', '--defaultintf', $interface);
246 }
247
248 sub toggle_would_disconnect {
249 my ($cmanager) = @_;
250
251 my $network = $cmanager->{connection} && $cmanager->{connection}->get_selected_network;
252 $cmanager->{connection} && $cmanager->{connection}->get_status &&
253 (!$network || keys(%{$cmanager->{connection}{networks}}) <= 1 || $network->{current});
254 }
255
256 sub toggle_connection {
257 my ($cmanager) = @_;
258
259 if ($cmanager->toggle_would_disconnect) {
260 $cmanager->stop_connection;
261 } else {
262 $cmanager->start_connection;
263 }
264 }
265
266 sub create_networks_list {
267 my ($cmanager) = @_;
268
269 if ($cmanager->{gui}{show_unique_network}) {
270 $cmanager->{gui}{networks_list} = gtknew('HBox', spacing => 20);
271 return;
272 }
273
274 $cmanager->{gui}{networks_list} = Gtk2::SimpleList->new(
275 "AP" => "hidden",
276 '' => "pixbuf",
277 N("SSID") => "text",
278 N("Signal strength") => "pixbuf",
279 N("Encryption") => "pixbuf",
280 N("Operating Mode") => "text",
281 );
282 $cmanager->{gui}{networks_list}->get_selection->set_mode('single');
283 $cmanager->{gui}{networks_list}->get_selection->signal_connect('changed' => sub { $cmanager->select_network });
284
285 $cmanager->{gui}{networks_list}->signal_connect('query-tooltip' => sub {
286 my ($widget, $x, $y, $kbd_tip, $tooltip) = @_;
287 (undef, undef, my $model, my $path, my $iter) = $widget->get_tooltip_context($x, $y, $kbd_tip) or return;
288 my $ap = $model->get($iter, 0);
289 my $network = $cmanager->{connection}{networks}{$ap};
290 $tooltip->set_text(sprintf("%2.2f%% %s\n", $network->{signal_strength}, $network->{flags}));
291 $widget->set_tooltip_row($tooltip, $path);
292 1;
293 });
294 $cmanager->{gui}{networks_list}->set_has_tooltip(1);
295 $cmanager->{gui}{networks_list}->get_column(1)->set_sort_column_id(1);
296 $cmanager->{gui}{networks_list}->get_model->set_sort_func (1, sub {
297 my ($sortable, $iter_left, $iter_right) = @_;
298 my $s1 = $sortable->get($iter_left, 2);
299 my $s2 = $sortable->get($iter_right, 2);
300 return $s1 cmp $s2;
301 });
302 $cmanager->{gui}{networks_list}->get_column(2)->set_sort_column_id(2);
303 $cmanager->{gui}{networks_list}->get_model->set_sort_func (2, sub {
304 my ($sortable, $iter_left, $iter_right) = @_;
305 my $s1 = $cmanager->{connection}{networks}{$sortable->get($iter_left, 0)}->{signal_strength};
306 my $s2 = $cmanager->{connection}{networks}{$sortable->get($iter_right, 0)}->{signal_strength};
307 return $s1 <=> $s2;
308 });
309 $cmanager->{gui}{networks_list}->get_column(3)->set_sort_column_id(3);
310 $cmanager->{gui}{networks_list}->get_model->set_sort_func (3, sub {
311 my ($sortable, $iter_left, $iter_right) = @_;
312 my $s1 = $cmanager->{connection}{networks}{$sortable->get($iter_left, 0)}->{flags};
313 my $s2 = $cmanager->{connection}{networks}{$sortable->get($iter_right, 0)}->{flags};
314 #FIXME Should define an explicit order OPEN < WEP < WPA
315 return $s1 cmp $s2;
316 });
317 $cmanager->{gui}{networks_list}->set_enable_search(1);
318 $cmanager->{gui}{networks_list}->set_search_column(1);
319 $cmanager->{gui}{networks_list}->set_search_equal_func(sub {
320 my ($model, $column, $key, $iter, $data) = @_;
321 return $model->get($iter, 2) !~ /^\Q$key/i;
322 });
323 # Sort by signal level by default
324 $cmanager->{gui}{networks_list}->get_model->set_sort_column_id(2, 'descending');
325 }
326
327 sub select_network {
328 my ($cmanager) = @_;
329
330 if ($cmanager->{connection}) {
331 my ($selected) = $cmanager->{gui}{networks_list}->get_selected_indices;
332 $cmanager->{connection}{network} = defined $selected && $cmanager->{gui}{networks_list}{data}[$selected][0];
333 }
334 $cmanager->update_on_status_change;
335 }
336
337 sub filter_networks {
338 my ($connection) = @_;
339 $_->{configured} = $connection->network_is_configured($_) foreach values %{$connection->{networks}};
340 sort {
341 $b->{current} <=> $a->{current} || $b->{configured} <=> $a->{configured} || $b->{signal_strength} <=> $a->{signal_strength} || $a->{name} cmp $b->{name};
342 } values %{$connection->{networks}};
343 }
344
345 sub update_networks {
346 my ($cmanager) = @_;
347
348 @{$cmanager->{gui}{networks_list}{data}} = ();
349
350 if ($cmanager->{connection}) {
351 $cmanager->check_setup || $cmanager->setup_connection or return;
352
353 my $wait = $cmanager->{connection}->network_scan_is_slow && $cmanager->{in}->wait_message(N("Please wait"), N("Scanning for networks..."));
354 $cmanager->{connection}{networks} = $cmanager->{connection}->get_networks($cmanager->{net});
355 $cmanager->{connection}{network} ||= find { $cmanager->{connection}{networks}{$_}{current} } keys %{$cmanager->{connection}{networks}};
356
357 my $routes = network::tools::get_routes();
358 my $interface = $cmanager->{connection}->get_interface;
359 my $connected = exists $routes->{$interface}{network};
360
361 my @networks = filter_networks($cmanager->{connection});
362 foreach my $network (@networks) {
363 my $ap = $network->{ap};
364 my $connected_pixbuf = $network->{current} ? $connected ? $cmanager->{gui}{pixbufs}{state}{connected} : $cmanager->{gui}{pixbufs}{state}{refresh} : undef;
365 my $network_name = !$network->{essid} && exists $cmanager->{net}{wireless}{$ap} && $cmanager->{net}{wireless}{$ap}{WIRELESS_ESSID} || $network->{name};
366 my $strength_pixbuf = network::signal_strength::get_strength_icon($network);
367
368 if ($cmanager->{gui}{show_unique_network}) {
369 gtkset($cmanager->{gui}{networks_list}, children => [
370 1, $network_name,
371 0, Gtk2::Image->new_from_pixbuf($strength_pixbuf),
372 ]);
373 $cmanager->{connection}{network} = $network_name;
374 } else {
375 push @{$cmanager->{gui}{networks_list}{data}}, [
376 $ap || $network->{name},
377 $connected_pixbuf,
378 $network_name,
379 $strength_pixbuf,
380 $cmanager->{gui}{pixbufs}{encryption}{$network->{flags} =~ /WPA/i ? 'strong' : $network->{flags} =~ /WEP/i ? 'weak' : 'open'},
381 $network->{mode},
382 ];
383 }
384 }
385
386 if ($cmanager->{connection}{network} && !$cmanager->{gui}{show_unique_network}) {
387 my $index = eval { find_index { $_->[0] eq $cmanager->{connection}{network} } @{$cmanager->{gui}{networks_list}{data}} };
388 $cmanager->{gui}{networks_list}->select($index) if defined $index;
389 }
390
391 undef $wait;
392 }
393
394 $cmanager->update_on_status_change;
395 }
396
397 sub update_on_status_change {
398 my ($cmanager) = @_;
399
400 if ($cmanager->{gui}{buttons}{connect_toggle}) {
401 my $disconnect = $cmanager->toggle_would_disconnect;
402 $cmanager->{gui}{buttons}{connect_toggle}->set_label($disconnect ? N("Disconnect") : N("Connect"));
403 gtkset($cmanager->{gui}{buttons}{connect_toggle}, image => gtknew('Image', file => $disconnect ? 'stop-16' : 'activate-16'))
404 if $cmanager->{gui}{buttons}{connect_toggle}->get_image;
405 $cmanager->{gui}{buttons}{connect_toggle}->set_sensitive(
406 $cmanager->{connection} && (
407 !$cmanager->{connection}->can('get_networks') ||
408 $cmanager->{connection}->get_status || #- always allow to disconnect if connected
409 $cmanager->{connection}{network}
410 ));
411 }
412
413 $cmanager->{gui}{buttons}{connect_start}->set_sensitive($cmanager->{connection} && (!$cmanager->{connection}->get_status || $cmanager->{connection}{network}))
414 if $cmanager->{gui}{buttons}{connect_start};
415 $cmanager->{gui}{buttons}{connect_stop}->set_sensitive($cmanager->{connection} && $cmanager->{connection}->get_status)
416 if $cmanager->{gui}{buttons}{connect_stop};
417
418 my $allow_configure;
419 if ($cmanager->{connection}) {
420 my $may_have_network =
421 !$cmanager->{connection}->can('get_networks') ||
422 $cmanager->{connection}{network};
423 $allow_configure = $may_have_network || !$cmanager->check_setup;
424 }
425
426 $cmanager->{gui}{buttons}{configure}->set_sensitive($allow_configure)
427 if $cmanager->{gui}{buttons}{configure};
428
429 my $has_interface = to_bool($cmanager->{connection} && $cmanager->{connection}->get_interface);
430 $cmanager->{gui}{buttons}{refresh}->set_sensitive($has_interface)
431 if $cmanager->{gui}{buttons}{refresh};
432 $cmanager->{gui}{buttons}{monitor}->set_sensitive($has_interface)
433 if $cmanager->{gui}{buttons}{monitor};
434
435 if ($cmanager->{gui}{status_image} && $cmanager->{connection}) {
436 my $icon = $cmanager->{connection}->get_status_icon;
437 ugtk2::_find_imgfile($icon) or $icon = $cmanager->{connection}->get_type_icon;
438 gtkset($cmanager->{gui}{status_image}, file => $icon);
439 }
440 }
441
442 sub _get_network_event_message {
443 my ($connections, $member, @args) = @_;
444 #- FIXME: the hostname.d script and s2u use a different D-Bus interface
445 if ($member eq 'hostname') {
446 my ($hostname) = @args;
447 N("Hostname changed to \"%s\"", $hostname);
448 } elsif ($member eq 'status') {
449 my ($status, $interface) = @args;
450 my $event_connection = find { $_->get_interface eq $interface } @$connections;
451 $event_connection && $event_connection->get_status_message($status);
452 }
453 }
454
455 sub setup_dbus_handlers {
456 my ($cmanagers, $connections, $on_network_event, $dbus) = @_;
457 #- FIXME: use network::monitor?
458 $dbus->{connection}->add_filter(
459 sub {
460 my ($_con, $msg) = @_;
461 if ($msg->get_interface eq 'org.mageia.network') {
462 my $member = $msg->get_member;
463 my $message = _get_network_event_message($connections, $member, $msg->get_args_list);
464 $on_network_event->($message) if $on_network_event && $message;
465 if ($member eq 'status') {
466 my ($status, $interface) = $msg->get_args_list;
467 print "got connection status event: $status $interface\n";
468 my $cmanager = find { $_->{connection}->get_interface eq $interface } @$cmanagers
469 or return;
470 #- FIXME: factorize in update_on_status_change() and check why update_networks() calls update_on_status_change()
471 if ($cmanager->{connection}->can('get_networks') && !$cmanager->{connection}->network_scan_is_slow) {
472 $cmanager->update_networks;
473 } else {
474 $cmanager->network::connection_manager::update_on_status_change;
475 }
476 if ($cmanager->{wait_message}) {
477 if ($status eq 'interface_up') {
478 undef $cmanager->{wait_message};
479 } elsif ($status =~ /_failure$/) {
480 undef $cmanager->{wait_message};
481 $cmanager->{in}->ask_warn(N("Error"), join("\n", N("Connection failed."), if_($message, $message)));
482 }
483 }
484 }
485 }
486 if ($msg->get_interface eq 'org.mageia.monitoring.wireless' && $msg->get_member eq 'Event') {
487 my ($event, $interface) = $msg->get_args_list;
488 print "got wireless event: $event $interface\n";
489 # eugeni: wpa_supplicant seems to issue 'Authentication..timed out messages' even if they
490 # are not fatal (#54002). We should either handle them with more care, or just ignore them altogether
491 # my $cmanager = find { $_->{connection}->get_interface eq $interface } @$cmanagers;
492 # if ($cmanager && $cmanager->{wait_message}) {
493 # # CTRL-EVENT-CONNECTED does not have to be handled, further status will be handled by interface status code
494 # if ($event =~ /Authentication with (.+?) timed out/) {
495 # undef $cmanager->{wait_message};
496 # $cmanager->{in}->ask_warn(N("Error"), N("Connection failed."));
497 # }
498 # }
499 }
500 });
501 $dbus->{connection}->add_match("type='signal',interface='org.mageia.network'");
502 $dbus->{connection}->add_match("type='signal',interface='org.mageia.monitoring.wireless'");
503 dbus_object::set_gtk2_watch_helper($dbus);
504 }
505
506 1;

  ViewVC Help
Powered by ViewVC 1.1.30