+
+
+static void wps_er_http_set_sel_reg_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: SetSelectedRegistrar OK");
+ break;
+ case HTTP_CLIENT_FAILED:
+ case HTTP_CLIENT_INVALID_REPLY:
+ case HTTP_CLIENT_TIMEOUT:
+ wpa_printf(MSG_DEBUG, "WPS ER: SetSelectedRegistrar failed");
+ break;
+ }
+ http_client_free(ap->http);
+ ap->http = NULL;
+}
+
+
+static void wps_er_send_set_sel_reg(struct wps_er_ap *ap, struct wpabuf *msg)
+{
+ struct wpabuf *buf;
+ char *len_ptr, *body_ptr;
+ struct sockaddr_in dst;
+ char *url, *path;
+
+ if (ap->control_url == NULL) {
+ wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
+ return;
+ }
+
+ if (ap->http) {
+ wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request for AP - "
+ "ignore new request");
+ return;
+ }
+
+ url = http_client_url_parse(ap->control_url, &dst, &path);
+ if (url == NULL) {
+ wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
+ return;
+ }
+
+ buf = wps_er_soap_hdr(msg, "SetSelectedRegistrar", path, &dst,
+ &len_ptr, &body_ptr);
+ os_free(url);
+ if (buf == NULL)
+ return;
+
+ wps_er_soap_end(buf, "SetSelectedRegistrar", len_ptr, body_ptr);
+
+ ap->http = http_client_addr(&dst, buf, 1000,
+ wps_er_http_set_sel_reg_cb, ap);
+ if (ap->http == NULL)
+ wpabuf_free(buf);
+}
+
+
+static int wps_er_build_selected_registrar(struct wpabuf *msg, int sel_reg)
+{
+ wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR);
+ wpabuf_put_be16(msg, 1);
+ wpabuf_put_u8(msg, !!sel_reg);
+ return 0;
+}
+
+
+static int wps_er_build_dev_password_id(struct wpabuf *msg, u16 dev_passwd_id)
+{
+ wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
+ wpabuf_put_be16(msg, 2);
+ wpabuf_put_be16(msg, dev_passwd_id);
+ return 0;
+}
+
+
+static int wps_er_build_sel_reg_config_methods(struct wpabuf *msg,
+ u16 sel_reg_config_methods)
+{
+ wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS);
+ wpabuf_put_be16(msg, 2);
+ wpabuf_put_be16(msg, sel_reg_config_methods);
+ return 0;
+}
+
+
+void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
+ u16 sel_reg_config_methods)
+{
+ struct wpabuf *msg;
+ struct wps_er_ap *ap;
+
+ msg = wpabuf_alloc(500);
+ if (msg == NULL)
+ return;
+
+ if (wps_build_version(msg) ||
+ wps_er_build_selected_registrar(msg, sel_reg) ||
+ wps_er_build_dev_password_id(msg, dev_passwd_id) ||
+ wps_er_build_sel_reg_config_methods(msg, sel_reg_config_methods)) {
+ wpabuf_free(msg);
+ return;
+ }
+
+ for (ap = er->ap; ap; ap = ap->next)
+ wps_er_send_set_sel_reg(ap, msg);
+
+ wpabuf_free(msg);
+}