WPS ER: Add preliminary PBC support
[libeap.git] / wpa_supplicant / wps_supplicant.c
index 95f3b88..a2193d1 100644 (file)
@@ -410,6 +410,69 @@ static void wpa_supplicant_wps_event_success(struct wpa_supplicant *wpa_s)
 }
 
 
+static void wpa_supplicant_wps_event_er_ap_add(struct wpa_supplicant *wpa_s,
+                                              struct wps_event_er_ap *ap)
+{
+       char uuid_str[100];
+       uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str));
+       wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_ADD "%s|%s|%s|%s|%s|%s|%s",
+               uuid_str,
+               ap->friendly_name ? ap->friendly_name : "",
+               ap->manufacturer ? ap->manufacturer : "",
+               ap->model_description ? ap->model_description : "",
+               ap->model_name ? ap->model_name : "",
+               ap->manufacturer_url ? ap->manufacturer_url : "",
+               ap->model_url ? ap->model_url : "");
+}
+
+
+static void wpa_supplicant_wps_event_er_ap_remove(struct wpa_supplicant *wpa_s,
+                                                 struct wps_event_er_ap *ap)
+{
+       char uuid_str[100];
+       uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str));
+       wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_REMOVE "%s", uuid_str);
+}
+
+
+static void wpa_supplicant_wps_event_er_enrollee_add(
+       struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee)
+{
+       char uuid_str[100];
+       char dev_type[20];
+
+       uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str));
+       if (enrollee->pri_dev_type)
+               os_snprintf(dev_type, sizeof(dev_type), "%u-%08X-%u",
+                           WPA_GET_BE16(enrollee->pri_dev_type),
+                           WPA_GET_BE32(enrollee->pri_dev_type + 2),
+                           WPA_GET_BE16(enrollee->pri_dev_type + 6));
+       else
+               dev_type[0] = '\0';
+
+       wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_ADD "%s " MACSTR
+               " M1=%d config_methods=0x%x dev_passwd_id=%d pri_dev_type=%s "
+               "|%s|%s|%s|%s|%s|",
+               uuid_str, MAC2STR(enrollee->mac_addr), enrollee->m1_received,
+               enrollee->config_methods, enrollee->dev_passwd_id, dev_type,
+               enrollee->dev_name ? enrollee->dev_name : "",
+               enrollee->manufacturer ? enrollee->manufacturer : "",
+               enrollee->model_name ? enrollee->model_name : "",
+               enrollee->model_number ? enrollee->model_number : "",
+               enrollee->serial_number ? enrollee->serial_number : "");
+}
+
+
+static void wpa_supplicant_wps_event_er_enrollee_remove(
+       struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee)
+{
+       char uuid_str[100];
+       uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str));
+       wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_REMOVE "%s " MACSTR,
+               uuid_str, MAC2STR(enrollee->mac_addr));
+}
+
+
 static void wpa_supplicant_wps_event(void *ctx, enum wps_event event,
                                     union wps_event_data *data)
 {
@@ -430,6 +493,20 @@ static void wpa_supplicant_wps_event(void *ctx, enum wps_event event,
                break;
        case WPS_EV_PBC_TIMEOUT:
                break;
+       case WPS_EV_ER_AP_ADD:
+               wpa_supplicant_wps_event_er_ap_add(wpa_s, &data->ap);
+               break;
+       case WPS_EV_ER_AP_REMOVE:
+               wpa_supplicant_wps_event_er_ap_remove(wpa_s, &data->ap);
+               break;
+       case WPS_EV_ER_ENROLLEE_ADD:
+               wpa_supplicant_wps_event_er_enrollee_add(wpa_s,
+                                                        &data->enrollee);
+               break;
+       case WPS_EV_ER_ENROLLEE_REMOVE:
+               wpa_supplicant_wps_event_er_enrollee_remove(wpa_s,
+                                                           &data->enrollee);
+               break;
        }
 }
 
@@ -723,6 +800,20 @@ static void wpas_wps_pin_needed_cb(void *ctx, const u8 *uuid_e,
 }
 
 
+static void wpas_wps_set_sel_reg_cb(void *ctx, int sel_reg, u16 dev_passwd_id,
+                                   u16 sel_reg_config_methods)
+{
+#ifdef CONFIG_WPS_ER
+       struct wpa_supplicant *wpa_s = ctx;
+
+       if (wpa_s->wps_er == NULL)
+               return;
+       wps_er_set_sel_reg(wpa_s->wps_er, sel_reg, dev_passwd_id,
+                          sel_reg_config_methods);
+#endif /* CONFIG_WPS_ER */
+}
+
+
 int wpas_wps_init(struct wpa_supplicant *wpa_s)
 {
        struct wps_context *wps;
@@ -784,6 +875,7 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
        os_memset(&rcfg, 0, sizeof(rcfg));
        rcfg.new_psk_cb = wpas_wps_new_psk_cb;
        rcfg.pin_needed_cb = wpas_wps_pin_needed_cb;
+       rcfg.set_sel_reg_cb = wpas_wps_set_sel_reg_cb;
        rcfg.cb_ctx = wpa_s;
 
        wps->registrar = wps_registrar_init(wps, &rcfg);
@@ -814,6 +906,11 @@ void wpas_wps_deinit(struct wpa_supplicant *wpa_s)
        os_free(wpa_s->wps->network_key);
        os_free(wpa_s->wps);
        wpa_s->wps = NULL;
+
+#ifdef CONFIG_WPS_ER
+       wps_er_deinit(wpa_s->wps_er);
+       wpa_s->wps_er = NULL;
+#endif /* CONFIG_WPS_ER */
 }
 
 
@@ -1021,3 +1118,57 @@ int wpas_wps_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
        wpabuf_free(wps_ie);
        return ret;
 }
+
+
+int wpas_wps_er_start(struct wpa_supplicant *wpa_s)
+{
+#ifdef CONFIG_WPS_ER
+       if (wpa_s->wps_er) {
+               /* TODO: re-send ctrl_iface events for current data? */
+               return 0;
+       }
+       wpa_s->wps_er = wps_er_init(wpa_s->wps, wpa_s->ifname);
+       if (wpa_s->wps_er == NULL)
+               return -1;
+       return 0;
+#else /* CONFIG_WPS_ER */
+       return 0;
+#endif /* CONFIG_WPS_ER */
+}
+
+
+int wpas_wps_er_stop(struct wpa_supplicant *wpa_s)
+{
+#ifdef CONFIG_WPS_ER
+       wps_er_deinit(wpa_s->wps_er);
+       wpa_s->wps_er = NULL;
+#endif /* CONFIG_WPS_ER */
+       return 0;
+}
+
+
+#ifdef CONFIG_WPS_ER
+int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const char *uuid,
+                       const char *pin)
+{
+       u8 u[UUID_LEN];
+       int any = 0;
+
+       if (os_strcmp(uuid, "any") == 0)
+               any = 1;
+       else if (uuid_str2bin(uuid, u))
+               return -1;
+       return wps_registrar_add_pin(wpa_s->wps->registrar, any ? NULL : u,
+                                    (const u8 *) pin, os_strlen(pin), 300);
+}
+
+
+int wpas_wps_er_pbc(struct wpa_supplicant *wpa_s, const char *uuid)
+{
+       u8 u[UUID_LEN];
+
+       if (uuid_str2bin(uuid, u))
+               return -1;
+       return wps_er_pbc(wpa_s->wps_er, u);
+}
+#endif /* CONFIG_WPS_ER */