P2P: Update D-Bus network object semantics during group formation
Do not emit network objects during P2P group formation since such network objects can confuse certain apps. Instead, a persistent group object is created to allow apps to keep track of persistent groups. Persistent group objects only represent the info needed to recreate the group. Also fixes a minor bug in the handling of persistent group objects during WPS operations. Signed-off-by: Jayant Sane <jayant.sane@intel.com>
This commit is contained in:
parent
c988980d95
commit
c2762e410f
10 changed files with 442 additions and 11 deletions
|
@ -1281,6 +1281,102 @@ error:
|
||||||
dbus_message_unref(msg);
|
dbus_message_unref(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wpas_dbus_signal_persistent_group - Send a persistent group related
|
||||||
|
* event signal
|
||||||
|
* @wpa_s: %wpa_supplicant network interface data
|
||||||
|
* @id: new persistent group id
|
||||||
|
* @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
|
||||||
|
* @properties: determines if add second argument with object properties
|
||||||
|
*
|
||||||
|
* Notify listeners about an event related to persistent groups.
|
||||||
|
*/
|
||||||
|
static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
|
||||||
|
int id, const char *sig_name,
|
||||||
|
int properties)
|
||||||
|
{
|
||||||
|
struct wpas_dbus_priv *iface;
|
||||||
|
DBusMessage *msg;
|
||||||
|
DBusMessageIter iter, iter_dict;
|
||||||
|
char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
|
||||||
|
|
||||||
|
iface = wpa_s->global->dbus;
|
||||||
|
|
||||||
|
/* Do nothing if the control interface is not turned on */
|
||||||
|
if (iface == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
|
||||||
|
"%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
|
||||||
|
wpa_s->dbus_new_path, id);
|
||||||
|
|
||||||
|
msg = dbus_message_new_signal(wpa_s->dbus_new_path,
|
||||||
|
WPAS_DBUS_NEW_IFACE_P2PDEVICE,
|
||||||
|
sig_name);
|
||||||
|
if (msg == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dbus_message_iter_init_append(msg, &iter);
|
||||||
|
path = pgrp_obj_path;
|
||||||
|
if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
|
||||||
|
&path))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (properties) {
|
||||||
|
if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
wpa_dbus_get_object_properties(
|
||||||
|
iface, pgrp_obj_path,
|
||||||
|
WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP,
|
||||||
|
&iter_dict);
|
||||||
|
|
||||||
|
if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbus_connection_send(iface->con, msg, NULL);
|
||||||
|
|
||||||
|
dbus_message_unref(msg);
|
||||||
|
return;
|
||||||
|
|
||||||
|
err:
|
||||||
|
wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
|
||||||
|
dbus_message_unref(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wpas_dbus_signal_persistent_group_added - Send a persistent_group
|
||||||
|
* added signal
|
||||||
|
* @wpa_s: %wpa_supplicant network interface data
|
||||||
|
* @id: new persistent group id
|
||||||
|
*
|
||||||
|
* Notify listeners about addition of a new persistent group.
|
||||||
|
*/
|
||||||
|
static void wpas_dbus_signal_persistent_group_added(
|
||||||
|
struct wpa_supplicant *wpa_s, int id)
|
||||||
|
{
|
||||||
|
wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded",
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wpas_dbus_signal_persistent_group_removed - Send a persistent_group
|
||||||
|
* removed signal
|
||||||
|
* @wpa_s: %wpa_supplicant network interface data
|
||||||
|
* @id: persistent group id
|
||||||
|
*
|
||||||
|
* Notify listeners about removal of a persistent group.
|
||||||
|
*/
|
||||||
|
static void wpas_dbus_signal_persistent_group_removed(
|
||||||
|
struct wpa_supplicant *wpa_s, int id)
|
||||||
|
{
|
||||||
|
wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved",
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /*CONFIG_P2P*/
|
#endif /*CONFIG_P2P*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -1654,6 +1750,14 @@ int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
|
||||||
struct network_handler_args *arg;
|
struct network_handler_args *arg;
|
||||||
char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
|
char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If it is a persistent group register it as such.
|
||||||
|
* This is to handle cases where an interface is being initialized
|
||||||
|
* with a list of networks read from config.
|
||||||
|
*/
|
||||||
|
if (network_is_persistent_group(ssid))
|
||||||
|
return wpas_dbus_register_persistent_group(wpa_s, ssid);
|
||||||
|
|
||||||
/* Do nothing if the control interface is not turned on */
|
/* Do nothing if the control interface is not turned on */
|
||||||
if (wpa_s == NULL || wpa_s->global == NULL)
|
if (wpa_s == NULL || wpa_s->global == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1716,6 +1820,13 @@ int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
|
||||||
struct wpas_dbus_priv *ctrl_iface;
|
struct wpas_dbus_priv *ctrl_iface;
|
||||||
char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
|
char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
|
||||||
int ret;
|
int ret;
|
||||||
|
struct wpa_ssid *ssid;
|
||||||
|
|
||||||
|
ssid = wpa_config_get_network(wpa_s->conf, nid);
|
||||||
|
|
||||||
|
/* If it is a persistent group unregister it as such */
|
||||||
|
if (ssid && network_is_persistent_group(ssid))
|
||||||
|
return wpas_dbus_unregister_persistent_group(wpa_s, nid);
|
||||||
|
|
||||||
/* Do nothing if the control interface is not turned on */
|
/* Do nothing if the control interface is not turned on */
|
||||||
if (wpa_s == NULL || wpa_s->global == NULL ||
|
if (wpa_s == NULL || wpa_s->global == NULL ||
|
||||||
|
@ -2245,6 +2356,10 @@ static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
|
||||||
(WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peergo,
|
(WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peergo,
|
||||||
NULL, R
|
NULL, R
|
||||||
},
|
},
|
||||||
|
{ "PersistentGroups", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
|
||||||
|
(WPADBusPropertyAccessor) wpas_dbus_getter_persistent_groups,
|
||||||
|
NULL, R
|
||||||
|
},
|
||||||
#endif /* CONFIG_P2P */
|
#endif /* CONFIG_P2P */
|
||||||
{ NULL, NULL, NULL, NULL, NULL, 0 }
|
{ NULL, NULL, NULL, NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
@ -2441,6 +2556,13 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
|
||||||
END_ARGS
|
END_ARGS
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{ "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
|
||||||
|
{
|
||||||
|
{ "path", "o", ARG_OUT },
|
||||||
|
{ "properties", "a{sv}", ARG_OUT },
|
||||||
|
END_ARGS
|
||||||
|
}
|
||||||
|
},
|
||||||
#endif /* CONFIG_P2P */
|
#endif /* CONFIG_P2P */
|
||||||
{ NULL, NULL, { END_ARGS } }
|
{ NULL, NULL, { END_ARGS } }
|
||||||
};
|
};
|
||||||
|
@ -2954,4 +3076,142 @@ void wpas_dbus_unregister_p2p_groupmember(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
wpa_dbus_unregister_object_per_iface(ctrl_iface, groupmember_obj_path);
|
wpa_dbus_unregister_object_per_iface(ctrl_iface, groupmember_obj_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const struct wpa_dbus_property_desc
|
||||||
|
wpas_dbus_persistent_group_properties[] = {
|
||||||
|
{ "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
|
||||||
|
(WPADBusPropertyAccessor)
|
||||||
|
wpas_dbus_getter_persistent_group_properties,
|
||||||
|
NULL,
|
||||||
|
R
|
||||||
|
},
|
||||||
|
{ NULL, NULL, NULL, NULL, NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* No signals intended for persistent group objects */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wpas_dbus_register_persistent_group - Register a configured(saved)
|
||||||
|
* persistent group with dbus
|
||||||
|
* @wpa_s: wpa_supplicant interface structure
|
||||||
|
* @ssid: persistent group (still represented as a network within wpa)
|
||||||
|
* configuration data
|
||||||
|
* Returns: 0 on success, -1 on failure
|
||||||
|
*
|
||||||
|
* Registers a persistent group representing object with dbus.
|
||||||
|
*/
|
||||||
|
int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
|
||||||
|
struct wpa_ssid *ssid)
|
||||||
|
{
|
||||||
|
struct wpas_dbus_priv *ctrl_iface;
|
||||||
|
struct wpa_dbus_object_desc *obj_desc;
|
||||||
|
struct network_handler_args *arg;
|
||||||
|
char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
|
||||||
|
|
||||||
|
/* Do nothing if the control interface is not turned on */
|
||||||
|
if (wpa_s == NULL || wpa_s->global == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Make sure ssid is a persistent group */
|
||||||
|
if (ssid->disabled != 2 && !ssid->p2p_persistent_group)
|
||||||
|
return -1; /* should we return w/o complaining? */
|
||||||
|
|
||||||
|
ctrl_iface = wpa_s->global->dbus;
|
||||||
|
if (ctrl_iface == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Intentionally not coming up with different numbering scheme
|
||||||
|
* for persistent groups.
|
||||||
|
*/
|
||||||
|
os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
|
||||||
|
"%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
|
||||||
|
wpa_s->dbus_new_path, ssid->id);
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'",
|
||||||
|
pgrp_obj_path);
|
||||||
|
obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
|
||||||
|
if (!obj_desc) {
|
||||||
|
wpa_printf(MSG_ERROR, "dbus: Not enough memory to create "
|
||||||
|
"object description");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reusing the same context structure as that for networks
|
||||||
|
* since these are represented using same data structure.
|
||||||
|
*/
|
||||||
|
/* allocate memory for handlers arguments */
|
||||||
|
arg = os_zalloc(sizeof(struct network_handler_args));
|
||||||
|
if (!arg) {
|
||||||
|
wpa_printf(MSG_ERROR, "dbus: Not enough memory to create "
|
||||||
|
"arguments for method");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
arg->wpa_s = wpa_s;
|
||||||
|
arg->ssid = ssid;
|
||||||
|
|
||||||
|
wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
|
||||||
|
wpas_dbus_persistent_group_properties,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path,
|
||||||
|
wpa_s->ifname, obj_desc))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
free_dbus_object_desc(obj_desc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wpas_dbus_unregister_persistent_group - Unregister a persistent_group
|
||||||
|
* from dbus
|
||||||
|
* @wpa_s: wpa_supplicant interface structure
|
||||||
|
* @nid: network id
|
||||||
|
* Returns: 0 on success, -1 on failure
|
||||||
|
*
|
||||||
|
* Unregisters persistent group representing object from dbus
|
||||||
|
*
|
||||||
|
* NOTE: There is a slight issue with the semantics here. While the
|
||||||
|
* implementation simply means the persistent group is unloaded from memory,
|
||||||
|
* it should not get interpreted as the group is actually being erased/removed
|
||||||
|
* from persistent storage as well.
|
||||||
|
*/
|
||||||
|
int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
|
||||||
|
int nid)
|
||||||
|
{
|
||||||
|
struct wpas_dbus_priv *ctrl_iface;
|
||||||
|
char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Do nothing if the control interface is not turned on */
|
||||||
|
if (wpa_s == NULL || wpa_s->global == NULL ||
|
||||||
|
wpa_s->dbus_new_path == NULL)
|
||||||
|
return 0;
|
||||||
|
ctrl_iface = wpa_s->global->dbus;
|
||||||
|
if (ctrl_iface == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
|
||||||
|
"%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
|
||||||
|
wpa_s->dbus_new_path, nid);
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'",
|
||||||
|
pgrp_obj_path);
|
||||||
|
ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
wpas_dbus_signal_persistent_group_removed(wpa_s, nid);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_P2P */
|
#endif /* CONFIG_P2P */
|
||||||
|
|
|
@ -72,6 +72,14 @@ enum wpas_dbus_bss_prop {
|
||||||
#define WPAS_DBUS_NEW_P2P_GROUPS_PART "Groups"
|
#define WPAS_DBUS_NEW_P2P_GROUPS_PART "Groups"
|
||||||
#define WPAS_DBUS_NEW_IFACE_P2P_GROUP WPAS_DBUS_NEW_INTERFACE ".Group"
|
#define WPAS_DBUS_NEW_IFACE_P2P_GROUP WPAS_DBUS_NEW_INTERFACE ".Group"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Different dbus object for persistent groups so they do not get confused
|
||||||
|
* with regular (configured) network objects.
|
||||||
|
*/
|
||||||
|
#define WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "PersistentGroups"
|
||||||
|
#define WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP \
|
||||||
|
WPAS_DBUS_NEW_INTERFACE ".PersistentGroup"
|
||||||
|
|
||||||
#define WPAS_DBUS_NEW_P2P_PEERS_PART "Peers"
|
#define WPAS_DBUS_NEW_P2P_PEERS_PART "Peers"
|
||||||
#define WPAS_DBUS_NEW_IFACE_P2P_PEER WPAS_DBUS_NEW_INTERFACE ".Peer"
|
#define WPAS_DBUS_NEW_IFACE_P2P_PEER WPAS_DBUS_NEW_INTERFACE ".Peer"
|
||||||
|
|
||||||
|
@ -170,6 +178,10 @@ void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
|
||||||
void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, int status);
|
void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, int status);
|
||||||
void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
|
void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
|
||||||
const struct wpa_ssid *ssid);
|
const struct wpa_ssid *ssid);
|
||||||
|
int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
|
||||||
|
struct wpa_ssid *ssid);
|
||||||
|
int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
|
||||||
|
int nid);
|
||||||
void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
|
void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
|
||||||
int status, const u8 *bssid);
|
int status, const u8 *bssid);
|
||||||
void wpas_dbus_register_p2p_groupmember(struct wpa_supplicant *wpa_s,
|
void wpas_dbus_register_p2p_groupmember(struct wpa_supplicant *wpa_s,
|
||||||
|
@ -344,6 +356,18 @@ wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int wpas_dbus_register_persistent_group(
|
||||||
|
struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int wpas_dbus_unregister_persistent_group(
|
||||||
|
struct wpa_supplicant *wpa_s, int nid)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, int status)
|
wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, int status)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2508,7 +2508,8 @@ DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
|
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
|
||||||
num++;
|
if (!network_is_persistent_group(ssid))
|
||||||
|
num++;
|
||||||
|
|
||||||
paths = os_zalloc(num * sizeof(char *));
|
paths = os_zalloc(num * sizeof(char *));
|
||||||
if (!paths) {
|
if (!paths) {
|
||||||
|
@ -2518,6 +2519,8 @@ DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
|
||||||
|
|
||||||
/* Loop through configured networks and append object path of each */
|
/* Loop through configured networks and append object path of each */
|
||||||
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
|
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
|
||||||
|
if (network_is_persistent_group(ssid))
|
||||||
|
continue;
|
||||||
paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
|
paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
|
||||||
if (paths[i] == NULL) {
|
if (paths[i] == NULL) {
|
||||||
reply = dbus_message_new_error(message,
|
reply = dbus_message_new_error(message,
|
||||||
|
|
|
@ -1207,6 +1207,90 @@ DBusMessage *wpas_dbus_getter_p2p_peer_ies(DBusMessage * message,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wpas_dbus_getter_persistent_groups - Get array of peristent group objects
|
||||||
|
* @message: Pointer to incoming dbus message
|
||||||
|
* @wpa_s: wpa_supplicant structure for a network interface
|
||||||
|
* Returns: a dbus message containing an array of all persistent group
|
||||||
|
* dbus object paths.
|
||||||
|
*
|
||||||
|
* Getter for "Networks" property.
|
||||||
|
*/
|
||||||
|
DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message,
|
||||||
|
struct wpa_supplicant *wpa_s)
|
||||||
|
{
|
||||||
|
DBusMessage *reply = NULL;
|
||||||
|
struct wpa_ssid *ssid;
|
||||||
|
char **paths;
|
||||||
|
unsigned int i = 0, num = 0;
|
||||||
|
|
||||||
|
if (wpa_s->conf == NULL) {
|
||||||
|
wpa_printf(MSG_ERROR, "dbus: "
|
||||||
|
"wpas_dbus_getter_persistent_groups: "
|
||||||
|
"An error occurred getting persistent groups list");
|
||||||
|
return wpas_dbus_error_unknown_error(message, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
|
||||||
|
if (network_is_persistent_group(ssid))
|
||||||
|
num++;
|
||||||
|
|
||||||
|
paths = os_zalloc(num * sizeof(char *));
|
||||||
|
if (!paths) {
|
||||||
|
return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop through configured networks and append object path of each */
|
||||||
|
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
|
||||||
|
if (!network_is_persistent_group(ssid))
|
||||||
|
continue;
|
||||||
|
paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
|
||||||
|
if (paths[i] == NULL) {
|
||||||
|
reply = dbus_message_new_error(message,
|
||||||
|
DBUS_ERROR_NO_MEMORY,
|
||||||
|
NULL);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
/* Construct the object path for this network. */
|
||||||
|
os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
|
||||||
|
"%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%d",
|
||||||
|
wpa_s->dbus_new_path, ssid->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
reply = wpas_dbus_simple_array_property_getter(message,
|
||||||
|
DBUS_TYPE_OBJECT_PATH,
|
||||||
|
paths, num);
|
||||||
|
|
||||||
|
out:
|
||||||
|
while (i)
|
||||||
|
os_free(paths[--i]);
|
||||||
|
os_free(paths);
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wpas_dbus_getter_persistent_group_properties - Get options for a persistent
|
||||||
|
* group
|
||||||
|
* @message: Pointer to incoming dbus message
|
||||||
|
* @net: wpa_supplicant structure for a network interface and
|
||||||
|
* wpa_ssid structure for a configured persistent group (internally network)
|
||||||
|
* Returns: DBus message with network properties or DBus error on failure
|
||||||
|
*
|
||||||
|
* Getter for "Properties" property of a persistent group.
|
||||||
|
*/
|
||||||
|
DBusMessage * wpas_dbus_getter_persistent_group_properties(
|
||||||
|
DBusMessage *message, struct network_handler_args *net)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Leveraging the fact that persistent group object is still
|
||||||
|
* represented in same manner as network within.
|
||||||
|
*/
|
||||||
|
return wpas_dbus_getter_network_properties(message, net);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Group object properties accessor methods
|
* Group object properties accessor methods
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -139,4 +139,13 @@ DBusMessage *wpas_dbus_setter_p2p_group_properties(
|
||||||
DBusMessage *message,
|
DBusMessage *message,
|
||||||
struct wpa_supplicant *wpa_s);
|
struct wpa_supplicant *wpa_s);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* P2P Persistent Group properties
|
||||||
|
*/
|
||||||
|
|
||||||
|
DBusMessage * wpas_dbus_getter_persistent_groups(DBusMessage *message,
|
||||||
|
struct wpa_supplicant *wpa_s);
|
||||||
|
DBusMessage * wpas_dbus_getter_persistent_group_properties(
|
||||||
|
DBusMessage *message, struct network_handler_args *net);
|
||||||
|
|
||||||
#endif /* DBUS_NEW_HANDLERS_P2P_H */
|
#endif /* DBUS_NEW_HANDLERS_P2P_H */
|
||||||
|
|
|
@ -206,14 +206,29 @@ void wpas_notify_wps_event_success(struct wpa_supplicant *wpa_s)
|
||||||
void wpas_notify_network_added(struct wpa_supplicant *wpa_s,
|
void wpas_notify_network_added(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_ssid *ssid)
|
struct wpa_ssid *ssid)
|
||||||
{
|
{
|
||||||
wpas_dbus_register_network(wpa_s, ssid);
|
/*
|
||||||
|
* Networks objects created during any P2P activities should not be
|
||||||
|
* exposed out. They might/will confuse certain non-P2P aware
|
||||||
|
* applications since these network objects won't behave like
|
||||||
|
* regular ones.
|
||||||
|
*/
|
||||||
|
if (wpa_s->global->p2p_group_formation != wpa_s)
|
||||||
|
wpas_dbus_register_network(wpa_s, ssid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wpas_notify_persistent_group_added(struct wpa_supplicant *wpa_s,
|
||||||
|
struct wpa_ssid *ssid)
|
||||||
|
{
|
||||||
|
wpas_dbus_register_persistent_group(wpa_s, ssid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void wpas_notify_network_removed(struct wpa_supplicant *wpa_s,
|
void wpas_notify_network_removed(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_ssid *ssid)
|
struct wpa_ssid *ssid)
|
||||||
{
|
{
|
||||||
wpas_dbus_unregister_network(wpa_s, ssid->id);
|
if (wpa_s->global->p2p_group_formation != wpa_s)
|
||||||
|
wpas_dbus_unregister_network(wpa_s, ssid->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -111,5 +111,7 @@ void wpas_notify_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
|
||||||
void wpas_notify_p2p_group_started(struct wpa_supplicant *wpa_s,
|
void wpas_notify_p2p_group_started(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_ssid *ssid, int network_id,
|
struct wpa_ssid *ssid, int network_id,
|
||||||
int client);
|
int client);
|
||||||
|
void wpas_notify_persistent_group_added(struct wpa_supplicant *wpa_s,
|
||||||
|
struct wpa_ssid *ssid);
|
||||||
|
|
||||||
#endif /* NOTIFY_H */
|
#endif /* NOTIFY_H */
|
||||||
|
|
|
@ -295,7 +295,15 @@ static void wpas_p2p_group_delete(struct wpa_supplicant *wpa_s)
|
||||||
int id = ssid->id;
|
int id = ssid->id;
|
||||||
if (ssid == wpa_s->current_ssid)
|
if (ssid == wpa_s->current_ssid)
|
||||||
wpa_s->current_ssid = NULL;
|
wpa_s->current_ssid = NULL;
|
||||||
wpas_notify_network_removed(wpa_s, ssid);
|
/*
|
||||||
|
* Networks objects created during any P2P activities are not
|
||||||
|
* exposed out as they might/will confuse certain non-P2P aware
|
||||||
|
* applications since these network objects won't behave like
|
||||||
|
* regular ones.
|
||||||
|
*
|
||||||
|
* Likewise, we don't send out network removed signals for such
|
||||||
|
* network objects.
|
||||||
|
*/
|
||||||
wpa_config_remove_network(wpa_s->conf, id);
|
wpa_config_remove_network(wpa_s->conf, id);
|
||||||
wpa_supplicant_clear_status(wpa_s);
|
wpa_supplicant_clear_status(wpa_s);
|
||||||
} else {
|
} else {
|
||||||
|
@ -400,7 +408,16 @@ static int wpas_p2p_store_persistent_group(struct wpa_supplicant *wpa_s,
|
||||||
s = wpa_config_add_network(wpa_s->conf);
|
s = wpa_config_add_network(wpa_s->conf);
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
wpas_notify_network_added(wpa_s, s);
|
|
||||||
|
/*
|
||||||
|
* Instead of network_added we emit persistent_group_added
|
||||||
|
* notification. Also to keep the defense checks in
|
||||||
|
* persistent_group obj registration method, we set the
|
||||||
|
* relevant flags in s to designate it as a persistent group.
|
||||||
|
*/
|
||||||
|
s->p2p_group = 1;
|
||||||
|
s->p2p_persistent_group = 1;
|
||||||
|
wpas_notify_persistent_group_added(wpa_s, s);
|
||||||
wpa_config_set_network_defaults(s);
|
wpa_config_set_network_defaults(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -904,7 +921,6 @@ static void wpas_start_wps_go(struct wpa_supplicant *wpa_s,
|
||||||
if (ssid == NULL)
|
if (ssid == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wpas_notify_network_added(wpa_s, ssid);
|
|
||||||
wpa_config_set_network_defaults(ssid);
|
wpa_config_set_network_defaults(ssid);
|
||||||
ssid->temporary = 1;
|
ssid->temporary = 1;
|
||||||
ssid->p2p_group = 1;
|
ssid->p2p_group = 1;
|
||||||
|
@ -3303,7 +3319,6 @@ static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
|
||||||
ssid = wpa_config_add_network(wpa_s->conf);
|
ssid = wpa_config_add_network(wpa_s->conf);
|
||||||
if (ssid == NULL)
|
if (ssid == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
wpas_notify_network_added(wpa_s, ssid);
|
|
||||||
wpa_config_set_network_defaults(ssid);
|
wpa_config_set_network_defaults(ssid);
|
||||||
ssid->temporary = 1;
|
ssid->temporary = 1;
|
||||||
ssid->proto = WPA_PROTO_RSN;
|
ssid->proto = WPA_PROTO_RSN;
|
||||||
|
@ -3312,7 +3327,6 @@ static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
|
||||||
ssid->key_mgmt = WPA_KEY_MGMT_PSK;
|
ssid->key_mgmt = WPA_KEY_MGMT_PSK;
|
||||||
ssid->ssid = os_malloc(params->ssid_len);
|
ssid->ssid = os_malloc(params->ssid_len);
|
||||||
if (ssid->ssid == NULL) {
|
if (ssid->ssid == NULL) {
|
||||||
wpas_notify_network_removed(wpa_s, ssid);
|
|
||||||
wpa_config_remove_network(wpa_s->conf, ssid->id);
|
wpa_config_remove_network(wpa_s->conf, ssid->id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "utils/list.h"
|
#include "utils/list.h"
|
||||||
#include "common/defs.h"
|
#include "common/defs.h"
|
||||||
|
#include "config_ssid.h"
|
||||||
|
|
||||||
extern const char *wpa_supplicant_version;
|
extern const char *wpa_supplicant_version;
|
||||||
extern const char *wpa_supplicant_license;
|
extern const char *wpa_supplicant_license;
|
||||||
|
@ -642,4 +643,14 @@ void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
|
||||||
/* eap_register.c */
|
/* eap_register.c */
|
||||||
int eap_register_methods(void);
|
int eap_register_methods(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility method to tell if a given network is a persistent group
|
||||||
|
* @ssid: Network object
|
||||||
|
* Returns: 1 if network is a persistent group, 0 otherwise
|
||||||
|
*/
|
||||||
|
static inline int network_is_persistent_group(struct wpa_ssid *ssid)
|
||||||
|
{
|
||||||
|
return ((ssid->disabled == 2) || ssid->p2p_persistent_group);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* WPA_SUPPLICANT_I_H */
|
#endif /* WPA_SUPPLICANT_I_H */
|
||||||
|
|
|
@ -780,9 +780,18 @@ static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s,
|
||||||
ssid = wpa_s->conf->ssid;
|
ssid = wpa_s->conf->ssid;
|
||||||
while (ssid) {
|
while (ssid) {
|
||||||
int was_disabled = ssid->disabled;
|
int was_disabled = ssid->disabled;
|
||||||
ssid->disabled = ssid != selected;
|
/*
|
||||||
if (was_disabled != ssid->disabled)
|
* In case the network object corresponds to a persistent group
|
||||||
wpas_notify_network_enabled_changed(wpa_s, ssid);
|
* then do not send out network disabled signal. In addition,
|
||||||
|
* do not change disabled status of persistent network objects
|
||||||
|
* from 2 to 1 should we connect to another network.
|
||||||
|
*/
|
||||||
|
if (was_disabled != 2) {
|
||||||
|
ssid->disabled = ssid != selected;
|
||||||
|
if (was_disabled != ssid->disabled)
|
||||||
|
wpas_notify_network_enabled_changed(wpa_s,
|
||||||
|
ssid);
|
||||||
|
}
|
||||||
ssid = ssid->next;
|
ssid = ssid->next;
|
||||||
}
|
}
|
||||||
wpa_s->disconnected = 0;
|
wpa_s->disconnected = 0;
|
||||||
|
|
Loading…
Reference in a new issue