WPS: Add support for setting timeout for PIN
[wpasupplicant] / hostapd / ctrl_iface.c
index df53419..3cd498c 100644 (file)
@@ -31,7 +31,7 @@
 #include "sta_info.h"
 #include "accounting.h"
 #include "wps_hostapd.h"
-#include "driver.h"
+#include "drivers/driver.h"
 
 
 struct wpa_ctrl_dst {
@@ -231,6 +231,7 @@ static int hostapd_ctrl_iface_new_sta(struct hostapd_data *hapd,
 
 
 #ifdef CONFIG_IEEE80211W
+#ifdef NEED_MLME
 static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd,
                                       const char *txtaddr)
 {
@@ -247,6 +248,7 @@ static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd,
 
        return 0;
 }
+#endif /* NEED_MLME */
 #endif /* CONFIG_IEEE80211W */
 
 
@@ -254,10 +256,21 @@ static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd,
 static int hostapd_ctrl_iface_wps_pin(struct hostapd_data *hapd, char *txt)
 {
        char *pin = os_strchr(txt, ' ');
+       char *timeout_txt;
+       int timeout;
+
        if (pin == NULL)
                return -1;
        *pin++ = '\0';
-       return hostapd_wps_add_pin(hapd, txt, pin);
+
+       timeout_txt = os_strchr(pin, ' ');
+       if (timeout_txt) {
+               *timeout_txt++ = '\0';
+               timeout = atoi(timeout_txt);
+       } else
+               timeout = 0;
+
+       return hostapd_wps_add_pin(hapd, txt, pin, timeout);
 }
 
 
@@ -370,9 +383,11 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
                if (hostapd_ctrl_iface_new_sta(hapd, buf + 8))
                        reply_len = -1;
 #ifdef CONFIG_IEEE80211W
+#ifdef NEED_MLME
        } else if (os_strncmp(buf, "SA_QUERY ", 9) == 0) {
                if (hostapd_ctrl_iface_sa_query(hapd, buf + 9))
                        reply_len = -1;
+#endif /* NEED_MLME */
 #endif /* CONFIG_IEEE80211W */
 #ifdef CONFIG_WPS
        } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
@@ -480,8 +495,35 @@ int hostapd_ctrl_iface_init(struct hostapd_data *hapd)
                goto fail;
        os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path));
        if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-               perror("bind(PF_UNIX)");
-               goto fail;
+               wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s",
+                          strerror(errno));
+               if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+                       wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
+                                  " allow connections - assuming it was left"
+                                  "over from forced program termination");
+                       if (unlink(fname) < 0) {
+                               perror("unlink[ctrl_iface]");
+                               wpa_printf(MSG_ERROR, "Could not unlink "
+                                          "existing ctrl_iface socket '%s'",
+                                          fname);
+                               goto fail;
+                       }
+                       if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) <
+                           0) {
+                               perror("bind(PF_UNIX)");
+                               goto fail;
+                       }
+                       wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
+                                  "ctrl_iface socket '%s'", fname);
+               } else {
+                       wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
+                                  "be in use - cannot override it");
+                       wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
+                                  "not used anymore", fname);
+                       os_free(fname);
+                       fname = NULL;
+                       goto fail;
+               }
        }
 
        if (hapd->conf->ctrl_interface_gid_set &&