Imported Upstream version 1.35
[platform/upstream/connman.git] / plugins / wifi.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2014  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/peer.h>
52 #include <connman/log.h>
53 #include <connman/option.h>
54 #include <connman/storage.h>
55 #include <include/setting.h>
56 #include <connman/provision.h>
57 #include <connman/utsname.h>
58 #include <connman/machine.h>
59
60 #include <gsupplicant/gsupplicant.h>
61
62 #define CLEANUP_TIMEOUT   8     /* in seconds */
63 #define INACTIVE_TIMEOUT  12    /* in seconds */
64 #define FAVORITE_MAXIMUM_RETRIES 2
65
66 #define BGSCAN_DEFAULT "simple:30:-45:300"
67 #define AUTOSCAN_DEFAULT "exponential:3:300"
68
69 #define P2P_FIND_TIMEOUT 30
70 #define P2P_CONNECTION_TIMEOUT 100
71 #define P2P_LISTEN_PERIOD 500
72 #define P2P_LISTEN_INTERVAL 2000
73
74 #define ASSOC_STATUS_NO_CLIENT 17
75 #define LOAD_SHAPING_MAX_RETRIES 3
76
77 static struct connman_technology *wifi_technology = NULL;
78 static struct connman_technology *p2p_technology = NULL;
79
80 enum wifi_ap_capability{
81         WIFI_AP_UNKNOWN         = 0,
82         WIFI_AP_SUPPORTED       = 1,
83         WIFI_AP_NOT_SUPPORTED   = 2,
84 };
85
86 struct hidden_params {
87         char ssid[32];
88         unsigned int ssid_len;
89         char *identity;
90         char *anonymous_identity;
91         char *subject_match;
92         char *altsubject_match;
93         char *domain_suffix_match;
94         char *domain_match;
95         char *passphrase;
96         char *security;
97         GSupplicantScanParams *scan_params;
98         gpointer user_data;
99 };
100
101 /**
102  * Used for autoscan "emulation".
103  * Should be removed when wpa_s autoscan support will be by default.
104  */
105 struct autoscan_params {
106         int base;
107         int limit;
108         int interval;
109         unsigned int timeout;
110 };
111
112 struct wifi_tethering_info {
113         struct wifi_data *wifi;
114         struct connman_technology *technology;
115         char *ifname;
116         GSupplicantSSID *ssid;
117 };
118
119 struct wifi_data {
120         char *identifier;
121         struct connman_device *device;
122         struct connman_network *network;
123         struct connman_network *pending_network;
124         GSList *networks;
125         GSupplicantInterface *interface;
126         GSupplicantState state;
127         bool connected;
128         bool disconnecting;
129         bool tethering;
130         enum wifi_ap_capability ap_supported;
131         bool bridged;
132         bool interface_ready;
133         const char *bridge;
134         int index;
135         unsigned flags;
136         unsigned int watch;
137         int retries;
138         int load_shaping_retries;
139         struct hidden_params *hidden;
140         bool postpone_hidden;
141         struct wifi_tethering_info *tethering_param;
142         /**
143          * autoscan "emulation".
144          */
145         struct autoscan_params *autoscan;
146
147         GSupplicantScanParams *scan_params;
148         unsigned int p2p_find_timeout;
149         unsigned int p2p_connection_timeout;
150         struct connman_peer *pending_peer;
151         GSList *peers;
152         bool p2p_connecting;
153         bool p2p_device;
154         int servicing;
155         int disconnect_code;
156         int assoc_code;
157 };
158
159 static GList *iface_list = NULL;
160
161 static GList *pending_wifi_device = NULL;
162 static GList *p2p_iface_list = NULL;
163 bool wfd_service_registered = false;
164
165 static void start_autoscan(struct connman_device *device);
166 static int tech_set_tethering(struct connman_technology *technology,
167                                 const char *identifier, const char *passphrase,
168                                 const char *bridge, bool enabled);
169
170 static int p2p_tech_probe(struct connman_technology *technology)
171 {
172         p2p_technology = technology;
173
174         return 0;
175 }
176
177 static void p2p_tech_remove(struct connman_technology *technology)
178 {
179         p2p_technology = NULL;
180 }
181
182 static struct connman_technology_driver p2p_tech_driver = {
183         .name           = "p2p",
184         .type           = CONNMAN_SERVICE_TYPE_P2P,
185         .probe          = p2p_tech_probe,
186         .remove         = p2p_tech_remove,
187 };
188
189 static bool is_p2p_connecting(void)
190 {
191         GList *list;
192
193         for (list = iface_list; list; list = list->next) {
194                 struct wifi_data *wifi = list->data;
195
196                 if (wifi->p2p_connecting)
197                         return true;
198         }
199
200         return false;
201 }
202
203 static void add_pending_wifi_device(struct wifi_data *wifi)
204 {
205         if (g_list_find(pending_wifi_device, wifi))
206                 return;
207
208         pending_wifi_device = g_list_append(pending_wifi_device, wifi);
209 }
210
211 static struct wifi_data *get_pending_wifi_data(const char *ifname)
212 {
213         GList *list;
214
215         for (list = pending_wifi_device; list; list = list->next) {
216                 struct wifi_data *wifi;
217                 const char *dev_name;
218
219                 wifi = list->data;
220                 if (!wifi || !wifi->device)
221                         continue;
222
223                 dev_name = connman_device_get_string(wifi->device, "Interface");
224                 if (!g_strcmp0(ifname, dev_name)) {
225                         pending_wifi_device = g_list_delete_link(
226                                                 pending_wifi_device, list);
227                         return wifi;
228                 }
229         }
230
231         return NULL;
232 }
233
234 static void remove_pending_wifi_device(struct wifi_data *wifi)
235 {
236         GList *link;
237
238         link = g_list_find(pending_wifi_device, wifi);
239
240         if (!link)
241                 return;
242
243         pending_wifi_device = g_list_delete_link(pending_wifi_device, link);
244 }
245
246 static void peer_cancel_timeout(struct wifi_data *wifi)
247 {
248         if (wifi->p2p_connection_timeout > 0)
249                 g_source_remove(wifi->p2p_connection_timeout);
250
251         wifi->p2p_connection_timeout = 0;
252         wifi->p2p_connecting = false;
253
254         if (wifi->pending_peer) {
255                 connman_peer_unref(wifi->pending_peer);
256                 wifi->pending_peer = NULL;
257         }
258 }
259
260 static gboolean peer_connect_timeout(gpointer data)
261 {
262         struct wifi_data *wifi = data;
263
264         DBG("");
265
266         if (wifi->p2p_connecting) {
267                 enum connman_peer_state state = CONNMAN_PEER_STATE_FAILURE;
268                 GSupplicantPeer *gs_peer =
269                         g_supplicant_interface_peer_lookup(wifi->interface,
270                                 connman_peer_get_identifier(wifi->pending_peer));
271
272                 if (g_supplicant_peer_has_requested_connection(gs_peer))
273                         state = CONNMAN_PEER_STATE_IDLE;
274
275                 connman_peer_set_state(wifi->pending_peer, state);
276         }
277
278         peer_cancel_timeout(wifi);
279
280         return FALSE;
281 }
282
283 static void peer_connect_callback(int result, GSupplicantInterface *interface,
284                                                         void *user_data)
285 {
286         struct wifi_data *wifi = user_data;
287         struct connman_peer *peer = wifi->pending_peer;
288
289         DBG("peer %p - %d", peer, result);
290
291         if (!peer)
292                 return;
293
294         if (result < 0) {
295                 peer_connect_timeout(wifi);
296                 return;
297         }
298
299         connman_peer_set_state(peer, CONNMAN_PEER_STATE_ASSOCIATION);
300
301         wifi->p2p_connection_timeout = g_timeout_add_seconds(
302                                                 P2P_CONNECTION_TIMEOUT,
303                                                 peer_connect_timeout, wifi);
304 }
305
306 static int peer_connect(struct connman_peer *peer,
307                         enum connman_peer_wps_method wps_method,
308                         const char *wps_pin)
309 {
310         struct connman_device *device = connman_peer_get_device(peer);
311         GSupplicantPeerParams *peer_params;
312         GSupplicantPeer *gs_peer;
313         struct wifi_data *wifi;
314         bool pbc, pin;
315         int ret;
316
317         DBG("peer %p", peer);
318
319         if (!device)
320                 return -ENODEV;
321
322         wifi = connman_device_get_data(device);
323         if (!wifi || !wifi->interface)
324                 return -ENODEV;
325
326         if (wifi->p2p_connecting)
327                 return -EBUSY;
328
329         gs_peer = g_supplicant_interface_peer_lookup(wifi->interface,
330                                         connman_peer_get_identifier(peer));
331         if (!gs_peer)
332                 return -EINVAL;
333
334         pbc = g_supplicant_peer_is_wps_pbc(gs_peer);
335         pin = g_supplicant_peer_is_wps_pin(gs_peer);
336
337         switch (wps_method) {
338         case CONNMAN_PEER_WPS_UNKNOWN:
339                 if ((pbc && pin) || pin)
340                         return -ENOKEY;
341                 break;
342         case CONNMAN_PEER_WPS_PBC:
343                 if (!pbc)
344                         return -EINVAL;
345                 wps_pin = NULL;
346                 break;
347         case CONNMAN_PEER_WPS_PIN:
348                 if (!pin || !wps_pin)
349                         return -EINVAL;
350                 break;
351         }
352
353         peer_params = g_try_malloc0(sizeof(GSupplicantPeerParams));
354         if (!peer_params)
355                 return -ENOMEM;
356
357         peer_params->path = g_strdup(g_supplicant_peer_get_path(gs_peer));
358         if (wps_pin)
359                 peer_params->wps_pin = g_strdup(wps_pin);
360
361         peer_params->master = connman_peer_service_is_master();
362
363         ret = g_supplicant_interface_p2p_connect(wifi->interface, peer_params,
364                                                 peer_connect_callback, wifi);
365         if (ret == -EINPROGRESS) {
366                 wifi->pending_peer = connman_peer_ref(peer);
367                 wifi->p2p_connecting = true;
368         } else if (ret < 0) {
369                 g_free(peer_params->path);
370                 g_free(peer_params->wps_pin);
371                 g_free(peer_params);
372         }
373
374         return ret;
375 }
376
377 static int peer_disconnect(struct connman_peer *peer)
378 {
379         struct connman_device *device = connman_peer_get_device(peer);
380         GSupplicantPeerParams peer_params = {};
381         GSupplicantPeer *gs_peer;
382         struct wifi_data *wifi;
383         int ret;
384
385         DBG("peer %p", peer);
386
387         if (!device)
388                 return -ENODEV;
389
390         wifi = connman_device_get_data(device);
391         if (!wifi)
392                 return -ENODEV;
393
394         gs_peer = g_supplicant_interface_peer_lookup(wifi->interface,
395                                         connman_peer_get_identifier(peer));
396         if (!gs_peer)
397                 return -EINVAL;
398
399         peer_params.path = g_strdup(g_supplicant_peer_get_path(gs_peer));
400
401         ret = g_supplicant_interface_p2p_disconnect(wifi->interface,
402                                                         &peer_params);
403         g_free(peer_params.path);
404
405         if (ret == -EINPROGRESS) {
406                 peer_cancel_timeout(wifi);
407                 wifi->p2p_device = false;
408         }
409
410         return ret;
411 }
412
413 struct peer_service_registration {
414         peer_service_registration_cb_t callback;
415         void *user_data;
416 };
417
418 static bool is_service_wfd(const unsigned char *specs, int length)
419 {
420         if (length < 9 || specs[0] != 0 || specs[1] != 0 || specs[2] != 6)
421                 return false;
422
423         return true;
424 }
425
426 static void apply_p2p_listen_on_iface(gpointer data, gpointer user_data)
427 {
428         struct wifi_data *wifi = data;
429
430         if (!wifi->interface ||
431                         !g_supplicant_interface_has_p2p(wifi->interface))
432                 return;
433
434         if (!wifi->servicing) {
435                 g_supplicant_interface_p2p_listen(wifi->interface,
436                                 P2P_LISTEN_PERIOD, P2P_LISTEN_INTERVAL);
437         }
438
439         wifi->servicing++;
440 }
441
442 static void register_wfd_service_cb(int result,
443                                 GSupplicantInterface *iface, void *user_data)
444 {
445         struct peer_service_registration *reg_data = user_data;
446
447         DBG("");
448
449         if (result == 0)
450                 g_list_foreach(iface_list, apply_p2p_listen_on_iface, NULL);
451
452         if (reg_data && reg_data->callback) {
453                 reg_data->callback(result, reg_data->user_data);
454                 g_free(reg_data);
455         }
456 }
457
458 static GSupplicantP2PServiceParams *fill_in_peer_service_params(
459                                 const unsigned char *spec,
460                                 int spec_length, const unsigned char *query,
461                                 int query_length, int version)
462 {
463         GSupplicantP2PServiceParams *params;
464
465         params = g_try_malloc0(sizeof(GSupplicantP2PServiceParams));
466         if (!params)
467                 return NULL;
468
469         if (version > 0) {
470                 params->version = version;
471                 params->service = g_memdup(spec, spec_length);
472         } else if (query_length > 0 && spec_length > 0) {
473                 params->query = g_memdup(query, query_length);
474                 params->query_length = query_length;
475
476                 params->response = g_memdup(spec, spec_length);
477                 params->response_length = spec_length;
478         } else {
479                 params->wfd_ies = g_memdup(spec, spec_length);
480                 params->wfd_ies_length = spec_length;
481         }
482
483         return params;
484 }
485
486 static void free_peer_service_params(GSupplicantP2PServiceParams *params)
487 {
488         if (!params)
489                 return;
490
491         g_free(params->service);
492         g_free(params->query);
493         g_free(params->response);
494         g_free(params->wfd_ies);
495
496         g_free(params);
497 }
498
499 static int peer_register_wfd_service(const unsigned char *specification,
500                                 int specification_length,
501                                 peer_service_registration_cb_t callback,
502                                 void *user_data)
503 {
504         struct peer_service_registration *reg_data = NULL;
505         static GSupplicantP2PServiceParams *params;
506         int ret;
507
508         DBG("");
509
510         if (wfd_service_registered)
511                 return -EBUSY;
512
513         params = fill_in_peer_service_params(specification,
514                                         specification_length, NULL, 0, 0);
515         if (!params)
516                 return -ENOMEM;
517
518         reg_data = g_try_malloc0(sizeof(*reg_data));
519         if (!reg_data) {
520                 ret = -ENOMEM;
521                 goto error;
522         }
523
524         reg_data->callback = callback;
525         reg_data->user_data = user_data;
526
527         ret = g_supplicant_set_widi_ies(params,
528                                         register_wfd_service_cb, reg_data);
529         if (ret < 0 && ret != -EINPROGRESS)
530                 goto error;
531
532         wfd_service_registered = true;
533
534         return ret;
535 error:
536         free_peer_service_params(params);
537         g_free(reg_data);
538
539         return ret;
540 }
541
542 static void register_peer_service_cb(int result,
543                                 GSupplicantInterface *iface, void *user_data)
544 {
545         struct wifi_data *wifi = g_supplicant_interface_get_data(iface);
546         struct peer_service_registration *reg_data = user_data;
547
548         DBG("");
549
550         if (result == 0)
551                 apply_p2p_listen_on_iface(wifi, NULL);
552
553         if (reg_data->callback)
554                 reg_data->callback(result, reg_data->user_data);
555
556         g_free(reg_data);
557 }
558
559 static int peer_register_service(const unsigned char *specification,
560                                 int specification_length,
561                                 const unsigned char *query,
562                                 int query_length, int version,
563                                 peer_service_registration_cb_t callback,
564                                 void *user_data)
565 {
566         struct peer_service_registration *reg_data;
567         GSupplicantP2PServiceParams *params;
568         bool found = false;
569         int ret, ret_f;
570         GList *list;
571
572         DBG("");
573
574         if (specification && !version && !query &&
575                         is_service_wfd(specification, specification_length)) {
576                 return peer_register_wfd_service(specification,
577                                 specification_length, callback, user_data);
578         }
579
580         reg_data = g_try_malloc0(sizeof(*reg_data));
581         if (!reg_data)
582                 return -ENOMEM;
583
584         reg_data->callback = callback;
585         reg_data->user_data = user_data;
586
587         ret_f = -EOPNOTSUPP;
588
589         for (list = iface_list; list; list = list->next) {
590                 struct wifi_data *wifi = list->data;
591                 GSupplicantInterface *iface = wifi->interface;
592
593                 if (!g_supplicant_interface_has_p2p(iface))
594                         continue;
595
596                 params = fill_in_peer_service_params(specification,
597                                                 specification_length, query,
598                                                 query_length, version);
599                 if (!params) {
600                         ret = -ENOMEM;
601                         continue;
602                 }
603
604                 if (!found) {
605                         ret_f = g_supplicant_interface_p2p_add_service(iface,
606                                 register_peer_service_cb, params, reg_data);
607                         if (ret_f == 0 || ret_f == -EINPROGRESS)
608                                 found = true;
609                         ret = ret_f;
610                 } else
611                         ret = g_supplicant_interface_p2p_add_service(iface,
612                                 register_peer_service_cb, params, NULL);
613                 if (ret != 0 && ret != -EINPROGRESS)
614                         free_peer_service_params(params);
615         }
616
617         if (ret_f != 0 && ret_f != -EINPROGRESS)
618                 g_free(reg_data);
619
620         return ret_f;
621 }
622
623 static int peer_unregister_wfd_service(void)
624 {
625         GSupplicantP2PServiceParams *params;
626         GList *list;
627
628         if (!wfd_service_registered)
629                 return -EALREADY;
630
631         params = fill_in_peer_service_params(NULL, 0, NULL, 0, 0);
632         if (!params)
633                 return -ENOMEM;
634
635         wfd_service_registered = false;
636
637         g_supplicant_set_widi_ies(params, NULL, NULL);
638
639         for (list = iface_list; list; list = list->next) {
640                 struct wifi_data *wifi = list->data;
641
642                 if (!g_supplicant_interface_has_p2p(wifi->interface))
643                         continue;
644
645                 wifi->servicing--;
646                 if (!wifi->servicing || wifi->servicing < 0) {
647                         g_supplicant_interface_p2p_listen(wifi->interface,
648                                                                         0, 0);
649                         wifi->servicing = 0;
650                 }
651         }
652
653         return 0;
654 }
655
656 static int peer_unregister_service(const unsigned char *specification,
657                                                 int specification_length,
658                                                 const unsigned char *query,
659                                                 int query_length, int version)
660 {
661         GSupplicantP2PServiceParams *params;
662         bool wfd = false;
663         GList *list;
664         int ret;
665
666         if (specification && !version && !query &&
667                         is_service_wfd(specification, specification_length)) {
668                 ret = peer_unregister_wfd_service();
669                 if (ret != 0 && ret != -EINPROGRESS)
670                         return ret;
671                 wfd = true;
672         }
673
674         for (list = iface_list; list; list = list->next) {
675                 struct wifi_data *wifi = list->data;
676                 GSupplicantInterface *iface = wifi->interface;
677
678                 if (wfd)
679                         goto stop_listening;
680
681                 if (!g_supplicant_interface_has_p2p(iface))
682                         continue;
683
684                 params = fill_in_peer_service_params(specification,
685                                                 specification_length, query,
686                                                 query_length, version);
687                 if (!params) {
688                         ret = -ENOMEM;
689                         continue;
690                 }
691
692                 ret = g_supplicant_interface_p2p_del_service(iface, params);
693                 if (ret != 0 && ret != -EINPROGRESS)
694                         free_peer_service_params(params);
695 stop_listening:
696                 wifi->servicing--;
697                 if (!wifi->servicing || wifi->servicing < 0) {
698                         g_supplicant_interface_p2p_listen(iface, 0, 0);
699                         wifi->servicing = 0;
700                 }
701         }
702
703         return 0;
704 }
705
706 static struct connman_peer_driver peer_driver = {
707         .connect    = peer_connect,
708         .disconnect = peer_disconnect,
709         .register_service = peer_register_service,
710         .unregister_service = peer_unregister_service,
711 };
712
713 static void handle_tethering(struct wifi_data *wifi)
714 {
715         if (!wifi->tethering)
716                 return;
717
718         if (!wifi->bridge)
719                 return;
720
721         if (wifi->bridged)
722                 return;
723
724         DBG("index %d bridge %s", wifi->index, wifi->bridge);
725
726         if (connman_inet_add_to_bridge(wifi->index, wifi->bridge) < 0)
727                 return;
728
729         wifi->bridged = true;
730 }
731
732 static void wifi_newlink(unsigned flags, unsigned change, void *user_data)
733 {
734         struct connman_device *device = user_data;
735         struct wifi_data *wifi = connman_device_get_data(device);
736
737         if (!wifi)
738                 return;
739
740         DBG("index %d flags %d change %d", wifi->index, flags, change);
741
742         if ((wifi->flags & IFF_UP) != (flags & IFF_UP)) {
743                 if (flags & IFF_UP)
744                         DBG("interface up");
745                 else
746                         DBG("interface down");
747         }
748
749         if ((wifi->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
750                 if (flags & IFF_LOWER_UP) {
751                         DBG("carrier on");
752
753                         handle_tethering(wifi);
754                 } else
755                         DBG("carrier off");
756         }
757
758         wifi->flags = flags;
759 }
760
761 static int wifi_probe(struct connman_device *device)
762 {
763         struct wifi_data *wifi;
764
765         DBG("device %p", device);
766
767         wifi = g_try_new0(struct wifi_data, 1);
768         if (!wifi)
769                 return -ENOMEM;
770
771         wifi->state = G_SUPPLICANT_STATE_INACTIVE;
772         wifi->ap_supported = WIFI_AP_UNKNOWN;
773         wifi->tethering_param = NULL;
774
775         connman_device_set_data(device, wifi);
776         wifi->device = connman_device_ref(device);
777
778         wifi->index = connman_device_get_index(device);
779         wifi->flags = 0;
780
781         wifi->watch = connman_rtnl_add_newlink_watch(wifi->index,
782                                                         wifi_newlink, device);
783         if (is_p2p_connecting())
784                 add_pending_wifi_device(wifi);
785         else
786                 iface_list = g_list_append(iface_list, wifi);
787
788         return 0;
789 }
790
791 static void remove_networks(struct connman_device *device,
792                                 struct wifi_data *wifi)
793 {
794         GSList *list;
795
796         for (list = wifi->networks; list; list = list->next) {
797                 struct connman_network *network = list->data;
798
799                 connman_device_remove_network(device, network);
800                 connman_network_unref(network);
801         }
802
803         g_slist_free(wifi->networks);
804         wifi->networks = NULL;
805 }
806
807 static void remove_peers(struct wifi_data *wifi)
808 {
809         GSList *list;
810
811         for (list = wifi->peers; list; list = list->next) {
812                 struct connman_peer *peer = list->data;
813
814                 connman_peer_unregister(peer);
815                 connman_peer_unref(peer);
816         }
817
818         g_slist_free(wifi->peers);
819         wifi->peers = NULL;
820 }
821
822 static void reset_autoscan(struct connman_device *device)
823 {
824         struct wifi_data *wifi = connman_device_get_data(device);
825         struct autoscan_params *autoscan;
826
827         DBG("");
828
829         if (!wifi || !wifi->autoscan)
830                 return;
831
832         autoscan = wifi->autoscan;
833
834         if (autoscan->timeout == 0 && autoscan->interval == 0)
835                 return;
836
837         g_source_remove(autoscan->timeout);
838
839         autoscan->timeout = 0;
840         autoscan->interval = 0;
841
842         connman_device_unref(device);
843 }
844
845 static void stop_autoscan(struct connman_device *device)
846 {
847         const struct wifi_data *wifi = connman_device_get_data(device);
848
849         if (!wifi || !wifi->autoscan)
850                 return;
851
852         reset_autoscan(device);
853
854         connman_device_set_scanning(device, CONNMAN_SERVICE_TYPE_WIFI, false);
855 }
856
857 static void check_p2p_technology(void)
858 {
859         bool p2p_exists = false;
860         GList *list;
861
862         for (list = iface_list; list; list = list->next) {
863                 struct wifi_data *w = list->data;
864
865                 if (w->interface &&
866                                 g_supplicant_interface_has_p2p(w->interface))
867                         p2p_exists = true;
868         }
869
870         if (!p2p_exists) {
871                 connman_technology_driver_unregister(&p2p_tech_driver);
872                 connman_peer_driver_unregister(&peer_driver);
873         }
874 }
875
876 static void wifi_remove(struct connman_device *device)
877 {
878         struct wifi_data *wifi = connman_device_get_data(device);
879
880         DBG("device %p wifi %p", device, wifi);
881
882         if (!wifi)
883                 return;
884
885         stop_autoscan(device);
886
887         if (wifi->p2p_device)
888                 p2p_iface_list = g_list_remove(p2p_iface_list, wifi);
889         else
890                 iface_list = g_list_remove(iface_list, wifi);
891
892         check_p2p_technology();
893
894         remove_pending_wifi_device(wifi);
895
896         if (wifi->p2p_find_timeout) {
897                 g_source_remove(wifi->p2p_find_timeout);
898                 connman_device_unref(wifi->device);
899         }
900
901         if (wifi->p2p_connection_timeout)
902                 g_source_remove(wifi->p2p_connection_timeout);
903
904         remove_networks(device, wifi);
905         remove_peers(wifi);
906
907         connman_device_set_powered(device, false);
908         connman_device_set_data(device, NULL);
909         connman_device_unref(wifi->device);
910         connman_rtnl_remove_watch(wifi->watch);
911
912         g_supplicant_interface_set_data(wifi->interface, NULL);
913
914         g_supplicant_interface_cancel(wifi->interface);
915
916         if (wifi->scan_params)
917                 g_supplicant_free_scan_params(wifi->scan_params);
918
919         g_free(wifi->autoscan);
920         g_free(wifi->identifier);
921         g_free(wifi);
922 }
923
924 static bool is_duplicate(GSList *list, gchar *ssid, int ssid_len)
925 {
926         GSList *iter;
927
928         for (iter = list; iter; iter = g_slist_next(iter)) {
929                 struct scan_ssid *scan_ssid = iter->data;
930
931                 if (ssid_len == scan_ssid->ssid_len &&
932                                 memcmp(ssid, scan_ssid->ssid, ssid_len) == 0)
933                         return true;
934         }
935
936         return false;
937 }
938
939 static int add_scan_param(gchar *hex_ssid, char *raw_ssid, int ssid_len,
940                         int freq, GSupplicantScanParams *scan_data,
941                         int driver_max_scan_ssids, char *ssid_name)
942 {
943         unsigned int i;
944         struct scan_ssid *scan_ssid;
945
946         if ((driver_max_scan_ssids == 0 ||
947                         driver_max_scan_ssids > scan_data->num_ssids) &&
948                         (hex_ssid || raw_ssid)) {
949                 gchar *ssid;
950                 unsigned int j = 0, hex;
951
952                 if (hex_ssid) {
953                         size_t hex_ssid_len = strlen(hex_ssid);
954
955                         ssid = g_try_malloc0(hex_ssid_len / 2);
956                         if (!ssid)
957                                 return -ENOMEM;
958
959                         for (i = 0; i < hex_ssid_len; i += 2) {
960                                 sscanf(hex_ssid + i, "%02x", &hex);
961                                 ssid[j++] = hex;
962                         }
963                 } else {
964                         ssid = raw_ssid;
965                         j = ssid_len;
966                 }
967
968                 /*
969                  * If we have already added hidden AP to the list,
970                  * then do not do it again. This might happen if you have
971                  * used or are using multiple wifi cards, so in that case
972                  * you might have multiple service files for same AP.
973                  */
974                 if (is_duplicate(scan_data->ssids, ssid, j)) {
975                         if (hex_ssid)
976                                 g_free(ssid);
977                         return 0;
978                 }
979
980                 scan_ssid = g_try_new(struct scan_ssid, 1);
981                 if (!scan_ssid) {
982                         if (hex_ssid)
983                                 g_free(ssid);
984                         return -ENOMEM;
985                 }
986
987                 memcpy(scan_ssid->ssid, ssid, j);
988                 scan_ssid->ssid_len = j;
989                 scan_data->ssids = g_slist_prepend(scan_data->ssids,
990                                                                 scan_ssid);
991
992                 scan_data->num_ssids++;
993
994                 DBG("SSID %s added to scanned list of %d entries", ssid_name,
995                                                         scan_data->num_ssids);
996
997                 if (hex_ssid)
998                         g_free(ssid);
999         } else
1000                 return -EINVAL;
1001
1002         scan_data->ssids = g_slist_reverse(scan_data->ssids);
1003
1004         if (!scan_data->freqs) {
1005                 scan_data->freqs = g_try_malloc0(sizeof(uint16_t));
1006                 if (!scan_data->freqs) {
1007                         g_slist_free_full(scan_data->ssids, g_free);
1008                         return -ENOMEM;
1009                 }
1010
1011                 scan_data->num_freqs = 1;
1012                 scan_data->freqs[0] = freq;
1013         } else {
1014                 bool duplicate = false;
1015
1016                 /* Don't add duplicate entries */
1017                 for (i = 0; i < scan_data->num_freqs; i++) {
1018                         if (scan_data->freqs[i] == freq) {
1019                                 duplicate = true;
1020                                 break;
1021                         }
1022                 }
1023
1024                 if (!duplicate) {
1025                         scan_data->num_freqs++;
1026                         scan_data->freqs = g_try_realloc(scan_data->freqs,
1027                                 sizeof(uint16_t) * scan_data->num_freqs);
1028                         if (!scan_data->freqs) {
1029                                 g_slist_free_full(scan_data->ssids, g_free);
1030                                 return -ENOMEM;
1031                         }
1032                         scan_data->freqs[scan_data->num_freqs - 1] = freq;
1033                 }
1034         }
1035
1036         return 1;
1037 }
1038
1039 static int get_hidden_connections(GSupplicantScanParams *scan_data)
1040 {
1041         struct connman_config_entry **entries;
1042         GKeyFile *keyfile;
1043         gchar **services;
1044         char *ssid, *name;
1045         int i, ret;
1046         bool value;
1047         int num_ssids = 0, add_param_failed = 0;
1048
1049         services = connman_storage_get_services();
1050         for (i = 0; services && services[i]; i++) {
1051                 if (strncmp(services[i], "wifi_", 5) != 0)
1052                         continue;
1053
1054                 keyfile = connman_storage_load_service(services[i]);
1055                 if (!keyfile)
1056                         continue;
1057
1058                 value = g_key_file_get_boolean(keyfile,
1059                                         services[i], "Hidden", NULL);
1060                 if (!value) {
1061                         g_key_file_free(keyfile);
1062                         continue;
1063                 }
1064
1065                 value = g_key_file_get_boolean(keyfile,
1066                                         services[i], "Favorite", NULL);
1067                 if (!value) {
1068                         g_key_file_free(keyfile);
1069                         continue;
1070                 }
1071
1072                 ssid = g_key_file_get_string(keyfile,
1073                                         services[i], "SSID", NULL);
1074
1075                 name = g_key_file_get_string(keyfile, services[i], "Name",
1076                                                                 NULL);
1077
1078                 ret = add_scan_param(ssid, NULL, 0, 0, scan_data, 0, name);
1079                 if (ret < 0)
1080                         add_param_failed++;
1081                 else if (ret > 0)
1082                         num_ssids++;
1083
1084                 g_free(ssid);
1085                 g_free(name);
1086                 g_key_file_free(keyfile);
1087         }
1088
1089         /*
1090          * Check if there are any hidden AP that needs to be provisioned.
1091          */
1092         entries = connman_config_get_entries("wifi");
1093         for (i = 0; entries && entries[i]; i++) {
1094                 int len;
1095
1096                 if (!entries[i]->hidden)
1097                         continue;
1098
1099                 if (!entries[i]->ssid) {
1100                         ssid = entries[i]->name;
1101                         len = strlen(ssid);
1102                 } else {
1103                         ssid = entries[i]->ssid;
1104                         len = entries[i]->ssid_len;
1105                 }
1106
1107                 if (!ssid)
1108                         continue;
1109
1110                 ret = add_scan_param(NULL, ssid, len, 0, scan_data, 0, ssid);
1111                 if (ret < 0)
1112                         add_param_failed++;
1113                 else if (ret > 0)
1114                         num_ssids++;
1115         }
1116
1117         connman_config_free_entries(entries);
1118
1119         if (add_param_failed > 0)
1120                 DBG("Unable to scan %d out of %d SSIDs",
1121                                         add_param_failed, num_ssids);
1122
1123         g_strfreev(services);
1124
1125         return num_ssids;
1126 }
1127
1128 static int get_hidden_connections_params(struct wifi_data *wifi,
1129                                         GSupplicantScanParams *scan_params)
1130 {
1131         int driver_max_ssids, i;
1132         GSupplicantScanParams *orig_params;
1133
1134         /*
1135          * Scan hidden networks so that we can autoconnect to them.
1136          * We will assume 1 as a default number of ssid to scan.
1137          */
1138         driver_max_ssids = g_supplicant_interface_get_max_scan_ssids(
1139                                                         wifi->interface);
1140         if (driver_max_ssids == 0)
1141                 driver_max_ssids = 1;
1142
1143         DBG("max ssids %d", driver_max_ssids);
1144
1145         if (!wifi->scan_params) {
1146                 wifi->scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
1147                 if (!wifi->scan_params)
1148                         return 0;
1149
1150                 if (get_hidden_connections(wifi->scan_params) == 0) {
1151                         g_supplicant_free_scan_params(wifi->scan_params);
1152                         wifi->scan_params = NULL;
1153
1154                         return 0;
1155                 }
1156         }
1157
1158         orig_params = wifi->scan_params;
1159
1160         /* Let's transfer driver_max_ssids params */
1161         for (i = 0; i < driver_max_ssids; i++) {
1162                 struct scan_ssid *ssid;
1163
1164                 if (!wifi->scan_params->ssids)
1165                         break;
1166
1167                 ssid = orig_params->ssids->data;
1168                 orig_params->ssids = g_slist_remove(orig_params->ssids, ssid);
1169                 scan_params->ssids = g_slist_prepend(scan_params->ssids, ssid);
1170         }
1171
1172         if (i > 0) {
1173                 scan_params->num_ssids = i;
1174                 scan_params->ssids = g_slist_reverse(scan_params->ssids);
1175
1176                 scan_params->freqs = g_memdup(orig_params->freqs,
1177                                 sizeof(uint16_t) * orig_params->num_freqs);
1178                 if (!scan_params->freqs)
1179                         goto err;
1180
1181                 scan_params->num_freqs = orig_params->num_freqs;
1182
1183         } else
1184                 goto err;
1185
1186         orig_params->num_ssids -= scan_params->num_ssids;
1187
1188         return scan_params->num_ssids;
1189
1190 err:
1191         g_slist_free_full(scan_params->ssids, g_free);
1192         g_supplicant_free_scan_params(wifi->scan_params);
1193         wifi->scan_params = NULL;
1194
1195         return 0;
1196 }
1197
1198 static int throw_wifi_scan(struct connman_device *device,
1199                         GSupplicantInterfaceCallback callback)
1200 {
1201         struct wifi_data *wifi = connman_device_get_data(device);
1202         int ret;
1203
1204         if (!wifi)
1205                 return -ENODEV;
1206
1207         DBG("device %p %p", device, wifi->interface);
1208
1209         if (wifi->tethering)
1210                 return -EBUSY;
1211
1212         if (connman_device_get_scanning(device))
1213                 return -EALREADY;
1214
1215         connman_device_ref(device);
1216
1217         ret = g_supplicant_interface_scan(wifi->interface, NULL,
1218                                                 callback, device);
1219         if (ret == 0) {
1220                 connman_device_set_scanning(device,
1221                                 CONNMAN_SERVICE_TYPE_WIFI, true);
1222         } else
1223                 connman_device_unref(device);
1224
1225         return ret;
1226 }
1227
1228 static void hidden_free(struct hidden_params *hidden)
1229 {
1230         if (!hidden)
1231                 return;
1232
1233         if (hidden->scan_params)
1234                 g_supplicant_free_scan_params(hidden->scan_params);
1235         g_free(hidden->identity);
1236         g_free(hidden->passphrase);
1237         g_free(hidden->security);
1238         g_free(hidden);
1239 }
1240
1241 static void scan_callback(int result, GSupplicantInterface *interface,
1242                                                 void *user_data)
1243 {
1244         struct connman_device *device = user_data;
1245         struct wifi_data *wifi = connman_device_get_data(device);
1246         bool scanning;
1247
1248         DBG("result %d wifi %p", result, wifi);
1249
1250         if (wifi) {
1251                 if (wifi->hidden && !wifi->postpone_hidden) {
1252                         connman_network_clear_hidden(wifi->hidden->user_data);
1253                         hidden_free(wifi->hidden);
1254                         wifi->hidden = NULL;
1255                 }
1256
1257                 if (wifi->scan_params) {
1258                         g_supplicant_free_scan_params(wifi->scan_params);
1259                         wifi->scan_params = NULL;
1260                 }
1261         }
1262
1263         if (result < 0)
1264                 connman_device_reset_scanning(device);
1265
1266         /* User is connecting to a hidden AP, let's wait for finished event */
1267         if (wifi && wifi->hidden && wifi->postpone_hidden) {
1268                 GSupplicantScanParams *scan_params;
1269                 int ret;
1270
1271                 wifi->postpone_hidden = false;
1272                 scan_params = wifi->hidden->scan_params;
1273                 wifi->hidden->scan_params = NULL;
1274
1275                 reset_autoscan(device);
1276
1277                 ret = g_supplicant_interface_scan(wifi->interface, scan_params,
1278                                                         scan_callback, device);
1279                 if (ret == 0)
1280                         return;
1281
1282                 /* On error, let's recall scan_callback, which will cleanup */
1283                 return scan_callback(ret, interface, user_data);
1284         }
1285
1286         scanning = connman_device_get_scanning(device);
1287
1288         if (scanning) {
1289                 connman_device_set_scanning(device,
1290                                 CONNMAN_SERVICE_TYPE_WIFI, false);
1291         }
1292
1293         if (result != -ENOLINK)
1294                 start_autoscan(device);
1295
1296         /*
1297          * If we are here then we were scanning; however, if we are
1298          * also mid-flight disabling the interface, then wifi_disable
1299          * has already cleared the device scanning state and
1300          * unreferenced the device, obviating the need to do it here.
1301          */
1302
1303         if (scanning)
1304                 connman_device_unref(device);
1305 }
1306
1307 static void scan_callback_hidden(int result,
1308                         GSupplicantInterface *interface, void *user_data)
1309 {
1310         struct connman_device *device = user_data;
1311         struct wifi_data *wifi = connman_device_get_data(device);
1312         GSupplicantScanParams *scan_params;
1313         int ret;
1314
1315         DBG("result %d wifi %p", result, wifi);
1316
1317         if (!wifi)
1318                 goto out;
1319
1320         /* User is trying to connect to a hidden AP */
1321         if (wifi->hidden && wifi->postpone_hidden)
1322                 goto out;
1323
1324         scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
1325         if (!scan_params)
1326                 goto out;
1327
1328         if (get_hidden_connections_params(wifi, scan_params) > 0) {
1329                 ret = g_supplicant_interface_scan(wifi->interface,
1330                                                         scan_params,
1331                                                         scan_callback_hidden,
1332                                                         device);
1333                 if (ret == 0)
1334                         return;
1335         }
1336
1337         g_supplicant_free_scan_params(scan_params);
1338
1339 out:
1340         scan_callback(result, interface, user_data);
1341 }
1342
1343 static gboolean autoscan_timeout(gpointer data)
1344 {
1345         struct connman_device *device = data;
1346         struct wifi_data *wifi = connman_device_get_data(device);
1347         struct autoscan_params *autoscan;
1348         int interval;
1349
1350         if (!wifi)
1351                 return FALSE;
1352
1353         autoscan = wifi->autoscan;
1354
1355         if (autoscan->interval <= 0) {
1356                 interval = autoscan->base;
1357                 goto set_interval;
1358         } else
1359                 interval = autoscan->interval * autoscan->base;
1360
1361         if (interval > autoscan->limit)
1362                 interval = autoscan->limit;
1363
1364         throw_wifi_scan(wifi->device, scan_callback_hidden);
1365
1366 set_interval:
1367         DBG("interval %d", interval);
1368
1369         autoscan->interval = interval;
1370
1371         autoscan->timeout = g_timeout_add_seconds(interval,
1372                                                 autoscan_timeout, device);
1373
1374         return FALSE;
1375 }
1376
1377 static void start_autoscan(struct connman_device *device)
1378 {
1379         struct wifi_data *wifi = connman_device_get_data(device);
1380         struct autoscan_params *autoscan;
1381
1382         DBG("");
1383
1384         if (!wifi)
1385                 return;
1386
1387         if (wifi->p2p_device)
1388                 return;
1389
1390         if (wifi->connected)
1391                 return;
1392
1393         autoscan = wifi->autoscan;
1394         if (!autoscan)
1395                 return;
1396
1397         if (autoscan->timeout > 0 || autoscan->interval > 0)
1398                 return;
1399
1400         connman_device_ref(device);
1401
1402         autoscan_timeout(device);
1403 }
1404
1405 static struct autoscan_params *parse_autoscan_params(const char *params)
1406 {
1407         struct autoscan_params *autoscan;
1408         char **list_params;
1409         int limit;
1410         int base;
1411
1412         DBG("Emulating autoscan");
1413
1414         list_params = g_strsplit(params, ":", 0);
1415         if (list_params == 0)
1416                 return NULL;
1417
1418         if (g_strv_length(list_params) < 3) {
1419                 g_strfreev(list_params);
1420                 return NULL;
1421         }
1422
1423         base = atoi(list_params[1]);
1424         limit = atoi(list_params[2]);
1425
1426         g_strfreev(list_params);
1427
1428         autoscan = g_try_malloc0(sizeof(struct autoscan_params));
1429         if (!autoscan) {
1430                 DBG("Could not allocate memory for autoscan");
1431                 return NULL;
1432         }
1433
1434         DBG("base %d - limit %d", base, limit);
1435         autoscan->base = base;
1436         autoscan->limit = limit;
1437
1438         return autoscan;
1439 }
1440
1441 static void setup_autoscan(struct wifi_data *wifi)
1442 {
1443         if (!wifi->autoscan)
1444                 wifi->autoscan = parse_autoscan_params(AUTOSCAN_DEFAULT);
1445
1446         start_autoscan(wifi->device);
1447 }
1448
1449 static void finalize_interface_creation(struct wifi_data *wifi)
1450 {
1451         DBG("interface is ready wifi %p tethering %d", wifi, wifi->tethering);
1452
1453         if (!wifi->device) {
1454                 connman_error("WiFi device not set");
1455                 return;
1456         }
1457
1458         connman_device_set_powered(wifi->device, true);
1459
1460         if (!connman_setting_get_bool("BackgroundScanning"))
1461                 return;
1462
1463         if (wifi->p2p_device)
1464                 return;
1465
1466         setup_autoscan(wifi);
1467 }
1468
1469 static void interface_create_callback(int result,
1470                                         GSupplicantInterface *interface,
1471                                                         void *user_data)
1472 {
1473         struct wifi_data *wifi = user_data;
1474
1475         DBG("result %d ifname %s, wifi %p", result,
1476                                 g_supplicant_interface_get_ifname(interface),
1477                                 wifi);
1478
1479         if (result < 0 || !wifi)
1480                 return;
1481
1482         wifi->interface = interface;
1483         g_supplicant_interface_set_data(interface, wifi);
1484
1485         if (g_supplicant_interface_get_ready(interface)) {
1486                 wifi->interface_ready = true;
1487                 finalize_interface_creation(wifi);
1488         }
1489 }
1490
1491 static int wifi_enable(struct connman_device *device)
1492 {
1493         struct wifi_data *wifi = connman_device_get_data(device);
1494         int index;
1495         char *interface;
1496         const char *driver = connman_option_get_string("wifi");
1497         int ret;
1498
1499         DBG("device %p %p", device, wifi);
1500
1501         index = connman_device_get_index(device);
1502         if (!wifi || index < 0)
1503                 return -ENODEV;
1504
1505         if (is_p2p_connecting())
1506                 return -EINPROGRESS;
1507
1508         interface = connman_inet_ifname(index);
1509         ret = g_supplicant_interface_create(interface, driver, NULL,
1510                                                 interface_create_callback,
1511                                                         wifi);
1512         g_free(interface);
1513
1514         if (ret < 0)
1515                 return ret;
1516
1517         return -EINPROGRESS;
1518 }
1519
1520 static int wifi_disable(struct connman_device *device)
1521 {
1522         struct wifi_data *wifi = connman_device_get_data(device);
1523         int ret;
1524
1525         DBG("device %p wifi %p", device, wifi);
1526
1527         if (!wifi)
1528                 return -ENODEV;
1529
1530         wifi->connected = false;
1531         wifi->disconnecting = false;
1532
1533         if (wifi->pending_network)
1534                 wifi->pending_network = NULL;
1535
1536         stop_autoscan(device);
1537
1538         if (wifi->p2p_find_timeout) {
1539                 g_source_remove(wifi->p2p_find_timeout);
1540                 wifi->p2p_find_timeout = 0;
1541                 connman_device_set_scanning(device, CONNMAN_SERVICE_TYPE_P2P, false);
1542                 connman_device_unref(wifi->device);
1543         }
1544
1545         /* In case of a user scan, device is still referenced */
1546         if (connman_device_get_scanning(device)) {
1547                 connman_device_set_scanning(device,
1548                                 CONNMAN_SERVICE_TYPE_WIFI, false);
1549                 connman_device_unref(wifi->device);
1550         }
1551
1552         remove_networks(device, wifi);
1553         remove_peers(wifi);
1554
1555         ret = g_supplicant_interface_remove(wifi->interface, NULL, NULL);
1556         if (ret < 0)
1557                 return ret;
1558
1559         return -EINPROGRESS;
1560 }
1561
1562 struct last_connected {
1563         GTimeVal modified;
1564         gchar *ssid;
1565         int freq;
1566 };
1567
1568 static gint sort_entry(gconstpointer a, gconstpointer b, gpointer user_data)
1569 {
1570         GTimeVal *aval = (GTimeVal *)a;
1571         GTimeVal *bval = (GTimeVal *)b;
1572
1573         /* Note that the sort order is descending */
1574         if (aval->tv_sec < bval->tv_sec)
1575                 return 1;
1576
1577         if (aval->tv_sec > bval->tv_sec)
1578                 return -1;
1579
1580         return 0;
1581 }
1582
1583 static void free_entry(gpointer data)
1584 {
1585         struct last_connected *entry = data;
1586
1587         g_free(entry->ssid);
1588         g_free(entry);
1589 }
1590
1591 static int get_latest_connections(int max_ssids,
1592                                 GSupplicantScanParams *scan_data)
1593 {
1594         GSequenceIter *iter;
1595         GSequence *latest_list;
1596         struct last_connected *entry;
1597         GKeyFile *keyfile;
1598         GTimeVal modified;
1599         gchar **services;
1600         gchar *str;
1601         char *ssid;
1602         int i, freq;
1603         int num_ssids = 0;
1604
1605         latest_list = g_sequence_new(free_entry);
1606         if (!latest_list)
1607                 return -ENOMEM;
1608
1609         services = connman_storage_get_services();
1610         for (i = 0; services && services[i]; i++) {
1611                 if (strncmp(services[i], "wifi_", 5) != 0)
1612                         continue;
1613
1614                 keyfile = connman_storage_load_service(services[i]);
1615                 if (!keyfile)
1616                         continue;
1617
1618                 str = g_key_file_get_string(keyfile,
1619                                         services[i], "Favorite", NULL);
1620                 if (!str || g_strcmp0(str, "true")) {
1621                         g_free(str);
1622                         g_key_file_free(keyfile);
1623                         continue;
1624                 }
1625                 g_free(str);
1626
1627                 str = g_key_file_get_string(keyfile,
1628                                         services[i], "AutoConnect", NULL);
1629                 if (!str || g_strcmp0(str, "true")) {
1630                         g_free(str);
1631                         g_key_file_free(keyfile);
1632                         continue;
1633                 }
1634                 g_free(str);
1635
1636                 str = g_key_file_get_string(keyfile,
1637                                         services[i], "Modified", NULL);
1638                 if (!str) {
1639                         g_key_file_free(keyfile);
1640                         continue;
1641                 }
1642                 g_time_val_from_iso8601(str, &modified);
1643                 g_free(str);
1644
1645                 ssid = g_key_file_get_string(keyfile,
1646                                         services[i], "SSID", NULL);
1647
1648                 freq = g_key_file_get_integer(keyfile, services[i],
1649                                         "Frequency", NULL);
1650                 if (freq) {
1651                         entry = g_try_new(struct last_connected, 1);
1652                         if (!entry) {
1653                                 g_sequence_free(latest_list);
1654                                 g_key_file_free(keyfile);
1655                                 g_free(ssid);
1656                                 return -ENOMEM;
1657                         }
1658
1659                         entry->ssid = ssid;
1660                         entry->modified = modified;
1661                         entry->freq = freq;
1662
1663                         g_sequence_insert_sorted(latest_list, entry,
1664                                                 sort_entry, NULL);
1665                         num_ssids++;
1666                 } else
1667                         g_free(ssid);
1668
1669                 g_key_file_free(keyfile);
1670         }
1671
1672         g_strfreev(services);
1673
1674         num_ssids = num_ssids > max_ssids ? max_ssids : num_ssids;
1675
1676         iter = g_sequence_get_begin_iter(latest_list);
1677
1678         for (i = 0; i < num_ssids; i++) {
1679                 entry = g_sequence_get(iter);
1680
1681                 DBG("ssid %s freq %d modified %lu", entry->ssid, entry->freq,
1682                                                 entry->modified.tv_sec);
1683
1684                 add_scan_param(entry->ssid, NULL, 0, entry->freq, scan_data,
1685                                                 max_ssids, entry->ssid);
1686
1687                 iter = g_sequence_iter_next(iter);
1688         }
1689
1690         g_sequence_free(latest_list);
1691         return num_ssids;
1692 }
1693
1694 static int wifi_scan_simple(struct connman_device *device)
1695 {
1696         reset_autoscan(device);
1697
1698         return throw_wifi_scan(device, scan_callback_hidden);
1699 }
1700
1701 static gboolean p2p_find_stop(gpointer data)
1702 {
1703         struct connman_device *device = data;
1704         struct wifi_data *wifi = connman_device_get_data(device);
1705
1706         DBG("");
1707
1708         if (wifi) {
1709                 wifi->p2p_find_timeout = 0;
1710
1711                 g_supplicant_interface_p2p_stop_find(wifi->interface);
1712         }
1713
1714         connman_device_set_scanning(device, CONNMAN_SERVICE_TYPE_P2P, false);
1715
1716         connman_device_unref(device);
1717         reset_autoscan(device);
1718
1719         return FALSE;
1720 }
1721
1722 static void p2p_find_callback(int result, GSupplicantInterface *interface,
1723                                                         void *user_data)
1724 {
1725         struct connman_device *device = user_data;
1726         struct wifi_data *wifi = connman_device_get_data(device);
1727
1728         DBG("result %d wifi %p", result, wifi);
1729
1730         if (!wifi)
1731                 goto error;
1732
1733         if (wifi->p2p_find_timeout) {
1734                 g_source_remove(wifi->p2p_find_timeout);
1735                 wifi->p2p_find_timeout = 0;
1736         }
1737
1738         if (result)
1739                 goto error;
1740
1741         wifi->p2p_find_timeout = g_timeout_add_seconds(P2P_FIND_TIMEOUT,
1742                                                         p2p_find_stop, device);
1743         if (!wifi->p2p_find_timeout)
1744                 goto error;
1745
1746         return;
1747 error:
1748         p2p_find_stop(device);
1749 }
1750
1751 static int p2p_find(struct connman_device *device)
1752 {
1753         struct wifi_data *wifi;
1754         int ret;
1755
1756         DBG("");
1757
1758         if (!p2p_technology)
1759                 return -ENOTSUP;
1760
1761         wifi = connman_device_get_data(device);
1762
1763         if (g_supplicant_interface_is_p2p_finding(wifi->interface))
1764                 return -EALREADY;
1765
1766         reset_autoscan(device);
1767         connman_device_ref(device);
1768
1769         ret = g_supplicant_interface_p2p_find(wifi->interface,
1770                                                 p2p_find_callback, device);
1771         if (ret) {
1772                 connman_device_unref(device);
1773                 start_autoscan(device);
1774         } else {
1775                 connman_device_set_scanning(device,
1776                                 CONNMAN_SERVICE_TYPE_P2P, true);
1777         }
1778
1779         return ret;
1780 }
1781
1782 /*
1783  * Note that the hidden scan is only used when connecting to this specific
1784  * hidden AP first time. It is not used when system autoconnects to hidden AP.
1785  */
1786 static int wifi_scan(enum connman_service_type type,
1787                         struct connman_device *device,
1788                         const char *ssid, unsigned int ssid_len,
1789                         const char *identity, const char* passphrase,
1790                         const char *security, void *user_data)
1791 {
1792         struct wifi_data *wifi = connman_device_get_data(device);
1793         GSupplicantScanParams *scan_params = NULL;
1794         struct scan_ssid *scan_ssid;
1795         struct hidden_params *hidden;
1796         int ret;
1797         int driver_max_ssids = 0;
1798         bool do_hidden;
1799         bool scanning;
1800
1801         if (!wifi)
1802                 return -ENODEV;
1803
1804         if (wifi->p2p_device)
1805                 return -EBUSY;
1806
1807         if (wifi->tethering)
1808                 return -EBUSY;
1809
1810         if (type == CONNMAN_SERVICE_TYPE_P2P)
1811                 return p2p_find(device);
1812
1813         DBG("device %p wifi %p hidden ssid %s", device, wifi->interface, ssid);
1814
1815         scanning = connman_device_get_scanning(device);
1816
1817         if (!ssid || ssid_len == 0 || ssid_len > 32) {
1818                 if (scanning)
1819                         return -EALREADY;
1820
1821                 driver_max_ssids = g_supplicant_interface_get_max_scan_ssids(
1822                                                         wifi->interface);
1823                 DBG("max ssids %d", driver_max_ssids);
1824                 if (driver_max_ssids == 0)
1825                         return wifi_scan_simple(device);
1826
1827                 do_hidden = false;
1828         } else {
1829                 if (scanning && wifi->hidden && wifi->postpone_hidden)
1830                         return -EALREADY;
1831
1832                 do_hidden = true;
1833         }
1834
1835         scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
1836         if (!scan_params)
1837                 return -ENOMEM;
1838
1839         if (do_hidden) {
1840                 scan_ssid = g_try_new(struct scan_ssid, 1);
1841                 if (!scan_ssid) {
1842                         g_free(scan_params);
1843                         return -ENOMEM;
1844                 }
1845
1846                 memcpy(scan_ssid->ssid, ssid, ssid_len);
1847                 scan_ssid->ssid_len = ssid_len;
1848                 scan_params->ssids = g_slist_prepend(scan_params->ssids,
1849                                                                 scan_ssid);
1850                 scan_params->num_ssids = 1;
1851
1852                 hidden = g_try_new0(struct hidden_params, 1);
1853                 if (!hidden) {
1854                         g_supplicant_free_scan_params(scan_params);
1855                         return -ENOMEM;
1856                 }
1857
1858                 if (wifi->hidden) {
1859                         hidden_free(wifi->hidden);
1860                         wifi->hidden = NULL;
1861                 }
1862
1863                 memcpy(hidden->ssid, ssid, ssid_len);
1864                 hidden->ssid_len = ssid_len;
1865                 hidden->identity = g_strdup(identity);
1866                 hidden->passphrase = g_strdup(passphrase);
1867                 hidden->security = g_strdup(security);
1868                 hidden->user_data = user_data;
1869                 wifi->hidden = hidden;
1870
1871                 if (scanning) {
1872                         /* Let's keep this active scan for later,
1873                          * when current scan will be over. */
1874                         wifi->postpone_hidden = TRUE;
1875                         hidden->scan_params = scan_params;
1876
1877                         return 0;
1878                 }
1879         } else if (wifi->connected) {
1880                 g_supplicant_free_scan_params(scan_params);
1881                 return wifi_scan_simple(device);
1882         } else {
1883                 ret = get_latest_connections(driver_max_ssids, scan_params);
1884                 if (ret <= 0) {
1885                         g_supplicant_free_scan_params(scan_params);
1886                         return wifi_scan_simple(device);
1887                 }
1888         }
1889
1890         connman_device_ref(device);
1891
1892         reset_autoscan(device);
1893
1894         ret = g_supplicant_interface_scan(wifi->interface, scan_params,
1895                                                 scan_callback, device);
1896         if (ret == 0) {
1897                 connman_device_set_scanning(device,
1898                                 CONNMAN_SERVICE_TYPE_WIFI, true);
1899         } else {
1900                 g_supplicant_free_scan_params(scan_params);
1901                 connman_device_unref(device);
1902
1903                 if (do_hidden) {
1904                         hidden_free(wifi->hidden);
1905                         wifi->hidden = NULL;
1906                 }
1907         }
1908
1909         return ret;
1910 }
1911
1912 static void wifi_regdom_callback(int result,
1913                                         const char *alpha2,
1914                                                 void *user_data)
1915 {
1916         struct connman_device *device = user_data;
1917
1918         connman_device_regdom_notify(device, result, alpha2);
1919
1920         connman_device_unref(device);
1921 }
1922
1923 static int wifi_set_regdom(struct connman_device *device, const char *alpha2)
1924 {
1925         struct wifi_data *wifi = connman_device_get_data(device);
1926         int ret;
1927
1928         if (!wifi)
1929                 return -EINVAL;
1930
1931         connman_device_ref(device);
1932
1933         ret = g_supplicant_interface_set_country(wifi->interface,
1934                                                 wifi_regdom_callback,
1935                                                         alpha2, device);
1936         if (ret != 0)
1937                 connman_device_unref(device);
1938
1939         return ret;
1940 }
1941
1942 static struct connman_device_driver wifi_ng_driver = {
1943         .name           = "wifi",
1944         .type           = CONNMAN_DEVICE_TYPE_WIFI,
1945         .priority       = CONNMAN_DEVICE_PRIORITY_LOW,
1946         .probe          = wifi_probe,
1947         .remove         = wifi_remove,
1948         .enable         = wifi_enable,
1949         .disable        = wifi_disable,
1950         .scan           = wifi_scan,
1951         .set_regdom     = wifi_set_regdom,
1952 };
1953
1954 static void system_ready(void)
1955 {
1956         DBG("");
1957
1958         if (connman_device_driver_register(&wifi_ng_driver) < 0)
1959                 connman_error("Failed to register WiFi driver");
1960 }
1961
1962 static void system_killed(void)
1963 {
1964         DBG("");
1965
1966         connman_device_driver_unregister(&wifi_ng_driver);
1967 }
1968
1969 static int network_probe(struct connman_network *network)
1970 {
1971         DBG("network %p", network);
1972
1973         return 0;
1974 }
1975
1976 static void network_remove(struct connman_network *network)
1977 {
1978         struct connman_device *device = connman_network_get_device(network);
1979         struct wifi_data *wifi;
1980
1981         DBG("network %p", network);
1982
1983         wifi = connman_device_get_data(device);
1984         if (!wifi)
1985                 return;
1986
1987         if (wifi->network != network)
1988                 return;
1989
1990         wifi->network = NULL;
1991 }
1992
1993 static void connect_callback(int result, GSupplicantInterface *interface,
1994                                                         void *user_data)
1995 {
1996         struct connman_network *network = user_data;
1997
1998         DBG("network %p result %d", network, result);
1999
2000         if (result == -ENOKEY) {
2001                 connman_network_set_error(network,
2002                                         CONNMAN_NETWORK_ERROR_INVALID_KEY);
2003         } else if (result < 0) {
2004                 connman_network_set_error(network,
2005                                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
2006         }
2007
2008         connman_network_unref(network);
2009 }
2010
2011 static GSupplicantSecurity network_security(const char *security)
2012 {
2013         if (g_str_equal(security, "none"))
2014                 return G_SUPPLICANT_SECURITY_NONE;
2015         else if (g_str_equal(security, "wep"))
2016                 return G_SUPPLICANT_SECURITY_WEP;
2017         else if (g_str_equal(security, "psk"))
2018                 return G_SUPPLICANT_SECURITY_PSK;
2019         else if (g_str_equal(security, "wpa"))
2020                 return G_SUPPLICANT_SECURITY_PSK;
2021         else if (g_str_equal(security, "rsn"))
2022                 return G_SUPPLICANT_SECURITY_PSK;
2023         else if (g_str_equal(security, "ieee8021x"))
2024                 return G_SUPPLICANT_SECURITY_IEEE8021X;
2025
2026         return G_SUPPLICANT_SECURITY_UNKNOWN;
2027 }
2028
2029 static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network)
2030 {
2031         const char *security;
2032
2033         memset(ssid, 0, sizeof(*ssid));
2034         ssid->mode = G_SUPPLICANT_MODE_INFRA;
2035         ssid->ssid = connman_network_get_blob(network, "WiFi.SSID",
2036                                                 &ssid->ssid_len);
2037         ssid->scan_ssid = 1;
2038         security = connman_network_get_string(network, "WiFi.Security");
2039         ssid->security = network_security(security);
2040         ssid->passphrase = connman_network_get_string(network,
2041                                                 "WiFi.Passphrase");
2042
2043         ssid->eap = connman_network_get_string(network, "WiFi.EAP");
2044
2045         /*
2046          * If our private key password is unset,
2047          * we use the supplied passphrase. That is needed
2048          * for PEAP where 2 passphrases (identity and client
2049          * cert may have to be provided.
2050          */
2051         if (!connman_network_get_string(network, "WiFi.PrivateKeyPassphrase"))
2052                 connman_network_set_string(network,
2053                                                 "WiFi.PrivateKeyPassphrase",
2054                                                 ssid->passphrase);
2055         /* We must have an identity for both PEAP and TLS */
2056         ssid->identity = connman_network_get_string(network, "WiFi.Identity");
2057
2058         /* Use agent provided identity as a fallback */
2059         if (!ssid->identity || strlen(ssid->identity) == 0)
2060                 ssid->identity = connman_network_get_string(network,
2061                                                         "WiFi.AgentIdentity");
2062
2063         ssid->anonymous_identity = connman_network_get_string(network,
2064                                                 "WiFi.AnonymousIdentity");
2065         ssid->ca_cert_path = connman_network_get_string(network,
2066                                                         "WiFi.CACertFile");
2067         ssid->subject_match = connman_network_get_string(network,
2068                                                         "WiFi.SubjectMatch");
2069         ssid->altsubject_match = connman_network_get_string(network,
2070                                                         "WiFi.AltSubjectMatch");
2071         ssid->domain_suffix_match = connman_network_get_string(network,
2072                                                         "WiFi.DomainSuffixMatch");
2073         ssid->domain_match = connman_network_get_string(network,
2074                                                         "WiFi.DomainMatch");
2075         ssid->client_cert_path = connman_network_get_string(network,
2076                                                         "WiFi.ClientCertFile");
2077         ssid->private_key_path = connman_network_get_string(network,
2078                                                         "WiFi.PrivateKeyFile");
2079         ssid->private_key_passphrase = connman_network_get_string(network,
2080                                                 "WiFi.PrivateKeyPassphrase");
2081         ssid->phase2_auth = connman_network_get_string(network, "WiFi.Phase2");
2082
2083         ssid->use_wps = connman_network_get_bool(network, "WiFi.UseWPS");
2084         ssid->pin_wps = connman_network_get_string(network, "WiFi.PinWPS");
2085
2086         if (connman_setting_get_bool("BackgroundScanning"))
2087                 ssid->bgscan = BGSCAN_DEFAULT;
2088 }
2089
2090 static int network_connect(struct connman_network *network)
2091 {
2092         struct connman_device *device = connman_network_get_device(network);
2093         struct wifi_data *wifi;
2094         GSupplicantInterface *interface;
2095         GSupplicantSSID *ssid;
2096
2097         DBG("network %p", network);
2098
2099         if (!device)
2100                 return -ENODEV;
2101
2102         wifi = connman_device_get_data(device);
2103         if (!wifi)
2104                 return -ENODEV;
2105
2106         ssid = g_try_malloc0(sizeof(GSupplicantSSID));
2107         if (!ssid)
2108                 return -ENOMEM;
2109
2110         interface = wifi->interface;
2111
2112         ssid_init(ssid, network);
2113
2114         if (wifi->disconnecting) {
2115                 wifi->pending_network = network;
2116                 g_free(ssid);
2117         } else {
2118                 wifi->network = connman_network_ref(network);
2119                 wifi->retries = 0;
2120
2121                 return g_supplicant_interface_connect(interface, ssid,
2122                                                 connect_callback, network);
2123         }
2124
2125         return -EINPROGRESS;
2126 }
2127
2128 static void disconnect_callback(int result, GSupplicantInterface *interface,
2129                                                                 void *user_data)
2130 {
2131         struct wifi_data *wifi = user_data;
2132
2133         DBG("result %d supplicant interface %p wifi %p",
2134                         result, interface, wifi);
2135
2136         if (result == -ECONNABORTED) {
2137                 DBG("wifi interface no longer available");
2138                 return;
2139         }
2140
2141         if (wifi->network) {
2142                 connman_network_set_connected(wifi->network, false);
2143                 wifi->network = NULL;
2144         }
2145
2146         wifi->disconnecting = false;
2147         wifi->connected = false;
2148
2149         if (wifi->pending_network) {
2150                 network_connect(wifi->pending_network);
2151                 wifi->pending_network = NULL;
2152         }
2153
2154         start_autoscan(wifi->device);
2155 }
2156
2157 static int network_disconnect(struct connman_network *network)
2158 {
2159         struct connman_device *device = connman_network_get_device(network);
2160         struct wifi_data *wifi;
2161         int err;
2162
2163         DBG("network %p", network);
2164
2165         wifi = connman_device_get_data(device);
2166         if (!wifi || !wifi->interface)
2167                 return -ENODEV;
2168
2169         connman_network_set_associating(network, false);
2170
2171         if (wifi->disconnecting)
2172                 return -EALREADY;
2173
2174         wifi->disconnecting = true;
2175
2176         err = g_supplicant_interface_disconnect(wifi->interface,
2177                                                 disconnect_callback, wifi);
2178         if (err < 0)
2179                 wifi->disconnecting = false;
2180
2181         return err;
2182 }
2183
2184 static struct connman_network_driver network_driver = {
2185         .name           = "wifi",
2186         .type           = CONNMAN_NETWORK_TYPE_WIFI,
2187         .priority       = CONNMAN_NETWORK_PRIORITY_LOW,
2188         .probe          = network_probe,
2189         .remove         = network_remove,
2190         .connect        = network_connect,
2191         .disconnect     = network_disconnect,
2192 };
2193
2194 static void interface_added(GSupplicantInterface *interface)
2195 {
2196         const char *ifname = g_supplicant_interface_get_ifname(interface);
2197         const char *driver = g_supplicant_interface_get_driver(interface);
2198         struct wifi_data *wifi;
2199
2200         wifi = g_supplicant_interface_get_data(interface);
2201         if (!wifi) {
2202                 wifi = get_pending_wifi_data(ifname);
2203                 if (!wifi)
2204                         return;
2205
2206                 wifi->interface = interface;
2207                 g_supplicant_interface_set_data(interface, wifi);
2208                 p2p_iface_list = g_list_append(p2p_iface_list, wifi);
2209                 wifi->p2p_device = true;
2210         }
2211
2212         DBG("ifname %s driver %s wifi %p tethering %d",
2213                         ifname, driver, wifi, wifi->tethering);
2214
2215         if (!wifi->device) {
2216                 connman_error("WiFi device not set");
2217                 return;
2218         }
2219
2220         connman_device_set_powered(wifi->device, true);
2221 }
2222
2223 static bool is_idle(struct wifi_data *wifi)
2224 {
2225         DBG("state %d", wifi->state);
2226
2227         switch (wifi->state) {
2228         case G_SUPPLICANT_STATE_UNKNOWN:
2229         case G_SUPPLICANT_STATE_DISABLED:
2230         case G_SUPPLICANT_STATE_DISCONNECTED:
2231         case G_SUPPLICANT_STATE_INACTIVE:
2232         case G_SUPPLICANT_STATE_SCANNING:
2233                 return true;
2234
2235         case G_SUPPLICANT_STATE_AUTHENTICATING:
2236         case G_SUPPLICANT_STATE_ASSOCIATING:
2237         case G_SUPPLICANT_STATE_ASSOCIATED:
2238         case G_SUPPLICANT_STATE_4WAY_HANDSHAKE:
2239         case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
2240         case G_SUPPLICANT_STATE_COMPLETED:
2241                 return false;
2242         }
2243
2244         return false;
2245 }
2246
2247 static bool is_idle_wps(GSupplicantInterface *interface,
2248                                                 struct wifi_data *wifi)
2249 {
2250         /* First, let's check if WPS processing did not went wrong */
2251         if (g_supplicant_interface_get_wps_state(interface) ==
2252                 G_SUPPLICANT_WPS_STATE_FAIL)
2253                 return false;
2254
2255         /* Unlike normal connection, being associated while processing wps
2256          * actually means that we are idling. */
2257         switch (wifi->state) {
2258         case G_SUPPLICANT_STATE_UNKNOWN:
2259         case G_SUPPLICANT_STATE_DISABLED:
2260         case G_SUPPLICANT_STATE_DISCONNECTED:
2261         case G_SUPPLICANT_STATE_INACTIVE:
2262         case G_SUPPLICANT_STATE_SCANNING:
2263         case G_SUPPLICANT_STATE_ASSOCIATED:
2264                 return true;
2265         case G_SUPPLICANT_STATE_AUTHENTICATING:
2266         case G_SUPPLICANT_STATE_ASSOCIATING:
2267         case G_SUPPLICANT_STATE_4WAY_HANDSHAKE:
2268         case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
2269         case G_SUPPLICANT_STATE_COMPLETED:
2270                 return false;
2271         }
2272
2273         return false;
2274 }
2275
2276 static bool handle_wps_completion(GSupplicantInterface *interface,
2277                                         struct connman_network *network,
2278                                         struct connman_device *device,
2279                                         struct wifi_data *wifi)
2280 {
2281         bool wps;
2282
2283         wps = connman_network_get_bool(network, "WiFi.UseWPS");
2284         if (wps) {
2285                 const unsigned char *ssid, *wps_ssid;
2286                 unsigned int ssid_len, wps_ssid_len;
2287                 const char *wps_key;
2288
2289                 /* Checking if we got associated with requested
2290                  * network */
2291                 ssid = connman_network_get_blob(network, "WiFi.SSID",
2292                                                 &ssid_len);
2293
2294                 wps_ssid = g_supplicant_interface_get_wps_ssid(
2295                         interface, &wps_ssid_len);
2296
2297                 if (!wps_ssid || wps_ssid_len != ssid_len ||
2298                                 memcmp(ssid, wps_ssid, ssid_len) != 0) {
2299                         connman_network_set_associating(network, false);
2300                         g_supplicant_interface_disconnect(wifi->interface,
2301                                                 disconnect_callback, wifi);
2302                         return false;
2303                 }
2304
2305                 wps_key = g_supplicant_interface_get_wps_key(interface);
2306                 connman_network_set_string(network, "WiFi.Passphrase",
2307                                         wps_key);
2308
2309                 connman_network_set_string(network, "WiFi.PinWPS", NULL);
2310         }
2311
2312         return true;
2313 }
2314
2315 static bool handle_assoc_status_code(GSupplicantInterface *interface,
2316                                      struct wifi_data *wifi)
2317 {
2318         if (wifi->state == G_SUPPLICANT_STATE_ASSOCIATING &&
2319                         wifi->assoc_code == ASSOC_STATUS_NO_CLIENT &&
2320                         wifi->load_shaping_retries < LOAD_SHAPING_MAX_RETRIES) {
2321                 wifi->load_shaping_retries ++;
2322                 return TRUE;
2323         }
2324         wifi->load_shaping_retries = 0;
2325         return FALSE;
2326 }
2327
2328 static bool handle_4way_handshake_failure(GSupplicantInterface *interface,
2329                                         struct connman_network *network,
2330                                         struct wifi_data *wifi)
2331 {
2332         struct connman_service *service;
2333
2334         if (wifi->state != G_SUPPLICANT_STATE_4WAY_HANDSHAKE)
2335                 return false;
2336
2337         if (wifi->connected)
2338                 return false;
2339
2340         service = connman_service_lookup_from_network(network);
2341         if (!service)
2342                 return false;
2343
2344         wifi->retries++;
2345
2346         if (connman_service_get_favorite(service)) {
2347                 if (wifi->retries < FAVORITE_MAXIMUM_RETRIES)
2348                         return true;
2349         }
2350
2351         wifi->retries = 0;
2352         connman_network_set_error(network, CONNMAN_NETWORK_ERROR_INVALID_KEY);
2353
2354         return false;
2355 }
2356
2357 static void interface_state(GSupplicantInterface *interface)
2358 {
2359         struct connman_network *network;
2360         struct connman_device *device;
2361         struct wifi_data *wifi;
2362         GSupplicantState state = g_supplicant_interface_get_state(interface);
2363         bool wps;
2364         bool old_connected;
2365
2366         wifi = g_supplicant_interface_get_data(interface);
2367
2368         DBG("wifi %p interface state %d", wifi, state);
2369
2370         if (!wifi)
2371                 return;
2372
2373         if (state == G_SUPPLICANT_STATE_COMPLETED) {
2374                 if (wifi->tethering_param) {
2375                         g_free(wifi->tethering_param->ssid);
2376                         g_free(wifi->tethering_param);
2377                         wifi->tethering_param = NULL;
2378                 }
2379         }
2380
2381         device = wifi->device;
2382         if (!device)
2383                 return;
2384
2385         if (g_supplicant_interface_get_ready(interface) &&
2386                                         !wifi->interface_ready) {
2387                 wifi->interface_ready = true;
2388                 finalize_interface_creation(wifi);
2389         }
2390
2391         network = wifi->network;
2392         if (!network)
2393                 return;
2394
2395         switch (state) {
2396         case G_SUPPLICANT_STATE_SCANNING:
2397                 if (wifi->connected)
2398                         connman_network_set_connected(network, false);
2399
2400                 break;
2401
2402         case G_SUPPLICANT_STATE_AUTHENTICATING:
2403         case G_SUPPLICANT_STATE_ASSOCIATING:
2404                 stop_autoscan(device);
2405
2406                 if (!wifi->connected)
2407                         connman_network_set_associating(network, true);
2408
2409                 break;
2410
2411         case G_SUPPLICANT_STATE_COMPLETED:
2412                 /* though it should be already stopped: */
2413                 stop_autoscan(device);
2414
2415                 if (!handle_wps_completion(interface, network, device, wifi))
2416                         break;
2417
2418                 connman_network_set_connected(network, true);
2419
2420                 wifi->disconnect_code = 0;
2421                 wifi->assoc_code = 0;
2422                 wifi->load_shaping_retries = 0;
2423                 break;
2424
2425         case G_SUPPLICANT_STATE_DISCONNECTED:
2426                 /*
2427                  * If we're in one of the idle modes, we have
2428                  * not started association yet and thus setting
2429                  * those ones to FALSE could cancel an association
2430                  * in progress.
2431                  */
2432                 wps = connman_network_get_bool(network, "WiFi.UseWPS");
2433                 if (wps)
2434                         if (is_idle_wps(interface, wifi))
2435                                 break;
2436
2437                 if (is_idle(wifi))
2438                         break;
2439
2440                 if (handle_assoc_status_code(interface, wifi))
2441                         break;
2442
2443                 /* If previous state was 4way-handshake, then
2444                  * it's either: psk was incorrect and thus we retry
2445                  * or if we reach the maximum retries we declare the
2446                  * psk as wrong */
2447                 if (handle_4way_handshake_failure(interface,
2448                                                 network, wifi))
2449                         break;
2450
2451                 /* See table 8-36 Reason codes in IEEE Std 802.11 */
2452                 switch (wifi->disconnect_code) {
2453                 case 1: /* Unspecified reason */
2454                         /* Let's assume it's because we got blocked */
2455
2456                 case 6: /* Class 2 frame received from nonauthenticated STA */
2457                         connman_network_set_error(network,
2458                                                 CONNMAN_NETWORK_ERROR_BLOCKED);
2459                         break;
2460
2461                 default:
2462                         break;
2463                 }
2464                 connman_network_set_connected(network, false);
2465                 connman_network_set_associating(network, false);
2466                 wifi->disconnecting = false;
2467
2468                 start_autoscan(device);
2469
2470                 break;
2471
2472         case G_SUPPLICANT_STATE_INACTIVE:
2473                 connman_network_set_associating(network, false);
2474                 start_autoscan(device);
2475
2476                 break;
2477
2478         case G_SUPPLICANT_STATE_UNKNOWN:
2479         case G_SUPPLICANT_STATE_DISABLED:
2480         case G_SUPPLICANT_STATE_ASSOCIATED:
2481         case G_SUPPLICANT_STATE_4WAY_HANDSHAKE:
2482         case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
2483                 break;
2484         }
2485
2486         old_connected = wifi->connected;
2487         wifi->state = state;
2488
2489         /* Saving wpa_s state policy:
2490          * If connected and if the state changes are roaming related:
2491          * --> We stay connected
2492          * If completed
2493          * --> We are connected
2494          * All other case:
2495          * --> We are not connected
2496          * */
2497         switch (state) {
2498         case G_SUPPLICANT_STATE_AUTHENTICATING:
2499         case G_SUPPLICANT_STATE_ASSOCIATING:
2500         case G_SUPPLICANT_STATE_ASSOCIATED:
2501         case G_SUPPLICANT_STATE_4WAY_HANDSHAKE:
2502         case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
2503                 if (wifi->connected)
2504                         connman_warn("Probably roaming right now!"
2505                                                 " Staying connected...");
2506                 break;
2507         case G_SUPPLICANT_STATE_SCANNING:
2508                 wifi->connected = false;
2509
2510                 if (old_connected)
2511                         start_autoscan(device);
2512                 break;
2513         case G_SUPPLICANT_STATE_COMPLETED:
2514                 wifi->connected = true;
2515                 break;
2516         default:
2517                 wifi->connected = false;
2518                 break;
2519         }
2520
2521         DBG("DONE");
2522 }
2523
2524 static void interface_removed(GSupplicantInterface *interface)
2525 {
2526         const char *ifname = g_supplicant_interface_get_ifname(interface);
2527         struct wifi_data *wifi;
2528
2529         DBG("ifname %s", ifname);
2530
2531         wifi = g_supplicant_interface_get_data(interface);
2532
2533         if (wifi)
2534                 wifi->interface = NULL;
2535
2536         if (wifi && wifi->tethering)
2537                 return;
2538
2539         if (!wifi || !wifi->device) {
2540                 DBG("wifi interface already removed");
2541                 return;
2542         }
2543
2544         connman_device_set_powered(wifi->device, false);
2545
2546         check_p2p_technology();
2547 }
2548
2549 static void set_device_type(const char *type, char dev_type[17])
2550 {
2551         const char *oui = "0050F204";
2552         const char *category = "0001";
2553         const char *sub_category = "0000";
2554
2555         if (!g_strcmp0(type, "handset")) {
2556                 category = "000A";
2557                 sub_category = "0005";
2558         } else if (!g_strcmp0(type, "vm") || !g_strcmp0(type, "container"))
2559                 sub_category = "0001";
2560         else if (!g_strcmp0(type, "server"))
2561                 sub_category = "0002";
2562         else if (!g_strcmp0(type, "laptop"))
2563                 sub_category = "0005";
2564         else if (!g_strcmp0(type, "desktop"))
2565                 sub_category = "0006";
2566         else if (!g_strcmp0(type, "tablet"))
2567                 sub_category = "0009";
2568         else if (!g_strcmp0(type, "watch"))
2569                 category = "00FF";
2570
2571         snprintf(dev_type, 17, "%s%s%s", category, oui, sub_category);
2572 }
2573
2574 static void p2p_support(GSupplicantInterface *interface)
2575 {
2576         char dev_type[17] = {};
2577         const char *hostname;
2578
2579         DBG("");
2580
2581         if (!interface)
2582                 return;
2583
2584         if (!g_supplicant_interface_has_p2p(interface))
2585                 return;
2586
2587         if (connman_technology_driver_register(&p2p_tech_driver) < 0) {
2588                 DBG("Could not register P2P technology driver");
2589                 return;
2590         }
2591
2592         hostname = connman_utsname_get_hostname();
2593         if (!hostname)
2594                 hostname = "ConnMan";
2595
2596         set_device_type(connman_machine_get_type(), dev_type);
2597         g_supplicant_interface_set_p2p_device_config(interface,
2598                                                         hostname, dev_type);
2599         connman_peer_driver_register(&peer_driver);
2600 }
2601
2602 static void scan_started(GSupplicantInterface *interface)
2603 {
2604         DBG("");
2605 }
2606
2607 static void scan_finished(GSupplicantInterface *interface)
2608 {
2609         DBG("");
2610 }
2611
2612 static void ap_create_fail(GSupplicantInterface *interface)
2613 {
2614         struct wifi_data *wifi = g_supplicant_interface_get_data(interface);
2615         int ret;
2616
2617         if ((wifi->tethering) && (wifi->tethering_param)) {
2618                 DBG("%s create AP fail \n",
2619                                 g_supplicant_interface_get_ifname(wifi->interface));
2620
2621                 connman_inet_remove_from_bridge(wifi->index, wifi->bridge);
2622                 wifi->ap_supported = WIFI_AP_NOT_SUPPORTED;
2623                 wifi->tethering = false;
2624
2625                 ret = tech_set_tethering(wifi->tethering_param->technology,
2626                                 wifi->tethering_param->ssid->ssid,
2627                                 wifi->tethering_param->ssid->passphrase,
2628                                 wifi->bridge, true);
2629
2630                 if ((ret == -EOPNOTSUPP) && (wifi_technology)) {
2631                         connman_technology_tethering_notify(wifi_technology,false);
2632                 }
2633
2634                 g_free(wifi->tethering_param->ssid);
2635                 g_free(wifi->tethering_param);
2636                 wifi->tethering_param = NULL;
2637         }
2638
2639         return;
2640 }
2641
2642 static unsigned char calculate_strength(GSupplicantNetwork *supplicant_network)
2643 {
2644         unsigned char strength;
2645
2646         strength = 120 + g_supplicant_network_get_signal(supplicant_network);
2647         if (strength > 100)
2648                 strength = 100;
2649
2650         return strength;
2651 }
2652
2653 static void network_added(GSupplicantNetwork *supplicant_network)
2654 {
2655         struct connman_network *network;
2656         GSupplicantInterface *interface;
2657         struct wifi_data *wifi;
2658         const char *name, *identifier, *security, *group, *mode;
2659         const unsigned char *ssid;
2660         unsigned int ssid_len;
2661         bool wps;
2662         bool wps_pbc;
2663         bool wps_ready;
2664         bool wps_advertizing;
2665
2666         mode = g_supplicant_network_get_mode(supplicant_network);
2667         identifier = g_supplicant_network_get_identifier(supplicant_network);
2668
2669         DBG("%s", identifier);
2670
2671         if (!g_strcmp0(mode, "adhoc"))
2672                 return;
2673
2674         interface = g_supplicant_network_get_interface(supplicant_network);
2675         wifi = g_supplicant_interface_get_data(interface);
2676         name = g_supplicant_network_get_name(supplicant_network);
2677         security = g_supplicant_network_get_security(supplicant_network);
2678         group = g_supplicant_network_get_identifier(supplicant_network);
2679         wps = g_supplicant_network_get_wps(supplicant_network);
2680         wps_pbc = g_supplicant_network_is_wps_pbc(supplicant_network);
2681         wps_ready = g_supplicant_network_is_wps_active(supplicant_network);
2682         wps_advertizing = g_supplicant_network_is_wps_advertizing(
2683                                                         supplicant_network);
2684
2685         if (!wifi)
2686                 return;
2687
2688         ssid = g_supplicant_network_get_ssid(supplicant_network, &ssid_len);
2689
2690         network = connman_device_get_network(wifi->device, identifier);
2691
2692         if (!network) {
2693                 network = connman_network_create(identifier,
2694                                                 CONNMAN_NETWORK_TYPE_WIFI);
2695                 if (!network)
2696                         return;
2697
2698                 connman_network_set_index(network, wifi->index);
2699
2700                 if (connman_device_add_network(wifi->device, network) < 0) {
2701                         connman_network_unref(network);
2702                         return;
2703                 }
2704
2705                 wifi->networks = g_slist_prepend(wifi->networks, network);
2706         }
2707
2708         if (name && name[0] != '\0')
2709                 connman_network_set_name(network, name);
2710
2711         connman_network_set_blob(network, "WiFi.SSID",
2712                                                 ssid, ssid_len);
2713         connman_network_set_string(network, "WiFi.Security", security);
2714         connman_network_set_strength(network,
2715                                 calculate_strength(supplicant_network));
2716         connman_network_set_bool(network, "WiFi.WPS", wps);
2717
2718         if (wps) {
2719                 /* Is AP advertizing for WPS association?
2720                  * If so, we decide to use WPS by default */
2721                 if (wps_ready && wps_pbc &&
2722                                                 wps_advertizing)
2723                         connman_network_set_bool(network, "WiFi.UseWPS", true);
2724         }
2725
2726         connman_network_set_frequency(network,
2727                         g_supplicant_network_get_frequency(supplicant_network));
2728
2729         connman_network_set_available(network, true);
2730         connman_network_set_string(network, "WiFi.Mode", mode);
2731
2732         if (ssid)
2733                 connman_network_set_group(network, group);
2734
2735         if (wifi->hidden && ssid) {
2736                 if (!g_strcmp0(wifi->hidden->security, security) &&
2737                                 wifi->hidden->ssid_len == ssid_len &&
2738                                 !memcmp(wifi->hidden->ssid, ssid, ssid_len)) {
2739                         connman_network_connect_hidden(network,
2740                                         wifi->hidden->identity,
2741                                         wifi->hidden->passphrase,
2742                                         wifi->hidden->user_data);
2743                         wifi->hidden->user_data = NULL;
2744                         hidden_free(wifi->hidden);
2745                         wifi->hidden = NULL;
2746                 }
2747         }
2748 }
2749
2750 static void network_removed(GSupplicantNetwork *network)
2751 {
2752         GSupplicantInterface *interface;
2753         struct wifi_data *wifi;
2754         const char *name, *identifier;
2755         struct connman_network *connman_network;
2756
2757         interface = g_supplicant_network_get_interface(network);
2758         wifi = g_supplicant_interface_get_data(interface);
2759         identifier = g_supplicant_network_get_identifier(network);
2760         name = g_supplicant_network_get_name(network);
2761
2762         DBG("name %s", name);
2763
2764         if (!wifi)
2765                 return;
2766
2767         connman_network = connman_device_get_network(wifi->device, identifier);
2768         if (!connman_network)
2769                 return;
2770
2771         wifi->networks = g_slist_remove(wifi->networks, connman_network);
2772
2773         connman_device_remove_network(wifi->device, connman_network);
2774         connman_network_unref(connman_network);
2775 }
2776
2777 static void network_changed(GSupplicantNetwork *network, const char *property)
2778 {
2779         GSupplicantInterface *interface;
2780         struct wifi_data *wifi;
2781         const char *name, *identifier;
2782         struct connman_network *connman_network;
2783
2784         interface = g_supplicant_network_get_interface(network);
2785         wifi = g_supplicant_interface_get_data(interface);
2786         identifier = g_supplicant_network_get_identifier(network);
2787         name = g_supplicant_network_get_name(network);
2788
2789         DBG("name %s", name);
2790
2791         if (!wifi)
2792                 return;
2793
2794         connman_network = connman_device_get_network(wifi->device, identifier);
2795         if (!connman_network)
2796                 return;
2797
2798         if (g_str_equal(property, "Signal")) {
2799                connman_network_set_strength(connman_network,
2800                                         calculate_strength(network));
2801                connman_network_update(connman_network);
2802         }
2803 }
2804
2805 static void network_associated(GSupplicantNetwork *network)
2806 {
2807         GSupplicantInterface *interface;
2808         struct wifi_data *wifi;
2809         struct connman_network *connman_network;
2810         const char *identifier;
2811
2812         DBG("");
2813
2814         interface = g_supplicant_network_get_interface(network);
2815         if (!interface)
2816                 return;
2817
2818         wifi = g_supplicant_interface_get_data(interface);
2819         if (!wifi)
2820                 return;
2821
2822         identifier = g_supplicant_network_get_identifier(network);
2823
2824         connman_network = connman_device_get_network(wifi->device, identifier);
2825         if (!connman_network)
2826                 return;
2827
2828         if (wifi->network) {
2829                 if (wifi->network == connman_network)
2830                         return;
2831
2832                 /*
2833                  * This should never happen, we got associated with
2834                  * a network different than the one we were expecting.
2835                  */
2836                 DBG("Associated to %p while expecting %p",
2837                                         connman_network, wifi->network);
2838
2839                 connman_network_set_associating(wifi->network, false);
2840         }
2841
2842         DBG("Reconnecting to previous network %p from wpa_s", connman_network);
2843
2844         wifi->network = connman_network_ref(connman_network);
2845         wifi->retries = 0;
2846
2847         /*
2848          * Interface state changes callback (interface_state) is always
2849          * called before network_associated callback thus we need to call
2850          * interface_state again in order to process the new state now that
2851          * we have the network properly set.
2852          */
2853         interface_state(interface);
2854 }
2855
2856 static void apply_peer_services(GSupplicantPeer *peer,
2857                                 struct connman_peer *connman_peer)
2858 {
2859         const unsigned char *data;
2860         int length;
2861
2862         DBG("");
2863
2864         connman_peer_reset_services(connman_peer);
2865
2866         data = g_supplicant_peer_get_widi_ies(peer, &length);
2867         if (data) {
2868                 connman_peer_add_service(connman_peer,
2869                         CONNMAN_PEER_SERVICE_WIFI_DISPLAY, data, length);
2870         }
2871 }
2872
2873 static void peer_found(GSupplicantPeer *peer)
2874 {
2875         GSupplicantInterface *iface = g_supplicant_peer_get_interface(peer);
2876         struct wifi_data *wifi = g_supplicant_interface_get_data(iface);
2877         struct connman_peer *connman_peer;
2878         const char *identifier, *name;
2879         int ret;
2880
2881         identifier = g_supplicant_peer_get_identifier(peer);
2882         name = g_supplicant_peer_get_name(peer);
2883
2884         DBG("ident: %s", identifier);
2885
2886         connman_peer = connman_peer_get(wifi->device, identifier);
2887         if (connman_peer)
2888                 return;
2889
2890         connman_peer = connman_peer_create(identifier);
2891         connman_peer_set_name(connman_peer, name);
2892         connman_peer_set_device(connman_peer, wifi->device);
2893         apply_peer_services(peer, connman_peer);
2894
2895         ret = connman_peer_register(connman_peer);
2896         if (ret < 0 && ret != -EALREADY)
2897                 connman_peer_unref(connman_peer);
2898         else
2899                 wifi->peers = g_slist_prepend(wifi->peers, connman_peer);
2900 }
2901
2902 static void peer_lost(GSupplicantPeer *peer)
2903 {
2904         GSupplicantInterface *iface = g_supplicant_peer_get_interface(peer);
2905         struct wifi_data *wifi = g_supplicant_interface_get_data(iface);
2906         struct connman_peer *connman_peer;
2907         const char *identifier;
2908
2909         if (!wifi)
2910                 return;
2911
2912         identifier = g_supplicant_peer_get_identifier(peer);
2913
2914         DBG("ident: %s", identifier);
2915
2916         connman_peer = connman_peer_get(wifi->device, identifier);
2917         if (connman_peer) {
2918                 if (wifi->p2p_connecting &&
2919                                 wifi->pending_peer == connman_peer) {
2920                         peer_connect_timeout(wifi);
2921                 }
2922                 connman_peer_unregister(connman_peer);
2923                 connman_peer_unref(connman_peer);
2924         }
2925
2926         wifi->peers = g_slist_remove(wifi->peers, connman_peer);
2927 }
2928
2929 static void peer_changed(GSupplicantPeer *peer, GSupplicantPeerState state)
2930 {
2931         GSupplicantInterface *iface = g_supplicant_peer_get_interface(peer);
2932         struct wifi_data *wifi = g_supplicant_interface_get_data(iface);
2933         enum connman_peer_state p_state = CONNMAN_PEER_STATE_UNKNOWN;
2934         struct connman_peer *connman_peer;
2935         const char *identifier;
2936
2937         identifier = g_supplicant_peer_get_identifier(peer);
2938
2939         DBG("ident: %s", identifier);
2940
2941         if (!wifi)
2942                 return;
2943
2944         connman_peer = connman_peer_get(wifi->device, identifier);
2945         if (!connman_peer)
2946                 return;
2947
2948         switch (state) {
2949         case G_SUPPLICANT_PEER_SERVICES_CHANGED:
2950                 apply_peer_services(peer, connman_peer);
2951                 connman_peer_services_changed(connman_peer);
2952                 return;
2953         case G_SUPPLICANT_PEER_GROUP_CHANGED:
2954                 if (!g_supplicant_peer_is_in_a_group(peer))
2955                         p_state = CONNMAN_PEER_STATE_IDLE;
2956                 else
2957                         p_state = CONNMAN_PEER_STATE_CONFIGURATION;
2958                 break;
2959         case G_SUPPLICANT_PEER_GROUP_STARTED:
2960                 break;
2961         case G_SUPPLICANT_PEER_GROUP_FINISHED:
2962                 p_state = CONNMAN_PEER_STATE_IDLE;
2963                 break;
2964         case G_SUPPLICANT_PEER_GROUP_JOINED:
2965                 connman_peer_set_iface_address(connman_peer,
2966                                 g_supplicant_peer_get_iface_address(peer));
2967                 break;
2968         case G_SUPPLICANT_PEER_GROUP_DISCONNECTED:
2969                 p_state = CONNMAN_PEER_STATE_IDLE;
2970                 break;
2971         case G_SUPPLICANT_PEER_GROUP_FAILED:
2972                 if (g_supplicant_peer_has_requested_connection(peer))
2973                         p_state = CONNMAN_PEER_STATE_IDLE;
2974                 else
2975                         p_state = CONNMAN_PEER_STATE_FAILURE;
2976                 break;
2977         }
2978
2979         if (p_state == CONNMAN_PEER_STATE_CONFIGURATION ||
2980                                         p_state == CONNMAN_PEER_STATE_FAILURE) {
2981                 if (wifi->p2p_connecting
2982                                 && connman_peer == wifi->pending_peer)
2983                         peer_cancel_timeout(wifi);
2984                 else
2985                         p_state = CONNMAN_PEER_STATE_UNKNOWN;
2986         }
2987
2988         if (p_state == CONNMAN_PEER_STATE_UNKNOWN)
2989                 return;
2990
2991         if (p_state == CONNMAN_PEER_STATE_CONFIGURATION) {
2992                 GSupplicantInterface *g_iface;
2993                 struct wifi_data *g_wifi;
2994
2995                 g_iface = g_supplicant_peer_get_group_interface(peer);
2996                 if (!g_iface)
2997                         return;
2998
2999                 g_wifi = g_supplicant_interface_get_data(g_iface);
3000                 if (!g_wifi)
3001                         return;
3002
3003                 connman_peer_set_as_master(connman_peer,
3004                                         !g_supplicant_peer_is_client(peer));
3005                 connman_peer_set_sub_device(connman_peer, g_wifi->device);
3006
3007                 /*
3008                  * If wpa_supplicant didn't create a dedicated p2p-group
3009                  * interface then mark this interface as p2p_device to avoid
3010                  * scan and auto-scan are launched on it while P2P is connected.
3011                  */
3012                 if (!g_list_find(p2p_iface_list, g_wifi))
3013                         wifi->p2p_device = true;
3014         }
3015
3016         connman_peer_set_state(connman_peer, p_state);
3017 }
3018
3019 static void peer_request(GSupplicantPeer *peer)
3020 {
3021         GSupplicantInterface *iface = g_supplicant_peer_get_interface(peer);
3022         struct wifi_data *wifi = g_supplicant_interface_get_data(iface);
3023         struct connman_peer *connman_peer;
3024         const char *identifier;
3025
3026         identifier = g_supplicant_peer_get_identifier(peer);
3027
3028         DBG("ident: %s", identifier);
3029
3030         connman_peer = connman_peer_get(wifi->device, identifier);
3031         if (!connman_peer)
3032                 return;
3033
3034         connman_peer_request_connection(connman_peer);
3035 }
3036
3037 static void debug(const char *str)
3038 {
3039         if (getenv("CONNMAN_SUPPLICANT_DEBUG"))
3040                 connman_debug("%s", str);
3041 }
3042
3043 static void disconnect_reasoncode(GSupplicantInterface *interface,
3044                                 int reasoncode)
3045 {
3046         struct wifi_data *wifi = g_supplicant_interface_get_data(interface);
3047
3048         if (wifi != NULL) {
3049                 wifi->disconnect_code = reasoncode;
3050         }
3051 }
3052
3053 static void assoc_status_code(GSupplicantInterface *interface, int status_code)
3054 {
3055         struct wifi_data *wifi = g_supplicant_interface_get_data(interface);
3056
3057         if (wifi != NULL) {
3058                 wifi->assoc_code = status_code;
3059         }
3060 }
3061
3062 static const GSupplicantCallbacks callbacks = {
3063         .system_ready           = system_ready,
3064         .system_killed          = system_killed,
3065         .interface_added        = interface_added,
3066         .interface_state        = interface_state,
3067         .interface_removed      = interface_removed,
3068         .p2p_support            = p2p_support,
3069         .scan_started           = scan_started,
3070         .scan_finished          = scan_finished,
3071         .ap_create_fail         = ap_create_fail,
3072         .network_added          = network_added,
3073         .network_removed        = network_removed,
3074         .network_changed        = network_changed,
3075         .network_associated     = network_associated,
3076         .peer_found             = peer_found,
3077         .peer_lost              = peer_lost,
3078         .peer_changed           = peer_changed,
3079         .peer_request           = peer_request,
3080         .debug                  = debug,
3081         .disconnect_reasoncode  = disconnect_reasoncode,
3082         .assoc_status_code      = assoc_status_code,
3083 };
3084
3085
3086 static int tech_probe(struct connman_technology *technology)
3087 {
3088         wifi_technology = technology;
3089
3090         return 0;
3091 }
3092
3093 static void tech_remove(struct connman_technology *technology)
3094 {
3095         wifi_technology = NULL;
3096 }
3097
3098 static GSupplicantSSID *ssid_ap_init(const char *ssid, const char *passphrase)
3099 {
3100         GSupplicantSSID *ap;
3101
3102         ap = g_try_malloc0(sizeof(GSupplicantSSID));
3103         if (!ap)
3104                 return NULL;
3105
3106         ap->mode = G_SUPPLICANT_MODE_MASTER;
3107         ap->ssid = ssid;
3108         ap->ssid_len = strlen(ssid);
3109         ap->scan_ssid = 0;
3110         ap->freq = 2412;
3111
3112         if (!passphrase || strlen(passphrase) == 0) {
3113                 ap->security = G_SUPPLICANT_SECURITY_NONE;
3114                 ap->passphrase = NULL;
3115         } else {
3116                ap->security = G_SUPPLICANT_SECURITY_PSK;
3117                ap->protocol = G_SUPPLICANT_PROTO_RSN;
3118                ap->pairwise_cipher = G_SUPPLICANT_PAIRWISE_CCMP;
3119                ap->group_cipher = G_SUPPLICANT_GROUP_CCMP;
3120                ap->passphrase = passphrase;
3121         }
3122
3123         return ap;
3124 }
3125
3126 static void ap_start_callback(int result, GSupplicantInterface *interface,
3127                                                         void *user_data)
3128 {
3129         struct wifi_tethering_info *info = user_data;
3130
3131         DBG("result %d index %d bridge %s",
3132                 result, info->wifi->index, info->wifi->bridge);
3133
3134         if ((result < 0) || (info->wifi->ap_supported != WIFI_AP_SUPPORTED)) {
3135                 connman_inet_remove_from_bridge(info->wifi->index,
3136                                                         info->wifi->bridge);
3137
3138                 if (info->wifi->ap_supported == WIFI_AP_SUPPORTED) {
3139                         connman_technology_tethering_notify(info->technology, false);
3140                         g_free(info->wifi->tethering_param->ssid);
3141                         g_free(info->wifi->tethering_param);
3142                         info->wifi->tethering_param = NULL;
3143                 }
3144         }
3145
3146         g_free(info->ifname);
3147         g_free(info);
3148 }
3149
3150 static void ap_create_callback(int result,
3151                                 GSupplicantInterface *interface,
3152                                         void *user_data)
3153 {
3154         struct wifi_tethering_info *info = user_data;
3155
3156         DBG("result %d ifname %s", result,
3157                                 g_supplicant_interface_get_ifname(interface));
3158
3159         if ((result < 0) || (info->wifi->ap_supported != WIFI_AP_SUPPORTED)) {
3160                 connman_inet_remove_from_bridge(info->wifi->index,
3161                                                         info->wifi->bridge);
3162
3163                 if (info->wifi->ap_supported == WIFI_AP_SUPPORTED) {
3164                         connman_technology_tethering_notify(info->technology, false);
3165                         g_free(info->wifi->tethering_param->ssid);
3166                         g_free(info->wifi->tethering_param);
3167                         info->wifi->tethering_param = NULL;
3168
3169                 }
3170
3171                 g_free(info->ifname);
3172                 g_free(info->ssid);
3173                 g_free(info);
3174                 return;
3175         }
3176
3177         info->wifi->interface = interface;
3178         g_supplicant_interface_set_data(interface, info->wifi);
3179
3180         if (g_supplicant_interface_set_apscan(interface, 2) < 0)
3181                 connman_error("Failed to set interface ap_scan property");
3182
3183         g_supplicant_interface_connect(interface, info->ssid,
3184                                                 ap_start_callback, info);
3185 }
3186
3187 static void sta_remove_callback(int result,
3188                                 GSupplicantInterface *interface,
3189                                         void *user_data)
3190 {
3191         struct wifi_tethering_info *info = user_data;
3192         const char *driver = connman_option_get_string("wifi");
3193
3194         DBG("ifname %s result %d ", info->ifname, result);
3195
3196         if ((result < 0) || (info->wifi->ap_supported != WIFI_AP_SUPPORTED)) {
3197                 info->wifi->tethering = false;
3198                 connman_technology_tethering_notify(info->technology, false);
3199
3200                 g_free(info->ifname);
3201                 g_free(info->ssid);
3202                 g_free(info);
3203
3204                 if (info->wifi->ap_supported == WIFI_AP_SUPPORTED) {
3205                         g_free(info->wifi->tethering_param->ssid);
3206                         g_free(info->wifi->tethering_param);
3207                         info->wifi->tethering_param = NULL;
3208                 }
3209                 return;
3210         }
3211
3212         info->wifi->interface = NULL;
3213
3214         g_supplicant_interface_create(info->ifname, driver, info->wifi->bridge,
3215                                                 ap_create_callback,
3216                                                         info);
3217 }
3218
3219 static int enable_wifi_tethering(struct connman_technology *technology,
3220                                 const char *bridge, const char *identifier,
3221                                 const char *passphrase, bool available)
3222 {
3223         GList *list;
3224         GSupplicantInterface *interface;
3225         struct wifi_data *wifi;
3226         struct wifi_tethering_info *info;
3227         const char *ifname;
3228         unsigned int mode;
3229         int err, berr = 0;
3230
3231         for (list = iface_list; list; list = list->next) {
3232                 wifi = list->data;
3233
3234                 DBG("wifi %p network %p pending_network %p", wifi,
3235                         wifi->network, wifi->pending_network);
3236
3237                 interface = wifi->interface;
3238
3239                 if (!interface)
3240                         continue;
3241
3242                 ifname = g_supplicant_interface_get_ifname(wifi->interface);
3243                 if (!ifname)
3244                         continue;
3245
3246                 if (wifi->ap_supported == WIFI_AP_NOT_SUPPORTED) {
3247                         DBG("%s does not support AP mode (detected)", ifname);
3248                         continue;
3249                 }
3250
3251                 mode = g_supplicant_interface_get_mode(interface);
3252                 if ((mode & G_SUPPLICANT_CAPABILITY_MODE_AP) == 0) {
3253                         wifi->ap_supported = WIFI_AP_NOT_SUPPORTED;
3254                         DBG("%s does not support AP mode (capability)", ifname);
3255                         continue;
3256                 }
3257
3258                 if (wifi->network && available)
3259                         continue;
3260
3261                 info = g_try_malloc0(sizeof(struct wifi_tethering_info));
3262                 if (!info)
3263                         return -ENOMEM;
3264
3265                 wifi->tethering_param = g_try_malloc0(sizeof(struct wifi_tethering_info));
3266                 if (!wifi->tethering_param) {
3267                         g_free(info);
3268                         return -ENOMEM;
3269                 }
3270
3271                 info->wifi = wifi;
3272                 info->technology = technology;
3273                 info->wifi->bridge = bridge;
3274                 info->ssid = ssid_ap_init(identifier, passphrase);
3275                 if (!info->ssid)
3276                         goto failed;
3277
3278                 info->ifname = g_strdup(ifname);
3279
3280                 wifi->tethering_param->technology = technology;
3281                 wifi->tethering_param->ssid = ssid_ap_init(identifier, passphrase);
3282                 if (!wifi->tethering_param->ssid)
3283                         goto failed;
3284
3285                 info->wifi->tethering = true;
3286                 info->wifi->ap_supported = WIFI_AP_SUPPORTED;
3287
3288                 berr = connman_technology_tethering_notify(technology, true);
3289                 if (berr < 0)
3290                         goto failed;
3291
3292                 err = g_supplicant_interface_remove(interface,
3293                                                 sta_remove_callback,
3294                                                         info);
3295                 if (err >= 0) {
3296                         DBG("tethering wifi %p ifname %s", wifi, ifname);
3297                         return 0;
3298                 }
3299
3300         failed:
3301                 g_free(info->ifname);
3302                 g_free(info->ssid);
3303                 g_free(info);
3304                 g_free(wifi->tethering_param);
3305                 wifi->tethering_param = NULL;
3306
3307                 /*
3308                  * Remove bridge if it was correctly created but remove
3309                  * operation failed. Instead, if bridge creation failed then
3310                  * break out and do not try again on another interface,
3311                  * bridge set-up does not depend on it.
3312                  */
3313                 if (berr == 0)
3314                         connman_technology_tethering_notify(technology, false);
3315                 else
3316                         break;
3317         }
3318
3319         return -EOPNOTSUPP;
3320 }
3321
3322 static int tech_set_tethering(struct connman_technology *technology,
3323                                 const char *identifier, const char *passphrase,
3324                                 const char *bridge, bool enabled)
3325 {
3326         GList *list;
3327         struct wifi_data *wifi;
3328         int err;
3329
3330         DBG("");
3331
3332         if (!enabled) {
3333                 for (list = iface_list; list; list = list->next) {
3334                         wifi = list->data;
3335
3336                         if (wifi->tethering) {
3337                                 wifi->tethering = false;
3338
3339                                 connman_inet_remove_from_bridge(wifi->index,
3340                                                                         bridge);
3341                                 wifi->bridged = false;
3342                         }
3343                 }
3344
3345                 connman_technology_tethering_notify(technology, false);
3346
3347                 return 0;
3348         }
3349
3350         DBG("trying tethering for available devices");
3351         err = enable_wifi_tethering(technology, bridge, identifier, passphrase,
3352                                 true);
3353
3354         if (err < 0) {
3355                 DBG("trying tethering for any device");
3356                 err = enable_wifi_tethering(technology, bridge, identifier,
3357                                         passphrase, false);
3358         }
3359
3360         return err;
3361 }
3362
3363 static void regdom_callback(int result, const char *alpha2, void *user_data)
3364 {
3365         DBG("");
3366
3367         if (!wifi_technology)
3368                 return;
3369
3370         if (result != 0)
3371                 alpha2 = NULL;
3372
3373         connman_technology_regdom_notify(wifi_technology, alpha2);
3374 }
3375
3376 static int tech_set_regdom(struct connman_technology *technology, const char *alpha2)
3377 {
3378         return g_supplicant_set_country(alpha2, regdom_callback, NULL);
3379 }
3380
3381 static struct connman_technology_driver tech_driver = {
3382         .name           = "wifi",
3383         .type           = CONNMAN_SERVICE_TYPE_WIFI,
3384         .probe          = tech_probe,
3385         .remove         = tech_remove,
3386         .set_tethering  = tech_set_tethering,
3387         .set_regdom     = tech_set_regdom,
3388 };
3389
3390 static int wifi_init(void)
3391 {
3392         int err;
3393
3394         err = connman_network_driver_register(&network_driver);
3395         if (err < 0)
3396                 return err;
3397
3398         err = g_supplicant_register(&callbacks);
3399         if (err < 0) {
3400                 connman_network_driver_unregister(&network_driver);
3401                 return err;
3402         }
3403
3404         err = connman_technology_driver_register(&tech_driver);
3405         if (err < 0) {
3406                 g_supplicant_unregister(&callbacks);
3407                 connman_network_driver_unregister(&network_driver);
3408                 return err;
3409         }
3410
3411         return 0;
3412 }
3413
3414 static void wifi_exit(void)
3415 {
3416         DBG();
3417
3418         connman_technology_driver_unregister(&tech_driver);
3419
3420         g_supplicant_unregister(&callbacks);
3421
3422         connman_network_driver_unregister(&network_driver);
3423 }
3424
3425 CONNMAN_PLUGIN_DEFINE(wifi, "WiFi interface plugin", VERSION,
3426                 CONNMAN_PLUGIN_PRIORITY_DEFAULT, wifi_init, wifi_exit)