mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-25 17:59:25 +01:00
hwsim: add new 'Delay' property to Rules
This allows a matching frame to be delayed by some number of milliseconds.
This commit is contained in:
parent
078c2d76c7
commit
32a55fb75c
@ -113,6 +113,7 @@ enum hwsim_tx_control_flags {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define IEEE80211_TX_RATE_TABLE_SIZE 4
|
#define IEEE80211_TX_RATE_TABLE_SIZE 4
|
||||||
|
#define HWSIM_DELAY_MIN_MS 1
|
||||||
|
|
||||||
struct hwsim_rule {
|
struct hwsim_rule {
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
@ -125,6 +126,7 @@ struct hwsim_rule {
|
|||||||
uint32_t frequency;
|
uint32_t frequency;
|
||||||
int priority;
|
int priority;
|
||||||
int signal;
|
int signal;
|
||||||
|
int delay;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hwsim_support {
|
struct hwsim_support {
|
||||||
@ -1106,7 +1108,8 @@ static bool radio_match_addr(const struct radio_info_rec *radio,
|
|||||||
|
|
||||||
static void process_rules(const struct radio_info_rec *src_radio,
|
static void process_rules(const struct radio_info_rec *src_radio,
|
||||||
const struct radio_info_rec *dst_radio,
|
const struct radio_info_rec *dst_radio,
|
||||||
struct hwsim_frame *frame, bool *drop)
|
struct hwsim_frame *frame, bool *drop,
|
||||||
|
uint32_t *delay)
|
||||||
{
|
{
|
||||||
const struct l_queue_entry *rule_entry;
|
const struct l_queue_entry *rule_entry;
|
||||||
|
|
||||||
@ -1149,6 +1152,9 @@ static void process_rules(const struct radio_info_rec *src_radio,
|
|||||||
frame->signal = rule->signal / 100;
|
frame->signal = rule->signal / 100;
|
||||||
|
|
||||||
*drop = rule->drop;
|
*drop = rule->drop;
|
||||||
|
|
||||||
|
if (delay)
|
||||||
|
*delay = rule->delay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1232,7 +1238,7 @@ static void hwsim_frame_unref(struct hwsim_frame *frame)
|
|||||||
bool drop = false;
|
bool drop = false;
|
||||||
|
|
||||||
process_rules(frame->ack_radio, frame->src_radio,
|
process_rules(frame->ack_radio, frame->src_radio,
|
||||||
frame, &drop);
|
frame, &drop, NULL);
|
||||||
|
|
||||||
if (!drop)
|
if (!drop)
|
||||||
frame->flags |= HWSIM_TX_STAT_ACK;
|
frame->flags |= HWSIM_TX_STAT_ACK;
|
||||||
@ -1374,13 +1380,14 @@ static void process_frame(struct hwsim_frame *frame)
|
|||||||
bool drop_mcast = false;
|
bool drop_mcast = false;
|
||||||
|
|
||||||
if (util_is_broadcast_address(frame->dst_ether_addr))
|
if (util_is_broadcast_address(frame->dst_ether_addr))
|
||||||
process_rules(frame->src_radio, NULL, frame, &drop_mcast);
|
process_rules(frame->src_radio, NULL, frame, &drop_mcast, NULL);
|
||||||
|
|
||||||
for (entry = l_queue_get_entries(radio_info); entry;
|
for (entry = l_queue_get_entries(radio_info); entry;
|
||||||
entry = entry->next) {
|
entry = entry->next) {
|
||||||
struct radio_info_rec *radio = entry->data;
|
struct radio_info_rec *radio = entry->data;
|
||||||
struct send_frame_info *send_info;
|
struct send_frame_info *send_info;
|
||||||
bool drop = drop_mcast;
|
bool drop = drop_mcast;
|
||||||
|
uint32_t delay = HWSIM_DELAY_MIN_MS;
|
||||||
|
|
||||||
if (radio == frame->src_radio)
|
if (radio == frame->src_radio)
|
||||||
continue;
|
continue;
|
||||||
@ -1413,7 +1420,7 @@ static void process_frame(struct hwsim_frame *frame)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
process_rules(frame->src_radio, radio, frame, &drop);
|
process_rules(frame->src_radio, radio, frame, &drop, &delay);
|
||||||
|
|
||||||
if (drop)
|
if (drop)
|
||||||
continue;
|
continue;
|
||||||
@ -1422,7 +1429,7 @@ static void process_frame(struct hwsim_frame *frame)
|
|||||||
send_info->radio = radio;
|
send_info->radio = radio;
|
||||||
send_info->frame = hwsim_frame_ref(frame);
|
send_info->frame = hwsim_frame_ref(frame);
|
||||||
|
|
||||||
if (!l_timeout_create_ms(1, frame_delay_callback,
|
if (!l_timeout_create_ms(delay, frame_delay_callback,
|
||||||
send_info, NULL)) {
|
send_info, NULL)) {
|
||||||
l_error("Error delaying frame, frame will be dropped");
|
l_error("Error delaying frame, frame will be dropped");
|
||||||
send_frame_destroy(send_info);
|
send_frame_destroy(send_info);
|
||||||
@ -1875,6 +1882,7 @@ static struct l_dbus_message *rule_add(struct l_dbus *dbus,
|
|||||||
rule->id = next_rule_id++;
|
rule->id = next_rule_id++;
|
||||||
rule->source_any = true;
|
rule->source_any = true;
|
||||||
rule->destination_any = true;
|
rule->destination_any = true;
|
||||||
|
rule->delay = HWSIM_DELAY_MIN_MS;
|
||||||
|
|
||||||
if (!rules)
|
if (!rules)
|
||||||
rules = l_queue_new();
|
rules = l_queue_new();
|
||||||
@ -2160,6 +2168,37 @@ static struct l_dbus_message *rule_property_set_drop(
|
|||||||
return l_dbus_message_new_method_return(message);
|
return l_dbus_message_new_method_return(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool rule_property_get_delay(struct l_dbus *dbus,
|
||||||
|
struct l_dbus_message *message,
|
||||||
|
struct l_dbus_message_builder *builder,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
struct hwsim_rule *rule = user_data;
|
||||||
|
|
||||||
|
l_dbus_message_builder_append_basic(builder, 'u', &rule->delay);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct l_dbus_message *rule_property_set_delay(
|
||||||
|
struct l_dbus *dbus,
|
||||||
|
struct l_dbus_message *message,
|
||||||
|
struct l_dbus_message_iter *new_value,
|
||||||
|
l_dbus_property_complete_cb_t complete,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
struct hwsim_rule *rule = user_data;
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
if (!l_dbus_message_iter_get_variant(new_value, "u", &val) ||
|
||||||
|
val < HWSIM_DELAY_MIN_MS)
|
||||||
|
return dbus_error_invalid_args(message);
|
||||||
|
|
||||||
|
rule->delay = val;
|
||||||
|
|
||||||
|
return l_dbus_message_new_method_return(message);
|
||||||
|
}
|
||||||
|
|
||||||
static void setup_rule_interface(struct l_dbus_interface *interface)
|
static void setup_rule_interface(struct l_dbus_interface *interface)
|
||||||
{
|
{
|
||||||
l_dbus_interface_method(interface, "Remove", 0, rule_remove, "", "");
|
l_dbus_interface_method(interface, "Remove", 0, rule_remove, "", "");
|
||||||
@ -2192,6 +2231,10 @@ static void setup_rule_interface(struct l_dbus_interface *interface)
|
|||||||
L_DBUS_PROPERTY_FLAG_AUTO_EMIT, "b",
|
L_DBUS_PROPERTY_FLAG_AUTO_EMIT, "b",
|
||||||
rule_property_get_drop,
|
rule_property_get_drop,
|
||||||
rule_property_set_drop);
|
rule_property_set_drop);
|
||||||
|
l_dbus_interface_property(interface, "Delay",
|
||||||
|
L_DBUS_PROPERTY_FLAG_AUTO_EMIT, "u",
|
||||||
|
rule_property_get_delay,
|
||||||
|
rule_property_set_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void request_name_callback(struct l_dbus *dbus, bool success,
|
static void request_name_callback(struct l_dbus *dbus, bool success,
|
||||||
|
Loading…
Reference in New Issue
Block a user