Imported Upstream version 1.40
[platform/upstream/connman.git] / src / device.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 <errno.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <sys/ioctl.h>
32 #include <net/ethernet.h>
33 #include <net/if.h>
34
35 #include "connman.h"
36
37 static GSList *device_list = NULL;
38 static gchar **device_filter = NULL;
39 static gchar **nodevice_filter = NULL;
40
41 enum connman_pending_type {
42         PENDING_NONE    = 0,
43         PENDING_ENABLE  = 1,
44         PENDING_DISABLE = 2,
45 };
46
47 struct connman_device {
48         int refcount;
49         enum connman_device_type type;
50         enum connman_pending_type powered_pending;      /* Indicates a pending
51                                                          * enable/disable
52                                                          * request
53                                                          */
54         bool powered;
55         bool scanning[MAX_CONNMAN_SERVICE_TYPES];
56         char *name;
57         char *node;
58         char *address;
59         char *interface;
60         char *ident;
61         char *path;
62         int index;
63         guint pending_timeout;
64
65         struct connman_device_driver *driver;
66         void *driver_data;
67
68         char *last_network;
69         struct connman_network *network;
70         GHashTable *networks;
71 };
72
73 static void clear_pending_trigger(struct connman_device *device)
74 {
75         if (device->pending_timeout > 0) {
76                 g_source_remove(device->pending_timeout);
77                 device->pending_timeout = 0;
78         }
79 }
80
81 static const char *type2description(enum connman_device_type type)
82 {
83         switch (type) {
84         case CONNMAN_DEVICE_TYPE_UNKNOWN:
85         case CONNMAN_DEVICE_TYPE_VENDOR:
86                 break;
87         case CONNMAN_DEVICE_TYPE_ETHERNET:
88                 return "Ethernet";
89         case CONNMAN_DEVICE_TYPE_WIFI:
90                 return "Wireless";
91         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
92                 return "Bluetooth";
93         case CONNMAN_DEVICE_TYPE_GPS:
94                 return "GPS";
95         case CONNMAN_DEVICE_TYPE_CELLULAR:
96                 return "Cellular";
97         case CONNMAN_DEVICE_TYPE_GADGET:
98                 return "Gadget";
99
100         }
101
102         return NULL;
103 }
104
105 static const char *type2string(enum connman_device_type type)
106 {
107         switch (type) {
108         case CONNMAN_DEVICE_TYPE_UNKNOWN:
109         case CONNMAN_DEVICE_TYPE_VENDOR:
110                 break;
111         case CONNMAN_DEVICE_TYPE_ETHERNET:
112                 return "ethernet";
113         case CONNMAN_DEVICE_TYPE_WIFI:
114                 return "wifi";
115         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
116                 return "bluetooth";
117         case CONNMAN_DEVICE_TYPE_GPS:
118                 return "gps";
119         case CONNMAN_DEVICE_TYPE_CELLULAR:
120                 return "cellular";
121         case CONNMAN_DEVICE_TYPE_GADGET:
122                 return "gadget";
123
124         }
125
126         return NULL;
127 }
128
129 enum connman_service_type __connman_device_get_service_type(
130                                 struct connman_device *device)
131 {
132         enum connman_device_type type = connman_device_get_type(device);
133
134         switch (type) {
135         case CONNMAN_DEVICE_TYPE_UNKNOWN:
136         case CONNMAN_DEVICE_TYPE_VENDOR:
137         case CONNMAN_DEVICE_TYPE_GPS:
138                 break;
139         case CONNMAN_DEVICE_TYPE_ETHERNET:
140                 return CONNMAN_SERVICE_TYPE_ETHERNET;
141         case CONNMAN_DEVICE_TYPE_WIFI:
142                 return CONNMAN_SERVICE_TYPE_WIFI;
143         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
144                 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
145         case CONNMAN_DEVICE_TYPE_CELLULAR:
146                 return CONNMAN_SERVICE_TYPE_CELLULAR;
147         case CONNMAN_DEVICE_TYPE_GADGET:
148                 return CONNMAN_SERVICE_TYPE_GADGET;
149
150         }
151
152         return CONNMAN_SERVICE_TYPE_UNKNOWN;
153 }
154
155 static bool device_has_service_type(struct connman_device *device,
156                                 enum connman_service_type service_type)
157 {
158         enum connman_service_type device_service_type =
159                 __connman_device_get_service_type(device);
160
161         /*
162          * For devices whose device_service_type is unknown we should
163          * allow to decide whether they support specific service_type
164          * by themself.
165          */
166         if (device_service_type == CONNMAN_SERVICE_TYPE_UNKNOWN)
167                 return true;
168
169         if (device_service_type == CONNMAN_SERVICE_TYPE_WIFI) {
170                 return service_type == CONNMAN_SERVICE_TYPE_WIFI ||
171                         service_type == CONNMAN_SERVICE_TYPE_P2P;
172         }
173
174         return service_type == device_service_type;
175 }
176
177 static gboolean device_pending_reset(gpointer user_data)
178 {
179         struct connman_device *device = user_data;
180
181         DBG("device %p", device);
182
183         /* Power request timedout, reset power pending state. */
184         device->pending_timeout = 0;
185         device->powered_pending = PENDING_NONE;
186
187         return FALSE;
188 }
189
190 int __connman_device_enable(struct connman_device *device)
191 {
192         int err;
193
194         DBG("device %p", device);
195
196         if (!device->driver || !device->driver->enable)
197                 return -EOPNOTSUPP;
198
199         /* There is an ongoing power disable request. */
200         if (device->powered_pending == PENDING_DISABLE)
201                 return -EBUSY;
202
203         if (device->powered_pending == PENDING_ENABLE)
204                 return -EINPROGRESS;
205
206         if (device->powered_pending == PENDING_NONE && device->powered)
207                 return -EALREADY;
208
209         if (device->index > 0) {
210                 err = connman_inet_ifup(device->index);
211                 if (err < 0 && err != -EALREADY)
212                         return err;
213         }
214
215         device->powered_pending = PENDING_ENABLE;
216
217         err = device->driver->enable(device);
218         /*
219          * device gets enabled right away.
220          * Invoke the callback
221          */
222         if (err == 0) {
223                 connman_device_set_powered(device, true);
224                 goto done;
225         }
226
227         if (err == -EALREADY) {
228                 /* If device is already powered, but connman is not updated */
229                 connman_device_set_powered(device, true);
230                 goto done;
231         }
232         /*
233          * if err == -EINPROGRESS, then the DBus call to the respective daemon
234          * was successful. We set a 4 sec timeout so if the daemon never
235          * returns a reply, we would reset the pending request.
236          */
237         if (err == -EINPROGRESS)
238                 device->pending_timeout = g_timeout_add_seconds(4,
239                                         device_pending_reset, device);
240 done:
241         return err;
242 }
243
244 int __connman_device_disable(struct connman_device *device)
245 {
246         int err;
247
248         DBG("device %p", device);
249
250         /* Ongoing power enable request */
251         if (device->powered_pending == PENDING_ENABLE)
252                 return -EBUSY;
253
254         if (device->powered_pending == PENDING_DISABLE)
255                 return -EINPROGRESS;
256
257         if (device->powered_pending == PENDING_NONE && !device->powered)
258                 return -EALREADY;
259
260         device->powered_pending = PENDING_DISABLE;
261
262         if (device->network) {
263                 struct connman_service *service =
264                         connman_service_lookup_from_network(device->network);
265
266                 if (service)
267                         __connman_service_disconnect(service);
268                 else
269                         connman_network_set_connected(device->network, false);
270         }
271
272         if (!device->driver || !device->driver->disable)
273                 return -EOPNOTSUPP;
274
275         err = device->driver->disable(device);
276         if (err == 0 || err == -EALREADY) {
277                 connman_device_set_powered(device, false);
278                 goto done;
279         }
280
281         if (err == -EINPROGRESS)
282                 device->pending_timeout = g_timeout_add_seconds(4,
283                                         device_pending_reset, device);
284 done:
285         return err;
286 }
287
288 static void probe_driver(struct connman_device_driver *driver)
289 {
290         GSList *list;
291
292         DBG("driver %p name %s", driver, driver->name);
293
294         for (list = device_list; list; list = list->next) {
295                 struct connman_device *device = list->data;
296
297                 if (device->driver)
298                         continue;
299
300                 if (driver->type != device->type)
301                         continue;
302
303                 if (driver->probe(device) < 0)
304                         continue;
305
306                 device->driver = driver;
307
308                 __connman_technology_add_device(device);
309         }
310 }
311
312 static void remove_device(struct connman_device *device)
313 {
314         DBG("device %p", device);
315
316         __connman_device_disable(device);
317
318         __connman_technology_remove_device(device);
319
320         if (device->driver->remove)
321                 device->driver->remove(device);
322
323         device->driver = NULL;
324 }
325
326 static void remove_driver(struct connman_device_driver *driver)
327 {
328         GSList *list;
329
330         DBG("driver %p name %s", driver, driver->name);
331
332         for (list = device_list; list; list = list->next) {
333                 struct connman_device *device = list->data;
334
335                 if (device->driver == driver)
336                         remove_device(device);
337         }
338 }
339
340 bool __connman_device_has_driver(struct connman_device *device)
341 {
342         if (!device || !device->driver)
343                 return false;
344
345         return true;
346 }
347
348 static GSList *driver_list = NULL;
349
350 static gint compare_priority(gconstpointer a, gconstpointer b)
351 {
352         const struct connman_device_driver *driver1 = a;
353         const struct connman_device_driver *driver2 = b;
354
355         return driver2->priority - driver1->priority;
356 }
357
358 /**
359  * connman_device_driver_register:
360  * @driver: device driver definition
361  *
362  * Register a new device driver
363  *
364  * Returns: %0 on success
365  */
366 int connman_device_driver_register(struct connman_device_driver *driver)
367 {
368         DBG("driver %p name %s", driver, driver->name);
369
370         driver_list = g_slist_insert_sorted(driver_list, driver,
371                                                         compare_priority);
372         probe_driver(driver);
373
374         return 0;
375 }
376
377 /**
378  * connman_device_driver_unregister:
379  * @driver: device driver definition
380  *
381  * Remove a previously registered device driver
382  */
383 void connman_device_driver_unregister(struct connman_device_driver *driver)
384 {
385         DBG("driver %p name %s", driver, driver->name);
386
387         driver_list = g_slist_remove(driver_list, driver);
388
389         remove_driver(driver);
390 }
391
392 static void free_network(gpointer data)
393 {
394         struct connman_network *network = data;
395
396         DBG("network %p", network);
397
398         __connman_network_set_device(network, NULL);
399
400         connman_network_unref(network);
401 }
402
403 static void device_destruct(struct connman_device *device)
404 {
405         DBG("device %p name %s", device, device->name);
406
407         clear_pending_trigger(device);
408
409         g_hash_table_destroy(device->networks);
410         device->networks = NULL;
411
412         g_free(device->ident);
413         g_free(device->node);
414         g_free(device->name);
415         g_free(device->address);
416         g_free(device->interface);
417         g_free(device->path);
418
419         g_free(device->last_network);
420
421         g_free(device);
422 }
423
424 /**
425  * connman_device_create:
426  * @node: device node name (for example an address)
427  * @type: device type
428  *
429  * Allocate a new device of given #type and assign the #node name to it.
430  *
431  * Returns: a newly-allocated #connman_device structure
432  */
433 struct connman_device *connman_device_create(const char *node,
434                                                 enum connman_device_type type)
435 {
436         struct connman_device *device;
437
438         DBG("node %s type %d", node, type);
439
440         device = g_try_new0(struct connman_device, 1);
441         if (!device)
442                 return NULL;
443
444         DBG("device %p", device);
445
446         device->refcount = 1;
447
448         device->type = type;
449         device->name = g_strdup(type2description(device->type));
450
451         device->networks = g_hash_table_new_full(g_str_hash, g_str_equal,
452                                                 g_free, free_network);
453
454         device_list = g_slist_prepend(device_list, device);
455
456         return device;
457 }
458
459 /**
460  * connman_device_ref:
461  * @device: device structure
462  *
463  * Increase reference counter of device
464  */
465 struct connman_device *connman_device_ref_debug(struct connman_device *device,
466                                 const char *file, int line, const char *caller)
467 {
468         DBG("%p ref %d by %s:%d:%s()", device, device->refcount + 1,
469                 file, line, caller);
470
471         __sync_fetch_and_add(&device->refcount, 1);
472
473         return device;
474 }
475
476 /**
477  * connman_device_unref:
478  * @device: device structure
479  *
480  * Decrease reference counter of device
481  */
482 void connman_device_unref_debug(struct connman_device *device,
483                                 const char *file, int line, const char *caller)
484 {
485         DBG("%p ref %d by %s:%d:%s()", device, device->refcount - 1,
486                 file, line, caller);
487
488         if (__sync_fetch_and_sub(&device->refcount, 1) != 1)
489                 return;
490
491         if (device->driver) {
492                 device->driver->remove(device);
493                 device->driver = NULL;
494         }
495
496         device_list = g_slist_remove(device_list, device);
497
498         device_destruct(device);
499 }
500
501 const char *__connman_device_get_type(struct connman_device *device)
502 {
503         return type2string(device->type);
504 }
505
506 /**
507  * connman_device_get_type:
508  * @device: device structure
509  *
510  * Get type of device
511  */
512 enum connman_device_type connman_device_get_type(struct connman_device *device)
513 {
514         return device->type;
515 }
516
517 /**
518  * connman_device_set_index:
519  * @device: device structure
520  * @index: index number
521  *
522  * Set index number of device
523  */
524 void connman_device_set_index(struct connman_device *device, int index)
525 {
526         device->index = index;
527 }
528
529 /**
530  * connman_device_get_index:
531  * @device: device structure
532  *
533  * Get index number of device
534  */
535 int connman_device_get_index(struct connman_device *device)
536 {
537         return device->index;
538 }
539
540 /**
541  * connman_device_set_interface:
542  * @device: device structure
543  * @interface: interface name
544  *
545  * Set interface name of device
546  */
547 void connman_device_set_interface(struct connman_device *device,
548                                                 const char *interface)
549 {
550         g_free(device->interface);
551         device->interface = g_strdup(interface);
552
553         if (!device->name) {
554                 const char *str = type2description(device->type);
555                 if (str && device->interface)
556                         device->name = g_strdup_printf("%s (%s)", str,
557                                                         device->interface);
558         }
559 }
560
561 /**
562  * connman_device_set_ident:
563  * @device: device structure
564  * @ident: unique identifier
565  *
566  * Set unique identifier of device
567  */
568 void connman_device_set_ident(struct connman_device *device,
569                                                         const char *ident)
570 {
571         g_free(device->ident);
572         device->ident = g_strdup(ident);
573 }
574
575 const char *connman_device_get_ident(struct connman_device *device)
576 {
577         return device->ident;
578 }
579
580 /**
581  * connman_device_set_powered:
582  * @device: device structure
583  * @powered: powered state
584  *
585  * Change power state of device
586  */
587 int connman_device_set_powered(struct connman_device *device,
588                                                 bool powered)
589 {
590         struct connman_device_scan_params params;
591         enum connman_service_type type;
592         int i;
593
594         DBG("device %p powered %d", device, powered);
595
596         if (device->powered == powered)
597                 return -EALREADY;
598
599         clear_pending_trigger(device);
600
601         device->powered_pending = PENDING_NONE;
602
603         device->powered = powered;
604
605         type = __connman_device_get_service_type(device);
606
607         if (!device->powered) {
608                 __connman_technology_disabled(type);
609                 return 0;
610         }
611
612         __connman_technology_enabled(type);
613
614         for (i = 0; i < MAX_CONNMAN_SERVICE_TYPES; i++)
615                 device->scanning[i] = false;
616
617         if (device->driver && device->driver->scan) {
618                 memset(&params, 0, sizeof(params));
619                 params.type = CONNMAN_SERVICE_TYPE_UNKNOWN;
620
621                 device->driver->scan(device, &params);
622         }
623
624         return 0;
625 }
626
627 bool connman_device_get_powered(struct connman_device *device)
628 {
629         return device->powered;
630 }
631
632 static int device_scan(enum connman_service_type type,
633                                 struct connman_device *device,
634                                 bool force_full_scan)
635 {
636         struct connman_device_scan_params params;
637
638         if (!device->driver || !device->driver->scan)
639                 return -EOPNOTSUPP;
640
641         if (!device->powered)
642                 return -ENOLINK;
643
644         memset(&params, 0, sizeof(params));
645         params.type = type;
646         params.force_full_scan = force_full_scan;
647
648         return device->driver->scan(device, &params);
649 }
650
651 int __connman_device_disconnect(struct connman_device *device)
652 {
653         GHashTableIter iter;
654         gpointer key, value;
655
656         DBG("device %p", device);
657
658         g_hash_table_iter_init(&iter, device->networks);
659
660         while (g_hash_table_iter_next(&iter, &key, &value)) {
661                 struct connman_network *network = value;
662
663                 if (connman_network_get_connecting(network)) {
664                         /*
665                          * Skip network in the process of connecting.
666                          * This is a workaround for WiFi networks serviced
667                          * by the supplicant plugin that hold a reference
668                          * to the network.  If we disconnect the network
669                          * here then the referenced object will not be
670                          * registered and usage (like launching DHCP client)
671                          * will fail.  There is nothing to be gained by
672                          * removing the network here anyway.
673                          */
674                         connman_warn("Skipping disconnect of %s, network is connecting.",
675                                 connman_network_get_identifier(network));
676                         continue;
677                 }
678
679                 __connman_network_disconnect(network);
680         }
681
682         return 0;
683 }
684
685 int connman_device_reconnect_service(struct connman_device *device)
686 {
687         DBG("device %p", device);
688
689         __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
690
691         return 0;
692 }
693
694 static void mark_network_available(gpointer key, gpointer value,
695                                                         gpointer user_data)
696 {
697         struct connman_network *network = value;
698
699         connman_network_set_available(network, true);
700 }
701
702 static void mark_network_unavailable(gpointer key, gpointer value,
703                                                         gpointer user_data)
704 {
705         struct connman_network *network = value;
706
707         if (connman_network_get_connected(network) ||
708                         connman_network_get_connecting(network))
709                 return;
710
711         connman_network_set_available(network, false);
712 }
713
714 static gboolean remove_unavailable_network(gpointer key, gpointer value,
715                                                         gpointer user_data)
716 {
717         struct connman_network *network = value;
718
719         if (connman_network_get_connected(network) ||
720                         connman_network_get_connecting(network))
721                 return FALSE;
722
723         if (connman_network_get_available(network))
724                 return FALSE;
725
726         return TRUE;
727 }
728
729 void __connman_device_cleanup_networks(struct connman_device *device)
730 {
731         g_hash_table_foreach_remove(device->networks,
732                                         remove_unavailable_network, NULL);
733 }
734
735 bool connman_device_get_scanning(struct connman_device *device,
736                                 enum connman_service_type type)
737 {
738         int i;
739
740         if (type != CONNMAN_SERVICE_TYPE_UNKNOWN)
741                 return device->scanning[type];
742
743         for (i = 0; i < MAX_CONNMAN_SERVICE_TYPES; i++)
744                 if (device->scanning[i])
745                         return true;
746
747         return false;
748 }
749
750 void connman_device_reset_scanning(struct connman_device *device)
751 {
752         g_hash_table_foreach(device->networks,
753                                 mark_network_available, NULL);
754 }
755
756 /**
757  * connman_device_set_scanning:
758  * @device: device structure
759  * @scanning: scanning state
760  *
761  * Change scanning state of device
762  */
763 int connman_device_set_scanning(struct connman_device *device,
764                                 enum connman_service_type type, bool scanning)
765 {
766         DBG("device %p scanning %d", device, scanning);
767
768         if (!device->driver || !device->driver->scan)
769                 return -EINVAL;
770
771         if (type == CONNMAN_SERVICE_TYPE_UNKNOWN)
772                 return -EINVAL;
773
774         if (device->scanning[type] == scanning)
775                 return -EALREADY;
776
777         device->scanning[type] = scanning;
778
779         if (scanning) {
780                 __connman_technology_scan_started(device);
781
782                 g_hash_table_foreach(device->networks,
783                                         mark_network_unavailable, NULL);
784
785                 return 0;
786         }
787
788         __connman_device_cleanup_networks(device);
789
790         __connman_technology_scan_stopped(device, type);
791
792         __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
793
794         return 0;
795 }
796
797 /**
798  * connman_device_set_string:
799  * @device: device structure
800  * @key: unique identifier
801  * @value: string value
802  *
803  * Set string value for specific key
804  */
805 int connman_device_set_string(struct connman_device *device,
806                                         const char *key, const char *value)
807 {
808         DBG("device %p key %s value %s", device, key, value);
809
810         if (g_str_equal(key, "Address")) {
811                 g_free(device->address);
812                 device->address = g_strdup(value);
813         } else if (g_str_equal(key, "Name")) {
814                 g_free(device->name);
815                 device->name = g_strdup(value);
816         } else if (g_str_equal(key, "Node")) {
817                 g_free(device->node);
818                 device->node = g_strdup(value);
819         } else if (g_str_equal(key, "Path")) {
820                 g_free(device->path);
821                 device->path = g_strdup(value);
822         } else {
823                 return -EINVAL;
824         }
825
826         return 0;
827 }
828
829 /**
830  * connman_device_get_string:
831  * @device: device structure
832  * @key: unique identifier
833  *
834  * Get string value for specific key
835  */
836 const char *connman_device_get_string(struct connman_device *device,
837                                                         const char *key)
838 {
839         DBG("device %p key %s", device, key);
840
841         if (g_str_equal(key, "Address"))
842                 return device->address;
843         else if (g_str_equal(key, "Name"))
844                 return device->name;
845         else if (g_str_equal(key, "Node"))
846                 return device->node;
847         else if (g_str_equal(key, "Interface"))
848                 return device->interface;
849         else if (g_str_equal(key, "Path"))
850                 return device->path;
851
852         return NULL;
853 }
854
855 /**
856  * connman_device_add_network:
857  * @device: device structure
858  * @network: network structure
859  *
860  * Add new network to the device
861  */
862 int connman_device_add_network(struct connman_device *device,
863                                         struct connman_network *network)
864 {
865         const char *identifier = connman_network_get_identifier(network);
866
867         DBG("device %p network %p", device, network);
868
869         if (!identifier)
870                 return -EINVAL;
871
872         connman_network_ref(network);
873
874         __connman_network_set_device(network, device);
875
876         g_hash_table_replace(device->networks, g_strdup(identifier),
877                                                                 network);
878
879         return 0;
880 }
881
882 /**
883  * connman_device_get_network:
884  * @device: device structure
885  * @identifier: network identifier
886  *
887  * Get network for given identifier
888  */
889 struct connman_network *connman_device_get_network(struct connman_device *device,
890                                                         const char *identifier)
891 {
892         DBG("device %p identifier %s", device, identifier);
893
894         return g_hash_table_lookup(device->networks, identifier);
895 }
896
897 /**
898  * connman_device_remove_network:
899  * @device: device structure
900  * @identifier: network identifier
901  *
902  * Remove network for given identifier
903  */
904 int connman_device_remove_network(struct connman_device *device,
905                                                 struct connman_network *network)
906 {
907         const char *identifier;
908
909         DBG("device %p network %p", device, network);
910
911         if (!network)
912                 return 0;
913
914         identifier = connman_network_get_identifier(network);
915         g_hash_table_remove(device->networks, identifier);
916
917         return 0;
918 }
919
920 void __connman_device_set_network(struct connman_device *device,
921                                         struct connman_network *network)
922 {
923         const char *name;
924
925         if (!device)
926                 return;
927
928         if (device->network == network)
929                 return;
930
931         if (network) {
932                 name = connman_network_get_string(network, "Name");
933                 g_free(device->last_network);
934                 device->last_network = g_strdup(name);
935
936                 device->network = network;
937         } else {
938                 g_free(device->last_network);
939                 device->last_network = NULL;
940
941                 device->network = NULL;
942         }
943 }
944
945 static bool match_driver(struct connman_device *device,
946                                         struct connman_device_driver *driver)
947 {
948         if (device->type == driver->type ||
949                         driver->type == CONNMAN_DEVICE_TYPE_UNKNOWN)
950                 return true;
951
952         return false;
953 }
954
955 /**
956  * connman_device_register:
957  * @device: device structure
958  *
959  * Register device with the system
960  */
961 int connman_device_register(struct connman_device *device)
962 {
963         GSList *list;
964
965         DBG("device %p name %s", device, device->name);
966
967         if (device->driver)
968                 return -EALREADY;
969
970         for (list = driver_list; list; list = list->next) {
971                 struct connman_device_driver *driver = list->data;
972
973                 if (!match_driver(device, driver))
974                         continue;
975
976                 DBG("driver %p name %s", driver, driver->name);
977
978                 if (driver->probe(device) == 0) {
979                         device->driver = driver;
980                         break;
981                 }
982         }
983
984         if (!device->driver)
985                 return 0;
986
987         return __connman_technology_add_device(device);
988 }
989
990 /**
991  * connman_device_unregister:
992  * @device: device structure
993  *
994  * Unregister device with the system
995  */
996 void connman_device_unregister(struct connman_device *device)
997 {
998         DBG("device %p name %s", device, device->name);
999
1000         if (!device->driver)
1001                 return;
1002
1003         remove_device(device);
1004 }
1005
1006 /**
1007  * connman_device_get_data:
1008  * @device: device structure
1009  *
1010  * Get private device data pointer
1011  */
1012 void *connman_device_get_data(struct connman_device *device)
1013 {
1014         return device->driver_data;
1015 }
1016
1017 /**
1018  * connman_device_set_data:
1019  * @device: device structure
1020  * @data: data pointer
1021  *
1022  * Set private device data pointer
1023  */
1024 void connman_device_set_data(struct connman_device *device, void *data)
1025 {
1026         device->driver_data = data;
1027 }
1028
1029 struct connman_device *__connman_device_find_device(
1030                                 enum connman_service_type type)
1031 {
1032         GSList *list;
1033
1034         for (list = device_list; list; list = list->next) {
1035                 struct connman_device *device = list->data;
1036                 enum connman_service_type service_type =
1037                         __connman_device_get_service_type(device);
1038
1039                 if (service_type != type)
1040                         continue;
1041
1042                 return device;
1043         }
1044
1045         return NULL;
1046 }
1047
1048 struct connman_device *connman_device_find_by_index(int index)
1049 {
1050         GSList *list;
1051
1052         for (list = device_list; list; list = list->next) {
1053                 struct connman_device *device = list->data;
1054                 if (device->index == index)
1055                         return device;
1056         }
1057
1058         return NULL;
1059 }
1060
1061 /**
1062  * connman_device_set_regdom
1063  * @device: device structure
1064  * @alpha2: string representing regulatory domain
1065  *
1066  * Set regulatory domain on device basis
1067  */
1068 int connman_device_set_regdom(struct connman_device *device,
1069                                                 const char *alpha2)
1070 {
1071         if (!device->driver || !device->driver->set_regdom)
1072                 return -ENOTSUP;
1073
1074         if (!device->powered)
1075                 return -EINVAL;
1076
1077         return device->driver->set_regdom(device, alpha2);
1078 }
1079
1080 /**
1081  * connman_device_regdom_notify
1082  * @device: device structure
1083  * @alpha2: string representing regulatory domain
1084  *
1085  * Notify on setting regulatory domain on device basis
1086  */
1087 void connman_device_regdom_notify(struct connman_device *device,
1088                                         int result, const char *alpha2)
1089 {
1090         __connman_technology_notify_regdom_by_device(device, result, alpha2);
1091 }
1092
1093 static int connman_device_request_scan(enum connman_service_type type,
1094                                         bool force_full_scan)
1095 {
1096         bool success = false;
1097         int last_err = -ENOSYS;
1098         GSList *list;
1099         int err;
1100
1101         switch (type) {
1102         case CONNMAN_SERVICE_TYPE_UNKNOWN:
1103         case CONNMAN_SERVICE_TYPE_SYSTEM:
1104         case CONNMAN_SERVICE_TYPE_ETHERNET:
1105         case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1106         case CONNMAN_SERVICE_TYPE_CELLULAR:
1107         case CONNMAN_SERVICE_TYPE_GPS:
1108         case CONNMAN_SERVICE_TYPE_VPN:
1109         case CONNMAN_SERVICE_TYPE_GADGET:
1110                 return -EOPNOTSUPP;
1111         case CONNMAN_SERVICE_TYPE_WIFI:
1112         case CONNMAN_SERVICE_TYPE_P2P:
1113                 break;
1114         }
1115
1116         for (list = device_list; list; list = list->next) {
1117                 struct connman_device *device = list->data;
1118
1119                 if (!device_has_service_type(device, type))
1120                         continue;
1121
1122                 err = device_scan(type, device, force_full_scan);
1123                 if (err == 0 || err == -EALREADY || err == -EINPROGRESS) {
1124                         success = true;
1125                 } else {
1126                         last_err = err;
1127                         DBG("device %p err %d", device, err);
1128                 }
1129         }
1130
1131         if (success)
1132                 return 0;
1133
1134         return last_err;
1135 }
1136
1137 int __connman_device_request_scan(enum connman_service_type type)
1138 {
1139         return connman_device_request_scan(type, false);
1140 }
1141
1142 int __connman_device_request_scan_full(enum connman_service_type type)
1143 {
1144         return connman_device_request_scan(type, true);
1145 }
1146
1147 int __connman_device_request_hidden_scan(struct connman_device *device,
1148                                 const char *ssid, unsigned int ssid_len,
1149                                 const char *identity, const char *passphrase,
1150                                 const char *security, void *user_data)
1151 {
1152         struct connman_device_scan_params params;
1153
1154         DBG("device %p", device);
1155
1156         if (!device || !device->driver ||
1157                         !device->driver->scan)
1158                 return -EINVAL;
1159
1160         params.type = CONNMAN_SERVICE_TYPE_UNKNOWN;
1161         params.ssid = ssid;
1162         params.ssid_len = ssid_len;
1163         params.identity = identity;
1164         params.passphrase = passphrase;
1165         params.security = security;
1166         params.user_data = user_data;
1167
1168         return device->driver->scan(device, &params);
1169 }
1170
1171 void __connman_device_stop_scan(enum connman_service_type type)
1172 {
1173         GSList *list;
1174
1175         for (list = device_list; list; list = list->next) {
1176                 struct connman_device *device = list->data;
1177
1178                 if (!device_has_service_type(device, type))
1179                         continue;
1180
1181                 if (device->driver && device->driver->stop_scan)
1182                         device->driver->stop_scan(type, device);
1183         }
1184 }
1185
1186 static char *index2ident(int index, const char *prefix)
1187 {
1188         struct ifreq ifr;
1189         struct ether_addr eth;
1190         char *str;
1191         int sk, err, len;
1192
1193         if (index < 0)
1194                 return NULL;
1195
1196         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1197         if (sk < 0)
1198                 return NULL;
1199
1200         memset(&ifr, 0, sizeof(ifr));
1201         ifr.ifr_ifindex = index;
1202
1203         err = ioctl(sk, SIOCGIFNAME, &ifr);
1204
1205         if (err == 0)
1206                 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
1207
1208         close(sk);
1209
1210         if (err < 0)
1211                 return NULL;
1212
1213         len = prefix ? strlen(prefix) + 18 : 18;
1214
1215         str = g_malloc(len);
1216         if (!str)
1217                 return NULL;
1218
1219         memcpy(&eth, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
1220         snprintf(str, len, "%s%02x%02x%02x%02x%02x%02x",
1221                                                 prefix ? prefix : "",
1222                                                 eth.ether_addr_octet[0],
1223                                                 eth.ether_addr_octet[1],
1224                                                 eth.ether_addr_octet[2],
1225                                                 eth.ether_addr_octet[3],
1226                                                 eth.ether_addr_octet[4],
1227                                                 eth.ether_addr_octet[5]);
1228
1229         return str;
1230 }
1231
1232 static char *index2addr(int index)
1233 {
1234         struct ifreq ifr;
1235         struct ether_addr eth;
1236         char *str;
1237         int sk, err;
1238
1239         if (index < 0)
1240                 return NULL;
1241
1242         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1243         if (sk < 0)
1244                 return NULL;
1245
1246         memset(&ifr, 0, sizeof(ifr));
1247         ifr.ifr_ifindex = index;
1248
1249         err = ioctl(sk, SIOCGIFNAME, &ifr);
1250
1251         if (err == 0)
1252                 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
1253
1254         close(sk);
1255
1256         if (err < 0)
1257                 return NULL;
1258
1259         str = g_malloc(18);
1260         if (!str)
1261                 return NULL;
1262
1263         memcpy(&eth, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
1264         snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
1265                                                 eth.ether_addr_octet[0],
1266                                                 eth.ether_addr_octet[1],
1267                                                 eth.ether_addr_octet[2],
1268                                                 eth.ether_addr_octet[3],
1269                                                 eth.ether_addr_octet[4],
1270                                                 eth.ether_addr_octet[5]);
1271
1272         return str;
1273 }
1274
1275 struct connman_device *connman_device_create_from_index(int index)
1276 {
1277         enum connman_device_type type;
1278         struct connman_device *device;
1279         char *devname, *ident = NULL;
1280         char *addr = NULL, *name = NULL;
1281
1282         if (index < 0)
1283                 return NULL;
1284
1285         devname = connman_inet_ifname(index);
1286         if (!devname)
1287                 return NULL;
1288
1289         if (__connman_device_isfiltered(devname)) {
1290                 connman_info("Ignoring interface %s (filtered)", devname);
1291                 g_free(devname);
1292                 return NULL;
1293         }
1294
1295         type = __connman_rtnl_get_device_type(index);
1296
1297         switch (type) {
1298         case CONNMAN_DEVICE_TYPE_UNKNOWN:
1299                 connman_info("Ignoring interface %s (type unknown)", devname);
1300                 g_free(devname);
1301                 return NULL;
1302         case CONNMAN_DEVICE_TYPE_ETHERNET:
1303         case CONNMAN_DEVICE_TYPE_GADGET:
1304         case CONNMAN_DEVICE_TYPE_WIFI:
1305                 name = index2ident(index, "");
1306                 addr = index2addr(index);
1307                 break;
1308         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
1309         case CONNMAN_DEVICE_TYPE_CELLULAR:
1310         case CONNMAN_DEVICE_TYPE_GPS:
1311         case CONNMAN_DEVICE_TYPE_VENDOR:
1312                 name = g_strdup(devname);
1313                 break;
1314         }
1315
1316         device = connman_device_create(name, type);
1317         if (!device)
1318                 goto done;
1319
1320         switch (type) {
1321         case CONNMAN_DEVICE_TYPE_UNKNOWN:
1322         case CONNMAN_DEVICE_TYPE_VENDOR:
1323         case CONNMAN_DEVICE_TYPE_GPS:
1324                 break;
1325         case CONNMAN_DEVICE_TYPE_ETHERNET:
1326         case CONNMAN_DEVICE_TYPE_GADGET:
1327                 ident = index2ident(index, NULL);
1328                 break;
1329         case CONNMAN_DEVICE_TYPE_WIFI:
1330                 ident = index2ident(index, NULL);
1331                 break;
1332         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
1333                 break;
1334         case CONNMAN_DEVICE_TYPE_CELLULAR:
1335                 ident = index2ident(index, NULL);
1336                 break;
1337         }
1338
1339         connman_device_set_index(device, index);
1340         connman_device_set_interface(device, devname);
1341
1342         if (ident) {
1343                 connman_device_set_ident(device, ident);
1344                 g_free(ident);
1345         }
1346
1347         connman_device_set_string(device, "Address", addr);
1348
1349 done:
1350         g_free(devname);
1351         g_free(name);
1352         g_free(addr);
1353
1354         return device;
1355 }
1356
1357 bool __connman_device_isfiltered(const char *devname)
1358 {
1359         char **pattern;
1360         char **blacklisted_interfaces;
1361         bool match;
1362
1363         if (!device_filter)
1364                 goto nodevice;
1365
1366         for (pattern = device_filter, match = false; *pattern; pattern++) {
1367                 if (g_pattern_match_simple(*pattern, devname)) {
1368                         match = true;
1369                         break;
1370                 }
1371         }
1372
1373         if (!match) {
1374                 DBG("ignoring device %s (match)", devname);
1375                 return true;
1376         }
1377
1378 nodevice:
1379         if (g_pattern_match_simple("dummy*", devname)) {
1380                 DBG("ignoring dummy networking devices");
1381                 return true;
1382         }
1383
1384         if (!nodevice_filter)
1385                 goto list;
1386
1387         for (pattern = nodevice_filter; *pattern; pattern++) {
1388                 if (g_pattern_match_simple(*pattern, devname)) {
1389                         DBG("ignoring device %s (no match)", devname);
1390                         return true;
1391                 }
1392         }
1393
1394 list:
1395         if (__connman_inet_isrootnfs_device(devname)) {
1396                 DBG("ignoring device %s (rootnfs)", devname);
1397                 return true;
1398         }
1399
1400         blacklisted_interfaces =
1401                 connman_setting_get_string_list("NetworkInterfaceBlacklist");
1402         if (!blacklisted_interfaces)
1403                 return false;
1404
1405         for (pattern = blacklisted_interfaces; *pattern; pattern++) {
1406                 if (g_str_has_prefix(devname, *pattern)) {
1407                         DBG("ignoring device %s (blacklist)", devname);
1408                         return true;
1409                 }
1410         }
1411
1412         return false;
1413 }
1414
1415 static void cleanup_devices(void)
1416 {
1417         /*
1418          * Check what interfaces are currently up and if connman is
1419          * suppose to handle the interface, then cleanup the mess
1420          * related to that interface. There might be weird routes etc
1421          * that are related to that interface and that might confuse
1422          * connmand. So in this case we just turn the interface down
1423          * so that kernel removes routes/addresses automatically and
1424          * then proceed the startup.
1425          *
1426          * Note that this cleanup must be done before rtnl/detect code
1427          * has activated interface watches.
1428          */
1429
1430         char **interfaces;
1431         int i;
1432
1433         interfaces = __connman_inet_get_running_interfaces();
1434
1435         if (!interfaces)
1436                 return;
1437
1438         for (i = 0; interfaces[i]; i++) {
1439                 bool filtered;
1440                 int index;
1441                 struct sockaddr_in sin_addr, sin_mask;
1442
1443                 filtered = __connman_device_isfiltered(interfaces[i]);
1444                 if (filtered)
1445                         continue;
1446
1447                 index = connman_inet_ifindex(interfaces[i]);
1448                 if (index < 0)
1449                         continue;
1450
1451                 if (!__connman_inet_get_address_netmask(index, &sin_addr,
1452                                                         &sin_mask)) {
1453                         char *address = g_strdup(inet_ntoa(sin_addr.sin_addr));
1454                         char *netmask = g_strdup(inet_ntoa(sin_mask.sin_addr));
1455
1456                         if (__connman_config_address_provisioned(address,
1457                                                                 netmask)) {
1458                                 DBG("Skip %s which is already provisioned "
1459                                         "with %s/%s", interfaces[i], address,
1460                                         netmask);
1461                                 g_free(address);
1462                                 g_free(netmask);
1463                                 continue;
1464                         }
1465
1466                         g_free(address);
1467                         g_free(netmask);
1468                 }
1469
1470                 DBG("cleaning up %s index %d", interfaces[i], index);
1471
1472                 connman_inet_ifdown(index);
1473
1474                 /*
1475                  * ConnMan will turn the interface UP automatically so
1476                  * no need to do it here.
1477                  */
1478         }
1479
1480         g_strfreev(interfaces);
1481 }
1482
1483 int __connman_device_init(const char *device, const char *nodevice)
1484 {
1485         DBG("");
1486
1487         if (device)
1488                 device_filter = g_strsplit(device, ",", -1);
1489
1490         if (nodevice)
1491                 nodevice_filter = g_strsplit(nodevice, ",", -1);
1492
1493         cleanup_devices();
1494
1495         return 0;
1496 }
1497
1498 void __connman_device_cleanup(void)
1499 {
1500         DBG("");
1501
1502         g_strfreev(nodevice_filter);
1503         g_strfreev(device_filter);
1504 }