diff --git a/src/wps/wps_er.c b/src/wps/wps_er.c
index 05c33dada..6bfdac430 100644
--- a/src/wps/wps_er.c
+++ b/src/wps/wps_er.c
@@ -15,6 +15,7 @@
#include "includes.h"
#include "common.h"
+#include "base64.h"
#include "uuid.h"
#include "eloop.h"
#include "httpread.h"
@@ -140,13 +141,6 @@ static void wps_er_sta_remove_all(struct wps_er_ap *ap)
}
-static void wps_er_pin_needed_cb(void *ctx, const u8 *uuid_e,
- const struct wps_device_data *dev)
-{
- wpa_printf(MSG_DEBUG, "WPS ER: PIN needed");
-}
-
-
static struct wps_er_ap * wps_er_ap_get(struct wps_er *er,
struct in_addr *addr)
{
@@ -717,12 +711,110 @@ static void wps_er_process_wlanevent_probe_req(struct wps_er_ap *ap,
}
+static void wps_er_http_put_wlan_response_cb(void *ctx, struct http_client *c,
+ enum http_client_event event)
+{
+ struct wps_er_sta *sta = ctx;
+
+ switch (event) {
+ case HTTP_CLIENT_OK:
+ wpa_printf(MSG_DEBUG, "WPS ER: PutWLANResponse OK");
+ break;
+ case HTTP_CLIENT_FAILED:
+ case HTTP_CLIENT_INVALID_REPLY:
+ case HTTP_CLIENT_TIMEOUT:
+ wpa_printf(MSG_DEBUG, "WPS ER: PutWLANResponse failed");
+ break;
+ }
+ http_client_free(sta->http);
+ sta->http = NULL;
+}
+
+
+static const char *soap_prefix =
+ "\n"
+ "\n"
+ "\n";
+static const char *soap_postfix =
+ "\n\n";
+static const char *urn_wfawlanconfig =
+ "urn:schemas-wifialliance-org:service:WFAWLANConfig:1";
+
static void wps_er_sta_send_msg(struct wps_er_sta *sta, struct wpabuf *msg)
{
- /* TODO: send msg as UPnP POST: PutWLANResponse(NewMessage,
- * NewWLANEventType, NewWLANEventMAC) */
+ unsigned char *encoded;
+ size_t encoded_len;
+ struct wpabuf *buf;
+ char *len_ptr, *body_ptr;
+ char len_buf[10];
+ struct sockaddr_in dst;
+ char *url, *path;
+ if (sta->http) {
+ wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request for STA - "
+ "ignore new request");
+ return;
+ }
+
+ url = http_client_url_parse(sta->ap->control_url, &dst, &path);
+ if (url == NULL) {
+ wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse eventSubURL");
+ return;
+ }
+
+ encoded = base64_encode(wpabuf_head(msg), wpabuf_len(msg),
+ &encoded_len);
wpabuf_free(msg);
+ if (encoded == NULL) {
+ os_free(url);
+ return;
+ }
+
+ buf = wpabuf_alloc(1000 + encoded_len);
+ if (buf == NULL) {
+ os_free(encoded);
+ os_free(url);
+ return;
+ }
+
+ wpabuf_printf(buf,
+ "POST %s HTTP/1.1\r\n"
+ "Host: %s:%d\r\n"
+ "Content-Type: text/xml; charset=\"utf-8\"\r\n"
+ "Content-Length: ",
+ path, inet_ntoa(dst.sin_addr), ntohs(dst.sin_port));
+ os_free(url);
+ len_ptr = wpabuf_put(buf, 0);
+ wpabuf_printf(buf,
+ " \r\n"
+ "SOAPACTION: \"%s#PutWLANResponse\"\r\n"
+ "\r\n",
+ urn_wfawlanconfig);
+
+ body_ptr = wpabuf_put(buf, 0);
+
+ wpabuf_put_str(buf, soap_prefix);
+ wpabuf_put_str(buf, "\n");
+ wpabuf_printf(buf, "%s\n", (char *) encoded);
+ os_free(encoded);
+ wpabuf_printf(buf, "%d\n",
+ UPNP_WPS_WLANEVENT_TYPE_EAP);
+ wpabuf_printf(buf, "" MACSTR "\n",
+ MAC2STR(sta->addr));
+ wpabuf_put_str(buf, "\n");
+ wpabuf_put_str(buf, soap_postfix);
+
+ os_snprintf(len_buf, sizeof(len_buf), "%d",
+ (int) ((char *) wpabuf_put(buf, 0) - body_ptr));
+ os_memcpy(len_ptr, len_buf, os_strlen(len_buf));
+
+ sta->http = http_client_addr(&dst, buf, 1000,
+ wps_er_http_put_wlan_response_cb, sta);
+ if (sta->http == NULL)
+ wpabuf_free(buf);
}
@@ -915,7 +1007,6 @@ struct wps_er *
wps_er_init(struct wps_context *wps, const char *ifname)
{
struct wps_er *er;
- struct wps_registrar_config rcfg;
struct in_addr addr;
er = os_zalloc(sizeof(*er));
@@ -927,9 +1018,6 @@ wps_er_init(struct wps_context *wps, const char *ifname)
os_strlcpy(er->ifname, ifname, sizeof(er->ifname));
er->wps = wps;
- os_memset(&rcfg, 0, sizeof(rcfg));
- rcfg.pin_needed_cb = wps_er_pin_needed_cb;
- rcfg.cb_ctx = er;
if (get_netif_info(ifname,
&er->ip_addr, &er->ip_addr_text,