Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 053fc2b in mainline


Ignore:
Timestamp:
2015-04-10T13:52:11Z (7 years ago)
Author:
Jan Kolarik <kolarik@…>
Branches:
lfn, master
Children:
a931b7b
Parents:
d7dadcb4
Message:

Locking, correctly disconnecting device, sending DHCP address discover after connecting to WiFi? network

Location:
uspace
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/wifi_supplicant/wifi_supplicant.c

    rd7dadcb4 r053fc2b  
    3636#include <ieee80211_iface.h>
    3737
     38#include <inet/inetcfg.h>
     39#include <inet/dhcp.h>
    3840#include <errno.h>
    3941#include <stdio.h>
     
    173175        }
    174176       
    175         int rc = ieee80211_connect(sess, ssid_start, password);
     177        int rc = ieee80211_disconnect(sess);
     178        if(rc != EOK) {
     179                if(rc == EREFUSED) {
     180                        printf("Device is not ready yet.\n");                   
     181                } else {
     182                        printf("Error when disconnecting device. "
     183                                "Error: %d\n", rc);
     184                }
     185               
     186                return rc;
     187        }
     188       
     189        ieee80211_connect(sess, ssid_start, password);
    176190        if(rc != EOK) {
    177191                if(rc == EREFUSED) {
     
    179193                } else if(rc == ETIMEOUT) {
    180194                        printf("Timeout when authenticating to network.\n");
    181                 } else if(rc == EPERM) {
    182                         printf("Bad password provided.\n");
     195                } else if(rc == ENOENT) {
     196                        printf("Given SSID not in scan results.\n");
    183197                } else {
    184198                        printf("Error when connecting to network. "
     
    188202                return rc;
    189203        }
     204       
     205        // TODO: Wait for DHCP address ?
    190206       
    191207        printf("Successfully connected to network!\n");
     
    274290        int rc;
    275291        uint32_t index;
     292       
     293        rc = inetcfg_init();
     294        if (rc != EOK) {
     295                printf(NAME ": Failed connecting to inetcfg service (%d).\n",
     296                    rc);
     297                return 1;
     298        }
     299       
     300        rc = dhcp_init();
     301        if (rc != EOK) {
     302                printf(NAME ": Failed connecting to dhcp service (%d).\n", rc);
     303                return 1;
     304        }
    276305       
    277306        if(argc == 2) {
  • uspace/drv/nic/ar9271/ar9271.c

    rd7dadcb4 r053fc2b  
    105105static int ar9271_ieee80211_set_freq(ieee80211_dev_t *ieee80211_dev,
    106106        uint16_t freq);
    107 static int ar9271_ieee80211_bssid_change(ieee80211_dev_t *ieee80211_dev);
     107static int ar9271_ieee80211_bssid_change(ieee80211_dev_t *ieee80211_dev,
     108        bool connected);
    108109static int ar9271_ieee80211_key_config(ieee80211_dev_t *ieee80211_dev,
    109110        ieee80211_key_config_t *key_conf, bool insert);
     
    351352        ar9271_t *ar9271 = (ar9271_t *) ieee80211_get_specific(ieee80211_dev);
    352353       
    353         //hw_wakeup(ar9271);
    354        
    355354        wmi_send_command(ar9271->htc_device, WMI_DISABLE_INTR, NULL, 0, NULL);
    356355        wmi_send_command(ar9271->htc_device, WMI_DRAIN_TXQ_ALL, NULL, 0, NULL);
     
    379378}
    380379
    381 static int ar9271_ieee80211_bssid_change(ieee80211_dev_t *ieee80211_dev)
     380static int ar9271_ieee80211_bssid_change(ieee80211_dev_t *ieee80211_dev,
     381        bool connected)
    382382{
    383383        assert(ieee80211_dev);
     
    385385        ar9271_t *ar9271 = (ar9271_t *) ieee80211_get_specific(ieee80211_dev);
    386386
    387         /* Check if we are connected or disconnected. */
    388         if(ieee80211_is_connected(ieee80211_dev)) {
     387        if(connected) {
    389388                nic_address_t bssid;
    390389                ieee80211_query_bssid(ieee80211_dev, &bssid);
     
    433432{
    434433        assert(ieee80211_dev);
    435         assert(key_conf);
    436434       
    437435        ar9271_t *ar9271 = (ar9271_t *) ieee80211_get_specific(ieee80211_dev);
    438436       
    439         uint32_t key[5];
    440         uint32_t key_type;
    441         uint32_t reg_ptr;
    442         void *data_start;
    443        
    444437        if(insert) {
     438                assert(key_conf);
     439               
     440                uint32_t key[5];
     441                uint32_t key_type;
     442                uint32_t reg_ptr;
     443                void *data_start;
     444               
    445445                nic_address_t bssid;
    446446                ieee80211_query_bssid(ieee80211_dev, &bssid);
     
    520520                        ieee80211_setup_key_confirm(ieee80211_dev, true);
    521521        } else {
    522                 // TODO
     522                // TODO: Delete keys from device
     523                ieee80211_setup_key_confirm(ieee80211_dev, false);
    523524        }
    524525       
     
    562563                        data_header->keyix = AR9271_STA_KEY_INDEX;
    563564                        int sec_suite =
    564                                 ieee80211_get_security_suite(ieee80211_dev);
     565                                ieee80211_get_pairwise_security(ieee80211_dev);
    565566                        switch(sec_suite) {
    566567                                case IEEE80211_SECURITY_SUITE_WEP40:
  • uspace/drv/nic/ar9271/hw.c

    rd7dadcb4 r053fc2b  
    377377}
    378378
    379 int hw_wakeup(ar9271_t *ar9271)
    380 {
    381         int rc;
    382        
    383         uint32_t rtc_status;
    384         wmi_reg_read(ar9271->htc_device, AR9271_RTC_STATUS, &rtc_status);
    385         if((rtc_status & AR9271_RTC_STATUS_MASK) == AR9271_RTC_STATUS_SHUTDOWN) {
    386                 rc = hw_reset_power_on(ar9271);
    387                 if(rc != EOK) {
    388                         usb_log_info("Failed to HW reset power on.\n");
    389                         return rc;
    390                 }
    391 
    392                 rc = hw_set_reset(ar9271, false);
    393                 if(rc != EOK) {
    394                         usb_log_info("Failed to HW warm reset.\n");
    395                         return rc;
    396                 }
    397         }
    398        
    399         wmi_reg_set_bit(ar9271->htc_device, AR9271_RTC_FORCE_WAKE,
    400                 AR9271_RTC_FORCE_WAKE_ENABLE);
    401        
    402         size_t i;
    403         for(i = 0; i < HW_WAIT_LOOPS; i++) {
    404                 wmi_reg_read(ar9271->htc_device, AR9271_RTC_STATUS,
    405                         &rtc_status);
    406                 if((rtc_status & AR9271_RTC_STATUS_MASK) ==
    407                         AR9271_RTC_STATUS_ON) {
    408                         break;
    409                 }
    410                 wmi_reg_set_bit(ar9271->htc_device, AR9271_RTC_FORCE_WAKE,
    411                         AR9271_RTC_FORCE_WAKE_ENABLE);
    412                 udelay(50);
    413         }       
    414        
    415         if(i == HW_WAIT_LOOPS) {
    416                 return EINVAL;
    417         } else {
    418                 return EOK;
    419         }
    420 }
    421 
    422379int hw_freq_switch(ar9271_t *ar9271, uint16_t freq)
    423380{
  • uspace/drv/nic/ar9271/hw.h

    rd7dadcb4 r053fc2b  
    4545extern int hw_rx_init(ar9271_t *ar9271);
    4646extern int hw_reset(ar9271_t *ar9271);
    47 extern int hw_wakeup(ar9271_t *ar9271);
    4847extern int hw_set_bssid(ar9271_t *ar9271);
    4948extern int hw_set_rx_filter(ar9271_t *ar9271, bool assoc);
  • uspace/lib/c/generic/dhcp.c

    rd7dadcb4 r053fc2b  
    8484}
    8585
     86int dhcp_discover(sysarg_t link_id)
     87{
     88        async_exch_t *exch = async_exchange_begin(dhcp_sess);
     89
     90        int rc = async_req_1_0(exch, DHCP_DISCOVER, link_id);
     91        async_exchange_end(exch);
     92
     93        return rc;
     94}
     95
    8696/** @}
    8797 */
  • uspace/lib/c/include/inet/dhcp.h

    rd7dadcb4 r053fc2b  
    4141extern int dhcp_link_add(sysarg_t);
    4242extern int dhcp_link_remove(sysarg_t);
     43extern int dhcp_discover(sysarg_t);
    4344
    4445#endif
  • uspace/lib/c/include/ipc/dhcp.h

    rd7dadcb4 r053fc2b  
    4141typedef enum {
    4242        DHCP_LINK_ADD = IPC_FIRST_USER_METHOD,
    43         DHCP_LINK_REMOVE
     43        DHCP_LINK_REMOVE,
     44        DHCP_DISCOVER
    4445} dhcp_request_t;
    4546
  • uspace/lib/drv/generic/remote_ieee80211.c

    rd7dadcb4 r053fc2b  
    3838#include <macros.h>
    3939#include <str.h>
     40#include <inet/dhcp.h>
     41#include <inet/inetcfg.h>
    4042
    4143#include "ops/ieee80211.h"
    4244#include "ieee80211_iface.h"
     45#include "nic_iface.h"
    4346
    4447#define MAX_STRING_SIZE 32
     
    8083}
    8184
     85static bool mac_matches(uint8_t *mac1, uint8_t *mac2)
     86{
     87        for(size_t i = 0; i < ETH_ADDR; i++) {
     88                if(mac1[i] != mac2[i])
     89                        return false;
     90        }
     91       
     92        return true;
     93}
     94
     95static sysarg_t get_link_id(uint8_t *mac)
     96{
     97        sysarg_t *link_list;
     98        inet_link_info_t link_info;
     99        size_t count;
     100       
     101        int rc = inetcfg_get_link_list(&link_list, &count);
     102        if (rc != EOK)
     103                return -1;
     104       
     105        for (size_t i = 0; i < count; i++) {
     106                rc = inetcfg_link_get(link_list[i], &link_info);
     107                if (rc != EOK)
     108                        return -1;
     109               
     110                if(mac_matches(mac, link_info.mac_addr)) {
     111                        return link_list[i];
     112                }
     113        }
     114       
     115        return -1;
     116}
     117
    82118/** Connect to specified network.
    83119 *
     
    130166
    131167        async_wait_for(aid, &rc);
     168        if (rc != EOK)
     169                return rc;
     170       
     171        /* Send DHCP discover. */
     172        nic_address_t wifi_mac;
     173        rc = nic_get_address(dev_sess, &wifi_mac);
     174        if (rc != EOK)
     175                return rc;
     176       
     177        sysarg_t link_id = get_link_id(wifi_mac.address);
     178        if(link_id == ((sysarg_t) -1))
     179                return EINVAL;
     180       
     181        rc = dhcp_discover(link_id);
    132182       
    133183        return (int) rc;
     
    147197            IEEE80211_DISCONNECT);
    148198        async_exchange_end(exch);
     199       
     200        if(rc != EOK)
     201                return rc;
     202       
     203        nic_address_t wifi_mac;
     204        rc = nic_get_address(dev_sess, &wifi_mac);
     205        if (rc != EOK)
     206                return rc;
     207       
     208        inet_link_info_t link_info;
     209        inet_addr_info_t addr_info;
     210        inet_sroute_info_t route_info;
     211        sysarg_t *addr_list;
     212        sysarg_t *route_list;
     213        size_t count;
     214       
     215        /* Remove previous DHCP address. */
     216        rc = inetcfg_get_addr_list(&addr_list, &count);
     217        if (rc != EOK)
     218                return rc;
     219       
     220        for (size_t i = 0; i < count; i++) {
     221                rc = inetcfg_addr_get(addr_list[i], &addr_info);
     222                if (rc != EOK)
     223                        return rc;
     224               
     225                rc = inetcfg_link_get(addr_info.ilink, &link_info);
     226                if (rc != EOK)
     227                        return rc;
     228               
     229                if(mac_matches(wifi_mac.address, link_info.mac_addr)) {
     230                        if(str_test_prefix(addr_info.name, "dhcp")) {
     231                                rc = inetcfg_addr_delete(addr_list[i]);
     232                                if(rc != EOK)
     233                                        return rc;
     234                                break;
     235                        }
     236                }
     237        }
     238       
     239        /*
     240         * TODO: At this moment there can be only one DHCP route,
     241         * so it must be reimplemented after this limitation will be
     242         * dropped.
     243         */
     244        /* Remove previous DHCP static route. */
     245        rc = inetcfg_get_sroute_list(&route_list, &count);
     246        if (rc != EOK)
     247                return rc;
     248       
     249        for (size_t i = 0; i < count; i++) {
     250                rc = inetcfg_sroute_get(route_list[i], &route_info);
     251                if (rc != EOK)
     252                        return rc;
     253               
     254                if(str_test_prefix(route_info.name, "dhcp")) {
     255                        rc = inetcfg_sroute_delete(route_list[i]);
     256                        if(rc != EOK)
     257                                return rc;
     258                        break;
     259                }
     260        }
    149261       
    150262        return rc;
  • uspace/lib/ieee80211/include/ieee80211.h

    rd7dadcb4 r053fc2b  
    6060#define IEEE80211_MAX_AMPDU_FACTOR 13
    6161
    62 /* Max passphrase length in WPA/WPA2 protocols. */
    63 #define IEEE80211_WPA_MAX_PASSWORD_LENGTH 64
     62/* Max authentication password length. */
     63#define IEEE80211_MAX_PASSW_LEN 64
    6464
    6565/** IEEE 802.11 b/g supported data rates in units of 500 kb/s. */
     
    139139         *
    140140         * @param ieee80211_dev Pointer to IEEE 802.11 device structure.
    141          *
    142          * @return EOK if succeed, negative error code otherwise.
    143          */
    144         int (*bssid_change)(struct ieee80211_dev *);
     141         * @param connected True if connected to new BSSID, otherwise false.
     142         *
     143         * @return EOK if succeed, negative error code otherwise.
     144         */
     145        int (*bssid_change)(struct ieee80211_dev *, bool);
    145146       
    146147        /**
     
    181182        uint16_t freq);
    182183extern uint16_t ieee80211_get_aid(ieee80211_dev_t* ieee80211_dev);
    183 extern int ieee80211_get_security_suite(ieee80211_dev_t* ieee80211_dev);
     184extern int ieee80211_get_pairwise_security(ieee80211_dev_t* ieee80211_dev);
    184185extern bool ieee80211_is_ready(ieee80211_dev_t* ieee80211_dev);
    185186extern void ieee80211_set_ready(ieee80211_dev_t* ieee80211_dev, bool ready);
  • uspace/lib/ieee80211/include/ieee80211_impl.h

    rd7dadcb4 r053fc2b  
    4747extern int ieee80211_set_freq_impl(ieee80211_dev_t *ieee80211_dev,
    4848        uint16_t freq);
    49 extern int ieee80211_bssid_change_impl(ieee80211_dev_t *ieee80211_dev);
     49extern int ieee80211_bssid_change_impl(ieee80211_dev_t *ieee80211_dev,
     50        bool connected);
    5051extern int ieee80211_key_config_impl(ieee80211_dev_t *ieee80211_dev,
    5152        ieee80211_key_config_t *key_conf, bool insert);
  • uspace/lib/ieee80211/include/ieee80211_private.h

    rd7dadcb4 r053fc2b  
    5454#define HANDSHAKE_TIMEOUT 3000000
    5555
    56 /* Max period to rerun scan. */
    57 #define MAX_SCAN_SPAN_SEC 30
     56/* Scanning period. */
     57#define SCAN_PERIOD_USEC 35000000
     58
     59/* Time to wait for beacons on channel. */
     60#define SCAN_CHANNEL_WAIT_USEC 200000
    5861
    5962/* Max time to keep scan result. */
     
    187190        IEEE80211_AUTH_DISCONNECTED,
    188191        IEEE80211_AUTH_AUTHENTICATED,
    189         IEEE80211_AUTH_ASSOCIATED
     192        IEEE80211_AUTH_ASSOCIATED,
     193        IEEE80211_AUTH_CONNECTED
    190194} ieee80211_auth_phase_t;
    191195
     
    202206typedef struct {
    203207        list_t list;
    204         time_t last_scan;
    205         fibril_mutex_t scan_mutex;
     208        fibril_mutex_t results_mutex;
    206209        size_t size;
    207210} ieee80211_scan_result_list_t;
     
    210213typedef struct {
    211214        uint16_t aid;
    212         char password[IEEE80211_WPA_MAX_PASSWORD_LENGTH];
     215        char password[IEEE80211_MAX_PASSW_LEN];
    213216        uint8_t ptk[MAX_PTK_LENGTH];
    214217        uint8_t gtk[MAX_GTK_LENGTH];
     
    256259        /** Current authentication phase. */
    257260        ieee80211_auth_phase_t current_auth_phase;
     261       
     262        /** Flag indicating whether client wants connect to network. */
     263        bool pending_conn_req;
     264       
     265        /** Scanning guard. */
     266        fibril_mutex_t scan_mutex;
    258267       
    259268        /** General purpose guard. */
     
    368377{
    369378        list_initialize(&results->list);
    370         fibril_mutex_initialize(&results->scan_mutex);
     379        fibril_mutex_initialize(&results->results_mutex);
    371380}
    372381
     
    387396}
    388397
     398extern void ieee80211_set_connect_request(ieee80211_dev_t *ieee80211_dev);
     399extern bool ieee80211_pending_connect_request(ieee80211_dev_t *ieee80211_dev);
     400extern ieee80211_auth_phase_t ieee80211_get_auth_phase(ieee80211_dev_t
     401        *ieee80211_dev);
     402extern void ieee80211_set_auth_phase(ieee80211_dev_t *ieee80211_dev,
     403        ieee80211_auth_phase_t auth_phase);
    389404extern int ieee80211_probe_request(ieee80211_dev_t *ieee80211_dev,
    390405        char *ssid);
  • uspace/lib/ieee80211/src/ieee80211.c

    rd7dadcb4 r053fc2b  
    5151#define IEEE80211_EXT_DATA_RATES_SIZE 4
    5252
     53#define ATOMIC_GET(state)
     54
    5355/** Frame encapsulation used in IEEE 802.11. */
    5456static const uint8_t rfc1042_header[] = {
     
    282284        ieee80211_dev)
    283285{
    284         return ieee80211_dev->current_op_mode;
     286        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
     287        ieee80211_operating_mode_t op_mode = ieee80211_dev->current_op_mode;
     288        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
     289       
     290        return op_mode;
    285291}
    286292
     
    294300uint16_t ieee80211_query_current_freq(ieee80211_dev_t* ieee80211_dev)
    295301{
    296         return ieee80211_dev->current_freq;
     302        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
     303        uint16_t current_freq = ieee80211_dev->current_freq;
     304        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
     305       
     306        return current_freq;
    297307}
    298308
    299309/**
    300310 * Query BSSID the device is connected to.
     311 *
     312 * Note: Expecting locked results_mutex.
    301313 *
    302314 * @param ieee80211_dev IEEE 802.11 device.
     
    306318        nic_address_t *bssid)
    307319{
     320        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
     321       
    308322        if(bssid) {
    309                 ieee80211_scan_result_t *auth_data =
    310                         &ieee80211_dev->bssid_info.res_link->scan_result;
    311                
    312                 memcpy(bssid, (void *)&auth_data->bssid, sizeof(nic_address_t));
    313         }
     323                ieee80211_scan_result_link_t *res_link =
     324                        ieee80211_dev->bssid_info.res_link;
     325               
     326                if(res_link) {
     327                        memcpy(bssid, &res_link->scan_result.bssid,
     328                                sizeof(nic_address_t));
     329                } else {
     330                        nic_address_t broadcast_addr;
     331                        memcpy(broadcast_addr.address,
     332                                ieee80211_broadcast_mac_addr,
     333                                ETH_ADDR);
     334                        memcpy(bssid, &broadcast_addr, sizeof(nic_address_t));
     335                }
     336        }
     337       
     338        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
    314339}
    315340
     
    323348uint16_t ieee80211_get_aid(ieee80211_dev_t* ieee80211_dev)
    324349{
    325         return ieee80211_dev->bssid_info.aid;
    326 }
    327 
    328 /**
    329  * Get security suite used for HW encryption.
     350        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
     351        uint16_t aid = ieee80211_dev->bssid_info.aid;
     352        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
     353       
     354        return aid;
     355}
     356
     357/**
     358 * Get pairwise security suite used for HW encryption.
    330359 *
    331360 * @param ieee80211_dev IEEE 802.11 device.
     
    333362 * @return Security suite indicator.
    334363 */
    335 int ieee80211_get_security_suite(ieee80211_dev_t* ieee80211_dev)
    336 {
     364int ieee80211_get_pairwise_security(ieee80211_dev_t* ieee80211_dev)
     365{
     366        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
    337367        ieee80211_scan_result_link_t *auth_link =
    338368                ieee80211_dev->bssid_info.res_link;
    339        
    340         return auth_link->scan_result.security.pair_alg;
     369        int suite = auth_link->scan_result.security.pair_alg;
     370        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
     371       
     372        return suite;
    341373}
    342374
     
    350382bool ieee80211_is_connected(ieee80211_dev_t* ieee80211_dev)
    351383{
    352         return ieee80211_dev->current_auth_phase == IEEE80211_AUTH_ASSOCIATED;
     384        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
     385        bool conn_state =
     386                ieee80211_dev->current_auth_phase == IEEE80211_AUTH_CONNECTED;
     387        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
     388        return conn_state;
     389}
     390
     391void ieee80211_set_auth_phase(ieee80211_dev_t *ieee80211_dev,
     392        ieee80211_auth_phase_t auth_phase)
     393{
     394        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
     395        ieee80211_dev->current_auth_phase = auth_phase;
     396        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
     397}
     398
     399ieee80211_auth_phase_t ieee80211_get_auth_phase(ieee80211_dev_t
     400        *ieee80211_dev)
     401{
     402        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
     403        ieee80211_auth_phase_t conn_state = ieee80211_dev->current_auth_phase;
     404        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
     405        return conn_state;
     406}
     407
     408void ieee80211_set_connect_request(ieee80211_dev_t *ieee80211_dev)
     409{
     410        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
     411        ieee80211_dev->pending_conn_req = true;
     412        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
     413}
     414
     415bool ieee80211_pending_connect_request(ieee80211_dev_t *ieee80211_dev)
     416{
     417        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
     418        bool conn_request = ieee80211_dev->pending_conn_req;
     419        ieee80211_dev->pending_conn_req = false;
     420        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
     421        return conn_request;
    353422}
    354423
     
    362431        ieee80211_operating_mode_t op_mode)
    363432{
     433        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
    364434        ieee80211_dev->current_op_mode = op_mode;
     435        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
    365436}
    366437
     
    374445        uint16_t freq)
    375446{
     447        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
    376448        ieee80211_dev->current_freq = freq;
     449        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
    377450}
    378451
     
    408481extern bool ieee80211_query_using_key(ieee80211_dev_t* ieee80211_dev)
    409482{
    410         return ieee80211_dev->using_hw_key;
     483        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
     484        bool using_key = ieee80211_dev->using_hw_key;
     485        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
     486       
     487        return using_key;
    411488}
    412489
     
    414491        bool using_key)
    415492{
     493        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
    416494        ieee80211_dev->using_hw_key = using_key;
     495        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
     496}
     497
     498static int ieee80211_scan(void *arg)
     499{
     500        assert(arg);
     501       
     502        ieee80211_dev_t *ieee80211_dev = (ieee80211_dev_t *) arg;
     503       
     504        while(true) {
     505                ieee80211_dev->ops->scan(ieee80211_dev);
     506                async_usleep(35000000);
     507        }
     508       
     509        return EOK;
    417510}
    418511
     
    439532                return rc;
    440533       
    441         rc = ieee80211_dev->ops->scan(ieee80211_dev);
    442         if(rc != EOK)
    443                 return rc;
     534        /* Add scanning fibril. */
     535        fid_t fibril = fibril_create(ieee80211_scan, ieee80211_dev);
     536        if (fibril == 0) {
     537                return ENOMEM;
     538        }
     539        fibril_add_ready(fibril);
    444540       
    445541        return EOK;
     
    458554                nic_get_specific(nic);
    459555       
    460         if(!ieee80211_is_connected(ieee80211_dev)) {
     556        ieee80211_auth_phase_t auth_phase =
     557                ieee80211_get_auth_phase(ieee80211_dev);
     558        if(auth_phase != IEEE80211_AUTH_ASSOCIATED &&
     559                auth_phase != IEEE80211_AUTH_CONNECTED) {
    461560                return;
    462561        }
     
    478577        memset(add_data, 0, 8);
    479578       
    480         if(ieee80211_dev->using_hw_key) {
     579        if(ieee80211_query_using_key(ieee80211_dev)) {
    481580                int sec_suite = auth_data->security.pair_alg;
    482581                switch(sec_suite) {
     
    630729        ieee80211_dev->ready = false;
    631730        ieee80211_dev->using_hw_key = false;
     731        ieee80211_dev->pending_conn_req = false;
    632732        ieee80211_dev->current_op_mode = IEEE80211_OPMODE_STATION;
    633733        ieee80211_dev->current_auth_phase = IEEE80211_AUTH_DISCONNECTED;
     
    637737        ieee80211_scan_result_list_init(&ieee80211_dev->ap_list);
    638738       
     739        fibril_mutex_initialize(&ieee80211_dev->scan_mutex);
    639740        fibril_mutex_initialize(&ieee80211_dev->gen_mutex);
    640741        fibril_condvar_initialize(&ieee80211_dev->gen_cond);
     
    9231024       
    9241025        /*
    925          * Save password and SSID to be used in eventual authentication
    926          * handshake.
     1026         * Save password to be used in eventual authentication handshake.
    9271027         */
     1028        memset(ieee80211_dev->bssid_info.password, 0, IEEE80211_MAX_PASSW_LEN);
    9281029        memcpy(ieee80211_dev->bssid_info.password, password,
    9291030                str_size(password));
     
    9451046        ieee80211_scan_result_t *auth_data =
    9461047                &ieee80211_dev->bssid_info.res_link->scan_result;
    947        
    948         ieee80211_dev->current_auth_phase = IEEE80211_AUTH_DISCONNECTED;
    949         ieee80211_dev->bssid_info.aid = (uint16_t) -1;
    950         memcpy(auth_data->bssid.address, ieee80211_broadcast_mac_addr,
    951                 ETH_ADDR);
    9521048       
    9531049        nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev);
     
    9751071        free(buffer);
    9761072       
    977         ieee80211_dev->ops->bssid_change(ieee80211_dev);
     1073        ieee80211_dev->bssid_info.res_link = NULL;
     1074        ieee80211_dev->ops->bssid_change(ieee80211_dev, false);
     1075       
     1076        if(ieee80211_query_using_key(ieee80211_dev))
     1077                ieee80211_dev->ops->key_config(ieee80211_dev, NULL, false);
     1078       
     1079        ieee80211_set_auth_phase(ieee80211_dev, IEEE80211_AUTH_DISCONNECTED);
    9781080       
    9791081        return EOK;
     
    11211223        /* Not empty SSID. */
    11221224        if(ssid_ie_header->length > 0) {
    1123                 fibril_mutex_t *scan_mutex = &ieee80211_dev->ap_list.scan_mutex;
    1124                
    1125                 fibril_mutex_lock(scan_mutex);
    1126                
    11271225                ieee80211_scan_result_list_t *result_list =
    11281226                        &ieee80211_dev->ap_list;
     
    11381236                        if(!str_cmp(ssid, result->scan_result.ssid)) {
    11391237                                result->last_beacon = time(NULL);
    1140                                 fibril_mutex_unlock(scan_mutex);
    11411238                                return EOK;
    11421239                        }
     
    11451242                /* Results are full. */
    11461243                if(result_list->size == IEEE80211_MAX_RESULTS_LENGTH - 1) {
    1147                         fibril_mutex_unlock(scan_mutex);
    11481244                        return EOK;
    11491245                }
     
    11831279                ap_data->last_beacon = time(NULL);
    11841280               
     1281                fibril_mutex_lock(&ieee80211_dev->ap_list.results_mutex);
    11851282                ieee80211_scan_result_list_append(result_list, ap_data);
    1186                
    1187                 fibril_mutex_unlock(scan_mutex);
     1283                fibril_mutex_unlock(&ieee80211_dev->ap_list.results_mutex);
    11881284        }
    11891285       
     
    12021298        ieee80211_mgmt_header_t *mgmt_header)
    12031299{
    1204         fibril_mutex_lock(&ieee80211_dev->gen_mutex);
    1205        
    1206         ieee80211_dev->current_auth_phase = IEEE80211_AUTH_AUTHENTICATED;
    1207        
     1300        ieee80211_auth_body_t *auth_body =
     1301                (ieee80211_auth_body_t *)
     1302                ((void *)mgmt_header + sizeof(ieee80211_mgmt_header_t));
     1303       
     1304        if(auth_body->status != 0) {
     1305                ieee80211_set_auth_phase(ieee80211_dev,
     1306                        IEEE80211_AUTH_DISCONNECTED);
     1307        } else {
     1308                ieee80211_set_auth_phase(ieee80211_dev,
     1309                        IEEE80211_AUTH_AUTHENTICATED);
     1310        }
     1311       
     1312        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
    12081313        fibril_condvar_signal(&ieee80211_dev->gen_cond);
    12091314        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
     
    12231328        ieee80211_mgmt_header_t *mgmt_header)
    12241329{
    1225         ieee80211_scan_result_t *auth_data =
    1226                 &ieee80211_dev->bssid_info.res_link->scan_result;
    1227        
    1228         fibril_mutex_lock(&ieee80211_dev->gen_mutex);
    1229        
    12301330        ieee80211_assoc_resp_body_t *assoc_resp =
    12311331                (ieee80211_assoc_resp_body_t *) ((void *)mgmt_header +
    12321332                sizeof(ieee80211_mgmt_header_t));
    12331333       
    1234         ieee80211_dev->bssid_info.aid = uint16_t_le2host(assoc_resp->aid);
    1235         memcpy(auth_data->bssid.address, mgmt_header->bssid, ETH_ADDR);
    1236        
    1237         ieee80211_dev->current_auth_phase = IEEE80211_AUTH_ASSOCIATED;
    1238        
    1239         ieee80211_dev->ops->bssid_change(ieee80211_dev);
    1240        
     1334        if(assoc_resp->status != 0) {
     1335                ieee80211_set_auth_phase(ieee80211_dev,
     1336                        IEEE80211_AUTH_DISCONNECTED);
     1337        } else {
     1338                ieee80211_dev->bssid_info.aid =
     1339                        uint16_t_le2host(assoc_resp->aid);
     1340                ieee80211_set_auth_phase(ieee80211_dev,
     1341                        IEEE80211_AUTH_ASSOCIATED);
     1342                ieee80211_dev->ops->bssid_change(ieee80211_dev, true);
     1343        }
     1344       
     1345        fibril_mutex_lock(&ieee80211_dev->gen_mutex);
    12411346        fibril_condvar_signal(&ieee80211_dev->gen_cond);
    12421347        fibril_mutex_unlock(&ieee80211_dev->gen_mutex);
     
    14181523
    14191524        if(handshake_done) {
    1420                 /* Insert keys into device. */
    1421                
    1422                 /* Pairwise key. */
     1525                /* Insert Pairwise key. */
    14231526                ieee80211_key_config_t key_config;
    14241527                key_config.suite = auth_data->security.pair_alg;
     
    14321535                        &key_config, true);
    14331536               
    1434                 /* Group key. */
     1537                /* Insert Group key. */
    14351538                key_config.suite = auth_data->security.group_alg;
    14361539                key_config.flags =
  • uspace/lib/ieee80211/src/ieee80211_iface_impl.c

    rd7dadcb4 r053fc2b  
    4848 * @param results Structure where should be stored scan results.
    4949 *
    50  * @return EOK.
     50 * @return EOK if everything went OK, EREFUSED when device is not ready yet.
    5151 */
    5252int ieee80211_get_scan_results_impl(ddf_fun_t *fun,
     
    5959                return EREFUSED;
    6060       
    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) {
     61        if(now) {
    6662                ieee80211_dev->ops->scan(ieee80211_dev);
    6763        }
    6864       
    69         fibril_mutex_lock(&ieee80211_dev->ap_list.scan_mutex);
     65        fibril_mutex_lock(&ieee80211_dev->ap_list.results_mutex);
    7066        if(results) {
    7167                ieee80211_scan_result_list_t *result_list =
     
    8278                results->length = i;
    8379        }
    84         fibril_mutex_unlock(&ieee80211_dev->ap_list.scan_mutex);
     80        fibril_mutex_unlock(&ieee80211_dev->ap_list.results_mutex);
    8581       
    8682        return EOK;
     
    10399        ieee80211_scan_result_link_t *auth_data, char *password)
    104100{
    105         int rc;
    106        
    107101        ieee80211_dev->bssid_info.res_link = auth_data;
    108102       
    109103        /* Set channel. */
    110         rc = ieee80211_dev->ops->set_freq(ieee80211_dev,
     104        int rc = ieee80211_dev->ops->set_freq(ieee80211_dev,
    111105                ieee80211_channel_to_freq(auth_data->scan_result.channel));
    112106        if(rc != EOK)
     
    122116        if(rc != EOK)
    123117                return rc;
    124         if(ieee80211_dev->current_auth_phase != IEEE80211_AUTH_AUTHENTICATED)
     118        if(ieee80211_get_auth_phase(ieee80211_dev) !=
     119                IEEE80211_AUTH_AUTHENTICATED) {
     120                ieee80211_set_auth_phase(ieee80211_dev,
     121                        IEEE80211_AUTH_DISCONNECTED);
    125122                return EINVAL;
     123        }
    126124       
    127125        /* Try to associate. */
     
    134132        if(rc != EOK)
    135133                return rc;
    136         if(ieee80211_dev->current_auth_phase != IEEE80211_AUTH_ASSOCIATED)
     134        if(ieee80211_get_auth_phase(ieee80211_dev) !=
     135                IEEE80211_AUTH_ASSOCIATED) {
     136                ieee80211_set_auth_phase(ieee80211_dev,
     137                        IEEE80211_AUTH_DISCONNECTED);
    137138                return EINVAL;
     139        }
    138140       
    139141        /* 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;
     142        if(auth_data->scan_result.security.type != IEEE80211_SECURITY_OPEN) {
     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                        ieee80211_deauthenticate(ieee80211_dev);
     151                        return rc;
     152                }
     153        }
     154       
     155        ieee80211_set_auth_phase(ieee80211_dev, IEEE80211_AUTH_CONNECTED);
    153156       
    154157        return EOK;
     
    163166 * @return EOK if everything OK, ETIMEOUT when timeout during authenticating,
    164167 * EINVAL when SSID not in scan results list, EPERM when incorrect password
    165  * passed.
     168 * passed, EREFUSED when device is not ready yet.
    166169 */
    167170int ieee80211_connect_impl(ddf_fun_t *fun, char *ssid_start, char *password)
     
    170173        assert(password);
    171174       
     175        int rc;
     176       
    172177        nic_t *nic_data = nic_get_from_ddf_fun(fun);
    173178        ieee80211_dev_t *ieee80211_dev = nic_get_specific(nic_data);
     
    177182       
    178183        if(ieee80211_is_connected(ieee80211_dev)) {
    179                 int rc = ieee80211_dev->iface->disconnect(fun);
     184                rc = ieee80211_dev->iface->disconnect(fun);
    180185                if(rc != EOK)
    181186                        return rc;
    182187        }
    183188       
    184         fibril_mutex_lock(&ieee80211_dev->ap_list.scan_mutex);
     189        ieee80211_set_connect_request(ieee80211_dev);
     190       
     191        rc = ENOENT;
     192        fibril_mutex_lock(&ieee80211_dev->scan_mutex);
     193       
     194        ieee80211_dev->pending_conn_req = false;
    185195
    186196        ieee80211_scan_result_list_foreach(ieee80211_dev->ap_list, result) {
     
    188198                        result->scan_result.ssid,
    189199                        str_size(ssid_start))) {
    190                         fibril_mutex_unlock(&ieee80211_dev->ap_list.scan_mutex);
    191                         return ieee80211_connect_proc(ieee80211_dev, result,
     200                        rc = ieee80211_connect_proc(ieee80211_dev, result,
    192201                                password);
     202                        break;
    193203                }
    194204        }
    195205       
    196         fibril_mutex_unlock(&ieee80211_dev->ap_list.scan_mutex);
    197        
    198         return EINVAL;
     206        fibril_mutex_unlock(&ieee80211_dev->scan_mutex);
     207       
     208        return rc;
    199209}
    200210
     
    204214 * @param fun Device function.
    205215 *
    206  * @return EOK if everything OK, EINVAL when not connected to any network.
     216 * @return EOK if everything OK, EREFUSED if device is not ready yet.
    207217 */
    208218int ieee80211_disconnect_impl(ddf_fun_t *fun)
     
    215225       
    216226        if(!ieee80211_is_connected(ieee80211_dev)) {
    217                 return EINVAL;
     227                return EOK;
    218228        } else {
    219                 return ieee80211_deauthenticate(ieee80211_dev);
     229                fibril_mutex_lock(&ieee80211_dev->ap_list.results_mutex);
     230                int rc = ieee80211_deauthenticate(ieee80211_dev);
     231                fibril_mutex_unlock(&ieee80211_dev->ap_list.results_mutex);
     232                return rc;
    220233        }
    221234}
  • uspace/lib/ieee80211/src/ieee80211_impl.c

    rd7dadcb4 r053fc2b  
    9090 * @return EOK.
    9191 */
    92 int ieee80211_bssid_change_impl(ieee80211_dev_t *ieee80211_dev)
     92int ieee80211_bssid_change_impl(ieee80211_dev_t *ieee80211_dev,
     93        bool connected)
    9394{
    9495        return EOK;
     
    118119int ieee80211_scan_impl(ieee80211_dev_t *ieee80211_dev)
    119120{
    120         if(ieee80211_is_connected(ieee80211_dev))
    121                 return EOK;
    122        
    123         fibril_mutex_lock(&ieee80211_dev->ap_list.scan_mutex);
    124        
    125         /* Remove old entries we don't receive beacons from. */
    126         ieee80211_scan_result_list_t *result_list =
    127                 &ieee80211_dev->ap_list;
    128         list_foreach_safe(result_list->list, cur_link, next_link) {
    129                 ieee80211_scan_result_link_t *cur_result =
    130                         list_get_instance(cur_link,
    131                         ieee80211_scan_result_link_t,
    132                         link);
    133                 if((time(NULL) - cur_result->last_beacon) >
    134                         MAX_KEEP_SCAN_SPAN_SEC) {
    135                         ieee80211_scan_result_list_remove(result_list,
    136                                 cur_result);
     121        fibril_mutex_lock(&ieee80211_dev->scan_mutex);
     122       
     123        if(ieee80211_get_auth_phase(ieee80211_dev) ==
     124                IEEE80211_AUTH_DISCONNECTED) {
     125                fibril_mutex_lock(&ieee80211_dev->ap_list.results_mutex);
     126                /* Remove old entries we don't receive beacons from. */
     127                ieee80211_scan_result_list_t *result_list =
     128                        &ieee80211_dev->ap_list;
     129                list_foreach_safe(result_list->list, cur_link, next_link) {
     130                        ieee80211_scan_result_link_t *cur_result =
     131                                list_get_instance(cur_link,
     132                                ieee80211_scan_result_link_t,
     133                                link);
     134                        if((time(NULL) - cur_result->last_beacon) >
     135                                MAX_KEEP_SCAN_SPAN_SEC) {
     136                                ieee80211_scan_result_list_remove(result_list,
     137                                        cur_result);
     138                        }
    137139                }
    138         }
    139        
    140         fibril_mutex_unlock(&ieee80211_dev->ap_list.scan_mutex);
    141        
    142         uint16_t orig_freq = ieee80211_dev->current_freq;
    143        
    144         for(uint16_t freq = IEEE80211_FIRST_FREQ;
    145                 freq <= IEEE80211_MAX_FREQ;
    146                 freq += IEEE80211_CHANNEL_GAP) {
    147                 ieee80211_dev->ops->set_freq(ieee80211_dev, freq);
    148                 ieee80211_probe_request(ieee80211_dev, NULL);
    149                
    150                 /* Wait for probe responses. */
    151                 usleep(100000);
    152         }
    153        
    154         ieee80211_dev->ops->set_freq(ieee80211_dev, orig_freq);
    155        
    156         fibril_mutex_lock(&ieee80211_dev->ap_list.scan_mutex);
    157         time(&ieee80211_dev->ap_list.last_scan);
    158         fibril_mutex_unlock(&ieee80211_dev->ap_list.scan_mutex);
     140                fibril_mutex_unlock(&ieee80211_dev->ap_list.results_mutex);
     141
     142                uint16_t orig_freq = ieee80211_dev->current_freq;
     143
     144                for(uint16_t freq = IEEE80211_FIRST_FREQ;
     145                        freq <= IEEE80211_MAX_FREQ;
     146                        freq += IEEE80211_CHANNEL_GAP) {
     147                        if(ieee80211_pending_connect_request(ieee80211_dev)) {
     148                                break;
     149                        }
     150                       
     151                        ieee80211_dev->ops->set_freq(ieee80211_dev, freq);
     152                        ieee80211_probe_request(ieee80211_dev, NULL);
     153
     154                        /* Wait for probe responses. */
     155                        async_usleep(SCAN_CHANNEL_WAIT_USEC);
     156                }
     157
     158                ieee80211_dev->ops->set_freq(ieee80211_dev, orig_freq);
     159        }
     160       
     161        fibril_mutex_unlock(&ieee80211_dev->scan_mutex);
    159162       
    160163        return EOK;
  • uspace/srv/net/dhcp/dhcp.c

    rd7dadcb4 r053fc2b  
    418418}
    419419
     420static int dhcp_discover_proc(dhcp_link_t *dlink)
     421{
     422        dlink->state = ds_selecting;
     423
     424        int rc = dhcp_send_discover(dlink);
     425        if (rc != EOK)
     426                return EIO;
     427
     428        dlink->retries_left = dhcp_discover_retries;
     429       
     430        if(dlink->timeout->state == fts_not_set ||
     431                dlink->timeout->state == fts_fired) {
     432                fibril_timer_set(dlink->timeout, dhcp_discover_timeout_val,
     433                        dhcpsrv_discover_timeout, dlink);
     434        }
     435       
     436        return rc;
     437}
     438
    420439int dhcpsrv_link_add(service_id_t link_id)
    421440{
     
    459478        }
    460479
    461         dlink->state = ds_selecting;
    462 
    463480        log_msg(LOG_DEFAULT, LVL_DEBUG, "Send DHCPDISCOVER");
    464         rc = dhcp_send_discover(dlink);
     481        rc = dhcp_discover_proc(dlink);
    465482        if (rc != EOK) {
    466483                log_msg(LOG_DEFAULT, LVL_ERROR, "Error sending DHCPDISCOVER.");
     
    469486                goto error;
    470487        }
    471 
    472         dlink->retries_left = dhcp_discover_retries;
    473         fibril_timer_set(dlink->timeout, dhcp_discover_timeout_val,
    474             dhcpsrv_discover_timeout, dlink);
    475488
    476489        list_append(&dlink->links, &dhcp_links);
     
    487500{
    488501        return ENOTSUP;
     502}
     503
     504int dhcpsrv_discover(service_id_t link_id)
     505{
     506        log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcpsrv_link_add(%zu)", link_id);
     507       
     508        dhcp_link_t *dlink = dhcpsrv_link_find(link_id);
     509
     510        if (dlink == NULL) {
     511                log_msg(LOG_DEFAULT, LVL_NOTE, "Link %zu doesn't exist",
     512                    link_id);
     513                return EINVAL;
     514        }
     515       
     516        return dhcp_discover_proc(dlink);
    489517}
    490518
  • uspace/srv/net/dhcp/dhcp.h

    rd7dadcb4 r053fc2b  
    4343extern int dhcpsrv_link_add(service_id_t);
    4444extern int dhcpsrv_link_remove(service_id_t);
     45extern int dhcpsrv_discover(service_id_t);
    4546
    4647#endif
  • uspace/srv/net/dhcp/main.c

    rd7dadcb4 r053fc2b  
    109109}
    110110
     111static void dhcp_discover_srv(ipc_callid_t callid, ipc_call_t *call)
     112{
     113        sysarg_t link_id;
     114        int rc;
     115
     116        log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcp_discover_srv()");
     117
     118        link_id = IPC_GET_ARG1(*call);
     119
     120        rc = dhcpsrv_discover(link_id);
     121        async_answer_0(callid, rc);
     122}
     123
    111124static void dhcp_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    112125{
     
    133146                case DHCP_LINK_REMOVE:
    134147                        dhcp_link_remove_srv(callid, &call);
     148                        break;
     149                case DHCP_DISCOVER:
     150                        dhcp_discover_srv(callid, &call);
    135151                        break;
    136152                default:
Note: See TracChangeset for help on using the changeset viewer.