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