wifi: Scanning is set to false in case of effective autoscan stop.
[framework/connectivity/connman.git] / plugins / wifi.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2012  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <sys/ioctl.h>
32 #include <sys/socket.h>
33 #include <linux/if_arp.h>
34 #include <linux/wireless.h>
35 #include <net/ethernet.h>
36
37 #ifndef IFF_LOWER_UP
38 #define IFF_LOWER_UP    0x10000
39 #endif
40
41 #include <dbus/dbus.h>
42 #include <glib.h>
43
44 #define CONNMAN_API_SUBJECT_TO_CHANGE
45 #include <connman/plugin.h>
46 #include <connman/inet.h>
47 #include <connman/device.h>
48 #include <connman/rtnl.h>
49 #include <connman/technology.h>
50 #include <connman/log.h>
51 #include <connman/option.h>
52 #include <connman/storage.h>
53 #include <include/setting.h>
54
55 #include <gsupplicant/gsupplicant.h>
56
57 #define CLEANUP_TIMEOUT   8     /* in seconds */
58 #define INACTIVE_TIMEOUT  12    /* in seconds */
59 #define MAXIMUM_RETRIES   4
60
61 #define BGSCAN_DEFAULT "simple:30:-45:300"
62 #define AUTOSCAN_DEFAULT "exponential:3:300"
63
64 static struct connman_technology *wifi_technology = NULL;
65
66 struct hidden_params {
67         char ssid[32];
68         unsigned int ssid_len;
69         char *identity;
70         char *passphrase;
71 };
72
73 /**
74  * Used for autoscan "emulation".
75  * Should be removed when wpa_s autoscan support will be by default.
76  */
77 struct autoscan_params {
78         int base;
79         int limit;
80         int interval;
81         unsigned int timeout;
82 };
83
84 struct wifi_data {
85         char *identifier;
86         struct connman_device *device;
87         struct connman_network *network;
88         struct connman_network *pending_network;
89         GSList *networks;
90         GSupplicantInterface *interface;
91         GSupplicantState state;
92         connman_bool_t connected;
93         connman_bool_t disconnecting;
94         connman_bool_t tethering;
95         connman_bool_t bridged;
96         const char *bridge;
97         int index;
98         unsigned flags;
99         unsigned int watch;
100         int retries;
101         struct hidden_params *hidden;
102         /**
103          * autoscan "emulation".
104          */
105         struct autoscan_params *autoscan;
106 };
107
108 static GList *iface_list = NULL;
109
110 static void handle_tethering(struct wifi_data *wifi)
111 {
112         if (wifi->tethering == FALSE)
113                 return;
114
115         if (wifi->bridge == NULL)
116                 return;
117
118         if (wifi->bridged == TRUE)
119                 return;
120
121         DBG("index %d bridge %s", wifi->index, wifi->bridge);
122
123         if (connman_inet_add_to_bridge(wifi->index, wifi->bridge) < 0)
124                 return;
125
126         wifi->bridged = TRUE;
127 }
128
129 static void wifi_newlink(unsigned flags, unsigned change, void *user_data)
130 {
131         struct connman_device *device = user_data;
132         struct wifi_data *wifi = connman_device_get_data(device);
133
134         DBG("index %d flags %d change %d", wifi->index, flags, change);
135
136         if (!change)
137                 return;
138
139         if ((wifi->flags & IFF_UP) != (flags & IFF_UP)) {
140                 if (flags & IFF_UP)
141                         DBG("interface up");
142                 else
143                         DBG("interface down");
144         }
145
146         if ((wifi->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
147                 if (flags & IFF_LOWER_UP) {
148                         DBG("carrier on");
149
150                         handle_tethering(wifi);
151                 } else
152                         DBG("carrier off");
153         }
154
155         wifi->flags = flags;
156 }
157
158 static int wifi_probe(struct connman_device *device)
159 {
160         struct wifi_data *wifi;
161
162         DBG("device %p", device);
163
164         wifi = g_try_new0(struct wifi_data, 1);
165         if (wifi == NULL)
166                 return -ENOMEM;
167
168         wifi->connected = FALSE;
169         wifi->disconnecting = FALSE;
170         wifi->tethering = FALSE;
171         wifi->bridged = FALSE;
172         wifi->bridge = NULL;
173         wifi->state = G_SUPPLICANT_STATE_INACTIVE;
174
175         connman_device_set_data(device, wifi);
176         wifi->device = connman_device_ref(device);
177
178         wifi->index = connman_device_get_index(device);
179         wifi->flags = 0;
180
181         wifi->watch = connman_rtnl_add_newlink_watch(wifi->index,
182                                                         wifi_newlink, device);
183
184         iface_list = g_list_append(iface_list, wifi);
185
186         return 0;
187 }
188
189 static void remove_networks(struct connman_device *device,
190                                 struct wifi_data *wifi)
191 {
192         GSList *list;
193
194         for (list = wifi->networks; list != NULL; list = list->next) {
195                 struct connman_network *network = list->data;
196
197                 connman_device_remove_network(device, network);
198                 connman_network_unref(network);
199         }
200
201         g_slist_free(wifi->networks);
202         wifi->networks = NULL;
203 }
204
205 static void stop_autoscan(struct connman_device *device)
206 {
207         struct wifi_data *wifi = connman_device_get_data(device);
208         struct autoscan_params *autoscan;
209
210         DBG("");
211
212         if (wifi == NULL || wifi->autoscan == NULL)
213                 return;
214
215         autoscan = wifi->autoscan;
216
217         if (autoscan->timeout == 0 && autoscan->interval == 0)
218                 return;
219
220         g_source_remove(autoscan->timeout);
221
222         autoscan->timeout = 0;
223         autoscan->interval = 0;
224
225         connman_device_set_scanning(device, FALSE);
226
227         connman_device_unref(device);
228 }
229
230 static void wifi_remove(struct connman_device *device)
231 {
232         struct wifi_data *wifi = connman_device_get_data(device);
233
234         DBG("device %p wifi %p", device, wifi);
235
236         if (wifi == NULL)
237                 return;
238
239         stop_autoscan(device);
240
241         iface_list = g_list_remove(iface_list, wifi);
242
243         remove_networks(device, wifi);
244
245         connman_device_set_powered(device, FALSE);
246         connman_device_set_data(device, NULL);
247         connman_device_unref(wifi->device);
248         connman_rtnl_remove_watch(wifi->watch);
249
250         g_supplicant_interface_set_data(wifi->interface, NULL);
251
252         g_free(wifi->autoscan);
253         g_free(wifi->identifier);
254         g_free(wifi);
255 }
256
257 static int add_scan_param(gchar *hex_ssid, int freq,
258                         GSupplicantScanParams *scan_data,
259                         int driver_max_scan_ssids)
260 {
261         unsigned int i;
262         struct scan_ssid *scan_ssid;
263
264         if (driver_max_scan_ssids > scan_data->num_ssids && hex_ssid != NULL) {
265                 gchar *ssid;
266                 unsigned int j = 0, hex;
267                 size_t hex_ssid_len = strlen(hex_ssid);
268
269                 ssid = g_try_malloc0(hex_ssid_len / 2);
270                 if (ssid == NULL)
271                         return -ENOMEM;
272
273                 for (i = 0; i < hex_ssid_len; i += 2) {
274                         sscanf(hex_ssid + i, "%02x", &hex);
275                         ssid[j++] = hex;
276                 }
277
278                 scan_ssid = g_try_new(struct scan_ssid, 1);
279                 if (scan_ssid == NULL) {
280                         g_free(ssid);
281                         return -ENOMEM;
282                 }
283
284                 memcpy(scan_ssid->ssid, ssid, j);
285                 scan_ssid->ssid_len = j;
286                 scan_data->ssids = g_slist_prepend(scan_data->ssids,
287                                                                 scan_ssid);
288
289                 scan_data->num_ssids++;
290
291                 g_free(ssid);
292         } else
293                 return -EINVAL;
294
295         scan_data->ssids = g_slist_reverse(scan_data->ssids);
296
297         if (scan_data->freqs == NULL) {
298                 scan_data->freqs = g_try_malloc0(sizeof(uint16_t) *
299                                                 scan_data->num_ssids);
300                 if (scan_data->freqs == NULL) {
301                         g_slist_free_full(scan_data->ssids, g_free);
302                         return -ENOMEM;
303                 }
304         } else {
305                 scan_data->freqs = g_try_realloc(scan_data->freqs,
306                                 sizeof(uint16_t) * scan_data->num_ssids);
307                 if (scan_data->freqs == NULL) {
308                         g_slist_free_full(scan_data->ssids, g_free);
309                         return -ENOMEM;
310                 }
311                 scan_data->freqs[scan_data->num_ssids - 1] = 0;
312         }
313
314         /* Don't add duplicate entries */
315         for (i = 0; i < scan_data->num_ssids; i++) {
316                 if (scan_data->freqs[i] == 0) {
317                         scan_data->freqs[i] = freq;
318                         break;
319                 } else if (scan_data->freqs[i] == freq)
320                         break;
321         }
322
323         return 0;
324 }
325
326 static int get_hidden_connections(int max_ssids,
327                                 GSupplicantScanParams *scan_data)
328 {
329         GKeyFile *keyfile;
330         gchar **services;
331         char *ssid;
332         gchar *str;
333         int i, freq;
334         gboolean value;
335         int num_ssids = 0, add_param_failed = 0;
336
337         services = connman_storage_get_services();
338         for (i = 0; services && services[i]; i++) {
339                 if (strncmp(services[i], "wifi_", 5) != 0)
340                         continue;
341
342                 keyfile = connman_storage_load_service(services[i]);
343
344                 value = g_key_file_get_boolean(keyfile,
345                                         services[i], "Hidden", NULL);
346                 if (value == FALSE) {
347                         g_key_file_free(keyfile);
348                         continue;
349                 }
350
351                 value = g_key_file_get_boolean(keyfile,
352                                         services[i], "Favorite", NULL);
353                 if (value == FALSE) {
354                         g_key_file_free(keyfile);
355                         continue;
356                 }
357
358                 value = g_key_file_get_boolean(keyfile,
359                                         services[i], "AutoConnect", NULL);
360                 if (value == FALSE) {
361                         g_key_file_free(keyfile);
362                         continue;
363                 }
364
365                 ssid = g_key_file_get_string(keyfile,
366                                         services[i], "SSID", NULL);
367
368                 freq = g_key_file_get_integer(keyfile, services[i],
369                                         "Frequency", NULL);
370
371                 if (add_scan_param(ssid, freq, scan_data, max_ssids) < 0) {
372                         str = g_key_file_get_string(keyfile,
373                                         services[i], "Name", NULL);
374                         DBG("Cannot scan %s (%s)", ssid, str);
375                         g_free(str);
376                         add_param_failed++;
377                 }
378
379                 num_ssids++;
380
381                 g_key_file_free(keyfile);
382         }
383
384         if (add_param_failed > 0)
385                 connman_warn("Unable to scan %d out of %d SSIDs (max is %d)",
386                         add_param_failed, num_ssids, max_ssids);
387
388         g_strfreev(services);
389
390         return num_ssids > max_ssids ? max_ssids : num_ssids;
391 }
392
393 static int throw_wifi_scan(struct connman_device *device,
394                         GSupplicantInterfaceCallback callback)
395 {
396         struct wifi_data *wifi = connman_device_get_data(device);
397         int ret;
398
399         DBG("device %p %p", device, wifi->interface);
400
401         if (wifi->tethering == TRUE)
402                 return 0;
403
404         connman_device_ref(device);
405
406         ret = g_supplicant_interface_scan(wifi->interface, NULL,
407                                                 callback, device);
408         if (ret == 0)
409                 connman_device_set_scanning(device, TRUE);
410         else
411                 connman_device_unref(device);
412
413         return ret;
414 }
415
416 static void hidden_scan_callback(int result,
417                         GSupplicantInterface *interface, void *user_data)
418 {
419         struct connman_device *device = user_data;
420
421         DBG("result %d", result);
422
423         connman_device_set_scanning(device, FALSE);
424         connman_device_unref(device);
425 }
426
427 static void autoscan_scan_callback(int result,
428                         GSupplicantInterface *interface, void *user_data)
429 {
430         struct connman_device *device = user_data;
431         struct wifi_data *wifi = connman_device_get_data(device);
432         int driver_max_ssids;
433
434         DBG("result %d", result);
435
436         /*
437          * Scan hidden networks so that we can autoconnect to them.
438          */
439         driver_max_ssids = g_supplicant_interface_get_max_scan_ssids(
440                                                         wifi->interface);
441         DBG("max ssids %d", driver_max_ssids);
442
443         if (driver_max_ssids > 0) {
444                 GSupplicantScanParams *scan_params;
445                 int ret;
446
447                 scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
448                 if (scan_params == NULL)
449                         goto out;
450
451                 if (get_hidden_connections(driver_max_ssids,
452                                                 scan_params) > 0) {
453                         ret = g_supplicant_interface_scan(wifi->interface,
454                                                         scan_params,
455                                                         hidden_scan_callback,
456                                                         device);
457                         if (ret == 0)
458                                 return;
459                 }
460
461                 g_supplicant_free_scan_params(scan_params);
462         }
463
464 out:
465         connman_device_set_scanning(device, FALSE);
466         connman_device_unref(device);
467 }
468
469 static gboolean autoscan_timeout(gpointer data)
470 {
471         struct connman_device *device = data;
472         struct wifi_data *wifi = connman_device_get_data(device);
473         struct autoscan_params *autoscan;
474         int interval;
475
476         autoscan = wifi->autoscan;
477
478         if (autoscan->interval <= 0) {
479                 interval = autoscan->base;
480                 goto set_interval;
481         } else
482                 interval = autoscan->interval * autoscan->base;
483
484         if (autoscan->interval >= autoscan->limit)
485                 interval = autoscan->limit;
486
487         throw_wifi_scan(wifi->device, autoscan_scan_callback);
488
489 set_interval:
490         DBG("interval %d", interval);
491
492         autoscan->interval = interval;
493
494         autoscan->timeout = g_timeout_add_seconds(interval,
495                                                 autoscan_timeout, device);
496
497         return FALSE;
498 }
499
500 static void start_autoscan(struct connman_device *device)
501 {
502         struct wifi_data *wifi = connman_device_get_data(device);
503         struct autoscan_params *autoscan;
504
505         DBG("");
506
507         if (wifi == NULL)
508                 return;
509
510         autoscan = wifi->autoscan;
511         if (autoscan == NULL)
512                 return;
513
514         if (autoscan->timeout > 0 || autoscan->interval > 0)
515                 return;
516
517         connman_device_ref(device);
518
519         autoscan_timeout(device);
520 }
521
522 static struct autoscan_params *parse_autoscan_params(const char *params)
523 {
524         struct autoscan_params *autoscan;
525         char **list_params;
526         int limit;
527         int base;
528
529         DBG("Emulating autoscan");
530
531         list_params = g_strsplit(params, ":", 0);
532         if (list_params == 0)
533                 return NULL;
534
535         if (g_strv_length(list_params) < 3) {
536                 g_strfreev(list_params);
537                 return NULL;
538         }
539
540         base = atoi(list_params[1]);
541         limit = atoi(list_params[2]);
542
543         g_strfreev(list_params);
544
545         autoscan = g_try_malloc0(sizeof(struct autoscan_params));
546         if (autoscan == NULL) {
547                 DBG("Could not allocate memory for autoscan");
548                 return NULL;
549         }
550
551         DBG("base %d - limit %d", base, limit);
552         autoscan->base = base;
553         autoscan->limit = limit;
554
555         return autoscan;
556 }
557
558 static void setup_autoscan(struct wifi_data *wifi)
559 {
560         if (wifi->autoscan == NULL)
561                 wifi->autoscan = parse_autoscan_params(AUTOSCAN_DEFAULT);
562
563         start_autoscan(wifi->device);
564 }
565
566 static void interface_create_callback(int result,
567                                         GSupplicantInterface *interface,
568                                                         void *user_data)
569 {
570         struct wifi_data *wifi = user_data;
571
572         DBG("result %d ifname %s, wifi %p", result,
573                                 g_supplicant_interface_get_ifname(interface),
574                                 wifi);
575
576         if (result < 0 || wifi == NULL)
577                 return;
578
579         wifi->interface = interface;
580         g_supplicant_interface_set_data(interface, wifi);
581
582         if (g_supplicant_interface_get_ready(interface) == FALSE)
583                 return;
584
585         DBG("interface is ready wifi %p tethering %d", wifi, wifi->tethering);
586
587         if (wifi->device == NULL) {
588                 connman_error("WiFi device not set");
589                 return;
590         }
591
592         connman_device_set_powered(wifi->device, TRUE);
593
594         if (connman_setting_get_bool("BackgroundScanning") == FALSE)
595                 return;
596
597         /* Setting up automatic scanning */
598         setup_autoscan(wifi);
599 }
600
601 static int wifi_enable(struct connman_device *device)
602 {
603         struct wifi_data *wifi = connman_device_get_data(device);
604         const char *interface = connman_device_get_string(device, "Interface");
605         const char *driver = connman_option_get_string("wifi");
606         int ret;
607
608         DBG("device %p %p", device, wifi);
609
610         ret = g_supplicant_interface_create(interface, driver, NULL,
611                                                 interface_create_callback,
612                                                         wifi);
613         if (ret < 0)
614                 return ret;
615
616         return -EINPROGRESS;
617 }
618
619 static int wifi_disable(struct connman_device *device)
620 {
621         struct wifi_data *wifi = connman_device_get_data(device);
622         int ret;
623
624         DBG("device %p", device);
625
626         wifi->connected = FALSE;
627         wifi->disconnecting = FALSE;
628
629         if (wifi->pending_network != NULL)
630                 wifi->pending_network = NULL;
631
632         remove_networks(device, wifi);
633
634         ret = g_supplicant_interface_remove(wifi->interface, NULL, NULL);
635         if (ret < 0)
636                 return ret;
637
638         return -EINPROGRESS;
639 }
640
641 static void hidden_free(struct hidden_params *hidden)
642 {
643         if (hidden == NULL)
644                 return;
645
646         g_free(hidden->identity);
647         g_free(hidden->passphrase);
648         g_free(hidden);
649 }
650
651 static void scan_callback(int result, GSupplicantInterface *interface,
652                                                 void *user_data)
653 {
654         struct connman_device *device = user_data;
655         struct wifi_data *wifi = connman_device_get_data(device);
656
657         DBG("result %d", result);
658
659         if (wifi != NULL && wifi->hidden != NULL) {
660                 hidden_free(wifi->hidden);
661                 wifi->hidden = NULL;
662         }
663
664         if (result < 0)
665                 connman_device_reset_scanning(device);
666
667         connman_device_set_scanning(device, FALSE);
668         connman_device_unref(device);
669
670         start_autoscan(device);
671 }
672
673 struct last_connected {
674         GTimeVal modified;
675         gchar *ssid;
676         int freq;
677 };
678
679 static gint sort_entry(gconstpointer a, gconstpointer b, gpointer user_data)
680 {
681         GTimeVal *aval = (GTimeVal *)a;
682         GTimeVal *bval = (GTimeVal *)b;
683
684         /* Note that the sort order is descending */
685         if (aval->tv_sec < bval->tv_sec)
686                 return 1;
687
688         if (aval->tv_sec > bval->tv_sec)
689                 return -1;
690
691         return 0;
692 }
693
694 static void free_entry(gpointer data)
695 {
696         struct last_connected *entry = data;
697
698         g_free(entry->ssid);
699         g_free(entry);
700 }
701
702 static int get_latest_connections(int max_ssids,
703                                 GSupplicantScanParams *scan_data)
704 {
705         GSequenceIter *iter;
706         GSequence *latest_list;
707         struct last_connected *entry;
708         GKeyFile *keyfile;
709         GTimeVal modified;
710         gchar **services;
711         gchar *str;
712         char *ssid;
713         int i, freq;
714         int num_ssids = 0;
715
716         latest_list = g_sequence_new(free_entry);
717         if (latest_list == NULL)
718                 return -ENOMEM;
719
720         services = connman_storage_get_services();
721         for (i = 0; services && services[i]; i++) {
722                 if (strncmp(services[i], "wifi_", 5) != 0)
723                         continue;
724
725                 keyfile = connman_storage_load_service(services[i]);
726
727                 str = g_key_file_get_string(keyfile,
728                                         services[i], "Favorite", NULL);
729                 if (str == NULL || g_strcmp0(str, "true")) {
730                         if (str)
731                                 g_free(str);
732                         g_key_file_free(keyfile);
733                         continue;
734                 }
735                 g_free(str);
736
737                 str = g_key_file_get_string(keyfile,
738                                         services[i], "AutoConnect", NULL);
739                 if (str == NULL || g_strcmp0(str, "true")) {
740                         if (str)
741                                 g_free(str);
742                         g_key_file_free(keyfile);
743                         continue;
744                 }
745                 g_free(str);
746
747                 str = g_key_file_get_string(keyfile,
748                                         services[i], "Modified", NULL);
749                 if (str != NULL) {
750                         g_time_val_from_iso8601(str, &modified);
751                         g_free(str);
752                 }
753
754                 ssid = g_key_file_get_string(keyfile,
755                                         services[i], "SSID", NULL);
756
757                 freq = g_key_file_get_integer(keyfile, services[i],
758                                         "Frequency", NULL);
759                 if (freq) {
760                         entry = g_try_new(struct last_connected, 1);
761                         if (entry == NULL) {
762                                 g_sequence_free(latest_list);
763                                 g_key_file_free(keyfile);
764                                 g_free(ssid);
765                                 return -ENOMEM;
766                         }
767
768                         entry->ssid = ssid;
769                         entry->modified = modified;
770                         entry->freq = freq;
771
772                         g_sequence_insert_sorted(latest_list, entry,
773                                                 sort_entry, NULL);
774                         num_ssids++;
775                 } else
776                         g_free(ssid);
777
778                 g_key_file_free(keyfile);
779         }
780
781         g_strfreev(services);
782
783         num_ssids = num_ssids > max_ssids ? max_ssids : num_ssids;
784
785         iter = g_sequence_get_begin_iter(latest_list);
786
787         for (i = 0; i < num_ssids; i++) {
788                 entry = g_sequence_get(iter);
789
790                 DBG("ssid %s freq %d modified %lu", entry->ssid, entry->freq,
791                                                 entry->modified.tv_sec);
792
793                 add_scan_param(entry->ssid, entry->freq, scan_data, max_ssids);
794
795                 iter = g_sequence_iter_next(iter);
796         }
797
798         g_sequence_free(latest_list);
799         return num_ssids;
800 }
801
802 static int wifi_scan(struct connman_device *device)
803 {
804         stop_autoscan(device);
805
806         return throw_wifi_scan(device, scan_callback);
807 }
808
809 static int wifi_scan_fast(struct connman_device *device)
810 {
811         struct wifi_data *wifi = connman_device_get_data(device);
812         GSupplicantScanParams *scan_params = NULL;
813         int ret;
814         int driver_max_ssids = 0;
815
816         DBG("device %p %p", device, wifi->interface);
817
818         if (wifi->tethering == TRUE)
819                 return 0;
820
821         driver_max_ssids = g_supplicant_interface_get_max_scan_ssids(
822                                                         wifi->interface);
823         DBG("max ssids %d", driver_max_ssids);
824         if (driver_max_ssids == 0)
825                 return wifi_scan(device);
826
827         scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
828         if (scan_params == NULL)
829                 return -ENOMEM;
830
831         ret = get_latest_connections(driver_max_ssids, scan_params);
832         if (ret <= 0) {
833                 g_supplicant_free_scan_params(scan_params);
834                 return wifi_scan(device);
835         }
836
837         stop_autoscan(device);
838
839         connman_device_ref(device);
840         ret = g_supplicant_interface_scan(wifi->interface, scan_params,
841                                                 scan_callback, device);
842         if (ret == 0)
843                 connman_device_set_scanning(device, TRUE);
844         else {
845                 g_supplicant_free_scan_params(scan_params);
846                 connman_device_unref(device);
847         }
848
849         return ret;
850 }
851
852 /*
853  * This func is only used when connecting to this specific AP first time.
854  * It is not used when system autoconnects to hidden AP.
855  */
856 static int wifi_scan_hidden(struct connman_device *device,
857                 const char *ssid, unsigned int ssid_len,
858                 const char *identity, const char* passphrase)
859 {
860         struct wifi_data *wifi = connman_device_get_data(device);
861         GSupplicantScanParams *scan_params = NULL;
862         struct scan_ssid *scan_ssid;
863         struct hidden_params *hidden;
864         int ret;
865
866         DBG("hidden SSID %s", ssid);
867
868         if (wifi->tethering == TRUE || wifi->hidden != NULL)
869                 return -EBUSY;
870
871         if (ssid == NULL || ssid_len == 0 || ssid_len > 32)
872                 return -EINVAL;
873
874         scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
875         if (scan_params == NULL)
876                 return -ENOMEM;
877
878         scan_ssid = g_try_new(struct scan_ssid, 1);
879         if (scan_ssid == NULL) {
880                 g_free(scan_params);
881                 return -ENOMEM;
882         }
883
884         memcpy(scan_ssid->ssid, ssid, ssid_len);
885         scan_ssid->ssid_len = ssid_len;
886         scan_params->ssids = g_slist_prepend(scan_params->ssids, scan_ssid);
887
888         scan_params->num_ssids = 1;
889
890         hidden = g_try_new0(struct hidden_params, 1);
891         if (hidden == NULL) {
892                 g_free(scan_params);
893                 return -ENOMEM;
894         }
895         memcpy(hidden->ssid, ssid, ssid_len);
896         hidden->ssid_len = ssid_len;
897         hidden->identity = g_strdup(identity);
898         hidden->passphrase = g_strdup(passphrase);
899         wifi->hidden = hidden;
900
901         stop_autoscan(device);
902
903         connman_device_ref(device);
904         ret = g_supplicant_interface_scan(wifi->interface, scan_params,
905                         scan_callback, device);
906         if (ret == 0)
907                 connman_device_set_scanning(device, TRUE);
908         else {
909                 connman_device_unref(device);
910                 g_supplicant_free_scan_params(scan_params);
911                 hidden_free(wifi->hidden);
912                 wifi->hidden = NULL;
913         }
914
915         return ret;
916 }
917
918 static struct connman_device_driver wifi_ng_driver = {
919         .name           = "wifi",
920         .type           = CONNMAN_DEVICE_TYPE_WIFI,
921         .priority       = CONNMAN_DEVICE_PRIORITY_LOW,
922         .probe          = wifi_probe,
923         .remove         = wifi_remove,
924         .enable         = wifi_enable,
925         .disable        = wifi_disable,
926         .scan           = wifi_scan,
927         .scan_fast      = wifi_scan_fast,
928         .scan_hidden    = wifi_scan_hidden,
929 };
930
931 static void system_ready(void)
932 {
933         DBG("");
934
935         if (connman_device_driver_register(&wifi_ng_driver) < 0)
936                 connman_error("Failed to register WiFi driver");
937 }
938
939 static void system_killed(void)
940 {
941         DBG("");
942
943         connman_device_driver_unregister(&wifi_ng_driver);
944 }
945
946 static int network_probe(struct connman_network *network)
947 {
948         DBG("network %p", network);
949
950         return 0;
951 }
952
953 static void network_remove(struct connman_network *network)
954 {
955         struct connman_device *device = connman_network_get_device(network);
956         struct wifi_data *wifi;
957
958         DBG("network %p", network);
959
960         wifi = connman_device_get_data(device);
961         if (wifi == NULL)
962                 return;
963
964         if (wifi->network != network)
965                 return;
966
967         wifi->network = NULL;
968 }
969
970 static void connect_callback(int result, GSupplicantInterface *interface,
971                                                         void *user_data)
972 {
973         struct connman_network *network = user_data;
974
975         DBG("network %p result %d", network, result);
976
977         if (result == -ENOKEY) {
978                 connman_network_set_error(network,
979                                         CONNMAN_NETWORK_ERROR_INVALID_KEY);
980         } else if (result < 0) {
981                 connman_network_set_error(network,
982                                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
983         }
984 }
985
986 static GSupplicantSecurity network_security(const char *security)
987 {
988         if (g_str_equal(security, "none") == TRUE)
989                 return G_SUPPLICANT_SECURITY_NONE;
990         else if (g_str_equal(security, "wep") == TRUE)
991                 return G_SUPPLICANT_SECURITY_WEP;
992         else if (g_str_equal(security, "psk") == TRUE)
993                 return G_SUPPLICANT_SECURITY_PSK;
994         else if (g_str_equal(security, "wpa") == TRUE)
995                 return G_SUPPLICANT_SECURITY_PSK;
996         else if (g_str_equal(security, "rsn") == TRUE)
997                 return G_SUPPLICANT_SECURITY_PSK;
998         else if (g_str_equal(security, "ieee8021x") == TRUE)
999                 return G_SUPPLICANT_SECURITY_IEEE8021X;
1000
1001         return G_SUPPLICANT_SECURITY_UNKNOWN;
1002 }
1003
1004 static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network)
1005 {
1006         const char *security, *passphrase, *agent_passphrase;
1007
1008         memset(ssid, 0, sizeof(*ssid));
1009         ssid->mode = G_SUPPLICANT_MODE_INFRA;
1010         ssid->ssid = connman_network_get_blob(network, "WiFi.SSID",
1011                                                 &ssid->ssid_len);
1012         ssid->scan_ssid = 1;
1013         security = connman_network_get_string(network, "WiFi.Security");
1014         ssid->security = network_security(security);
1015         passphrase = connman_network_get_string(network,
1016                                                 "WiFi.Passphrase");
1017         if (passphrase == NULL || strlen(passphrase) == 0) {
1018
1019                 /* Use agent provided passphrase as a fallback */
1020                 agent_passphrase = connman_network_get_string(network,
1021                                                 "WiFi.AgentPassphrase");
1022
1023                 if (agent_passphrase == NULL || strlen(agent_passphrase) == 0)
1024                         ssid->passphrase = NULL;
1025                 else
1026                         ssid->passphrase = agent_passphrase;
1027         } else
1028                 ssid->passphrase = passphrase;
1029
1030         ssid->eap = connman_network_get_string(network, "WiFi.EAP");
1031
1032         /*
1033          * If our private key password is unset,
1034          * we use the supplied passphrase. That is needed
1035          * for PEAP where 2 passphrases (identity and client
1036          * cert may have to be provided.
1037          */
1038         if (connman_network_get_string(network,
1039                                         "WiFi.PrivateKeyPassphrase") == NULL)
1040                 connman_network_set_string(network,
1041                                                 "WiFi.PrivateKeyPassphrase",
1042                                                 ssid->passphrase);
1043         /* We must have an identity for both PEAP and TLS */
1044         ssid->identity = connman_network_get_string(network, "WiFi.Identity");
1045
1046         /* Use agent provided identity as a fallback */
1047         if (ssid->identity == NULL || strlen(ssid->identity) == 0)
1048                 ssid->identity = connman_network_get_string(network,
1049                                                         "WiFi.AgentIdentity");
1050
1051         ssid->ca_cert_path = connman_network_get_string(network,
1052                                                         "WiFi.CACertFile");
1053         ssid->client_cert_path = connman_network_get_string(network,
1054                                                         "WiFi.ClientCertFile");
1055         ssid->private_key_path = connman_network_get_string(network,
1056                                                         "WiFi.PrivateKeyFile");
1057         ssid->private_key_passphrase = connman_network_get_string(network,
1058                                                 "WiFi.PrivateKeyPassphrase");
1059         ssid->phase2_auth = connman_network_get_string(network, "WiFi.Phase2");
1060
1061         ssid->use_wps = connman_network_get_bool(network, "WiFi.UseWPS");
1062         ssid->pin_wps = connman_network_get_string(network, "WiFi.PinWPS");
1063
1064         if (connman_setting_get_bool("BackgroundScanning") == TRUE)
1065                 ssid->bgscan = BGSCAN_DEFAULT;
1066 }
1067
1068 static int network_connect(struct connman_network *network)
1069 {
1070         struct connman_device *device = connman_network_get_device(network);
1071         struct wifi_data *wifi;
1072         GSupplicantInterface *interface;
1073         GSupplicantSSID *ssid;
1074
1075         DBG("network %p", network);
1076
1077         if (device == NULL)
1078                 return -ENODEV;
1079
1080         wifi = connman_device_get_data(device);
1081         if (wifi == NULL)
1082                 return -ENODEV;
1083
1084         ssid = g_try_malloc0(sizeof(GSupplicantSSID));
1085         if (ssid == NULL)
1086                 return -ENOMEM;
1087
1088         interface = wifi->interface;
1089
1090         ssid_init(ssid, network);
1091
1092         if (wifi->disconnecting == TRUE)
1093                 wifi->pending_network = network;
1094         else {
1095                 wifi->network = network;
1096                 wifi->retries = 0;
1097
1098                 return g_supplicant_interface_connect(interface, ssid,
1099                                                 connect_callback, network);
1100         }
1101
1102         return -EINPROGRESS;
1103 }
1104
1105 static void disconnect_callback(int result, GSupplicantInterface *interface,
1106                                                                 void *user_data)
1107 {
1108         struct wifi_data *wifi = user_data;
1109
1110         if (wifi->network != NULL) {
1111                 /*
1112                  * if result < 0 supplican return an error because
1113                  * the network is not current.
1114                  * we wont receive G_SUPPLICANT_STATE_DISCONNECTED since it
1115                  * failed, call connman_network_set_connected to report
1116                  * disconnect is completed.
1117                  */
1118                 if (result < 0)
1119                         connman_network_set_connected(wifi->network, FALSE);
1120         }
1121
1122         wifi->network = NULL;
1123
1124         wifi->disconnecting = FALSE;
1125
1126         if (wifi->pending_network != NULL) {
1127                 network_connect(wifi->pending_network);
1128                 wifi->pending_network = NULL;
1129         }
1130
1131         start_autoscan(wifi->device);
1132 }
1133
1134 static int network_disconnect(struct connman_network *network)
1135 {
1136         struct connman_device *device = connman_network_get_device(network);
1137         struct wifi_data *wifi;
1138         int err;
1139
1140         DBG("network %p", network);
1141
1142         wifi = connman_device_get_data(device);
1143         if (wifi == NULL || wifi->interface == NULL)
1144                 return -ENODEV;
1145
1146         connman_network_set_associating(network, FALSE);
1147
1148         if (wifi->disconnecting == TRUE)
1149                 return -EALREADY;
1150
1151         wifi->disconnecting = TRUE;
1152
1153         err = g_supplicant_interface_disconnect(wifi->interface,
1154                                                 disconnect_callback, wifi);
1155         if (err < 0)
1156                 wifi->disconnecting = FALSE;
1157
1158         return err;
1159 }
1160
1161 static struct connman_network_driver network_driver = {
1162         .name           = "wifi",
1163         .type           = CONNMAN_NETWORK_TYPE_WIFI,
1164         .priority       = CONNMAN_NETWORK_PRIORITY_LOW,
1165         .probe          = network_probe,
1166         .remove         = network_remove,
1167         .connect        = network_connect,
1168         .disconnect     = network_disconnect,
1169 };
1170
1171 static void interface_added(GSupplicantInterface *interface)
1172 {
1173         const char *ifname = g_supplicant_interface_get_ifname(interface);
1174         const char *driver = g_supplicant_interface_get_driver(interface);
1175         struct wifi_data *wifi;
1176
1177         wifi = g_supplicant_interface_get_data(interface);
1178
1179         /*
1180          * We can get here with a NULL wifi pointer when
1181          * the interface added signal is sent before the
1182          * interface creation callback is called.
1183          */
1184         if (wifi == NULL)
1185                 return;
1186
1187         DBG("ifname %s driver %s wifi %p tethering %d",
1188                         ifname, driver, wifi, wifi->tethering);
1189
1190         if (wifi->device == NULL) {
1191                 connman_error("WiFi device not set");
1192                 return;
1193         }
1194
1195         connman_device_set_powered(wifi->device, TRUE);
1196
1197         if (wifi->tethering == TRUE)
1198                 return;
1199 }
1200
1201 static connman_bool_t is_idle(struct wifi_data *wifi)
1202 {
1203         DBG("state %d", wifi->state);
1204
1205         switch (wifi->state) {
1206         case G_SUPPLICANT_STATE_UNKNOWN:
1207         case G_SUPPLICANT_STATE_DISCONNECTED:
1208         case G_SUPPLICANT_STATE_INACTIVE:
1209         case G_SUPPLICANT_STATE_SCANNING:
1210                 return TRUE;
1211
1212         case G_SUPPLICANT_STATE_AUTHENTICATING:
1213         case G_SUPPLICANT_STATE_ASSOCIATING:
1214         case G_SUPPLICANT_STATE_ASSOCIATED:
1215         case G_SUPPLICANT_STATE_4WAY_HANDSHAKE:
1216         case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
1217         case G_SUPPLICANT_STATE_COMPLETED:
1218                 return FALSE;
1219         }
1220
1221         return FALSE;
1222 }
1223
1224 static connman_bool_t is_idle_wps(GSupplicantInterface *interface,
1225                                                 struct wifi_data *wifi)
1226 {
1227         /* First, let's check if WPS processing did not went wrong */
1228         if (g_supplicant_interface_get_wps_state(interface) ==
1229                 G_SUPPLICANT_WPS_STATE_FAIL)
1230                 return FALSE;
1231
1232         /* Unlike normal connection, being associated while processing wps
1233          * actually means that we are idling. */
1234         switch (wifi->state) {
1235         case G_SUPPLICANT_STATE_UNKNOWN:
1236         case G_SUPPLICANT_STATE_DISCONNECTED:
1237         case G_SUPPLICANT_STATE_INACTIVE:
1238         case G_SUPPLICANT_STATE_SCANNING:
1239         case G_SUPPLICANT_STATE_ASSOCIATED:
1240                 return TRUE;
1241         case G_SUPPLICANT_STATE_AUTHENTICATING:
1242         case G_SUPPLICANT_STATE_ASSOCIATING:
1243         case G_SUPPLICANT_STATE_4WAY_HANDSHAKE:
1244         case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
1245         case G_SUPPLICANT_STATE_COMPLETED:
1246                 return FALSE;
1247         }
1248
1249         return FALSE;
1250 }
1251
1252 static connman_bool_t handle_wps_completion(GSupplicantInterface *interface,
1253                                         struct connman_network *network,
1254                                         struct connman_device *device,
1255                                         struct wifi_data *wifi)
1256 {
1257         connman_bool_t wps;
1258
1259         wps = connman_network_get_bool(network, "WiFi.UseWPS");
1260         if (wps == TRUE) {
1261                 const unsigned char *ssid, *wps_ssid;
1262                 unsigned int ssid_len, wps_ssid_len;
1263                 const char *wps_key;
1264
1265                 /* Checking if we got associated with requested
1266                  * network */
1267                 ssid = connman_network_get_blob(network, "WiFi.SSID",
1268                                                 &ssid_len);
1269
1270                 wps_ssid = g_supplicant_interface_get_wps_ssid(
1271                         interface, &wps_ssid_len);
1272
1273                 if (wps_ssid == NULL || wps_ssid_len != ssid_len ||
1274                                 memcmp(ssid, wps_ssid, ssid_len) != 0) {
1275                         connman_network_set_associating(network, FALSE);
1276                         g_supplicant_interface_disconnect(wifi->interface,
1277                                                 disconnect_callback, wifi);
1278                         return FALSE;
1279                 }
1280
1281                 wps_key = g_supplicant_interface_get_wps_key(interface);
1282                 connman_network_set_string(network, "WiFi.Passphrase",
1283                                         wps_key);
1284
1285                 connman_network_set_string(network, "WiFi.PinWPS", NULL);
1286         }
1287
1288         return TRUE;
1289 }
1290
1291 static connman_bool_t handle_4way_handshake_failure(GSupplicantInterface *interface,
1292                                         struct connman_network *network,
1293                                         struct wifi_data *wifi)
1294 {
1295         if (wifi->state != G_SUPPLICANT_STATE_4WAY_HANDSHAKE)
1296                 return FALSE;
1297
1298         wifi->retries++;
1299
1300         if (wifi->retries < MAXIMUM_RETRIES)
1301                 return TRUE;
1302
1303         connman_network_set_error(network, CONNMAN_NETWORK_ERROR_INVALID_KEY);
1304
1305         return FALSE;
1306 }
1307
1308 static void interface_state(GSupplicantInterface *interface)
1309 {
1310         struct connman_network *network;
1311         struct connman_device *device;
1312         struct wifi_data *wifi;
1313         GSupplicantState state = g_supplicant_interface_get_state(interface);
1314         connman_bool_t wps;
1315
1316         wifi = g_supplicant_interface_get_data(interface);
1317
1318         DBG("wifi %p interface state %d", wifi, state);
1319
1320         if (wifi == NULL)
1321                 return;
1322
1323         network = wifi->network;
1324         device = wifi->device;
1325
1326         if (device == NULL || network == NULL)
1327                 return;
1328
1329         switch (state) {
1330         case G_SUPPLICANT_STATE_SCANNING:
1331                 break;
1332
1333         case G_SUPPLICANT_STATE_AUTHENTICATING:
1334         case G_SUPPLICANT_STATE_ASSOCIATING:
1335                 stop_autoscan(device);
1336
1337                 if (wifi->connected == FALSE)
1338                         connman_network_set_associating(network, TRUE);
1339
1340                 break;
1341
1342         case G_SUPPLICANT_STATE_COMPLETED:
1343                 /* though it should be already stopped: */
1344                 stop_autoscan(device);
1345
1346                 if (handle_wps_completion(interface, network, device, wifi) ==
1347                                                                         FALSE)
1348                         break;
1349
1350                 connman_network_set_connected(network, TRUE);
1351                 break;
1352
1353         case G_SUPPLICANT_STATE_DISCONNECTED:
1354                 /*
1355                  * If we're in one of the idle modes, we have
1356                  * not started association yet and thus setting
1357                  * those ones to FALSE could cancel an association
1358                  * in progress.
1359                  */
1360                 wps = connman_network_get_bool(network, "WiFi.UseWPS");
1361                 if (wps == TRUE)
1362                         if (is_idle_wps(interface, wifi) == TRUE)
1363                                 break;
1364
1365                 if (is_idle(wifi))
1366                         break;
1367
1368                 /* If previous state was 4way-handshake, then
1369                  * it's either: psk was incorrect and thus we retry
1370                  * or if we reach the maximum retries we declare the
1371                  * psk as wrong */
1372                 if (handle_4way_handshake_failure(interface,
1373                                                 network, wifi) == TRUE)
1374                         break;
1375
1376                 /* We disable the selected network, if not then
1377                  * wpa_supplicant will loop retrying */
1378                 if (g_supplicant_interface_enable_selected_network(interface,
1379                                                 FALSE) != 0)
1380                         DBG("Could not disables selected network");
1381
1382                 connman_network_set_connected(network, FALSE);
1383                 connman_network_set_associating(network, FALSE);
1384                 wifi->disconnecting = FALSE;
1385
1386                 start_autoscan(device);
1387
1388                 break;
1389
1390         case G_SUPPLICANT_STATE_INACTIVE:
1391                 connman_network_set_associating(network, FALSE);
1392                 start_autoscan(device);
1393
1394                 break;
1395
1396         case G_SUPPLICANT_STATE_UNKNOWN:
1397         case G_SUPPLICANT_STATE_ASSOCIATED:
1398         case G_SUPPLICANT_STATE_4WAY_HANDSHAKE:
1399         case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
1400                 break;
1401         }
1402
1403         wifi->state = state;
1404
1405         /* Saving wpa_s state policy:
1406          * If connected and if the state changes are roaming related:
1407          * --> We stay connected
1408          * If completed
1409          * --> We are connected
1410          * All other case:
1411          * --> We are not connected
1412          * */
1413         switch (state) {
1414         case G_SUPPLICANT_STATE_AUTHENTICATING:
1415         case G_SUPPLICANT_STATE_ASSOCIATING:
1416         case G_SUPPLICANT_STATE_ASSOCIATED:
1417         case G_SUPPLICANT_STATE_4WAY_HANDSHAKE:
1418         case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
1419                 if (wifi->connected == TRUE)
1420                         connman_warn("Probably roaming right now!"
1421                                                 " Staying connected...");
1422                 else
1423                         wifi->connected = FALSE;
1424                 break;
1425         case G_SUPPLICANT_STATE_COMPLETED:
1426                 wifi->connected = TRUE;
1427                 break;
1428         default:
1429                 wifi->connected = FALSE;
1430                 break;
1431         }
1432
1433         DBG("DONE");
1434 }
1435
1436 static void interface_removed(GSupplicantInterface *interface)
1437 {
1438         const char *ifname = g_supplicant_interface_get_ifname(interface);
1439         struct wifi_data *wifi;
1440
1441         DBG("ifname %s", ifname);
1442
1443         wifi = g_supplicant_interface_get_data(interface);
1444
1445         if (wifi != NULL && wifi->tethering == TRUE)
1446                 return;
1447
1448         if (wifi == NULL || wifi->device == NULL) {
1449                 connman_error("Wrong wifi pointer");
1450                 return;
1451         }
1452
1453         wifi->interface = NULL;
1454         connman_device_set_powered(wifi->device, FALSE);
1455 }
1456
1457 static void scan_started(GSupplicantInterface *interface)
1458 {
1459         DBG("");
1460 }
1461
1462 static void scan_finished(GSupplicantInterface *interface)
1463 {
1464         DBG("");
1465 }
1466
1467 static unsigned char calculate_strength(GSupplicantNetwork *supplicant_network)
1468 {
1469         unsigned char strength;
1470
1471         strength = 120 + g_supplicant_network_get_signal(supplicant_network);
1472         if (strength > 100)
1473                 strength = 100;
1474
1475         return strength;
1476 }
1477
1478 static void network_added(GSupplicantNetwork *supplicant_network)
1479 {
1480         struct connman_network *network;
1481         GSupplicantInterface *interface;
1482         struct wifi_data *wifi;
1483         const char *name, *identifier, *security, *group, *mode;
1484         const unsigned char *ssid;
1485         unsigned int ssid_len;
1486         connman_bool_t wps;
1487         connman_bool_t wps_pbc;
1488         connman_bool_t wps_ready;
1489         connman_bool_t wps_advertizing;
1490
1491         DBG("");
1492
1493         interface = g_supplicant_network_get_interface(supplicant_network);
1494         wifi = g_supplicant_interface_get_data(interface);
1495         name = g_supplicant_network_get_name(supplicant_network);
1496         identifier = g_supplicant_network_get_identifier(supplicant_network);
1497         security = g_supplicant_network_get_security(supplicant_network);
1498         group = g_supplicant_network_get_identifier(supplicant_network);
1499         wps = g_supplicant_network_get_wps(supplicant_network);
1500         wps_pbc = g_supplicant_network_is_wps_pbc(supplicant_network);
1501         wps_ready = g_supplicant_network_is_wps_active(supplicant_network);
1502         wps_advertizing = g_supplicant_network_is_wps_advertizing(
1503                                                         supplicant_network);
1504         mode = g_supplicant_network_get_mode(supplicant_network);
1505
1506         if (wifi == NULL)
1507                 return;
1508
1509         ssid = g_supplicant_network_get_ssid(supplicant_network, &ssid_len);
1510
1511         network = connman_device_get_network(wifi->device, identifier);
1512
1513         if (network == NULL) {
1514                 network = connman_network_create(identifier,
1515                                                 CONNMAN_NETWORK_TYPE_WIFI);
1516                 if (network == NULL)
1517                         return;
1518
1519                 connman_network_set_index(network, wifi->index);
1520
1521                 if (connman_device_add_network(wifi->device, network) < 0) {
1522                         connman_network_unref(network);
1523                         return;
1524                 }
1525
1526                 wifi->networks = g_slist_append(wifi->networks, network);
1527         }
1528
1529         if (name != NULL && name[0] != '\0')
1530                 connman_network_set_name(network, name);
1531
1532         connman_network_set_blob(network, "WiFi.SSID",
1533                                                 ssid, ssid_len);
1534         connman_network_set_string(network, "WiFi.Security", security);
1535         connman_network_set_strength(network,
1536                                 calculate_strength(supplicant_network));
1537         connman_network_set_bool(network, "WiFi.WPS", wps);
1538
1539         if (wps == TRUE) {
1540                 /* Is AP advertizing for WPS association?
1541                  * If so, we decide to use WPS by default */
1542                 if (wps_ready == TRUE && wps_pbc == TRUE &&
1543                                                 wps_advertizing == TRUE)
1544                         connman_network_set_bool(network, "WiFi.UseWPS", TRUE);
1545         }
1546
1547         connman_network_set_frequency(network,
1548                         g_supplicant_network_get_frequency(supplicant_network));
1549
1550         connman_network_set_available(network, TRUE);
1551         connman_network_set_string(network, "WiFi.Mode", mode);
1552
1553         if (ssid != NULL)
1554                 connman_network_set_group(network, group);
1555
1556         if (wifi->hidden != NULL && ssid != NULL) {
1557                 if (wifi->hidden->ssid_len == ssid_len &&
1558                                 memcmp(wifi->hidden->ssid, ssid,
1559                                                 ssid_len) == 0) {
1560                         connman_network_connect_hidden(network,
1561                                         wifi->hidden->identity,
1562                                         wifi->hidden->passphrase);
1563                         hidden_free(wifi->hidden);
1564                         wifi->hidden = NULL;
1565                 }
1566         }
1567 }
1568
1569 static void network_removed(GSupplicantNetwork *network)
1570 {
1571         GSupplicantInterface *interface;
1572         struct wifi_data *wifi;
1573         const char *name, *identifier;
1574         struct connman_network *connman_network;
1575
1576         interface = g_supplicant_network_get_interface(network);
1577         wifi = g_supplicant_interface_get_data(interface);
1578         identifier = g_supplicant_network_get_identifier(network);
1579         name = g_supplicant_network_get_name(network);
1580
1581         DBG("name %s", name);
1582
1583         if (wifi == NULL)
1584                 return;
1585
1586         connman_network = connman_device_get_network(wifi->device, identifier);
1587         if (connman_network == NULL)
1588                 return;
1589
1590         wifi->networks = g_slist_remove(wifi->networks, connman_network);
1591
1592         connman_device_remove_network(wifi->device, connman_network);
1593         connman_network_unref(connman_network);
1594 }
1595
1596 static void network_changed(GSupplicantNetwork *network, const char *property)
1597 {
1598         GSupplicantInterface *interface;
1599         struct wifi_data *wifi;
1600         const char *name, *identifier;
1601         struct connman_network *connman_network;
1602
1603         interface = g_supplicant_network_get_interface(network);
1604         wifi = g_supplicant_interface_get_data(interface);
1605         identifier = g_supplicant_network_get_identifier(network);
1606         name = g_supplicant_network_get_name(network);
1607
1608         DBG("name %s", name);
1609
1610         if (wifi == NULL)
1611                 return;
1612
1613         connman_network = connman_device_get_network(wifi->device, identifier);
1614         if (connman_network == NULL)
1615                 return;
1616
1617         if (g_str_equal(property, "Signal") == TRUE) {
1618                connman_network_set_strength(connman_network,
1619                                         calculate_strength(network));
1620                connman_network_update(connman_network);
1621         }
1622 }
1623
1624 static void debug(const char *str)
1625 {
1626         if (getenv("CONNMAN_SUPPLICANT_DEBUG"))
1627                 connman_debug("%s", str);
1628 }
1629
1630 static const GSupplicantCallbacks callbacks = {
1631         .system_ready           = system_ready,
1632         .system_killed          = system_killed,
1633         .interface_added        = interface_added,
1634         .interface_state        = interface_state,
1635         .interface_removed      = interface_removed,
1636         .scan_started           = scan_started,
1637         .scan_finished          = scan_finished,
1638         .network_added          = network_added,
1639         .network_removed        = network_removed,
1640         .network_changed        = network_changed,
1641         .debug                  = debug,
1642 };
1643
1644
1645 static int tech_probe(struct connman_technology *technology)
1646 {
1647         wifi_technology = technology;
1648
1649         return 0;
1650 }
1651
1652 static void tech_remove(struct connman_technology *technology)
1653 {
1654         wifi_technology = NULL;
1655 }
1656
1657 struct wifi_tethering_info {
1658         struct wifi_data *wifi;
1659         struct connman_technology *technology;
1660         char *ifname;
1661         GSupplicantSSID *ssid;
1662 };
1663
1664 static GSupplicantSSID *ssid_ap_init(const char *ssid, const char *passphrase)
1665 {
1666         GSupplicantSSID *ap;
1667
1668         ap = g_try_malloc0(sizeof(GSupplicantSSID));
1669         if (ap == NULL)
1670                 return NULL;
1671
1672         ap->mode = G_SUPPLICANT_MODE_MASTER;
1673         ap->ssid = ssid;
1674         ap->ssid_len = strlen(ssid);
1675         ap->scan_ssid = 0;
1676         ap->freq = 2412;
1677
1678         if (passphrase == NULL || strlen(passphrase) == 0) {
1679                 ap->security = G_SUPPLICANT_SECURITY_NONE;
1680                 ap->passphrase = NULL;
1681         } else {
1682                ap->security = G_SUPPLICANT_SECURITY_PSK;
1683                ap->protocol = G_SUPPLICANT_PROTO_RSN;
1684                ap->pairwise_cipher = G_SUPPLICANT_PAIRWISE_CCMP;
1685                ap->group_cipher = G_SUPPLICANT_GROUP_CCMP;
1686                ap->passphrase = passphrase;
1687         }
1688
1689         return ap;
1690 }
1691
1692 static void ap_start_callback(int result, GSupplicantInterface *interface,
1693                                                         void *user_data)
1694 {
1695         struct wifi_tethering_info *info = user_data;
1696
1697         DBG("result %d index %d bridge %s",
1698                 result, info->wifi->index, info->wifi->bridge);
1699
1700         if (result < 0) {
1701                 connman_inet_remove_from_bridge(info->wifi->index,
1702                                                         info->wifi->bridge);
1703                 connman_technology_tethering_notify(info->technology, FALSE);
1704         }
1705
1706         g_free(info->ifname);
1707         g_free(info);
1708 }
1709
1710 static void ap_create_callback(int result,
1711                                 GSupplicantInterface *interface,
1712                                         void *user_data)
1713 {
1714         struct wifi_tethering_info *info = user_data;
1715
1716         DBG("result %d ifname %s", result,
1717                                 g_supplicant_interface_get_ifname(interface));
1718
1719         if (result < 0) {
1720                 connman_inet_remove_from_bridge(info->wifi->index,
1721                                                         info->wifi->bridge);
1722                 connman_technology_tethering_notify(info->technology, FALSE);
1723
1724                 g_free(info->ifname);
1725                 g_free(info);
1726                 return;
1727         }
1728
1729         info->wifi->interface = interface;
1730         g_supplicant_interface_set_data(interface, info->wifi);
1731
1732         if (g_supplicant_interface_set_apscan(interface, 2) < 0)
1733                 connman_error("Failed to set interface ap_scan property");
1734
1735         g_supplicant_interface_connect(interface, info->ssid,
1736                                                 ap_start_callback, info);
1737 }
1738
1739 static void sta_remove_callback(int result,
1740                                 GSupplicantInterface *interface,
1741                                         void *user_data)
1742 {
1743         struct wifi_tethering_info *info = user_data;
1744         const char *driver = connman_option_get_string("wifi");
1745
1746         DBG("ifname %s result %d ", info->ifname, result);
1747
1748         if (result < 0) {
1749                 info->wifi->tethering = TRUE;
1750
1751                 g_free(info->ifname);
1752                 g_free(info);
1753                 return;
1754         }
1755
1756         info->wifi->interface = NULL;
1757
1758         connman_technology_tethering_notify(info->technology, TRUE);
1759
1760         g_supplicant_interface_create(info->ifname, driver, info->wifi->bridge,
1761                                                 ap_create_callback,
1762                                                         info);
1763 }
1764
1765 static int tech_set_tethering(struct connman_technology *technology,
1766                                 const char *identifier, const char *passphrase,
1767                                 const char *bridge, connman_bool_t enabled)
1768 {
1769         GList *list;
1770         GSupplicantInterface *interface;
1771         struct wifi_data *wifi;
1772         struct wifi_tethering_info *info;
1773         const char *ifname;
1774         unsigned int mode;
1775         int err;
1776
1777         DBG("");
1778
1779         if (enabled == FALSE) {
1780                 for (list = iface_list; list; list = list->next) {
1781                         wifi = list->data;
1782
1783                         if (wifi->tethering == TRUE) {
1784                                 wifi->tethering = FALSE;
1785
1786                                 connman_inet_remove_from_bridge(wifi->index,
1787                                                                         bridge);
1788                                 wifi->bridged = FALSE;
1789                         }
1790                 }
1791
1792                 connman_technology_tethering_notify(technology, FALSE);
1793
1794                 return 0;
1795         }
1796
1797         for (list = iface_list; list; list = list->next) {
1798                 wifi = list->data;
1799
1800                 interface = wifi->interface;
1801
1802                 if (interface == NULL)
1803                         continue;
1804
1805                 ifname = g_supplicant_interface_get_ifname(wifi->interface);
1806
1807                 mode = g_supplicant_interface_get_mode(interface);
1808                 if ((mode & G_SUPPLICANT_CAPABILITY_MODE_AP) == 0) {
1809                         DBG("%s does not support AP mode", ifname);
1810                         continue;
1811                 }
1812
1813                 info = g_try_malloc0(sizeof(struct wifi_tethering_info));
1814                 if (info == NULL)
1815                         return -ENOMEM;
1816
1817                 info->wifi = wifi;
1818                 info->technology = technology;
1819                 info->wifi->bridge = bridge;
1820                 info->ssid = ssid_ap_init(identifier, passphrase);
1821                 if (info->ssid == NULL) {
1822                         g_free(info);
1823                         continue;
1824                 }
1825                 info->ifname = g_strdup(ifname);
1826                 if (info->ifname == NULL) {
1827                         g_free(info);
1828                         continue;
1829                 }
1830
1831                 info->wifi->tethering = TRUE;
1832
1833                 err = g_supplicant_interface_remove(interface,
1834                                                 sta_remove_callback,
1835                                                         info);
1836                 if (err == 0)
1837                         return err;
1838         }
1839
1840         return -EOPNOTSUPP;
1841 }
1842
1843 static void regdom_callback(void *user_data)
1844 {
1845         char *alpha2 = user_data;
1846
1847         DBG("");
1848
1849         if (wifi_technology == NULL)
1850                 return;
1851
1852         connman_technology_regdom_notify(wifi_technology, alpha2);
1853 }
1854
1855 static int tech_set_regdom(struct connman_technology *technology, const char *alpha2)
1856 {
1857         return g_supplicant_set_country(alpha2, regdom_callback, alpha2);
1858 }
1859
1860 static struct connman_technology_driver tech_driver = {
1861         .name           = "wifi",
1862         .type           = CONNMAN_SERVICE_TYPE_WIFI,
1863         .probe          = tech_probe,
1864         .remove         = tech_remove,
1865         .set_tethering  = tech_set_tethering,
1866         .set_regdom     = tech_set_regdom,
1867 };
1868
1869 static int wifi_init(void)
1870 {
1871         int err;
1872
1873         err = connman_network_driver_register(&network_driver);
1874         if (err < 0)
1875                 return err;
1876
1877         err = g_supplicant_register(&callbacks);
1878         if (err < 0) {
1879                 connman_network_driver_unregister(&network_driver);
1880                 return err;
1881         }
1882
1883         err = connman_technology_driver_register(&tech_driver);
1884         if (err < 0) {
1885                 g_supplicant_unregister(&callbacks);
1886                 connman_network_driver_unregister(&network_driver);
1887                 return err;
1888         }
1889
1890         return 0;
1891 }
1892
1893 static void wifi_exit(void)
1894 {
1895         DBG();
1896
1897         connman_technology_driver_unregister(&tech_driver);
1898
1899         g_supplicant_unregister(&callbacks);
1900
1901         connman_network_driver_unregister(&network_driver);
1902 }
1903
1904 CONNMAN_PLUGIN_DEFINE(wifi, "WiFi interface plugin", VERSION,
1905                 CONNMAN_PLUGIN_PRIORITY_DEFAULT, wifi_init, wifi_exit)