source: mainline/uspace/lib/ieee80211/src/ieee80211_iface_impl.c@ 1dcc0b9

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1dcc0b9 was 1dcc0b9, checked in by Jan Kolarik <kolarik@…>, 10 years ago

Scanning whole 2.4GHz spectrum, created supplicant for managing connection between device STA and AP, finished association process between STA and AP, handling 4way handshake protocol used for key management, written needed cryptographic algorithms (AES, SHA1, HMAC, PBKDF2) for CCMP protocol, data communication on OPEN/CCMP networks.

  • Property mode set to 100644
File size: 6.5 KB
Line 
1/*
2 * Copyright (c) 2015 Jan Kolarik
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <str.h>
30#include <errno.h>
31
32#include <ieee80211_private.h>
33#include <ieee80211_iface_impl.h>
34
35/** @addtogroup libieee80211
36 * @{
37 */
38
39/** @file ieee80211_iface_impl.c
40 *
41 * IEEE 802.11 default interface functions implementation.
42 */
43
44/**
45 * Implementation of fetching scan results.
46 *
47 * @param fun Device function.
48 * @param results Structure where should be stored scan results.
49 *
50 * @return EOK.
51 */
52int ieee80211_get_scan_results_impl(ddf_fun_t *fun,
53 ieee80211_scan_results_t *results, bool now)
54{
55 nic_t *nic_data = nic_get_from_ddf_fun(fun);
56 ieee80211_dev_t *ieee80211_dev = nic_get_specific(nic_data);
57
58 if(!ieee80211_is_ready(ieee80211_dev))
59 return EREFUSED;
60
61 fibril_mutex_lock(&ieee80211_dev->ap_list.scan_mutex);
62 time_t scan_span = time(NULL) - ieee80211_dev->ap_list.last_scan;
63 fibril_mutex_unlock(&ieee80211_dev->ap_list.scan_mutex);
64
65 if(now || scan_span > MAX_SCAN_SPAN_SEC) {
66 ieee80211_dev->ops->scan(ieee80211_dev);
67 }
68
69 fibril_mutex_lock(&ieee80211_dev->ap_list.scan_mutex);
70 if(results) {
71 ieee80211_scan_result_list_t *result_list =
72 &ieee80211_dev->ap_list;
73
74 int i = 0;
75 ieee80211_scan_result_list_foreach(*result_list, result) {
76 memcpy(&results->results[i],
77 &result->scan_result,
78 sizeof(ieee80211_scan_result_t));
79 i++;
80 }
81
82 results->length = i;
83 }
84 fibril_mutex_unlock(&ieee80211_dev->ap_list.scan_mutex);
85
86 return EOK;
87}
88
89static uint16_t ieee80211_channel_to_freq(uint8_t channel)
90{
91 return IEEE80211_CHANNEL_GAP * (channel - 1) + IEEE80211_FIRST_FREQ;
92}
93
94/**
95 * Working procedure of connect function.
96 *
97 * @param ieee80211_dev Pointer to IEEE 802.11 device.
98 * @param auth_data Selected AP data we want to connect to.
99 *
100 * @return EOK if everything OK, ETIMEOUT when timeout during authenticating.
101 */
102static int ieee80211_connect_proc(ieee80211_dev_t *ieee80211_dev,
103 ieee80211_scan_result_link_t *auth_data, char *password)
104{
105 int rc;
106
107 ieee80211_dev->bssid_info.res_link = auth_data;
108
109 /* Set channel. */
110 rc = ieee80211_dev->ops->set_freq(ieee80211_dev,
111 ieee80211_channel_to_freq(auth_data->scan_result.channel));
112 if(rc != EOK)
113 return rc;
114
115 /* Try to authenticate. */
116 ieee80211_authenticate(ieee80211_dev);
117 fibril_mutex_lock(&ieee80211_dev->gen_mutex);
118 rc = fibril_condvar_wait_timeout(&ieee80211_dev->gen_cond,
119 &ieee80211_dev->gen_mutex,
120 AUTH_TIMEOUT);
121 fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
122 if(rc != EOK)
123 return rc;
124 if(ieee80211_dev->current_auth_phase != IEEE80211_AUTH_AUTHENTICATED)
125 return EINVAL;
126
127 /* Try to associate. */
128 ieee80211_associate(ieee80211_dev, password);
129 fibril_mutex_lock(&ieee80211_dev->gen_mutex);
130 rc = fibril_condvar_wait_timeout(&ieee80211_dev->gen_cond,
131 &ieee80211_dev->gen_mutex,
132 AUTH_TIMEOUT);
133 fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
134 if(rc != EOK)
135 return rc;
136 if(ieee80211_dev->current_auth_phase != IEEE80211_AUTH_ASSOCIATED)
137 return EINVAL;
138
139 /* On open network, we are finished. */
140 if(auth_data->scan_result.security.type == IEEE80211_SECURITY_OPEN)
141 return EOK;
142
143 /* Otherwise wait for 4-way handshake to complete. */
144 fibril_mutex_lock(&ieee80211_dev->gen_mutex);
145 rc = fibril_condvar_wait_timeout(&ieee80211_dev->gen_cond,
146 &ieee80211_dev->gen_mutex,
147 HANDSHAKE_TIMEOUT);
148 fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
149 if(rc != EOK)
150 return rc;
151 if(ieee80211_dev->current_auth_phase != IEEE80211_AUTH_ASSOCIATED)
152 return EINVAL;
153
154 return EOK;
155}
156
157/**
158 * Implementation of connecting to specified SSID.
159 *
160 * @param fun Device function.
161 * @param ssid_start SSID prefix of access point we want to connect to.
162 *
163 * @return EOK if everything OK, ETIMEOUT when timeout during authenticating,
164 * EINVAL when SSID not in scan results list, EPERM when incorrect password
165 * passed.
166 */
167int ieee80211_connect_impl(ddf_fun_t *fun, char *ssid_start, char *password)
168{
169 assert(ssid_start);
170 assert(password);
171
172 nic_t *nic_data = nic_get_from_ddf_fun(fun);
173 ieee80211_dev_t *ieee80211_dev = nic_get_specific(nic_data);
174
175 if(!ieee80211_is_ready(ieee80211_dev))
176 return EREFUSED;
177
178 if(ieee80211_is_connected(ieee80211_dev)) {
179 int rc = ieee80211_dev->iface->disconnect(fun);
180 if(rc != EOK)
181 return rc;
182 }
183
184 fibril_mutex_lock(&ieee80211_dev->ap_list.scan_mutex);
185
186 ieee80211_scan_result_list_foreach(ieee80211_dev->ap_list, result) {
187 if(!str_lcmp(ssid_start,
188 result->scan_result.ssid,
189 str_size(ssid_start))) {
190 fibril_mutex_unlock(&ieee80211_dev->ap_list.scan_mutex);
191 return ieee80211_connect_proc(ieee80211_dev, result,
192 password);
193 }
194 }
195
196 fibril_mutex_unlock(&ieee80211_dev->ap_list.scan_mutex);
197
198 return EINVAL;
199}
200
201/**
202 * Implementation of disconnecting device from network.
203 *
204 * @param fun Device function.
205 *
206 * @return EOK if everything OK, EINVAL when not connected to any network.
207 */
208int ieee80211_disconnect_impl(ddf_fun_t *fun)
209{
210 nic_t *nic_data = nic_get_from_ddf_fun(fun);
211 ieee80211_dev_t *ieee80211_dev = nic_get_specific(nic_data);
212
213 if(!ieee80211_is_ready(ieee80211_dev))
214 return EREFUSED;
215
216 if(!ieee80211_is_connected(ieee80211_dev)) {
217 return EINVAL;
218 } else {
219 return ieee80211_deauthenticate(ieee80211_dev);
220 }
221}
222
223/** @}
224 */
Note: See TracBrowser for help on using the repository browser.