}
+static void nl80211_reg_change_event(struct wpa_driver_nl80211_data *drv,
+ struct nlattr *tb[])
+{
+ union wpa_event_data data;
+ enum nl80211_reg_initiator init;
+
+ wpa_printf(MSG_DEBUG, "nl80211: Regulatory domain change");
+
+ if (tb[NL80211_ATTR_REG_INITIATOR] == NULL)
+ return;
+
+ os_memset(&data, 0, sizeof(data));
+ init = nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR]);
+ wpa_printf(MSG_DEBUG, " * initiator=%d", init);
+ switch (init) {
+ case NL80211_REGDOM_SET_BY_CORE:
+ data.channel_list_changed.initiator = REGDOM_SET_BY_CORE;
+ break;
+ case NL80211_REGDOM_SET_BY_USER:
+ data.channel_list_changed.initiator = REGDOM_SET_BY_USER;
+ break;
+ case NL80211_REGDOM_SET_BY_DRIVER:
+ data.channel_list_changed.initiator = REGDOM_SET_BY_DRIVER;
+ break;
+ case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+ data.channel_list_changed.initiator = REGDOM_SET_BY_COUNTRY_IE;
+ break;
+ }
+
+ if (tb[NL80211_ATTR_REG_TYPE]) {
+ enum nl80211_reg_type type;
+ type = nla_get_u8(tb[NL80211_ATTR_REG_TYPE]);
+ wpa_printf(MSG_DEBUG, " * type=%d", type);
+ switch (type) {
+ case NL80211_REGDOM_TYPE_COUNTRY:
+ data.channel_list_changed.type = REGDOM_TYPE_COUNTRY;
+ break;
+ case NL80211_REGDOM_TYPE_WORLD:
+ data.channel_list_changed.type = REGDOM_TYPE_WORLD;
+ break;
+ case NL80211_REGDOM_TYPE_CUSTOM_WORLD:
+ data.channel_list_changed.type =
+ REGDOM_TYPE_CUSTOM_WORLD;
+ break;
+ case NL80211_REGDOM_TYPE_INTERSECTION:
+ data.channel_list_changed.type =
+ REGDOM_TYPE_INTERSECTION;
+ break;
+ }
+ }
+
+ if (tb[NL80211_ATTR_REG_ALPHA2]) {
+ os_strlcpy(data.channel_list_changed.alpha2,
+ nla_get_string(tb[NL80211_ATTR_REG_ALPHA2]),
+ sizeof(data.channel_list_changed.alpha2));
+ wpa_printf(MSG_DEBUG, " * alpha2=%s",
+ data.channel_list_changed.alpha2);
+ }
+
+ wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, &data);
+}
+
+
static void do_process_drv_event(struct i802_bss *bss, int cmd,
struct nlattr **tb)
{
nl80211_cqm_event(drv, tb);
break;
case NL80211_CMD_REG_CHANGE:
- wpa_printf(MSG_DEBUG, "nl80211: Regulatory domain change");
- if (tb[NL80211_ATTR_REG_INITIATOR] == NULL)
- break;
- os_memset(&data, 0, sizeof(data));
- switch (nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR])) {
- case NL80211_REGDOM_SET_BY_CORE:
- data.channel_list_changed.initiator =
- REGDOM_SET_BY_CORE;
- break;
- case NL80211_REGDOM_SET_BY_USER:
- data.channel_list_changed.initiator =
- REGDOM_SET_BY_USER;
- break;
- case NL80211_REGDOM_SET_BY_DRIVER:
- data.channel_list_changed.initiator =
- REGDOM_SET_BY_DRIVER;
- break;
- case NL80211_REGDOM_SET_BY_COUNTRY_IE:
- data.channel_list_changed.initiator =
- REGDOM_SET_BY_COUNTRY_IE;
- break;
- default:
- wpa_printf(MSG_DEBUG, "nl80211: Unknown reg change initiator %d received",
- nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR]));
- break;
- }
- wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED,
- &data);
+ nl80211_reg_change_event(drv, tb);
break;
case NL80211_CMD_REG_BEACON_HINT:
wpa_printf(MSG_DEBUG, "nl80211: Regulatory beacon hint");
}
-static void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s)
+static const char * reg_init_str(enum reg_change_initiator init)
+{
+ switch (init) {
+ case REGDOM_SET_BY_CORE:
+ return "CORE";
+ case REGDOM_SET_BY_USER:
+ return "USER";
+ case REGDOM_SET_BY_DRIVER:
+ return "DRIVER";
+ case REGDOM_SET_BY_COUNTRY_IE:
+ return "COUNTRY_IE";
+ case REGDOM_BEACON_HINT:
+ return "BEACON_HINT";
+ }
+ return "?";
+}
+
+
+static const char * reg_type_str(enum reg_type type)
+{
+ switch (type) {
+ case REGDOM_TYPE_UNKNOWN:
+ return "UNKNOWN";
+ case REGDOM_TYPE_COUNTRY:
+ return "COUNTRY";
+ case REGDOM_TYPE_WORLD:
+ return "WORLD";
+ case REGDOM_TYPE_CUSTOM_WORLD:
+ return "CUSTOM_WORLD";
+ case REGDOM_TYPE_INTERSECTION:
+ return "INTERSECTION";
+ }
+ return "?";
+}
+
+
+static void wpa_supplicant_update_channel_list(
+ struct wpa_supplicant *wpa_s, struct channel_list_changed *info)
{
struct wpa_supplicant *ifs;
+ wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REGDOM_CHANGE "init=%s type=%s%s%s",
+ reg_init_str(info->type), reg_type_str(info->type),
+ info->alpha2[0] ? " alpha2=" : "",
+ info->alpha2[0] ? info->alpha2 : "");
+
if (wpa_s->drv_priv == NULL)
return; /* Ignore event during drv initialization */
wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
break;
case EVENT_CHANNEL_LIST_CHANGED:
- wpa_supplicant_update_channel_list(wpa_s);
+ wpa_supplicant_update_channel_list(
+ wpa_s, &data->channel_list_changed);
break;
case EVENT_INTERFACE_UNAVAILABLE:
#ifdef CONFIG_P2P