From patchwork Mon Sep 16 05:40:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz.Dziedzic@tieto.com X-Patchwork-Id: 275106 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from maxx.maxx.shmoo.com (maxx.shmoo.com [205.134.188.171]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "maxx.shmoo.com", Issuer "CA Cert Signing Authority" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 388D72C00DA for ; Mon, 16 Sep 2013 15:40:34 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 30AC59C1FB; Mon, 16 Sep 2013 01:40:30 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6s9BXqglwCc3; Mon, 16 Sep 2013 01:40:29 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 46FC69C204; Mon, 16 Sep 2013 01:40:25 -0400 (EDT) X-Original-To: mailman-post+hostap@maxx.shmoo.com Delivered-To: mailman-post+hostap@maxx.shmoo.com Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 3FD699C229 for ; Mon, 16 Sep 2013 01:40:23 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id YEa3SeQv5ixe for ; Mon, 16 Sep 2013 01:40:18 -0400 (EDT) Received: from mail-ea0-f170.google.com (mail-ea0-f170.google.com [209.85.215.170]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority" (not verified)) by maxx.maxx.shmoo.com (Postfix) with ESMTPS id B65379C1FB for ; Mon, 16 Sep 2013 01:40:17 -0400 (EDT) Received: by mail-ea0-f170.google.com with SMTP id h14so1774428eak.15 for ; Sun, 15 Sep 2013 22:40:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tieto.com; s=google; h=from:to:cc:subject:date:message-id; bh=SYauqoL9TQQ6bnZNMGwV+gTmZowAHJhavB9xYMgjKiA=; b=jhH7u2VKzKZFG/65J2fTf3GhQv98yE8TzNSo+xUcBElChPCYPz7cCS/BAM0qO81Rki j1uhVjJtOMnSRDGqpOZA1JoEhYVzFSYW1FNL79BWuHWgydx9GfL5/ciydyoHGLpXtDyH VrLVG7Qw+Q8plBFhrAFjSSYvj+ii1uvt6/veU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=SYauqoL9TQQ6bnZNMGwV+gTmZowAHJhavB9xYMgjKiA=; b=Gb3JOpMtwEAuR8KDTxWwo/WFmOW82yAj3a96FJePe5d61aTYhF+NXEKqFn6GlJJ98F 6bAFWXDuR0a117+wRDcLpwgmJh5QPk9JIePl4xuUYE12tkppsCPOdEjI27ykBnLGPVQR vcqEebX923NlXvMS4HofxRMlhnFnSQK34buwzLWSVJPuUPAia3AFGWvZDWGS3L2OIJBR VziEtFP8RVY4MstMRN3peq5G9WDSQhX6To3VjG1Nn12pIvcn0y7K5yzUtw9KHUU+pRcY fS64ziKKbMbd4p1GA0Q/+Ij5P40KAxlJIi2zJu8vKJpm7tuiNCreRg0HDhgJnY3UXWP1 TVDw== X-Gm-Message-State: ALoCoQnqDkMlyOLDdCZCNDezidBIHn+p9JdUeO1Y84758JVuV3rXIvyI1TNKppgSH5Mo4b9P2ERUhiuOegdJt2q/prvuKWYGupjIpaiMctiy0RryCscM1dE= X-Received: by 10.15.75.73 with SMTP id k49mr40384650eey.36.1379310016576; Sun, 15 Sep 2013 22:40:16 -0700 (PDT) Received: from localhost.localdomain ([91.198.246.8]) by mx.google.com with ESMTPSA id a6sm38750117eei.10.1969.12.31.16.00.00 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 15 Sep 2013 22:40:16 -0700 (PDT) From: Janusz Dziedzic To: hostap@lists.shmoo.com Subject: [PATCH 1/2] hostapd: Add DFS feature structures Date: Mon, 16 Sep 2013 07:40:06 +0200 Message-Id: <1379310007-2600-1-git-send-email-janusz.dziedzic@tieto.com> X-Mailer: git-send-email 1.7.9.5 X-DomainID: tieto.com X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.11 Precedence: list List-Id: HostAP Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: hostap-bounces@lists.shmoo.com Errors-To: hostap-bounces@lists.shmoo.com Add DFS structures/events handlers. Signed-hostap: Simon Wunderlich --- src/ap/ap_drv_ops.c | 27 +++++++++++++++++ src/ap/ap_drv_ops.h | 1 + src/ap/drv_callbacks.c | 56 ++++++++++++++++++++++++++++++++++ src/ap/hostapd.c | 5 ++++ src/ap/hostapd.h | 12 ++++++++ src/ap/hw_features.c | 78 +++++++++++++++++++++++++++++++++++++++++------- src/ap/hw_features.h | 5 ++++ 7 files changed, 174 insertions(+), 10 deletions(-) diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index 3072562..d9df9cc 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -699,3 +699,30 @@ int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq, hapd->own_addr, hapd->own_addr, data, len, 0); } + + +int hostapd_start_dfs_cac(struct hostapd_data *hapd, int freq, int flags) +{ + if (!hapd->driver || !hapd->driver->start_dfs_cac) + return 0; + + if (!(flags & HOSTAPD_CHAN_RADAR)) { + wpa_printf(MSG_ERROR, "Can't start DFS_CAC, the channel %u is " + "not DFS channel", hapd->iconf->channel); + return -1; + } + + if (!(hapd->iface->dfs_state & DFS_ENABLED)) { + wpa_printf(MSG_ERROR, "Can't start DFS CAC, DFS functionality " + "is not enabled"); + return -1; + } + + if (hapd->iface->conf->secondary_channel) { + wpa_printf(MSG_ERROR, "Can't start DFS CAC, DFS functionality " + "on HT40 is not supported"); + return -1; + } + + return hapd->driver->start_dfs_cac(hapd->drv_priv, freq); +} diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h index 23277b6..d56aa91 100644 --- a/src/ap/ap_drv_ops.h +++ b/src/ap/ap_drv_ops.h @@ -101,6 +101,7 @@ int hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr, int reassoc, u16 status, const u8 *ie, size_t len); int hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr, u8 *tspec_ie, size_t tspec_ielen); +int hostapd_start_dfs_cac(struct hostapd_data *hapd, int freq, int flags); #include "drivers/driver.h" diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index d6bc98d..a54ab0c 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -785,6 +785,35 @@ static void hostapd_event_get_survey(struct hostapd_data *hapd, } +static void hostapd_event_dfs_radar_detected(struct hostapd_data *hapd, + struct dfs_event *radar) +{ + wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq); + +} + + +static void hostapd_event_dfs_cac_finished(struct hostapd_data *hapd, + struct dfs_event *radar) +{ + wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq); +} + + +static void hostapd_event_dfs_cac_aborted(struct hostapd_data *hapd, + struct dfs_event *radar) +{ + wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq); +} + + +static void hostapd_event_dfs_nop_finished(struct hostapd_data *hapd, + struct dfs_event *radar) +{ + wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq); +} + + void wpa_supplicant_event(void *ctx, enum wpa_event_type event, union wpa_event_data *data) { @@ -929,6 +958,33 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, case EVENT_SURVEY: hostapd_event_get_survey(hapd, &data->survey_results); break; + case EVENT_DFS_RADAR_DETECTED: + if (!data) + break; + hostapd_event_dfs_radar_detected(hapd, &data->dfs_event); + break; + case EVENT_DFS_CAC_FINISHED: + if (!data) + break; + hostapd_event_dfs_cac_finished(hapd, &data->dfs_event); + break; + case EVENT_DFS_CAC_ABORTED: + if (!data) + break; + hostapd_event_dfs_cac_aborted(hapd, &data->dfs_event); + break; + case EVENT_DFS_NOP_FINISHED: + if (!data) + break; + hostapd_event_dfs_nop_finished(hapd, &data->dfs_event); + break; + case EVENT_CHANNEL_LIST_CHANGED: + /* channel list changed (regulatory?), update channel list */ + /* TODO: check this. hostapd_get_hw_features() initializes + * too much stuff. */ + /* hostapd_get_hw_features(hapd->iface); */ + break; + default: wpa_printf(MSG_DEBUG, "Unknown event %d", event); break; diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index fd1ca2b..55e6c95 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -931,6 +931,11 @@ static int setup_interface(struct hostapd_iface *iface) "be completed in a callback"); return 0; } + + if (iface->conf->ieee80211h) { + wpa_printf(MSG_DEBUG, "DFS support is enabled"); + iface->dfs_state |= DFS_ENABLED; + } } return hostapd_setup_interface_complete(iface, 0); } diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index dbf1b52..b5595e7 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -315,6 +315,18 @@ struct hostapd_iface { /* lowest observed noise floor in dBm */ s8 lowest_nf; + + /* DFS functionality is enabled. */ +#define DFS_ENABLED BIT(0) + + /* DFS channel availability check during initialization. */ +#define DFS_CAC_ACTIVE BIT(1) + + /* DFS channel availability check completed successfully. */ +#define DFS_CAC_SUCCESS BIT(2) + + u8 dfs_state; /* DFS_* bitfield */ + #ifdef CONFIG_ACS unsigned int acs_num_completed_scans; #endif /* CONFIG_ACS */ diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c index 8a239f4..c3e2080 100644 --- a/src/ap/hw_features.c +++ b/src/ap/hw_features.c @@ -45,6 +45,36 @@ void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features, } +#ifndef CONFIG_NO_STDOUT_DEBUG +static char * dfs_info(struct hostapd_channel_data *chan) +{ + static char info[256], *state; + + switch (chan->flag & HOSTAPD_CHAN_DFS_MASK) { + case HOSTAPD_CHAN_DFS_UNKNOWN: + state = "unknown"; + break; + case HOSTAPD_CHAN_DFS_USABLE: + state = "usable"; + break; + case HOSTAPD_CHAN_DFS_UNAVAILABLE: + state = "unavailable"; + break; + case HOSTAPD_CHAN_DFS_AVAILABLE: + state = "available"; + break; + default: + return ""; + } + os_snprintf(info, sizeof(info), " (DFS state = %s)", + state); + info[sizeof(info) - 1] = '\0'; + + return info; +} +#endif /* CONFIG_NO_STDOUT_DEBUG */ + + int hostapd_get_hw_features(struct hostapd_iface *iface) { struct hostapd_data *hapd = iface->bss[0]; @@ -71,30 +101,40 @@ int hostapd_get_hw_features(struct hostapd_iface *iface) for (i = 0; i < num_modes; i++) { struct hostapd_hw_modes *feature = &modes[i]; + int dfs_enabled = hapd->iconf->ieee80211h && + (iface->drv_flags & WPA_DRIVER_FLAGS_RADAR); + /* set flag for channels we can use in current regulatory * domain */ for (j = 0; j < feature->num_channels; j++) { + int dfs = 0; + /* * Disable all channels that are marked not to allow - * IBSS operation or active scanning. In addition, - * disable all channels that require radar detection, - * since that (in addition to full DFS) is not yet - * supported. + * IBSS operation or active scanning. + * Use radar channels only if the driver supports DFS. */ - if (feature->channels[j].flag & - (HOSTAPD_CHAN_NO_IBSS | - HOSTAPD_CHAN_PASSIVE_SCAN | - HOSTAPD_CHAN_RADAR)) + if ((feature->channels[j].flag & + HOSTAPD_CHAN_RADAR) && dfs_enabled) { + dfs = 1; + } else if (feature->channels[j].flag & + (HOSTAPD_CHAN_NO_IBSS | + HOSTAPD_CHAN_PASSIVE_SCAN | + HOSTAPD_CHAN_RADAR)) { feature->channels[j].flag |= HOSTAPD_CHAN_DISABLED; + } + if (feature->channels[j].flag & HOSTAPD_CHAN_DISABLED) continue; + wpa_printf(MSG_MSGDUMP, "Allowed channel: mode=%d " - "chan=%d freq=%d MHz max_tx_power=%d dBm", + "chan=%d freq=%d MHz max_tx_power=%d dBm%s", feature->mode, feature->channels[j].chan, feature->channels[j].freq, - feature->channels[j].max_tx_power); + feature->channels[j].max_tx_power, + dfs ? dfs_info(&feature->channels[j]) : ""); } } @@ -849,3 +889,21 @@ int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq) return 0; } + + +int hostapd_hw_get_channel_flag(struct hostapd_data *hapd, int chan) +{ + int i; + + if (!hapd->iface->current_mode) + return 0; + + for (i = 0; i < hapd->iface->current_mode->num_channels; i++) { + struct hostapd_channel_data *ch = + &hapd->iface->current_mode->channels[i]; + if (ch->chan == chan) + return ch->flag; + } + + return 0; +} diff --git a/src/ap/hw_features.h b/src/ap/hw_features.h index abadcd1..fe18d7c 100644 --- a/src/ap/hw_features.h +++ b/src/ap/hw_features.h @@ -28,6 +28,7 @@ int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq); int hostapd_check_ht_capab(struct hostapd_iface *iface); int hostapd_prepare_rates(struct hostapd_iface *iface, struct hostapd_hw_modes *mode); +int hostapd_hw_get_channel_flag(struct hostapd_data *hapd, int chan); #else /* NEED_AP_MLME */ static inline void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features, @@ -66,6 +67,10 @@ static inline int hostapd_prepare_rates(struct hostapd_iface *iface, return 0; } +static inline int hostapd_get_channel_flag(struct hostapd_data *hapd, int chan) +{ + return 0; +} #endif /* NEED_AP_MLME */ #endif /* HW_FEATURES_H */