Update dhclient plugin with support for element infrastructure
[connman] / plugins / 80211.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2008  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 <stdio.h>
27 #include <errno.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/ioctl.h>
32 #include <sys/socket.h>
33 #include <arpa/inet.h>
34 #include <net/if.h>
35 #include <net/ethernet.h>
36 #include <linux/wireless.h>
37
38 #include <glib.h>
39
40 #include <connman/plugin.h>
41 #include <connman/iface.h>
42 #include <connman/log.h>
43
44 #include "supplicant.h"
45
46 struct iface_data {
47         char ifname[IFNAMSIZ];
48 };
49
50 static int wifi_probe(struct connman_iface *iface)
51 {
52         struct iface_data *data;
53         struct ifreq ifr;
54         int sk, err;
55
56         sk = socket(PF_INET, SOCK_DGRAM, 0);
57         if (sk < 0)
58                 return -EIO;
59
60         memset(&ifr, 0, sizeof(ifr));
61         ifr.ifr_ifindex = iface->index;
62
63         err = ioctl(sk, SIOCGIFNAME, &ifr);
64
65         close(sk);
66
67         if (err < 0)
68                 return -EIO;
69
70         DBG("iface %p %s", iface, ifr.ifr_name);
71
72         data = malloc(sizeof(*data));
73         if (data == NULL)
74                 return -ENOMEM;
75
76         memset(data, 0, sizeof(*data));
77
78         memcpy(data->ifname, ifr.ifr_name, IFNAMSIZ);
79
80         iface->type = CONNMAN_IFACE_TYPE_80211;
81
82         iface->flags = CONNMAN_IFACE_FLAG_RTNL |
83                                 CONNMAN_IFACE_FLAG_IPV4 |
84                                 CONNMAN_IFACE_FLAG_SCANNING |
85                                 CONNMAN_IFACE_FLAG_NOCARRIER;
86
87         connman_iface_set_data(iface, data);
88
89         return 0;
90 }
91
92 static void wifi_remove(struct connman_iface *iface)
93 {
94         struct iface_data *data = connman_iface_get_data(iface);
95
96         DBG("iface %p %s", iface, data->ifname);
97
98         __supplicant_stop(iface);
99
100         connman_iface_set_data(iface, NULL);
101
102         free(data);
103 }
104
105 static int wifi_start(struct connman_iface *iface)
106 {
107         struct iface_data *data = connman_iface_get_data(iface);
108
109         DBG("iface %p %s", iface, data->ifname);
110
111         __supplicant_start(iface);
112
113         return 0;
114 }
115
116 static int wifi_stop(struct connman_iface *iface)
117 {
118         struct iface_data *data = connman_iface_get_data(iface);
119
120         DBG("iface %p %s", iface, data->ifname);
121
122         __supplicant_stop(iface);
123
124         return 0;
125 }
126
127 static int wifi_scan(struct connman_iface *iface)
128 {
129         struct iface_data *data = connman_iface_get_data(iface);
130
131         DBG("iface %p %s", iface, data->ifname);
132
133         __supplicant_scan(iface);
134
135         return 0;
136 }
137
138 static int wifi_connect(struct connman_iface *iface,
139                                         struct connman_network *network)
140 {
141         struct iface_data *data = connman_iface_get_data(iface);
142
143         DBG("iface %p %s", iface, data->ifname);
144
145         __supplicant_connect(iface, network->identifier, network->passphrase);
146
147         return 0;
148 }
149
150 static int wifi_disconnect(struct connman_iface *iface)
151 {
152         struct iface_data *data = connman_iface_get_data(iface);
153
154         DBG("iface %p %s", iface, data->ifname);
155
156         __supplicant_disconnect(iface);
157
158         return 0;
159 }
160
161 static struct connman_iface_driver wifi_driver = {
162         .name           = "80211",
163         .capability     = "net.80211",
164         .probe          = wifi_probe,
165         .remove         = wifi_remove,
166         .start          = wifi_start,
167         .stop           = wifi_stop,
168         .scan           = wifi_scan,
169         .connect        = wifi_connect,
170         .disconnect     = wifi_disconnect,
171 };
172
173 static int wifi_init(void)
174 {
175         return connman_iface_register(&wifi_driver);
176 }
177
178 static void wifi_exit(void)
179 {
180         connman_iface_unregister(&wifi_driver);
181 }
182
183 CONNMAN_PLUGIN_DEFINE("80211", "IEEE 802.11 interface plugin", VERSION,
184                                                         wifi_init, wifi_exit)