Changeset 9e5a51c in mainline for uspace/lib


Ignore:
Timestamp:
2015-03-08T22:20:34Z (11 years ago)
Author:
Jan Kolarik <kolarik@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
864762a
Parents:
4cb0148
Message:

Fixed PLL initialization value that blocked communication with external devices. Started implementing IEEE802.11 scanning and authentication functions.

Location:
uspace/lib/net
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/net/ieee80211/ieee80211.c

    r4cb0148 r9e5a51c  
    4242#include <ieee80211.h>
    4343
     44/** Broadcast MAC address used to spread probe request through channel. */
     45static const uint8_t ieee80211_broadcast_mac_addr[] = {
     46        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
     47};
     48
     49/** IEEE 802.11 b/g supported data rates in units of 500 kb/s. */
     50static const uint8_t ieee80211bg_data_rates[] = {
     51        2, 4, 11, 12, 18, 22, 24, 36
     52};
     53
     54/** IEEE 802.11 b/g extended supported data rates in units of 500 kb/s.
     55 *
     56 *  These are defined separately, because probe request message can
     57 *  only handle up to 8 data rates in supported rates IE.
     58 */
     59static const uint8_t ieee80211bg_ext_data_rates[] = {
     60        48, 72, 96, 108
     61};
     62
    4463/** Network interface options for IEEE 802.11 driver. */
    4564static nic_iface_t ieee80211_nic_iface;
     
    4766/** Basic driver operations for IEEE 802.11 NIC driver. */
    4867static driver_ops_t ieee80211_nic_driver_ops;
    49 
    50 bool ieee80211_is_data_frame(ieee80211_header_t *header)
    51 {
    52         return (header->frame_ctrl &
    53                 host2uint16_t_le(IEEE80211_FRAME_CTRL_FRAME_TYPE)) ==
    54                 host2uint16_t_le(IEEE80211_FRAME_CTRL_DATA_FRAME);
    55 }
    5668
    5769static int ieee80211_open(ddf_fun_t *fun)
     
    7082                return rc;
    7183       
    72         /*
    7384        rc = ieee80211_dev->ops->scan(ieee80211_dev);
    7485        if(rc != EOK)
    7586                return rc;
    76          */
    7787       
    7888        return EOK;
     
    93103        /* IEEE802.11 TX handler must be implemented. */
    94104        if(!ieee80211_ops->tx_handler)
     105                return EINVAL;
     106       
     107        /* IEEE802.11 set frequency handler must be implemented. */
     108        if(!ieee80211_ops->set_freq)
    95109                return EINVAL;
    96110       
     
    119133        ieee80211_dev->current_op_mode = IEEE80211_OPMODE_STATION;
    120134       
     135        memcpy(ieee80211_dev->bssid_mask, ieee80211_broadcast_mac_addr,
     136                ETH_ADDR);
     137       
    121138        /* Bind NIC to device */
    122139        nic_t *nic = nic_create_and_bind(ddf_dev);
     
    175192}
    176193
     194static uint8_t ieee80211_freq_to_channel(uint16_t freq)
     195{
     196        return (freq - IEEE80211_FIRST_FREQ) / IEEE80211_CHANNEL_GAP + 1;
     197}
     198
     199int ieee80211_probe_request(ieee80211_dev_t *ieee80211_dev)
     200{
     201        nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev);
     202        nic_address_t nic_address;
     203        nic_query_address(nic, &nic_address);
     204       
     205        size_t data_rates_size =
     206                sizeof(ieee80211bg_data_rates) /
     207                sizeof(ieee80211bg_data_rates[0]);
     208       
     209        size_t ext_data_rates_size =
     210                sizeof(ieee80211bg_ext_data_rates) /
     211                sizeof(ieee80211bg_ext_data_rates[0]);
     212       
     213        /* 3 headers - (rates, ext rates, current channel) and their data
     214         * lengths + pad.
     215         */
     216        size_t payload_size =
     217                sizeof(ieee80211_ie_header_t) * 3 +
     218                data_rates_size + ext_data_rates_size + sizeof(uint8_t) + 2;
     219       
     220        size_t buffer_size = sizeof(ieee80211_mgmt_header_t) + payload_size;
     221        void *buffer = malloc(buffer_size);
     222        memset(buffer, 0, buffer_size);
     223       
     224        ieee80211_mgmt_header_t *mgmt_header =
     225                (ieee80211_mgmt_header_t *) buffer;
     226       
     227        mgmt_header->frame_ctrl = host2uint16_t_le(
     228                IEEE80211_MGMT_FRAME |
     229                IEEE80211_MGMT_PROBE_REQ_FRAME
     230                );
     231        memcpy(mgmt_header->dest_addr, ieee80211_broadcast_mac_addr, ETH_ADDR);
     232        memcpy(mgmt_header->src_addr, nic_address.address, ETH_ADDR);
     233        memcpy(mgmt_header->bssid, ieee80211_broadcast_mac_addr, ETH_ADDR);
     234       
     235        /* Jump to payload -> header + padding. */
     236        uint8_t *it = buffer + sizeof(ieee80211_mgmt_header_t) + 2;
     237       
     238        *it++ = IEEE80211_RATES_IE;
     239        *it++ = data_rates_size;
     240        memcpy(it, ieee80211bg_data_rates, data_rates_size);
     241        it += data_rates_size;
     242       
     243        *it++ = IEEE80211_EXT_RATES_IE;
     244        *it++ = ext_data_rates_size;
     245        memcpy(it, ieee80211bg_ext_data_rates, ext_data_rates_size);
     246        it += ext_data_rates_size;
     247       
     248        *it++ = IEEE80211_CHANNEL_IE;
     249        *it++ = 1;
     250        *it = ieee80211_freq_to_channel(ieee80211_dev->current_freq);
     251       
     252        ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size);
     253       
     254        free(buffer);
     255       
     256        return EOK;
     257}
     258
     259int ieee80211_probe_auth(ieee80211_dev_t *ieee80211_dev)
     260{
     261        uint8_t test_bssid[] = {0x14, 0xF6, 0x5A, 0xAF, 0x5E, 0xB7};
     262       
     263        nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev);
     264        nic_address_t nic_address;
     265        nic_query_address(nic, &nic_address);
     266       
     267        size_t buffer_size = sizeof(ieee80211_mgmt_header_t) +
     268                sizeof(ieee80211_auth_body_t);
     269        void *buffer = malloc(buffer_size);
     270        memset(buffer, 0, buffer_size);
     271       
     272        ieee80211_mgmt_header_t *mgmt_header =
     273                (ieee80211_mgmt_header_t *) buffer;
     274       
     275        mgmt_header->frame_ctrl = host2uint16_t_le(
     276                IEEE80211_MGMT_FRAME |
     277                IEEE80211_MGMT_AUTH_FRAME
     278                );
     279        memcpy(mgmt_header->dest_addr, test_bssid, ETH_ADDR);
     280        memcpy(mgmt_header->src_addr, nic_address.address, ETH_ADDR);
     281        memcpy(mgmt_header->bssid, test_bssid, ETH_ADDR);
     282       
     283        ieee80211_auth_body_t *auth_body =
     284                (ieee80211_auth_body_t *)
     285                (buffer + sizeof(ieee80211_mgmt_header_t));
     286        auth_body->auth_alg = host2uint16_t_le(0);
     287        auth_body->auth_trans_no = host2uint16_t_le(0);
     288       
     289        ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size);
     290       
     291        free(buffer);
     292       
     293        return EOK;
     294}
     295
    177296/** @}
    178297 */
  • uspace/lib/net/ieee80211/ieee80211_impl.c

    r4cb0148 r9e5a51c  
    4040#include <ieee80211_impl.h>
    4141
    42 static int ieee80211_freq_to_channel(uint16_t freq)
    43 {
    44         return (freq - IEEE80211_FIRST_FREQ) / IEEE80211_CHANNEL_GAP + 1;
    45 }
    46 
    47 static int ieee80211_probe_request(ieee80211_dev_t *ieee80211_dev)
    48 {
    49         size_t buffer_size = sizeof(ieee80211_header_t);
    50         void *buffer = malloc(buffer_size);
    51        
    52         /* TODO */
    53        
    54         ieee80211_freq_to_channel(ieee80211_dev->current_freq);
    55        
    56         ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size);
    57        
    58         free(buffer);
    59        
    60         return EOK;
    61 }
    62 
    6342/**
    6443 * Default implementation of IEEE802.11 scan function.
     
    7049int ieee80211_scan_impl(ieee80211_dev_t *ieee80211_dev)
    7150{
    72         /* TODO */
    73         int rc = ieee80211_probe_request(ieee80211_dev);
    74         if(rc != EOK)
    75                 return rc;
     51        uint16_t orig_freq = ieee80211_dev->current_freq;
     52       
     53        for(uint16_t freq = IEEE80211_FIRST_FREQ;
     54                freq <= IEEE80211_MAX_FREQ;
     55                freq += IEEE80211_CHANNEL_GAP) {
     56                ieee80211_dev->ops->set_freq(ieee80211_dev, freq);
     57                ieee80211_probe_request(ieee80211_dev);
     58               
     59                /* Wait for probe responses. */
     60                usleep(100000);
     61        }
     62       
     63        ieee80211_dev->ops->set_freq(ieee80211_dev, orig_freq);
     64       
     65        /* TODO: Collect results. */
    7666       
    7767        return EOK;
  • uspace/lib/net/include/ieee80211.h

    r4cb0148 r9e5a51c  
    5252#define IEEE80211_CHANNEL_GAP 5
    5353
    54 #define IEEE80211_FRAME_CTRL_FRAME_TYPE 0x000C
    55 #define IEEE80211_FRAME_CTRL_DATA_FRAME 0x0008
    56 
    5754struct ieee80211_dev;
    5855
     
    6562} ieee80211_operating_mode_t;
    6663
     64/** IEEE 802.11 frame types. */
     65typedef enum {
     66        IEEE80211_MGMT_FRAME = 0x0,
     67        IEEE80211_CTRL_FRAME = 0x4,
     68        IEEE80211_DATA_FRAME = 0x8,
     69        IEEE80211_EXT_FRAME = 0xC
     70} ieee80211_frame_type_t;
     71
     72/** IEEE 802.11 frame subtypes. */
     73typedef enum {
     74        IEEE80211_MGMT_ASSOC_REQ_FRAME = 0x00,
     75        IEEE80211_MGMT_ASSOC_RESP_FRAME = 0x10,
     76        IEEE80211_MGMT_REASSOC_REQ_FRAME = 0x20,
     77        IEEE80211_MGMT_REASSOC_RESP_FRAME = 0x30,
     78        IEEE80211_MGMT_PROBE_REQ_FRAME = 0x40,
     79        IEEE80211_MGMT_PROBE_RESP_FRAME = 0x50,
     80        IEEE80211_MGMT_BEACON_FRAME = 0x80,
     81        IEEE80211_MGMT_DIASSOC_FRAME = 0xA0,
     82        IEEE80211_MGMT_AUTH_FRAME = 0xB0,
     83        IEEE80211_MGMT_DEAUTH_FRAME = 0xC0,
     84} ieee80211_frame_subtype_t;
     85
     86/** IEEE 802.11 information element types. */
     87typedef enum {
     88        IEEE80211_SSID_IE = 0,          /**< Target SSID. */
     89        IEEE80211_RATES_IE = 1,         /**< Supported data rates. */
     90        IEEE80211_CHANNEL_IE = 3,       /**< Current channel number. */
     91        IEEE80211_EXT_RATES_IE = 50     /**< Extended data rates. */
     92} ieee80211_ie_type_t;
     93
    6794/** IEEE 802.11 functions. */
    6895typedef struct {
     
    7097        int (*scan)(struct ieee80211_dev *);
    7198        int (*tx_handler)(struct ieee80211_dev *, void *, size_t);
     99        int (*set_freq)(struct ieee80211_dev *, uint16_t);
    72100} ieee80211_ops_t;
    73101
     
    89117        ieee80211_operating_mode_t current_op_mode;
    90118       
     119        /** BSSIDs we listen to. */
     120        uint8_t bssid_mask[ETH_ADDR];
     121       
    91122        /* TODO: Probably to be removed later - nic.open function is now
    92123         * executed multiple times, have to find out reason and fix it.
     
    96127} ieee80211_dev_t;
    97128
    98 /** IEEE 802.11 header structure. */
     129/** IEEE 802.11 management header structure. */
     130typedef struct {
     131        uint16_t frame_ctrl;            /**< Little Endian value! */
     132        uint16_t duration_id;           /**< Little Endian value! */
     133        uint8_t dest_addr[ETH_ADDR];
     134        uint8_t src_addr[ETH_ADDR];
     135        uint8_t bssid[ETH_ADDR];
     136        uint16_t seq_ctrl;              /**< Little Endian value! */
     137} __attribute__((packed)) __attribute__ ((aligned(2))) ieee80211_mgmt_header_t;
     138
     139/** IEEE 802.11 data header structure. */
    99140typedef struct {
    100141        uint16_t frame_ctrl;            /**< Little Endian value! */
     
    105146        uint16_t seq_ctrl;              /**< Little Endian value! */
    106147        uint8_t address4[ETH_ADDR];
    107 } __attribute__((packed)) __attribute__ ((aligned(2))) ieee80211_header_t;
     148        uint16_t qos_ctrl;              /**< Little Endian value! */
     149} __attribute__((packed)) __attribute__ ((aligned(2))) ieee80211_data_header_t;
    108150
    109 extern bool ieee80211_is_data_frame(ieee80211_header_t *header);
     151/** IEEE 802.11 information element header. */
     152typedef struct {
     153        uint8_t element_id;
     154        uint8_t length;
     155} __attribute__((packed)) __attribute__ ((aligned(2))) ieee80211_ie_header_t;
     156
     157/** IEEE 802.11 authentication frame body. */
     158typedef struct {
     159        uint16_t auth_alg;              /**< Little Endian value! */
     160        uint16_t auth_trans_no;         /**< Little Endian value! */
     161        uint16_t status;                /**< Little Endian value! */
     162} __attribute__((packed)) __attribute__ ((aligned(2))) ieee80211_auth_body_t;
     163
     164typedef struct {
     165        uint8_t bssid[ETH_ADDR];
     166        uint16_t auth_alg;
     167} __attribute__((packed)) __attribute__ ((aligned(2))) ieee80211_auth_data_t;
     168
    110169extern int ieee80211_device_init(ieee80211_dev_t *ieee80211_dev,
    111170        void *driver_data, ddf_dev_t *ddf_dev);
    112171extern int ieee80211_init(ieee80211_dev_t *ieee80211_dev,
    113172        ieee80211_ops_t *ieee80211_ops);
     173extern int ieee80211_probe_request(ieee80211_dev_t *ieee80211_dev);
     174extern int ieee80211_probe_auth(ieee80211_dev_t *ieee80211_dev);
    114175
    115176#endif /* LIBNET_IEEE80211_H */
Note: See TracChangeset for help on using the changeset viewer.