Hi Tomasz,

On 07/09/2014 02:36 PM, Tomasz Bursztyka wrote:
> These handlers make the link between the requested connection and the
> interface of the group instanciated in case of a successful group
> negociation.
> ---
>  gsupplicant/gsupplicant.h |   5 ++
>  gsupplicant/supplicant.c  | 174 
> ++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 179 insertions(+)
> 
> diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h
> index 99f9d90..6f79125 100644
> --- a/gsupplicant/gsupplicant.h
> +++ b/gsupplicant/gsupplicant.h
> @@ -80,6 +80,9 @@ extern "C" {
>  
>  #define G_SUPPLICANT_WPS_CONFIG_PBC  0x0080
>  
> +#define G_SUPPLICANT_GROUP_ROLE_CLIENT       (1 << 0)
> +#define G_SUPPLICANT_GROUP_ROLE_GO      (1 << 1)
> +
>  typedef enum {
>       G_SUPPLICANT_MODE_UNKNOWN,
>       G_SUPPLICANT_MODE_INFRA,
> @@ -239,9 +242,11 @@ int 
> g_supplicant_interface_set_p2p_device_config(GSupplicantInterface *interface
>  /* Network and Peer API */
>  struct _GSupplicantNetwork;
>  struct _GSupplicantPeer;
> +struct _GSupplicantGroup;
>  
>  typedef struct _GSupplicantNetwork GSupplicantNetwork;
>  typedef struct _GSupplicantPeer GSupplicantPeer;
> +typedef struct _GSupplicantGroup GSupplicantGroup;
>  
>  GSupplicantInterface *g_supplicant_network_get_interface(GSupplicantNetwork 
> *network);
>  const char *g_supplicant_network_get_name(GSupplicantNetwork *network);
> diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c
> index 026776a..4c05299 100644
> --- a/gsupplicant/supplicant.c
> +++ b/gsupplicant/supplicant.c
> @@ -169,6 +169,7 @@ struct _GSupplicantInterface {
>       GSupplicantWpsState wps_state;
>       GHashTable *network_table;
>       GHashTable *peer_table;
> +     GHashTable *group_table;
>       GHashTable *net_mapping;
>       GHashTable *bss_mapping;
>       void *data;
> @@ -221,11 +222,18 @@ struct _GSupplicantPeer {
>       GSupplicantInterface *interface;
>       char *path;
>       unsigned char device_address[6];
> +     unsigned char iface_address[6];

I know it is too late but I would prefer a define ETH_ALEN from if_ether.h

>       char *name;
>       char *identifier;
>       unsigned int wps_capabilities;
>  };
>  
> +struct _GSupplicantGroup {
> +     GSupplicantInterface *interface;
> +     char *path;
> +     int role;
> +};
> +
>  static inline void debug(const char *format, ...)
>  {
>       char str[256];
> @@ -478,6 +486,14 @@ static void callback_peer_lost(GSupplicantPeer *peer)
>       callbacks_pointer->peer_lost(peer);
>  }
>  
> +static void remove_group(gpointer data)
> +{
> +     GSupplicantGroup *group = data;
> +
> +     g_free(group->path);
> +     g_free(group);
> +}
> +
>  static void remove_interface(gpointer data)
>  {
>       GSupplicantInterface *interface = data;
> @@ -486,6 +502,7 @@ static void remove_interface(gpointer data)
>       g_hash_table_destroy(interface->net_mapping);
>       g_hash_table_destroy(interface->network_table);
>       g_hash_table_destroy(interface->peer_table);
> +     g_hash_table_destroy(interface->group_table);
>  
>       if (interface->scan_callback) {
>               SUPPLICANT_DBG("call interface %p callback %p scanning %d",
> @@ -1932,6 +1949,8 @@ static GSupplicantInterface *interface_alloc(const char 
> *path)
>                                       g_str_equal, NULL, remove_network);
>       interface->peer_table = g_hash_table_new_full(g_str_hash,
>                                       g_str_equal, NULL, remove_peer);
> +     interface->group_table = g_hash_table_new_full(g_str_hash,
> +                                     g_str_equal, NULL, remove_group);
>       interface->net_mapping = g_hash_table_new_full(g_str_hash, g_str_equal,
>                                                               NULL, NULL);
>       interface->bss_mapping = g_hash_table_new_full(g_str_hash, g_str_equal,
> @@ -2551,6 +2570,156 @@ static void signal_peer_lost(const char *path, 
> DBusMessageIter *iter)
>       g_hash_table_remove(interface->peer_table, obj_path);
>  }
>  
> +struct group_sig_data {
> +     const char *peer_obj_path;
> +     unsigned char iface_address[6];

ETH_ALEN

> +     const char *interface_obj_path;
> +     const char *group_obj_path;
> +     int role;
> +};
> +
> +static void group_sig_property(const char *key, DBusMessageIter *iter,
> +                                                     void *user_data)
> +{
> +     struct group_sig_data *data = user_data;
> +
> +     if (!key)
> +             return;
> +
> +     if (g_strcmp0(key, "peer_interface_addr") == 0) {
> +             unsigned char *dev_addr;
> +             DBusMessageIter array;
> +             int len;
> +
> +             dbus_message_iter_recurse(iter, &array);
> +             dbus_message_iter_get_fixed_array(&array, &dev_addr, &len);
> +
> +             if (len == 6)

ETH_ALEN

> +                     memcpy(data->iface_address, dev_addr, len);
> +
> +     } else if (g_strcmp0(key, "peer_object") == 0)
> +             dbus_message_iter_get_basic(iter, &data->peer_obj_path);
> +     else if (g_strcmp0(key, "interface_object") == 0)
> +             dbus_message_iter_get_basic(iter, &data->interface_obj_path);
> +     else if (g_strcmp0(key, "group_object") == 0)
> +             dbus_message_iter_get_basic(iter, &data->group_obj_path);
> +     else if (g_strcmp0(key, "role") == 0) {
> +             const char *str = NULL;
> +
> +             dbus_message_iter_get_basic(iter, &str);
> +             if (g_strcmp0(str, "GO") == 0)
> +                     data->role = G_SUPPLICANT_GROUP_ROLE_GO;
> +             else
> +                     data->role = G_SUPPLICANT_GROUP_ROLE_CLIENT;
> +     }


Please group the 'else if' with curly braces together if that is possible.

> +
> +}
> +
> +static void signal_group_success(const char *path, DBusMessageIter *iter)
> +{
> +     GSupplicantInterface *interface;
> +     struct group_sig_data data = {};
> +     GSupplicantPeer *peer;
> +
> +     SUPPLICANT_DBG("");
> +
> +     interface = g_hash_table_lookup(interface_table, path);
> +     if (!interface)
> +             return;
> +
> +     supplicant_dbus_property_foreach(iter, group_sig_property, &data);
> +     if (!data.peer_obj_path)
> +             return;
> +
> +     peer = g_hash_table_lookup(interface->peer_table, data.peer_obj_path);
> +     if (!peer)
> +             return;
> +
> +     memcpy(peer->iface_address, data.iface_address, 6);

ETH_ALEN

> +}
> +
> +static void signal_group_failure(const char *path, DBusMessageIter *iter)
> +{
> +     GSupplicantInterface *interface;
> +     struct group_sig_data data = {};
> +     GSupplicantPeer *peer;
> +
> +     SUPPLICANT_DBG("");
> +
> +     interface = g_hash_table_lookup(interface_table, path);
> +     if (!interface)
> +             return;
> +
> +     supplicant_dbus_property_foreach(iter, group_sig_property, &data);
> +     if (!data.peer_obj_path)
> +             return;
> +
> +     peer = g_hash_table_lookup(interface->peer_table, data.peer_obj_path);
> +     if (!peer)
> +             return;

What do you want to do with peer?

> +}
> +
> +static void signal_group_started(const char *path, DBusMessageIter *iter)
> +{
> +     GSupplicantInterface *interface;
> +     struct group_sig_data data = {};
> +     GSupplicantGroup *group;
> +
> +     SUPPLICANT_DBG("");
> +
> +     interface = g_hash_table_lookup(interface_table, path);
> +     if (!interface)
> +             return;
> +
> +     supplicant_dbus_property_foreach(iter, group_sig_property, &data);
> +     if (!data.interface_obj_path || !data.group_obj_path)
> +             return;
> +
> +     interface = g_hash_table_lookup(interface_table,
> +                                             data.interface_obj_path);
> +     if (!interface)
> +             return;
> +
> +     group = g_hash_table_lookup(interface->group_table,
> +                                             data.group_obj_path);
> +     if (group)
> +             return;
> +
> +     group = g_try_new0(GSupplicantGroup, 1);
> +     if (!group)
> +             return;
> +
> +     group->interface = interface;
> +     group->path = g_strdup(data.group_obj_path);
> +     group->role = data.role;
> +
> +     g_hash_table_insert(interface->group_table, group->path, group);

g_hash_table_replace?

> +}
> +
> +static void signal_group_finished(const char *path, DBusMessageIter *iter)
> +{
> +     GSupplicantInterface *interface;
> +     struct group_sig_data data = {};
> +     GSupplicantGroup *group;
> +
> +     SUPPLICANT_DBG("");
> +
> +     interface = g_hash_table_lookup(interface_table, path);
> +     if (!interface)
> +             return;
> +
> +     supplicant_dbus_property_foreach(iter, group_sig_property, &data);
> +     if (!data.interface_obj_path || !data.group_obj_path)
> +             return;
> +
> +     group = g_hash_table_lookup(interface->group_table,
> +                                             data.group_obj_path);
> +     if (!group)
> +             return;
> +
> +     g_hash_table_remove(interface->group_table, group->path);
> +}
> +
>  static struct {
>       const char *interface;
>       const char *member;
> @@ -2578,6 +2747,11 @@ static struct {
>       { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "DeviceFound", 
> signal_peer_found },
>       { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "DeviceLost",  
> signal_peer_lost  },
>  
> +     { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GONegotiationSuccess", 
> signal_group_success },
> +     { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GONegotiationFailure", 
> signal_group_failure },
> +     { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GroupStarted", 
> signal_group_started },
> +     { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GroupFinished", 
> signal_group_finished },
> +
>       { }
>  };
>  

cheers,
daniel
_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman

Reply via email to