handle WTP QoS IE
This commit is contained in:
parent
d93cd1044d
commit
5f98005414
@ -113,6 +113,42 @@ application: {
|
|||||||
current = 100;
|
current = 100;
|
||||||
supported = [ 100 ];
|
supported = [ 100 ];
|
||||||
};
|
};
|
||||||
|
qos = {
|
||||||
|
taggingpolicy = 0; # not used yet
|
||||||
|
voice = {
|
||||||
|
queuedepth = 1; # not used yet
|
||||||
|
cwmin = 2;
|
||||||
|
cwmax = 3;
|
||||||
|
aifs = 2;
|
||||||
|
priority8021p = 0; # not used yet
|
||||||
|
dscp = 0; # not used yet
|
||||||
|
};
|
||||||
|
video = {
|
||||||
|
queuedepth = 1; # not used yet
|
||||||
|
cwmin = 3;
|
||||||
|
cwmax = 4;
|
||||||
|
aifs = 2;
|
||||||
|
priority8021p = 0; # not used yet
|
||||||
|
dscp = 0; # not used yet
|
||||||
|
};
|
||||||
|
|
||||||
|
besteffort = {
|
||||||
|
queuedepth = 1; # not used yet
|
||||||
|
cwmin = 4;
|
||||||
|
cwmax = 10;
|
||||||
|
aifs = 3;
|
||||||
|
priority8021p = 0; # not used yet
|
||||||
|
dscp = 0; # not used yet
|
||||||
|
};
|
||||||
|
background = {
|
||||||
|
queuedepth = 1; # not used yet
|
||||||
|
cwmin = 4;
|
||||||
|
cwmax = 10;
|
||||||
|
aifs = 7;
|
||||||
|
priority8021p = 0; # not used yet
|
||||||
|
dscp = 0; # not used yet
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1438,6 +1438,37 @@ int wifi_device_setfrequency(struct wifi_device* device, uint32_t band, uint32_t
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int wifi_device_settxqueue(struct wifi_device *device, struct capwap_80211_wtpqos_element *qos)
|
||||||
|
{
|
||||||
|
int i, txop;
|
||||||
|
|
||||||
|
for (i = 0; i < CAPWAP_UPDATE_STATION_QOS_SUBELEMENTS; i++) {
|
||||||
|
switch (i) {
|
||||||
|
case 0: /* Best Effort */
|
||||||
|
txop = 0;
|
||||||
|
break;
|
||||||
|
case 1: /* Background */
|
||||||
|
txop = 0;
|
||||||
|
break;
|
||||||
|
case 2: /* Video */
|
||||||
|
txop = 94;
|
||||||
|
break;
|
||||||
|
case 3: /* Voice */
|
||||||
|
txop = 47;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->instance->ops->device_settxqueue(device, i,
|
||||||
|
qos->qos[i].aifs,
|
||||||
|
qos->qos[i].cwmin,
|
||||||
|
qos->qos[i].cwmax, txop) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
int wifi_device_updaterates(struct wifi_device* device, uint8_t* rates, int ratescount) {
|
int wifi_device_updaterates(struct wifi_device* device, uint8_t* rates, int ratescount) {
|
||||||
struct device_setrates_params buildrate;
|
struct device_setrates_params buildrate;
|
||||||
|
@ -67,6 +67,8 @@ DECLARE_OPAQUE_TYPE(wifi_global_handle);
|
|||||||
DECLARE_OPAQUE_TYPE(wifi_device_handle);
|
DECLARE_OPAQUE_TYPE(wifi_device_handle);
|
||||||
DECLARE_OPAQUE_TYPE(wifi_wlan_handle);
|
DECLARE_OPAQUE_TYPE(wifi_wlan_handle);
|
||||||
|
|
||||||
|
struct capwap_80211_wtpqos_element;
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
struct device_setrates_params {
|
struct device_setrates_params {
|
||||||
int supportedratescount;
|
int supportedratescount;
|
||||||
@ -380,6 +382,8 @@ struct wifi_driver_ops {
|
|||||||
int (*device_getcapability)(struct wifi_device* device, struct wifi_capability* capability);
|
int (*device_getcapability)(struct wifi_device* device, struct wifi_capability* capability);
|
||||||
void (*device_updatebeacons)(struct wifi_device* device);
|
void (*device_updatebeacons)(struct wifi_device* device);
|
||||||
int (*device_setfrequency)(struct wifi_device* device);
|
int (*device_setfrequency)(struct wifi_device* device);
|
||||||
|
int (*device_settxqueue)(struct wifi_device* device, int queue, int aifs,
|
||||||
|
int cw_min, int cw_max, int txop);
|
||||||
void (*device_deinit)(struct wifi_device* device);
|
void (*device_deinit)(struct wifi_device* device);
|
||||||
|
|
||||||
/* WLAN functions */
|
/* WLAN functions */
|
||||||
@ -410,6 +414,7 @@ struct wifi_device* wifi_device_connect(const char* ifname, const char* driver);
|
|||||||
const struct wifi_capability* wifi_device_getcapability(struct wifi_device* device);
|
const struct wifi_capability* wifi_device_getcapability(struct wifi_device* device);
|
||||||
int wifi_device_setconfiguration(struct wifi_device* device, struct device_setconfiguration_params* params);
|
int wifi_device_setconfiguration(struct wifi_device* device, struct device_setconfiguration_params* params);
|
||||||
int wifi_device_setfrequency(struct wifi_device* device, uint32_t band, uint32_t mode, uint8_t channel);
|
int wifi_device_setfrequency(struct wifi_device* device, uint32_t band, uint32_t mode, uint8_t channel);
|
||||||
|
int wifi_device_settxqueue(struct wifi_device *device, struct capwap_80211_wtpqos_element *qos);
|
||||||
int wifi_device_updaterates(struct wifi_device* device, uint8_t* rates, int ratescount);
|
int wifi_device_updaterates(struct wifi_device* device, uint8_t* rates, int ratescount);
|
||||||
|
|
||||||
/* WLAN management */
|
/* WLAN management */
|
||||||
|
@ -1553,6 +1553,80 @@ static void nl80211_device_updatebeacons(struct wifi_device* device) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
static int nl80211_device_settxqueue(struct wifi_device* device, int queue, int aifs,
|
||||||
|
int cw_min, int cw_max, int txop)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
struct nl_msg* msg;
|
||||||
|
struct capwap_list_item* wlansearch;
|
||||||
|
struct nl80211_device_handle* devicehandle;
|
||||||
|
struct wifi_wlan* wlan = NULL;
|
||||||
|
struct nlattr *txq, *params;
|
||||||
|
|
||||||
|
ASSERT(device != NULL);
|
||||||
|
ASSERT(device->handle != NULL);
|
||||||
|
|
||||||
|
/* Search a valid interface */
|
||||||
|
for (wlansearch = device->wlans->first; wlansearch; wlansearch = wlansearch->next) {
|
||||||
|
struct wifi_wlan* element = (struct wifi_wlan*)wlansearch->item;
|
||||||
|
|
||||||
|
if (element->flags & WIFI_WLAN_RUNNING) {
|
||||||
|
wlan = element;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!wlan)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
msg = nlmsg_alloc();
|
||||||
|
if (!msg)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Set TX Queue using device index of first BSS */
|
||||||
|
devicehandle = (struct nl80211_device_handle*)device->handle;
|
||||||
|
genlmsg_put(msg, 0, 0, devicehandle->globalhandle->nl80211_id, 0, 0, NL80211_CMD_SET_WIPHY, 0);
|
||||||
|
nla_put_u32(msg, NL80211_ATTR_IFINDEX, wlan->virtindex);
|
||||||
|
|
||||||
|
txq = nla_nest_start(msg, NL80211_ATTR_WIPHY_TXQ_PARAMS);
|
||||||
|
|
||||||
|
/* We are only sending parameters for a single TXQ at a time */
|
||||||
|
params = nla_nest_start(msg, 1);
|
||||||
|
|
||||||
|
switch (queue) {
|
||||||
|
case 0:
|
||||||
|
nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VO);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VI);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BE);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BK);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
nlmsg_free(msg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nla_put_u16(msg, NL80211_TXQ_ATTR_TXOP, txop);
|
||||||
|
nla_put_u16(msg, NL80211_TXQ_ATTR_CWMIN, cw_min);
|
||||||
|
nla_put_u16(msg, NL80211_TXQ_ATTR_CWMAX, cw_max);
|
||||||
|
nla_put_u8(msg, NL80211_TXQ_ATTR_AIFS, aifs);
|
||||||
|
nla_nest_end(msg, params);
|
||||||
|
|
||||||
|
nla_nest_end(msg, txq);
|
||||||
|
|
||||||
|
result = nl80211_send_and_recv_msg(devicehandle->globalhandle, msg, NULL, NULL);
|
||||||
|
if (result)
|
||||||
|
capwap_logging_error("Unable set TX Queue, error code: %d", result);
|
||||||
|
|
||||||
|
nlmsg_free(msg);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static int nl80211_device_setfrequency(struct wifi_device* device) {
|
static int nl80211_device_setfrequency(struct wifi_device* device) {
|
||||||
ASSERT(device != NULL);
|
ASSERT(device != NULL);
|
||||||
@ -1793,6 +1867,7 @@ const struct wifi_driver_ops wifi_driver_nl80211_ops = {
|
|||||||
.device_getfdevent = nl80211_device_getfdevent,
|
.device_getfdevent = nl80211_device_getfdevent,
|
||||||
.device_getcapability = nl80211_device_getcapability,
|
.device_getcapability = nl80211_device_getcapability,
|
||||||
.device_updatebeacons = nl80211_device_updatebeacons,
|
.device_updatebeacons = nl80211_device_updatebeacons,
|
||||||
|
.device_settxqueue = nl80211_device_settxqueue,
|
||||||
.device_setfrequency = nl80211_device_setfrequency,
|
.device_setfrequency = nl80211_device_setfrequency,
|
||||||
.device_deinit = nl80211_device_deinit,
|
.device_deinit = nl80211_device_deinit,
|
||||||
|
|
||||||
|
@ -157,6 +157,49 @@ static void wtp_print_usage(void) {
|
|||||||
/* TODO */
|
/* TODO */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int wtp_parsing_radio_qos_configuration(config_setting_t *elem, const char *section,
|
||||||
|
struct capwap_80211_wtpqos_subelement *qos)
|
||||||
|
{
|
||||||
|
config_setting_t *sect;
|
||||||
|
LIBCONFIG_LOOKUP_INT_ARG val;
|
||||||
|
|
||||||
|
sect = config_setting_get_member(elem, section);
|
||||||
|
if (!sect)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (config_setting_lookup_int(sect, "queuedepth", &val) != CONFIG_TRUE ||
|
||||||
|
val > 255)
|
||||||
|
return 0;
|
||||||
|
qos->queuedepth = val;
|
||||||
|
|
||||||
|
if (config_setting_lookup_int(sect, "cwmin", &val) != CONFIG_TRUE ||
|
||||||
|
val > 65565)
|
||||||
|
return 0;
|
||||||
|
qos->cwmin = val;
|
||||||
|
|
||||||
|
if (config_setting_lookup_int(sect, "cwmax", &val) != CONFIG_TRUE ||
|
||||||
|
val > 65565)
|
||||||
|
return 0;
|
||||||
|
qos->cwmax = val;
|
||||||
|
|
||||||
|
if (config_setting_lookup_int(sect, "aifs", &val) != CONFIG_TRUE ||
|
||||||
|
val > 255)
|
||||||
|
return 0;
|
||||||
|
qos->aifs = val;
|
||||||
|
|
||||||
|
if (config_setting_lookup_int(sect, "priority8021p", &val) != CONFIG_TRUE ||
|
||||||
|
val > 7)
|
||||||
|
return 0;
|
||||||
|
qos->priority8021p = val;
|
||||||
|
|
||||||
|
if (config_setting_lookup_int(sect, "dscp", &val) != CONFIG_TRUE ||
|
||||||
|
val > 255)
|
||||||
|
return 0;
|
||||||
|
qos->dscp = val;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
static int wtp_parsing_radio_configuration(config_setting_t* configElement, struct wtp_radio* radio) {
|
static int wtp_parsing_radio_configuration(config_setting_t* configElement, struct wtp_radio* radio) {
|
||||||
int i, len, cnt;
|
int i, len, cnt;
|
||||||
@ -398,6 +441,23 @@ static int wtp_parsing_radio_configuration(config_setting_t* configElement, stru
|
|||||||
else
|
else
|
||||||
radio->radioconfig.country[2] = (uint8_t)' ';
|
radio->radioconfig.country[2] = (uint8_t)' ';
|
||||||
|
|
||||||
|
/* QoS */
|
||||||
|
radio->qos.radioid = radio->radioid;
|
||||||
|
|
||||||
|
configSection = config_setting_get_member(configElement, "qos");
|
||||||
|
if (!configSection)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (config_setting_lookup_int(configSection, "taggingpolicy", &configInt) != CONFIG_TRUE ||
|
||||||
|
configInt > 255)
|
||||||
|
return 0;
|
||||||
|
radio->qos.taggingpolicy = (uint8_t)configInt;
|
||||||
|
|
||||||
|
if (wtp_parsing_radio_qos_configuration(configSection, "voice", &radio->qos.qos[3]) == 0 ||
|
||||||
|
wtp_parsing_radio_qos_configuration(configSection, "video", &radio->qos.qos[2]) == 0 ||
|
||||||
|
wtp_parsing_radio_qos_configuration(configSection, "besteffort", &radio->qos.qos[0]) == 0 ||
|
||||||
|
wtp_parsing_radio_qos_configuration(configSection, "background", &radio->qos.qos[1]) == 0)
|
||||||
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,8 +8,9 @@
|
|||||||
/* */
|
/* */
|
||||||
#define WTP_UPDATE_FREQUENCY_DSSS 1
|
#define WTP_UPDATE_FREQUENCY_DSSS 1
|
||||||
#define WTP_UPDATE_FREQUENCY_OFDM 2
|
#define WTP_UPDATE_FREQUENCY_OFDM 2
|
||||||
#define WTP_UPDATE_RATES 3
|
#define WTP_UPDATE_RATES 3
|
||||||
#define WTP_UPDATE_CONFIGURATION 4
|
#define WTP_UPDATE_CONFIGURATION 4
|
||||||
|
#define WTP_UPDATE_TX_QUEUE 5
|
||||||
|
|
||||||
struct wtp_update_configuration_item {
|
struct wtp_update_configuration_item {
|
||||||
int type;
|
int type;
|
||||||
@ -403,6 +404,11 @@ int wtp_radio_setconfiguration(struct capwap_parsed_packet* packet) {
|
|||||||
radio = wtp_radio_get_phy(qos->radioid);
|
radio = wtp_radio_get_phy(qos->radioid);
|
||||||
if (radio && (radio->radioid == qos->radioid)) {
|
if (radio && (radio->radioid == qos->radioid)) {
|
||||||
memcpy(&radio->qos, qos, sizeof(struct capwap_80211_wtpqos_element));
|
memcpy(&radio->qos, qos, sizeof(struct capwap_80211_wtpqos_element));
|
||||||
|
|
||||||
|
/* Pending change radio channel */
|
||||||
|
item = (struct wtp_update_configuration_item*)capwap_array_get_item_pointer(updateitems, updateitems->count);
|
||||||
|
item->type = WTP_UPDATE_TX_QUEUE;
|
||||||
|
item->radio = radio;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -483,6 +489,9 @@ int wtp_radio_setconfiguration(struct capwap_parsed_packet* packet) {
|
|||||||
result = wifi_device_setconfiguration(item->radio->devicehandle, ¶ms);
|
result = wifi_device_setconfiguration(item->radio->devicehandle, ¶ms);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case WTP_UPDATE_TX_QUEUE:
|
||||||
|
result = wifi_device_settxqueue(item->radio->devicehandle, &item->radio->qos);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user