dl_list_for_each_safe(s, tmp, &sm->subscriptions, struct subscription,
list) {
- if (event_add(s, buf) == 1) {
+ if (event_add(s, buf, sm->wlanevent_type ==
+ UPNP_WPS_WLANEVENT_TYPE_PROBE) == 1) {
wpa_printf(MSG_INFO, "WPS UPnP: Dropping "
"subscriber %p due to event backlog", s);
dl_list_del(&s->list);
wpabuf_put_property(buf, "WLANEvent", wlan_event);
wpabuf_put_str(buf, tail);
- ret = event_add(s, buf);
+ ret = event_add(s, buf, 0);
if (ret) {
wpabuf_free(buf);
return ret;
os_free(sm->wlanevent);
sm->wlanevent = val;
+ sm->wlanevent_type = ev_type;
upnp_wps_device_send_event(sm);
ret = 0;
wpa_printf(MSG_DEBUG, "WPS UPnP: Giving up on sending event "
"for %s", e->addr->domain_and_port);
event_delete(e);
+ s->last_event_failed = 1;
if (!dl_list_empty(&s->event_queue))
event_send_all_later(s->sm);
return;
"WPS UPnP: Got event %p reply OK from %s",
e, e->addr->domain_and_port);
e->addr->num_failures = 0;
+ s->last_event_failed = 0;
event_delete(e);
/* Schedule sending more if there is more to send */
* event_add - Add a new event to a queue
* @s: Subscription
* @data: Event data (is copied; caller retains ownership)
+ * @probereq: Whether this is a Probe Request event
* Returns: 0 on success, -1 on error, 1 on max event queue limit reached
*/
-int event_add(struct subscription *s, const struct wpabuf *data)
+int event_add(struct subscription *s, const struct wpabuf *data, int probereq)
{
struct wps_event_ *e;
unsigned int len;
return 1;
}
+ if (s->last_event_failed && probereq && len > 0) {
+ /*
+ * Avoid queuing frames for subscribers that may have left
+ * without unsubscribing.
+ */
+ wpa_printf(MSG_DEBUG, "WPS UPnP: Do not queue more Probe "
+ "Request frames for subscription %p since last "
+ "delivery failed", s);
+ return -1;
+ }
+
e = os_zalloc(sizeof(*e));
if (e == NULL)
return -1;
struct dl_list event_queue; /* Queued event messages. */
struct wps_event_ *current_event; /* non-NULL if being sent (not in q)
*/
+ int last_event_failed; /* Whether delivery of last event failed */
/* Information from SetSelectedRegistrar action */
u8 selected_registrar;
*/
char *wlanevent; /* the last WLANEvent data */
+ enum upnp_wps_wlanevent_type wlanevent_type;
/* FIX: maintain separate structures for each UPnP peer */
struct upnp_wps_peer peer;
void web_listener_stop(struct upnp_wps_device_sm *sm);
/* wps_upnp_event.c */
-int event_add(struct subscription *s, const struct wpabuf *data);
+int event_add(struct subscription *s, const struct wpabuf *data, int probereq);
void event_delete_all(struct subscription *s);
void event_send_all_later(struct upnp_wps_device_sm *sm);
void event_send_stop_all(struct upnp_wps_device_sm *sm);