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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since db51a6a6 was 8a64320e, checked in by Martin Decky <martin@…>, 10 years ago

pre-merge coding style cleanup and code review

  • Property mode set to 100644
File size: 6.9 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/** @addtogroup libieee80211
30 * @{
31 */
32
33/** @file ieee80211_iface_impl.c
34 *
35 * IEEE 802.11 default interface functions implementation.
36 */
37
38#include <str.h>
39#include <errno.h>
40#include <ieee80211_private.h>
41#include <ieee80211_iface_impl.h>
42
43/** Implementation of fetching scan results.
44 *
45 * @param fun Device function.
46 * @param results Structure where should be stored scan results.
47 *
48 * @return EOK if everything went OK,
49 * EREFUSED when device is not ready yet.
50 *
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 if (now)
62 ieee80211_dev->ops->scan(ieee80211_dev);
63
64 fibril_mutex_lock(&ieee80211_dev->ap_list.results_mutex);
65
66 if (results) {
67 ieee80211_scan_result_list_t *result_list =
68 &ieee80211_dev->ap_list;
69
70 unsigned int i = 0;
71 ieee80211_scan_result_list_foreach(*result_list, result) {
72 memcpy(&results->results[i],
73 &result->scan_result,
74 sizeof(ieee80211_scan_result_t));
75 i++;
76 }
77
78 results->length = i;
79 }
80
81 fibril_mutex_unlock(&ieee80211_dev->ap_list.results_mutex);
82
83 return EOK;
84}
85
86static uint16_t ieee80211_channel_to_freq(uint8_t channel)
87{
88 return IEEE80211_CHANNEL_GAP * (channel - 1) + IEEE80211_FIRST_FREQ;
89}
90
91/** Working procedure of connect function.
92 *
93 * @param ieee80211_dev Pointer to IEEE 802.11 device.
94 * @param auth_data Selected AP data we want to connect to.
95 *
96 * @return EOK if everything OK,
97 * ETIMEOUT when timeout during authenticating.
98 *
99 */
100static int ieee80211_connect_proc(ieee80211_dev_t *ieee80211_dev,
101 ieee80211_scan_result_link_t *auth_data, char *password)
102{
103 ieee80211_dev->bssid_info.res_link = auth_data;
104
105 /* Set channel. */
106 int rc = ieee80211_dev->ops->set_freq(ieee80211_dev,
107 ieee80211_channel_to_freq(auth_data->scan_result.channel));
108 if (rc != EOK)
109 return rc;
110
111 /* Try to authenticate. */
112 ieee80211_authenticate(ieee80211_dev);
113
114 fibril_mutex_lock(&ieee80211_dev->gen_mutex);
115 rc = fibril_condvar_wait_timeout(&ieee80211_dev->gen_cond,
116 &ieee80211_dev->gen_mutex, AUTH_TIMEOUT);
117 fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
118
119 if (rc != EOK)
120 return rc;
121
122 if (ieee80211_get_auth_phase(ieee80211_dev) !=
123 IEEE80211_AUTH_AUTHENTICATED) {
124 ieee80211_set_auth_phase(ieee80211_dev,
125 IEEE80211_AUTH_DISCONNECTED);
126 return EINVAL;
127 }
128
129 /* Try to associate. */
130 ieee80211_associate(ieee80211_dev, password);
131
132 fibril_mutex_lock(&ieee80211_dev->gen_mutex);
133 rc = fibril_condvar_wait_timeout(&ieee80211_dev->gen_cond,
134 &ieee80211_dev->gen_mutex, AUTH_TIMEOUT);
135 fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
136
137 if (rc != EOK)
138 return rc;
139
140 if (ieee80211_get_auth_phase(ieee80211_dev) !=
141 IEEE80211_AUTH_ASSOCIATED) {
142 ieee80211_set_auth_phase(ieee80211_dev,
143 IEEE80211_AUTH_DISCONNECTED);
144 return EINVAL;
145 }
146
147 /* On open network, we are finished. */
148 if (auth_data->scan_result.security.type !=
149 IEEE80211_SECURITY_OPEN) {
150 /* Otherwise wait for 4-way handshake to complete. */
151
152 fibril_mutex_lock(&ieee80211_dev->gen_mutex);
153 rc = fibril_condvar_wait_timeout(&ieee80211_dev->gen_cond,
154 &ieee80211_dev->gen_mutex, HANDSHAKE_TIMEOUT);
155 fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
156
157 if (rc != EOK) {
158 ieee80211_deauthenticate(ieee80211_dev);
159 return rc;
160 }
161 }
162
163 ieee80211_set_auth_phase(ieee80211_dev, IEEE80211_AUTH_CONNECTED);
164
165 return EOK;
166}
167
168/** Implementation of connecting to specified SSID.
169 *
170 * @param fun Device function.
171 * @param ssid_start SSID prefix of access point we want to connect to.
172 *
173 * @return EOK if everything OK,
174 * ETIMEOUT when timeout during authenticating,
175 * EINVAL when SSID not in scan results list,
176 * EPERM when incorrect password passed,
177 * EREFUSED when device is not ready yet.
178 *
179 */
180int ieee80211_connect_impl(ddf_fun_t *fun, char *ssid_start, char *password)
181{
182 assert(ssid_start);
183 assert(password);
184
185 nic_t *nic_data = nic_get_from_ddf_fun(fun);
186 ieee80211_dev_t *ieee80211_dev = nic_get_specific(nic_data);
187
188 if (!ieee80211_is_ready(ieee80211_dev))
189 return EREFUSED;
190
191 if (ieee80211_is_connected(ieee80211_dev)) {
192 int rc = ieee80211_dev->iface->disconnect(fun);
193 if (rc != EOK)
194 return rc;
195 }
196
197 ieee80211_set_connect_request(ieee80211_dev);
198
199 int rc = ENOENT;
200 fibril_mutex_lock(&ieee80211_dev->scan_mutex);
201
202 ieee80211_dev->pending_conn_req = false;
203
204 ieee80211_scan_result_list_foreach(ieee80211_dev->ap_list, result) {
205 if (!str_lcmp(ssid_start, result->scan_result.ssid,
206 str_size(ssid_start))) {
207 rc = ieee80211_connect_proc(ieee80211_dev, result,
208 password);
209 break;
210 }
211 }
212
213 fibril_mutex_unlock(&ieee80211_dev->scan_mutex);
214
215 return rc;
216}
217
218/** Implementation of disconnecting device from network.
219 *
220 * @param fun Device function.
221 *
222 * @return EOK if everything OK,
223 * EREFUSED if device is not ready yet.
224 *
225 */
226int ieee80211_disconnect_impl(ddf_fun_t *fun)
227{
228 nic_t *nic_data = nic_get_from_ddf_fun(fun);
229 ieee80211_dev_t *ieee80211_dev = nic_get_specific(nic_data);
230
231 if (!ieee80211_is_ready(ieee80211_dev))
232 return EREFUSED;
233
234 if (!ieee80211_is_connected(ieee80211_dev))
235 return EOK;
236
237 fibril_mutex_lock(&ieee80211_dev->ap_list.results_mutex);
238 int rc = ieee80211_deauthenticate(ieee80211_dev);
239 fibril_mutex_unlock(&ieee80211_dev->ap_list.results_mutex);
240
241 return rc;
242}
243
244/** @}
245 */
Note: See TracBrowser for help on using the repository browser.