+static void wps_er_http_subscribe_cb(void *ctx, struct http_client *c,
+ enum http_client_event event)
+{
+ struct wps_er_ap *ap = ctx;
+
+ switch (event) {
+ case HTTP_CLIENT_OK:
+ wpa_printf(MSG_DEBUG, "WPS ER: Subscribed to events");
+ break;
+ case HTTP_CLIENT_FAILED:
+ case HTTP_CLIENT_INVALID_REPLY:
+ case HTTP_CLIENT_TIMEOUT:
+ wpa_printf(MSG_DEBUG, "WPS ER: Failed to subscribe to events");
+ break;
+ }
+ http_client_free(ap->http);
+ ap->http = NULL;
+}
+
+
+static void wps_er_subscribe(struct wps_er_ap *ap)
+{
+ struct wpabuf *req;
+ struct sockaddr_in dst;
+ char *url, *path;
+
+ if (ap->event_sub_url == NULL) {
+ wpa_printf(MSG_DEBUG, "WPS ER: No eventSubURL - cannot "
+ "subscribe");
+ return;
+ }
+ if (ap->http) {
+ wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request - cannot "
+ "send subscribe request");
+ return;
+ }
+
+ url = http_client_url_parse(ap->event_sub_url, &dst, &path);
+ if (url == NULL) {
+ wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse eventSubURL");
+ return;
+ }
+
+ req = wpabuf_alloc(os_strlen(ap->event_sub_url) + 1000);
+ if (req == NULL) {
+ os_free(url);
+ return;
+ }
+ wpabuf_printf(req,
+ "SUBSCRIBE %s HTTP/1.1\r\n"
+ "HOST: %s:%d\r\n"
+ "CALLBACK: <http://%s:%d/event/%d>\r\n"
+ "NT: upnp:event\r\n"
+ "TIMEOUT: Second-%d\r\n"
+ "\r\n",
+ path, inet_ntoa(dst.sin_addr), ntohs(dst.sin_port),
+ ap->er->ip_addr_text, ap->er->http_port, ap->id, 1800);
+ os_free(url);
+ wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Subscription request",
+ wpabuf_head(req), wpabuf_len(req));
+
+ ap->http = http_client_addr(&dst, req, 1000, wps_er_http_subscribe_cb,
+ ap);
+ if (ap->http == NULL)
+ wpabuf_free(req);
+}
+
+