Scanning problem for hidden SSIDs

Dan Williams dcbw at redhat.com
Fri Jun 22 10:17:37 EDT 2007


On Fri, 2007-06-22 at 14:23 +0200, Holger Schurig wrote:
> > The problem is that the scan is TLV-based, and that we can only
> > scan 2 or 3 channels at a time 
> 
> AFAIK this is because inside the WLAN chip the scan response 
> would overflow.

That's the _original_ reason it was split up in the driver, but there
was no wait between channel sets.

But we also discovered an additional reason to wait between channel
sets, which was that the card lost association to the AP when doing a
full scan while associated.

There are two cases of scanning:

1) disconnected
    - Have to break up scan into 2 or 3 channel sets for firmware
    - Can do a full scan without pause between channel sets

2) connected
    - Have to break up scan into 2 or 3 channel sets for firmware
    - Have to pause between channel sets so card can go back to
associated channel for a while

(2) basically means that we have to fire off a partial scan for the
channel set, let it complete, schedule the next channel set for 300 or
400ms in the future, and repeat until all channel sets are done.  We
have to let the card go back to the associated channel for a bit so it
can talk to the AP and keep it's association.

I'd played around with this in February actually, but didn't get
anywhere.  My plan was to have a scan request structure for the current
in-flight scan that would contain the current status of the scan.  It
would contain each broken out channel set (of 2, 3, or 4 channels in
each set), whether a specific BSSID or SSID was requested in the scan,
what the current channel set being scanned was, and the timeout ID.  The
scanning code would detect whether or not the card was connected, and if
so, use the timeout, otherwise just do immediately run the next channel
set scan.

It's made somewhat more complicated because the association code needs
_synchronous_ scans, but the WEXT scan code doesn't, and should be using
asynchronous scans.  So the scan code needs to be flexible enough to do
both synchronous and asynchronous scans depending on where it's called
from.

> > before a pause
> 
> What do you mean with "pause", is a 
> 
>     ret = libertas_prepare_and_send_command(priv,
>         CMD_802_11_SCAN, 0,
>         CMD_OPTION_WAITFORRSP, 0, scan_cmd);
> 
> sufficient?  That is equal to calling
> 
>     wait_event_interruptible(adapter->cmd_pending,
>         !adapter->nr_cmd_pending);

No, that's not sufficient.  I'm talking about the last_scanned_channel
member of the the wlan_adapter structure.  Note the logic between
full_scan and not full_scan for wlan_scan_networks.  The WEXT code calls
with full_scan = FALSE, but the association code calls with full_scan =
True.

> I cannot see any other code in scan.c that would cause a pause.

In the SIOCGIWSCAN handler, it also schedules the next part of the
partial scan.  That's actually wrong, because we should be scheduling
the next part for 300 - 400ms after the last part was done in the case
of a partial scan for WEXT.  But the code to track scans through their
lifetime isn't there yet.

> Suppose I need to scan for "any" or a specific SSID. If I do 
> this:
> 
>    setup SCAN_CMD with TLV to scan chan 1+2
>    libertas_prepare_and_send_command with CMD_OPTION_WAITFORRSP
>    setup SCAN_CMD with TLV to scan chan 3+4
>    libertas_prepare_and_send_command with CMD_OPTION_WAITFORRSP
>    setup SCAN_CMD with TLV to scan chan 5+6
>    libertas_prepare_and_send_command with CMD_OPTION_WAITFORRSP
>    setup SCAN_CMD with TLV to scan chan 7+8
>    libertas_prepare_and_send_command with CMD_OPTION_WAITFORRSP
>    setup SCAN_CMD with TLV to scan chan 9+10
>    libertas_prepare_and_send_command with CMD_OPTION_WAITFORRSP
>    setup SCAN_CMD with TLV to scan chan 11+12
>    libertas_prepare_and_send_command with CMD_OPTION_WAITFORRSP
>    setup SCAN_CMD with TLV to scan chan 13 (+14)
>    libertas_prepare_and_send_command with CMD_OPTION_WAITFORRSP

The above ^^^ is only valid if you're disconnected, or if you are
calling scan from the association code in assoc.c because you are trying
to pre-scan the new BSS you want to join.

If you're connected, you need to do this instead:

   setup SCAN_CMD with TLV to scan chan 1+2
   libertas_prepare_and_send_command with CMD_OPTION_WAITFORRSP
   schedule next channel set for +300ms

   timeout triggered
   setup SCAN_CMD with TLV to scan chan 3+4
   libertas_prepare_and_send_command with CMD_OPTION_WAITFORRSP
   schedule next channel set for +300ms

   timeout triggered
   setup SCAN_CMD with TLV to scan chan 5+6
   libertas_prepare_and_send_command with CMD_OPTION_WAITFORRSP
   schedule next channel set for +300ms

   ...

etc.  Is that any clearer?  It's kind of hard to understand.  But there
are really two problems that need to be worked around: (a) firmware
can't handle too large scan result buffers, (b) when connected,
association gets lost when doing a full scan because you're away from
the channel too long.

Dan





More information about the libertas-dev mailing list