|
@@ -228,10 +228,41 @@ static void advertisement_state_machine_handler(void *eloop_data,
|
|
|
/**
|
|
|
* advertisement_state_machine_stop - Stop SSDP advertisements
|
|
|
* @sm: WPS UPnP state machine from upnp_wps_device_init()
|
|
|
+ * @send_byebye: Send byebye advertisement messages immediately
|
|
|
*/
|
|
|
-void advertisement_state_machine_stop(struct upnp_wps_device_sm *sm)
|
|
|
+void advertisement_state_machine_stop(struct upnp_wps_device_sm *sm,
|
|
|
+ int send_byebye)
|
|
|
{
|
|
|
+ struct advertisement_state_machine *a = &sm->advertisement;
|
|
|
+ int islast = 0;
|
|
|
+ struct wpabuf *msg;
|
|
|
+ struct sockaddr_in dest;
|
|
|
+
|
|
|
eloop_cancel_timeout(advertisement_state_machine_handler, NULL, sm);
|
|
|
+ if (!send_byebye)
|
|
|
+ return;
|
|
|
+
|
|
|
+ a->type = ADVERTISE_DOWN;
|
|
|
+ a->state = 0;
|
|
|
+ a->sm = sm;
|
|
|
+
|
|
|
+ os_memset(&dest, 0, sizeof(dest));
|
|
|
+ dest.sin_family = AF_INET;
|
|
|
+ dest.sin_addr.s_addr = inet_addr(UPNP_MULTICAST_ADDRESS);
|
|
|
+ dest.sin_port = htons(UPNP_MULTICAST_PORT);
|
|
|
+
|
|
|
+ while (!islast) {
|
|
|
+ msg = next_advertisement(a, &islast);
|
|
|
+ if (msg == NULL)
|
|
|
+ break;
|
|
|
+ if (sendto(sm->multicast_sd, wpabuf_head(msg), wpabuf_len(msg),
|
|
|
+ 0, (struct sockaddr *) &dest, sizeof(dest)) < 0) {
|
|
|
+ wpa_printf(MSG_INFO, "WPS UPnP: Advertisement sendto "
|
|
|
+ "failed: %d (%s)", errno, strerror(errno));
|
|
|
+ }
|
|
|
+ wpabuf_free(msg);
|
|
|
+ a->state++;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -317,7 +348,7 @@ int advertisement_state_machine_start(struct upnp_wps_device_sm *sm)
|
|
|
struct advertisement_state_machine *a = &sm->advertisement;
|
|
|
int next_timeout_msec;
|
|
|
|
|
|
- advertisement_state_machine_stop(sm);
|
|
|
+ advertisement_state_machine_stop(sm, 0);
|
|
|
|
|
|
/*
|
|
|
* Start out advertising down, this automatically switches
|