Skip to content

Commit

Permalink
libertas: implement SSID scanning for SIOCSIWSCAN
Browse files Browse the repository at this point in the history
After my bit scan re-writing the SIOCSIWSCAN wext ioctl no longer supported
scanning for a specific SSID. However, wpa_supplicant is a possible user of
this ioctl, so here is code that add's this.

While passing, removed even more of the debugfs-based scanning. You can (and
should) the SIOCSIWSCAN to ask for scans, so there is no need for
proprietary interfaces for scanning. And, besides, the scan result couldn't
be used further, e.g. not for associating.

Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>
Acked-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Holger Schurig authored and John W. Linville committed Mar 13, 2008
1 parent d935713 commit 52933d8
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 316 deletions.
4 changes: 2 additions & 2 deletions drivers/net/wireless/libertas/assoc.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static int assoc_helper_essid(struct lbs_private *priv,
escape_essid(assoc_req->ssid, assoc_req->ssid_len));
if (assoc_req->mode == IW_MODE_INFRA) {
lbs_send_specific_ssid_scan(priv, assoc_req->ssid,
assoc_req->ssid_len, 0);
assoc_req->ssid_len);

bss = lbs_find_ssid_in_list(priv, assoc_req->ssid,
assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel);
Expand All @@ -53,7 +53,7 @@ static int assoc_helper_essid(struct lbs_private *priv,
* scan data will cause us to join a non-existant adhoc network
*/
lbs_send_specific_ssid_scan(priv, assoc_req->ssid,
assoc_req->ssid_len, 1);
assoc_req->ssid_len);

/* Search for the requested SSID in the scan table */
bss = lbs_find_ssid_in_list(priv, assoc_req->ssid,
Expand Down
169 changes: 0 additions & 169 deletions drivers/net/wireless/libertas/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,173 +164,6 @@ static ssize_t lbs_sleepparams_read(struct file *file, char __user *userbuf,
return ret;
}

static ssize_t lbs_extscan(struct file *file, const char __user *userbuf,
size_t count, loff_t *ppos)
{
struct lbs_private *priv = file->private_data;
ssize_t res, buf_size;
union iwreq_data wrqu;
unsigned long addr = get_zeroed_page(GFP_KERNEL);
char *buf = (char *)addr;

buf_size = min(count, len - 1);
if (copy_from_user(buf, userbuf, buf_size)) {
res = -EFAULT;
goto out_unlock;
}

lbs_send_specific_ssid_scan(priv, buf, strlen(buf)-1, 0);

memset(&wrqu, 0, sizeof(union iwreq_data));
wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);

out_unlock:
free_page(addr);
return count;
}

static void lbs_parse_bssid(char *buf, size_t count,
struct lbs_ioctl_user_scan_cfg *scan_cfg)
{
char *hold;
unsigned int mac[ETH_ALEN];

hold = strstr(buf, "bssid=");
if (!hold)
return;
hold += 6;
sscanf(hold, "%02x:%02x:%02x:%02x:%02x:%02x",
mac, mac+1, mac+2, mac+3, mac+4, mac+5);
memcpy(scan_cfg->bssid, mac, ETH_ALEN);
}

static void lbs_parse_ssid(char *buf, size_t count,
struct lbs_ioctl_user_scan_cfg *scan_cfg)
{
char *hold, *end;
ssize_t size;

hold = strstr(buf, "ssid=");
if (!hold)
return;
hold += 5;
end = strchr(hold, ' ');
if (!end)
end = buf + count - 1;

size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold));
strncpy(scan_cfg->ssid, hold, size);

return;
}

static int lbs_parse_clear(char *buf, size_t count, const char *tag)
{
char *hold;
int val;

hold = strstr(buf, tag);
if (!hold)
return 0;
hold += strlen(tag);
sscanf(hold, "%d", &val);

if (val != 0)
val = 1;

return val;
}

static int lbs_parse_dur(char *buf, size_t count,
struct lbs_ioctl_user_scan_cfg *scan_cfg)
{
char *hold;
int val;

hold = strstr(buf, "dur=");
if (!hold)
return 0;
hold += 4;
sscanf(hold, "%d", &val);

return val;
}

static void lbs_parse_type(char *buf, size_t count,
struct lbs_ioctl_user_scan_cfg *scan_cfg)
{
char *hold;
int val;

hold = strstr(buf, "type=");
if (!hold)
return;
hold += 5;
sscanf(hold, "%d", &val);

/* type=1,2 or 3 */
if (val < 1 || val > 3)
return;

scan_cfg->bsstype = val;

return;
}

static ssize_t lbs_setuserscan(struct file *file,
const char __user *userbuf,
size_t count, loff_t *ppos)
{
struct lbs_private *priv = file->private_data;
ssize_t res, buf_size;
struct lbs_ioctl_user_scan_cfg *scan_cfg;
union iwreq_data wrqu;
int dur;
char *buf = (char *)get_zeroed_page(GFP_KERNEL);

if (!buf)
return -ENOMEM;

buf_size = min(count, len - 1);
if (copy_from_user(buf, userbuf, buf_size)) {
res = -EFAULT;
goto out_buf;
}

scan_cfg = kzalloc(sizeof(struct lbs_ioctl_user_scan_cfg), GFP_KERNEL);
if (!scan_cfg) {
res = -ENOMEM;
goto out_buf;
}
res = count;

scan_cfg->bsstype = LBS_SCAN_BSS_TYPE_ANY;

dur = lbs_parse_dur(buf, count, scan_cfg);
lbs_parse_bssid(buf, count, scan_cfg);
scan_cfg->clear_bssid = lbs_parse_clear(buf, count, "clear_bssid=");
lbs_parse_ssid(buf, count, scan_cfg);
scan_cfg->clear_ssid = lbs_parse_clear(buf, count, "clear_ssid=");
lbs_parse_type(buf, count, scan_cfg);

lbs_scan_networks(priv, scan_cfg, 1);
wait_event_interruptible(priv->cmd_pending,
priv->surpriseremoved || !priv->scan_channel);

if (priv->surpriseremoved)
goto out_scan_cfg;

memset(&wrqu, 0x00, sizeof(union iwreq_data));
wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);

out_scan_cfg:
kfree(scan_cfg);
out_buf:
free_page((unsigned long)buf);
return res;
}


/*
* When calling CMD_802_11_SUBSCRIBE_EVENT with CMD_ACT_GET, me might
* get a bunch of vendor-specific TLVs (a.k.a. IEs) back from the
Expand Down Expand Up @@ -857,8 +690,6 @@ static struct lbs_debugfs_files debugfs_files[] = {
write_file_dummy), },
{ "sleepparams", 0644, FOPS(lbs_sleepparams_read,
lbs_sleepparams_write), },
{ "extscan", 0600, FOPS(NULL, lbs_extscan), },
{ "setuserscan", 0600, FOPS(NULL, lbs_setuserscan), },
};

static struct lbs_debugfs_files debugfs_events_files[] = {
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/libertas/dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ struct lbs_private {
struct work_struct sync_channel;
/* remember which channel was scanned last, != 0 if currently scanning */
int scan_channel;
u8 scan_ssid[IW_ESSID_MAX_SIZE + 1];
u8 scan_ssid_len;

/** Hardware access */
int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb);
Expand Down
Loading

0 comments on commit 52933d8

Please sign in to comment.