@@ -1547,4 +1547,26 @@ int p2p_in_progress(struct p2p_data *p2p);
*/
int p2p_other_scan_completed(struct p2p_data *p2p);
+/**
+ * p2p_group_handle_driver_notify_noa - Handle driver notification about
+ * NOA change/set
+ * @p2p_group: P2P group context from p2p_group_init()
+ * @index: Instance of NOA timeing
+ * @oppps_ctwindow: Opportunistic power save capability
+ * BIT(7): 1 - enabled, 0 disabled
+ * BITS(0-6) - Client Traffic Window in TU
+ * @count_type: Indicates the number of absence intervals
+ * 255 - mean a continous schedule
+ * 0 - mean NOA disabled
+ * @duration: Duration in units of microseconds that P2P_GO
+ * can remain absent following the start of NOA
+ * interval
+ * @interval: NOA interval in units of microseconds
+ * @start_time: The start time for the schedule expressed in terms
+ * of lower 4 bytes of the TSF timer
+ */
+void p2p_group_handle_driver_notify_noa(struct p2p_group *group, u8 index,
+ u8 oppps_ctwindow, u8 count_type,
+ u32 duration, u32 interval,
+ u32 start_time);
#endif /* P2P_H */
@@ -696,3 +696,52 @@ const u8 * p2p_iterate_group_members(struct p2p_group *group, void **next)
return iter->addr;
}
+
+
+void p2p_group_handle_driver_notify_noa(struct p2p_group *group, u8 index,
+ u8 oppps_ctwindow, u8 count_type,
+ u32 duration, u32 interval,
+ u32 start_time)
+{
+ struct wpabuf *req;
+ struct p2p_noa_desc desc = {0}, *noa_desc;
+
+ wpa_printf(MSG_DEBUG, "%s called, index: %d, oppps: %d, count: %d, "
+ "duration: %d, interval: %d, start: %d\n",
+ __func__, index, oppps_ctwindow, count_type,
+ duration, interval, start_time);
+
+ noa_desc = &desc;
+ req = wpabuf_alloc(100);
+ if (req == NULL)
+ return;
+
+ desc.count_type = count_type;
+ desc.duration = duration;
+ desc.interval = interval;
+ desc.start_time = start_time;
+
+ /* Check if NOA disabled */
+ if(count_type == 0)
+ noa_desc = NULL;
+
+ /* Build NOA attr */
+ p2p_buf_add_noa(req,
+ index,
+ 0,
+ 0,
+ noa_desc, NULL);
+
+ /* Check if we should clear NOA attr */
+ if (!(oppps_ctwindow & BIT(7)) && !noa_desc) {
+ /* Remove NOA attr */
+ wpabuf_free(req);
+ req = NULL;
+ }
+
+ /* Update beacon, probe_resp IEs */
+ p2p_group_notif_noa(group, req);
+
+ if (req)
+ wpabuf_free(req);
+}
@@ -2471,10 +2471,14 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
break;
case EVENT_DRIVER_NOTIFY_NOA:
#ifdef CONFIG_P2P
- /* TODO: Update Beacon and probe response here
- * p2p_group_notif_noa()
- */
wpa_dbg(wpa_s, MSG_DEBUG, "EVENT_DRIVER_NOTIFY_NOA");
+ wpas_handle_notify_noa(wpa_s,
+ data->driver_notify_noa.index,
+ data->driver_notify_noa.oppps_ctwindow,
+ data->driver_notify_noa.count_type,
+ data->driver_notify_noa.duration,
+ data->driver_notify_noa.interval,
+ data->driver_notify_noa.start_time);
#endif /* CONFIG_P2P */
break;
default:
@@ -4161,3 +4161,22 @@ int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s)
return p2p_in_progress(wpa_s->global->p2p);
}
+
+
+void wpas_handle_notify_noa(void *ctx, u8 index, u8 oppps_ctwindow,
+ u8 count_type, u32 duration, u32 interval,
+ u32 start_time)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
+ return;
+
+ if (!wpa_s->ap_iface)
+ return;
+
+ p2p_group_handle_driver_notify_noa(wpa_s->ap_iface->bss[0]->p2p_group,
+ index, oppps_ctwindow,
+ count_type, duration, interval,
+ start_time);
+}
@@ -129,4 +129,7 @@ void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
struct wps_event_fail *fail);
int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s);
+void wpas_handle_notify_noa(void *ctx, u8 index, u8 oppps_ctwindow,
+ u8 count_type, u32 duration, u32 interval,
+ u32 start_time);
#endif /* P2P_SUPPLICANT_H */