[802.11] Revamped probe, fully asynchronous association, better error handling, much...
[people/oremanj/gpxe.git] / src / include / gpxe / net80211.h
index eeeb3af..85d8a6d 100644 (file)
@@ -173,27 +173,33 @@ enum net80211_crypto_alg {
 /** Whether the error code provided is a "reason" code, not a "status" code */
 #define NET80211_IS_REASON     0x80
 
+/** Whether we have found the network we will be associating with */
+#define NET80211_PROBED                (1 << 8)
+
 /** Whether we have successfully authenticated with the network
  *
  * This usually has nothing to do with actual security; it is a
  * holdover from older 802.11 implementation ideas.
  */
-#define NET80211_AUTHENTICATED  (1 << 8)
+#define NET80211_AUTHENTICATED  (1 << 9)
 
 /** Whether we have successfully associated with the network */
-#define NET80211_ASSOCIATED     (1 << 9)
+#define NET80211_ASSOCIATED     (1 << 10)
 
 /** Whether we have completed security handshaking with the network
  *
  * Once this is set, we can send data packets.
  */
-#define NET80211_CRYPTO_SYNCED  (1 << 10)
+#define NET80211_CRYPTO_SYNCED  (1 << 11)
 
 /** Whether the auto-association task is running */
-#define NET80211_WORKING        (1 << 11)
+#define NET80211_WORKING        (1 << 12)
 
 /** Whether the auto-association task is waiting for a reply from the AP */
-#define NET80211_WAITING        (1 << 12)
+#define NET80211_WAITING        (1 << 13)
+
+/** Whether the auto-association task should be suppressed */
+#define NET80211_NO_ASSOC      (1 << 14)
 
 /** @} */
 
@@ -600,6 +606,11 @@ struct net80211_crypto
        void *priv;
 };
 
+
+struct net80211_probe_ctx;
+struct net80211_assoc_ctx;
+
+
 /** Structure encapsulating the complete state of an 802.11 device
  *
  * An 802.11 device is always wrapped by a network device, and this
@@ -628,20 +639,7 @@ struct net80211_device
        /** Information about the hardware, provided to net80211_register() */
        struct net80211_hw_info *hw;
 
-       /** The asynchronous association process.
-        *
-        * When an 802.11 netdev is opened, or when the user changes
-        * the SSID setting on an open 802.11 device, an
-        * autoassociation task is started by net80211_autoassocate()
-        * to associate with the new best network. The association is
-        * generally asynchronous but may block for a few seconds
-        * during network probing. If it is successful, the wrapping
-        * net_device is set as "link up".
-        */
-       struct process proc_assoc;
-
-       /** Data structure for the association process. */
-       struct net80211_wlan *associating;
+       /* ---------- Channel and rate fields ---------- */
 
        /** A list of all possible channels we might use */
        struct net80211_channel channels[NET80211_MAX_CHANNELS];
@@ -683,19 +681,53 @@ struct net80211_device
         */
        u32 basic_rates;
 
+       /* ---------- Association fields ---------- */
+
+       /** The asynchronous association process.
+        *
+        * When an 802.11 netdev is opened, or when the user changes
+        * the SSID setting on an open 802.11 device, an
+        * autoassociation task is started by net80211_autoassocate()
+        * to associate with the new best network. The association is
+        * asynchronous, but no packets can be transmitted until it is
+        * complete. If it is successful, the wrapping net_device is
+        * set as "link up". If it fails, @c assoc_rc will be set with
+        * an error indication.
+        */
+       struct process proc_assoc;
+
+       /** Network with which we are associating
+        *
+        * This will be NULL when we are not associating or we haven't
+        * yet probed to determine the parameters of the network we
+        * are associating with.
+        */
+       struct net80211_wlan *associating;
+
+       /** Context for the association process
+        *
+        * This is a probe_ctx if the @c PROBED flag is not set in @c
+        * state, and an assoc_ctx otherwise.
+        */
+       union {
+               struct net80211_probe_ctx *probe;
+               struct net80211_assoc_ctx *assoc;
+       } ctx;
+
        /** State of our association to the network
         *
         * Since the association process happens asynchronously, it's
         * necessary to have some channel of communication so the
         * driver can say "I got an association reply and we're OK" or
         * similar. This variable provides that link. It is a bitmask
-        * of any of NET80211_AUTHENTICATED, NET80211_ASSOCIATED,
-        * NET80211_CRYPTO_SYNCED to indicate how far along in
-        * associating we are; NET80211_WORKING if the association
-        * task is running; and NET80211_WAITING if a packet has been
-        * sent that we're waiting for a reply to. We can only be
-        * crypto-synced if we're associated, and we can only be
-        * associated if we're authenticated.
+        * of any of NET80211_PROBED, NET80211_AUTHENTICATED,
+        * NET80211_ASSOCIATED, NET80211_CRYPTO_SYNCED to indicate how
+        * far along in associating we are; NET80211_WORKING if the
+        * association task is running; and NET80211_WAITING if a
+        * packet has been sent that we're waiting for a reply to. We
+        * can only be crypto-synced if we're associated, we can
+        * only be associated if we're authenticated, we can only be
+        * authenticated if we've probed.
         *
         * If an association process fails (that is, we receive a
         * packet with an error indication), the error code is copied
@@ -706,16 +738,25 @@ struct net80211_device
         * defined) explaining why it canceled an association after it
         * had originally OK'ed it. Status and reason codes serve
         * similar functions, but they use separate error message
-        * tables.
+        * tables. A gPXE-formatted return code (negative) is placed
+        * in @c assoc_rc.
         *
         * If the failure to associate is indicated by a status code,
         * the NET80211_IS_REASON bit will be clear; if it is
         * indicated by a reason code, the bit will be set. If we were
         * successful, both zero status and zero reason mean success,
         * so there is no ambiguity.
+        *
+        * To prevent association when opening the device, user code
+        * can set the NET80211_NO_ASSOC bit.
         */
        short state;
 
