P2P: Add a function to compute the group common freqs
authorIlan Peer <ilan.peer@intel.com>
Mon, 27 Jul 2015 19:24:20 +0000 (22:24 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 3 Aug 2015 21:18:51 +0000 (00:18 +0300)
Add a function to compute the group common frequencies, and
use it to update the group_common_frequencies as part of the
channel switch flows.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
src/p2p/p2p.h
src/p2p/p2p_group.c
wpa_supplicant/p2p_supplicant.c

index edfcc8a..d488738 100644 (file)
@@ -2325,4 +2325,14 @@ void p2p_set_own_pref_freq_list(struct p2p_data *p2p,
                                const unsigned int *pref_freq_list,
                                unsigned int size);
 
+/**
+ * p2p_group_get_common_freqs - Get the group common frequencies
+ * @group: P2P group context from p2p_group_init()
+ * @common_freqs: On return will hold the group common frequencies
+ * @num: On return will hold the number of group common frequencies
+ * Returns: 0 on success, -1 otherwise
+ */
+int p2p_group_get_common_freqs(struct p2p_group *group, int *common_freqs,
+                              unsigned int *num);
+
 #endif /* P2P_H */
index 41ca99f..0d66993 100644 (file)
@@ -1071,3 +1071,43 @@ void p2p_loop_on_all_groups(struct p2p_data *p2p,
                        break;
        }
 }
+
+
+int p2p_group_get_common_freqs(struct p2p_group *group, int *common_freqs,
+                              unsigned int *num)
+
+{
+       struct p2p_channels intersect, res;
+       struct p2p_group_member *m;
+
+       if (!group || !common_freqs || !num)
+               return -1;
+
+       os_memset(&intersect, 0, sizeof(intersect));
+       os_memset(&res, 0, sizeof(res));
+
+       p2p_channels_union(&intersect, &group->p2p->cfg->channels,
+                          &intersect);
+
+       p2p_channels_dump(group->p2p,
+                         "Group common freqs before iterating members",
+                         &intersect);
+
+       for (m = group->members; m; m = m->next) {
+               struct p2p_device *dev;
+
+               dev = p2p_get_device(group->p2p, m->dev_addr);
+               if (!dev)
+                       continue;
+
+               p2p_channels_intersect(&intersect, &dev->channels, &res);
+               intersect = res;
+       }
+
+       p2p_channels_dump(group->p2p, "Group common channels", &intersect);
+
+       os_memset(common_freqs, 0, *num * sizeof(int));
+       *num = p2p_channels_to_freqs(&intersect, common_freqs, *num);
+
+       return 0;
+}
index 9c256a5..88798e3 100644 (file)
@@ -2606,6 +2606,32 @@ static int freq_included(const struct p2p_channels *channels, unsigned int freq)
 }
 
 
+static void wpas_p2p_go_update_common_freqs(struct wpa_supplicant *wpa_s)
+{
+       unsigned int num = P2P_MAX_CHANNELS;
+       int *common_freqs;
+       int ret;
+
+       p2p_go_dump_common_freqs(wpa_s);
+       common_freqs = os_calloc(num, sizeof(int));
+       if (!common_freqs)
+               return;
+
+       ret = p2p_group_get_common_freqs(wpa_s->p2p_group, common_freqs, &num);
+       if (ret < 0) {
+               wpa_dbg(wpa_s, MSG_DEBUG,
+                       "P2P: Failed to get group common freqs");
+               os_free(common_freqs);
+               return;
+       }
+
+       os_free(wpa_s->p2p_group_common_freqs);
+       wpa_s->p2p_group_common_freqs = common_freqs;
+       wpa_s->p2p_group_common_freqs_num = num;
+       p2p_go_dump_common_freqs(wpa_s);
+}
+
+
 /*
  * Check if the given frequency is one of the possible operating frequencies
  * set after the completion of the GO Negotiation.
@@ -8345,6 +8371,8 @@ static void wpas_p2p_move_go(void *eloop_ctx, void *timeout_ctx)
        if (!wpa_s->ap_iface || !wpa_s->current_ssid)
                return;
 
+       wpas_p2p_go_update_common_freqs(wpa_s);
+
        /*
         * First, try a channel switch flow. If it is not supported or fails,
         * take down the GO and bring it up again.
@@ -8373,6 +8401,8 @@ static void wpas_p2p_consider_moving_one_go(struct wpa_supplicant *wpa_s,
        unsigned int timeout;
        int freq;
 
+       wpas_p2p_go_update_common_freqs(wpa_s);
+
        freq = wpa_s->current_ssid->frequency;
        for (i = 0, invalid_freq = 0; i < num; i++) {
                if (freqs[i].freq == freq) {