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
RevLine 
[59fa7ab]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
[8a64320e]34 *
[59fa7ab]35 * IEEE 802.11 default interface functions implementation.
36 */
37
[8a64320e]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.
[1dcc0b9]46 * @param results Structure where should be stored scan results.
[8a64320e]47 *
48 * @return EOK if everything went OK,
49 * EREFUSED when device is not ready yet.
50 *
[1dcc0b9]51 */
[8a64320e]52int ieee80211_get_scan_results_impl(ddf_fun_t *fun,
53 ieee80211_scan_results_t *results, bool now)
[59fa7ab]54{
55 nic_t *nic_data = nic_get_from_ddf_fun(fun);
56 ieee80211_dev_t *ieee80211_dev = nic_get_specific(nic_data);
57
[8a64320e]58 if (!ieee80211_is_ready(ieee80211_dev))
[1dcc0b9]59 return EREFUSED;
60
[8a64320e]61 if (now)
[1dcc0b9]62 ieee80211_dev->ops->scan(ieee80211_dev);
63
[053fc2b]64 fibril_mutex_lock(&ieee80211_dev->ap_list.results_mutex);
[8a64320e]65
66 if (results) {
[1dcc0b9]67 ieee80211_scan_result_list_t *result_list =
[8a64320e]68 &ieee80211_dev->ap_list;
[1dcc0b9]69
[8a64320e]70 unsigned int i = 0;
[1dcc0b9]71 ieee80211_scan_result_list_foreach(*result_list, result) {
[8a64320e]72 memcpy(&results->results[i],
73 &result->scan_result,
74 sizeof(ieee80211_scan_result_t));
[1dcc0b9]75 i++;
76 }
77
78 results->length = i;
[59fa7ab]79 }
[8a64320e]80
[053fc2b]81 fibril_mutex_unlock(&ieee80211_dev->ap_list.results_mutex);
[59fa7ab]82
83 return EOK;
84}
85
[1dcc0b9]86static uint16_t ieee80211_channel_to_freq(uint8_t channel)
[59fa7ab]87{
[1dcc0b9]88 return IEEE80211_CHANNEL_GAP * (channel - 1) + IEEE80211_FIRST_FREQ;
89}
90
[8a64320e]91/** Working procedure of connect function.
92 *
[1dcc0b9]93 * @param ieee80211_dev Pointer to IEEE 802.11 device.
[8a64320e]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 *
[1dcc0b9]99 */
100static int ieee80211_connect_proc(ieee80211_dev_t *ieee80211_dev,
[8a64320e]101 ieee80211_scan_result_link_t *auth_data, char *password)
[1dcc0b9]102{
103 ieee80211_dev->bssid_info.res_link = auth_data;
104
105 /* Set channel. */
[8a64320e]106 int rc = ieee80211_dev->ops->set_freq(ieee80211_dev,
107 ieee80211_channel_to_freq(auth_data->scan_result.channel));
108 if (rc != EOK)
[1dcc0b9]109 return rc;
110
111 /* Try to authenticate. */
112 ieee80211_authenticate(ieee80211_dev);
[8a64320e]113
[1dcc0b9]114 fibril_mutex_lock(&ieee80211_dev->gen_mutex);
115 rc = fibril_condvar_wait_timeout(&ieee80211_dev->gen_cond,
[8a64320e]116 &ieee80211_dev->gen_mutex, AUTH_TIMEOUT);
[1dcc0b9]117 fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
[8a64320e]118
119 if (rc != EOK)
[1dcc0b9]120 return rc;
[8a64320e]121
122 if (ieee80211_get_auth_phase(ieee80211_dev) !=
123 IEEE80211_AUTH_AUTHENTICATED) {
124 ieee80211_set_auth_phase(ieee80211_dev,
125 IEEE80211_AUTH_DISCONNECTED);
[1dcc0b9]126 return EINVAL;
[053fc2b]127 }
[1dcc0b9]128
129 /* Try to associate. */
130 ieee80211_associate(ieee80211_dev, password);
[8a64320e]131
[1dcc0b9]132 fibril_mutex_lock(&ieee80211_dev->gen_mutex);
133 rc = fibril_condvar_wait_timeout(&ieee80211_dev->gen_cond,
[8a64320e]134 &ieee80211_dev->gen_mutex, AUTH_TIMEOUT);
[1dcc0b9]135 fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
[8a64320e]136
137 if (rc != EOK)
[1dcc0b9]138 return rc;
[8a64320e]139
140 if (ieee80211_get_auth_phase(ieee80211_dev) !=
141 IEEE80211_AUTH_ASSOCIATED) {
142 ieee80211_set_auth_phase(ieee80211_dev,
143 IEEE80211_AUTH_DISCONNECTED);
[1dcc0b9]144 return EINVAL;
[053fc2b]145 }
[1dcc0b9]146
147 /* On open network, we are finished. */
[8a64320e]148 if (auth_data->scan_result.security.type !=
149 IEEE80211_SECURITY_OPEN) {
[053fc2b]150 /* Otherwise wait for 4-way handshake to complete. */
[8a64320e]151
[053fc2b]152 fibril_mutex_lock(&ieee80211_dev->gen_mutex);
153 rc = fibril_condvar_wait_timeout(&ieee80211_dev->gen_cond,
[8a64320e]154 &ieee80211_dev->gen_mutex, HANDSHAKE_TIMEOUT);
[053fc2b]155 fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
[8a64320e]156
157 if (rc != EOK) {
[053fc2b]158 ieee80211_deauthenticate(ieee80211_dev);
159 return rc;
160 }
161 }
[1dcc0b9]162
[053fc2b]163 ieee80211_set_auth_phase(ieee80211_dev, IEEE80211_AUTH_CONNECTED);
[1dcc0b9]164
165 return EOK;
166}
167
[8a64320e]168/** Implementation of connecting to specified SSID.
169 *
170 * @param fun Device function.
[1dcc0b9]171 * @param ssid_start SSID prefix of access point we want to connect to.
[8a64320e]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 *
[1dcc0b9]179 */
180int ieee80211_connect_impl(ddf_fun_t *fun, char *ssid_start, char *password)
181{
182 assert(ssid_start);
[59fa7ab]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
[8a64320e]188 if (!ieee80211_is_ready(ieee80211_dev))
[1dcc0b9]189 return EREFUSED;
[59fa7ab]190
[8a64320e]191 if (ieee80211_is_connected(ieee80211_dev)) {
192 int rc = ieee80211_dev->iface->disconnect(fun);
193 if (rc != EOK)
[1dcc0b9]194 return rc;
195 }
196
[053fc2b]197 ieee80211_set_connect_request(ieee80211_dev);
198
[8a64320e]199 int rc = ENOENT;
[053fc2b]200 fibril_mutex_lock(&ieee80211_dev->scan_mutex);
201
202 ieee80211_dev->pending_conn_req = false;
[8a64320e]203
[1dcc0b9]204 ieee80211_scan_result_list_foreach(ieee80211_dev->ap_list, result) {
[8a64320e]205 if (!str_lcmp(ssid_start, result->scan_result.ssid,
206 str_size(ssid_start))) {
[053fc2b]207 rc = ieee80211_connect_proc(ieee80211_dev, result,
[8a64320e]208 password);
[053fc2b]209 break;
[1dcc0b9]210 }
211 }
212
[053fc2b]213 fibril_mutex_unlock(&ieee80211_dev->scan_mutex);
[1dcc0b9]214
[053fc2b]215 return rc;
[1dcc0b9]216}
217
[8a64320e]218/** Implementation of disconnecting device from network.
219 *
[1dcc0b9]220 * @param fun Device function.
[8a64320e]221 *
222 * @return EOK if everything OK,
223 * EREFUSED if device is not ready yet.
224 *
[1dcc0b9]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
[8a64320e]231 if (!ieee80211_is_ready(ieee80211_dev))
[1dcc0b9]232 return EREFUSED;
233
[8a64320e]234 if (!ieee80211_is_connected(ieee80211_dev))
[053fc2b]235 return EOK;
[8a64320e]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;
[59fa7ab]242}
243
244/** @}
[8a64320e]245 */
Note: See TracBrowser for help on using the repository browser.