+       /** gPXE error code associated with @c state */
+       int assoc_rc;
+
+       /* ---------- Parameters of currently associated network ---------- */
+
        /** 802.11 cryptographic algorithm for our current network
         *
         * For an open network, this will be set to NULL.
@@ -736,6 +777,8 @@ struct net80211_device
        /** Association ID given to us by the AP */
        u16 aid;
 
+       /* ---------- Physical layer information ---------- */
+
        /** Physical layer options
         *
         * These control the use of CTS protection, short preambles,
@@ -746,6 +789,8 @@ struct net80211_device
        /** Signal strength of last received packet */
        int last_signal;
 
+       /* ---------- Packet handling state ---------- */
+
        /** Fragment reassembly state */
        struct net80211_frag_cache frags[NET80211_NR_CONCURRENT_FRAGS];
 
@@ -808,10 +853,6 @@ struct net80211_device
  * association functions. At least essid, bssid, channel, beacon, and
  * security must be filled in if you want to build this structure
  * manually.
- *
- * This structure is also used by the MAC layer in coordinating the
- * association state machine for associating with the network it
- * represents.
  */
 struct net80211_wlan
 {
@@ -840,18 +881,11 @@ struct net80211_wlan
        /** The complete beacon or probe-response frame received */
        struct io_buffer *beacon;
 
-       /** One of the NET80211_CRYPT_* constants indicating the
-           security mode of the network. */
-       int security;
-
-       /** Next authentication method to try using */
-       int method;
+       /** Security handshaking method used on the network */
+       enum net80211_security_proto handshaking;
 
-       /** Time (in ticks) of the last sent association-related packet */
-       int last_packet;
-
-       /** Number of times we have tried sending it */
-       int times_tried;
+       /** Cryptographic algorithm used on the network */
+       enum net80211_crypto_alg crypto;
 
        /** Link to allow chaining multiple structures into a list to
            be returned from net80211_scan(). */
@@ -863,18 +897,24 @@ struct net80211_wlan
 void net80211_autoassociate ( struct net80211_device *dev );
 
 /* Find networks: */
-struct net80211_wlan * net80211_probe ( struct net80211_device *dev,
-                                       const char *essid, int active );
+struct net80211_probe_ctx * net80211_probe_start ( struct net80211_device *dev,
+                                                  const char *essid,
+                                                  int active );
+int net80211_probe_step ( struct net80211_probe_ctx *ctx );
+struct net80211_wlan *net80211_probe_finish_best ( struct net80211_probe_ctx *ctx );
+struct list_head *net80211_probe_finish_all ( struct net80211_probe_ctx *ctx );
+
 void net80211_free_wlan ( struct net80211_wlan *wlan );
+void net80211_free_wlanlist ( struct list_head *list );
 
 /* Get the 802.11 device from a wrapping net_device: */
 struct net80211_device * net80211_get ( struct net_device *netdev );
 
 /* Association steps: */
-int net80211_prepare_default ( struct net80211_device *dev, int band,
-                              int active );
-int net80211_prepare ( struct net80211_device *dev,
-                      struct net80211_wlan *wlan );
+int net80211_prepare_probe ( struct net80211_device *dev, int band,
+                            int active );
+int net80211_prepare_assoc ( struct net80211_device *dev,
+                            struct net80211_wlan *wlan );
 int net80211_send_auth ( struct net80211_device *dev,
                         struct net80211_wlan *wlan, int method );
 int net80211_send_assoc ( struct net80211_device *dev,