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