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