예제 #1
0
static int
wps_pb_find_next()
{
	char *value, *next;
	int next_id;
	int max_id = wps_hal_led_wl_max();
	char tmp[100];
	char ifname[IFNAMSIZ];
	char *wlnames;

	int target_id = -1;
	int target_instance = 0;
	int i, imax;

	imax = wps_get_ess_num();

refind:
	for (i = 0; i < imax; i++) {
		sprintf(tmp, "ess%d_led_id", i);
		value = wps_get_conf(tmp);
		if (value == NULL)
			continue;

		next_id = atoi(value);
		if ((next_id > pb_last_led_id) && (next_id <= max_id)) {
			if ((target_id == -1) || (next_id < target_id)) {
				/* Save the candidate */
				target_id = next_id;
				target_instance = i;
			}
		}
	}

	/* A candidate found ? */
	if (target_id == -1) {
		pb_last_led_id = -1;
		goto refind;
	}

	pb_last_led_id = target_id;

	/* Take the first wl interface */
	sprintf(tmp, "ess%d_wlnames", target_instance);

	wlnames = wps_safe_get_conf(tmp);
	foreach(ifname, wlnames, next) {
		wps_strncpy(pb_ifname, ifname, sizeof(pb_ifname));
		break;
	}
예제 #2
0
/*
 * Name        : wpsenr_wksp_mainloop
 * Description : Main loop point for the WPS stack
 * Arguments   : wpsenr_param_t *param - argument set
 * Return type : int
 */
static wpssta_wksp_t *
wpssta_init(char *ifname)
{
	wpssta_wksp_t *sta_wksp = NULL;
	int pbc = WPS_UI_PBC_SW;
	char start_ok = false;
	wps_ap_list_info_t *wpsaplist;
	char scan = false;
	char *val, *next;
	char op[6] = {0};
	int oob = 0;
	int i, imax;
	int wps_action;
	char *env_ssid = NULL;
	char *env_sec = NULL;
	char *env_bssid = NULL;
	char *env_pin = NULL;
#ifdef __CONFIG_WFI__
	char *ui_env_pin = NULL;
#endif /* __CONFIG_WFI__ */
	char tmp[100];
	char *wlnames, name[256];


	TUTRACE((TUTRACE_INFO, "*********************************************\n"));
	TUTRACE((TUTRACE_INFO, "WPS - Enrollee App Broacom Corp.\n"));
	TUTRACE((TUTRACE_INFO, "Version: %s\n", MOD_VERSION_STR));
	TUTRACE((TUTRACE_INFO, "*********************************************\n"));

	/* we need to specify the if name before anything else */
	if (!ifname) {
		TUTRACE((TUTRACE_INFO, "no ifname exist!! return\n"));
		return 0;
	}

	/* WSC 2.0,  support WPS V2 or not */
	if (strcmp(wps_safe_get_conf("wps_version2"), "enabled") == 0)
		b_wps_version2 = true;

	wps_set_ifname(ifname);
	wps_osl_set_ifname(ifname);

	/* reset assoc_state in INIT state */
	assoc_state = WPS_ASSOC_STATE_INIT;

	/* reset enroll_again */
	enroll_again = false;

	/* Check whether scan needed */
	val = wps_ui_get_env("wps_enr_scan");
	if (val)
		scan = atoi(val);

	/* if scan requested : display and exit */
	if (scan) {
		/* do scan and wait the scan results */
		do_wps_scan();
		while (get_wps_scan_results() == NULL)
			WpsSleep(1);

		/* use scan result to create ap list */
		wpsaplist = create_aplist();
		if (wpsaplist) {
			wpssta_display_aplist(wpsaplist);
			wps_get_aplist(wpsaplist, wpsaplist);

			TUTRACE((TUTRACE_INFO, "WPS Enabled AP list :\n"));
			wpssta_display_aplist(wpsaplist);
		}
		goto exit;
	}

	/* init workspace */
	if ((sta_wksp = (wpssta_wksp_t *)alloc_init(sizeof(wpssta_wksp_t))) == NULL) {
		TUTRACE((TUTRACE_INFO, "Can not allocate memory for wps workspace...\n"));
		return NULL;
	}
	memset(sta_wksp, 0, sizeof(wpssta_wksp_t));
	wps_action = atoi(wps_ui_get_env("wps_action"));

	/* Setup STA action */
	if (wps_action == WPS_UI_ACT_STA_CONFIGAP || wps_action == WPS_UI_ACT_STA_GETAPCONFIG) {
		sta_wksp->mode = WPSM_STA_BUILTINREG;
		if (wps_action == WPS_UI_ACT_STA_CONFIGAP)
			sta_wksp->configap = true;
	}
	else
		sta_wksp->mode = WPSM_STA_ENROLL;

	val = wps_ui_get_env("wps_pbc_method");
	if (val)
		pbc = atoi(val);


	/* Save maximum instance number, and probe if any wl interface */
	imax = wps_get_ess_num();
	for (i = 0; i < imax; i++) {
		sprintf(tmp, "ess%d_wlnames", i);
		wlnames = wps_safe_get_conf(tmp);

		foreach(name, wlnames, next) {
			if (!strcmp(name, ifname)) {
				sta_wksp->ess_id = i;
				goto found;
			}
		}
	}
	goto exit;

found:
	/* Retrieve ENV */
	if (pbc ==  WPS_UI_PBC_HW) {
		strcat(op, "pb");
	}
	else {
		/* SW PBC */
		if (atoi(wps_ui_get_env("wps_method")) == WPS_UI_METHOD_PBC) {
			strcat(op, "pb");
		}
		else { /* PIN */
			strcat(op, "pin");
			env_pin = wps_get_conf("wps_device_pin");
			
			env_sec = wps_ui_get_env("wps_enr_wsec");
			if (env_sec[0] != 0) {
				wsec = atoi(env_sec);
			}

			env_ssid = wps_ui_get_env("wps_enr_ssid");
			if (env_ssid[0] == 0) {
				TUTRACE((TUTRACE_ERR, "\n\nPlease specify ssid or use pbc method\n\n"));
				goto exit;
			}
			wps_strncpy(ssid, env_ssid, sizeof(ssid));

			env_bssid = wps_ui_get_env("wps_enr_bssid");
			if (env_bssid[0] == 0) {
				/*
				 * WARNING : this "bssid" is used only to create an 802.1X socket.
				 *
				 * Normally, it should be the bssid of the AP we will associate to.
				 *
				 * Setting this manually means that we might be proceeding to
				 * eapol exchange with a different AP than the one we are associated to,
				 * which might work ... or not.
				 *
				 * When implementing an application, one might want to enforce association
				 * with the AP with that particular BSSID. In case of multiple AP
				 * on the ESS, this might not be stable with roaming enabled.
				 */
				ether_atoe(env_bssid, bssid);
			}
#ifdef __CONFIG_WFI__
			/* For WiFi-Invite session PIN */
			ui_env_pin = wps_ui_get_env("wps_device_pin");
			if (ui_env_pin[0] != '\0')
				env_pin = ui_env_pin;
#endif /* __CONFIG_WFI__ */

			if (sta_wksp->mode == WPSM_STA_BUILTINREG) {
				env_pin = wps_ui_get_env("wps_stareg_ap_pin");
				if (wps_validate_pin(env_pin) == FALSE) {
					TUTRACE((TUTRACE_INFO, "Not a valid PIN [%s]\n",
						env_pin ? (char *)env_pin : ""));
					goto exit;
				}

				sprintf(tmp, "ess%d_wps_oob", sta_wksp->ess_id);
				val = wps_ui_get_env(tmp);
				if (strcmp(val, "enabled") == 0)
					oob = 1;
			}

			/* If we want to get AP config and the AP is unconfigured,
			 * configure the AP directly
			*/
			if (sta_wksp->mode == WPSM_STA_BUILTINREG && sta_wksp->configap == false) {
				val = wps_ui_get_env("wps_scstate");
				if (strcmp(val, "unconfigured") == 0) {
					sta_wksp->configap = true;
					TUTRACE((TUTRACE_INFO, "AP-%s is unconfigure, "
						"using our security settings to configre it.\n"));
				}
			}
		}
	}

	TUTRACE((TUTRACE_INFO,
		"pbc = %s, wpsenr param: ifname = %s, mode= %s, op = %s, sec = %s, "
		"ssid = %s, bssid = %s, pin = %s, oob = %s\n",
		(pbc == 1? "HW_PBC": "SW_PBC"),
		ifname,
		(sta_wksp->mode == WPSM_STA_BUILTINREG) ? "STA_REG" : "STA_ENR",
		op,
		(env_sec? (char *)env_sec : "NULL"),
		(env_ssid? (char *)env_ssid : "NULL"),
		(env_bssid? (char *)env_bssid : "NULL"),
		(env_pin? (char *)env_pin : "NULL"),
		(oob == 1? "Enabled": "Disabled")));

	/*
	 * setup device configuration for WPS
	 * needs to be done before eventual scan for PBC.
	 */
	if (sta_wksp->mode == WPSM_STA_BUILTINREG) {
		if (wpssta_reg_config_init(sta_wksp, ifname, bssid, oob) != WPS_SUCCESS) {
			TUTRACE((TUTRACE_ERR, "wpssta_reg_config_init failed, exit.\n"));
			goto exit;
		}
	}
	else {
		if (wpssta_enr_config_init() != WPS_SUCCESS) {
			TUTRACE((TUTRACE_ERR, "wpssta_enr_config_init failed, exit.\n"));
			goto exit;
		}
	}

	/* if ssid specified, use it */
	if (!strcmp(op, "pin")) {
		pin = env_pin;
		if (!pin) {
			pin = def_pin;
			TUTRACE((TUTRACE_ERR,
				"\n\nStation Pin not specified, use default Pin %s\n\n",
				def_pin));
		}
		start_ok = true;
		/* WSC 2.0,  Test Plan 5.1.1 step 8 must add wps ie to probe request */
		if (b_wps_version2)
			add_wps_ie(NULL, 0, 0, b_wps_version2);
	}
	else {
		pin = NULL;
		wpsenr_osl_proc_states(WPS_FIND_PBC_AP);

		/* add wps ie to probe  */
		add_wps_ie(NULL, 0, TRUE, b_wps_version2);
		do_wps_scan();
		assoc_state_time = get_current_time();
		assoc_state = WPS_ASSOC_STATE_SCANNING;

		start_ok = false;
	}

	/* start WPS two minutes period at Finding a PBC AP or Associating with AP */
	start_time = get_current_time();

	if (start_ok) {
		/* clear current security setting */
		wpsenr_osl_clear_wsec();

		/*
		 * join. If user_bssid is specified, it might not
		 * match the actual associated AP.
		 * An implementation might want to make sure
		 * it associates to the same bssid.
		 * There might be problems with roaming.
		 */
		wpssta_do_join(false);
		return sta_wksp;
	}
	else if (assoc_state == WPS_ASSOC_STATE_SCANNING) {
		return sta_wksp;
	}

exit:
	wpssta_deinit(sta_wksp);
	return NULL;
}
예제 #3
0
/*
 *  Let customer have a chance to modify credential
 */
static int
wpssta_update_custom_cred(char *ssid, char *key, char *akm, char *crypto, int oob,
	bool b_wps_Version2)
{
	/*
	 * WSC 1.0 Old design : Because WSC 1.0 did not support Mix mode, in default
	 * we pick WPA2-PSK/AES up in Mix mode.  If NVRAM "wps_mixedmode" is "1"
	 * than change to pick WPA-PSK/TKIP up.
	 */

	/*
	 * WSC 2.0 support Mix mode and says "WPA-PSK and TKIP only allowed in
	 * Mix mode".  So in default we use Mix mode and if  NVRMA "wps_mixedmode"
	 * is "1" than change to pick WPA2-PSK/AES up.
	 */
	int mix_mode = 2;

	if (!strcmp(wps_safe_get_conf("wps_mixedmode"), "1"))
		mix_mode = 1;

	if (!strcmp(akm, "WPA-PSK WPA2-PSK")) {
		if (b_wps_Version2) {
				strcpy(akm, "WPA2-PSK");
		} else {
			if (mix_mode == 1)
				strcpy(akm, "WPA-PSK");
			else
				strcpy(akm, "WPA2-PSK");
		}
		TUTRACE((TUTRACE_INFO, "Update customized Key Mode : %s, ", akm));
	}

	if (!strcmp(crypto, "AES+TKIP")) {
		if (b_wps_Version2) {
				strcpy(crypto, "AES");
		} else {
			if (mix_mode == 1)
				strcpy(crypto, "TKIP");
			else
				strcpy(crypto, "AES");
		}
		TUTRACE((TUTRACE_INFO, "Update customized encrypt mode = %s\n", crypto));
	}

	if (oob) {
		char *p;

		/* get randomssid */
		if ((p = wps_get_conf("wps_randomssid"))) {
			strncpy(ssid, p, MAX_SSID_LEN);
			TUTRACE((TUTRACE_INFO, "Update customized SSID : %s\n", ssid));
		}

		/* get randomkey */
		if ((p = wps_get_conf("wps_randomkey")) && (strlen (p) >= 8)) {
			strncpy(key, p, SIZE_64_BYTES);
			TUTRACE((TUTRACE_INFO, "Update customized Key : %s\n", key));
		}

		/* Modify the crypto, if the station is legacy */
	}

	return 0;
}
예제 #4
0
static uint32
wpssta_reg_config_init(wpssta_wksp_t *sta_wksp, char *ifname, char *bssid, char oob)
{
	DevInfo info;
	char *value, *next;
	int auth = 0;
	char mac[6];
	char ssid[MAX_SSID_LEN + 1] = {0};
	char psk[MAX_USER_KEY_LEN + 1] = {0};
	char akmstr[32];
	char key[8];
	unsigned int akm = 0;
	unsigned int wsec = 0;
	int wep_index = 0;			/* wep key index */
	char *wep_key = NULL;			/* user-supplied wep key */
	char dev_akm[64] = {0};
	char dev_crypto[64] = {0};
	char prefix[] = "wlXXXXXXXXXX_";
	char tmp[100];
	uint32 ret;

	/* TBD, is going to use osname only */
	sprintf(prefix, "%s_", ifname);

	/* fill in device specific info. */
	memset((char *)(&info), 0, sizeof(info));

	info.version = WPS_VERSION;

	/* MAC addr */
	wps_osl_get_mac(mac);
	memcpy(info.macAddr, mac, 6);

	memcpy(info.uuid, wps_get_uuid(), SIZE_16_BYTES);
	strcpy(info.deviceName, "Broadcom Registrar");
	info.primDeviceCategory = WPS_DEVICE_TYPE_CAT_NW_INFRA;
	info.primDeviceOui = 0x0050F204;
	info.primDeviceSubCategory = WPS_DEVICE_TYPE_SUB_CAT_NW_GATEWAY;
	strcpy(info.manufacturer, "Broadcom");
	strcpy(info.modelName, "WPS Wireless Registrar");
	strcpy(info.modelNumber, "1234");
	strcpy(info.serialNumber, "5678");

	if (b_wps_version2) {
		info.configMethods = (WPS_CONFMET_VIRT_PBC | WPS_CONFMET_PHY_PBC |
			WPS_CONFMET_VIRT_DISPLAY);
	}
	else {
		info.configMethods = WPS_CONFMET_PBC | WPS_CONFMET_DISPLAY;
	}

	/* WSC 2.0, WPS-PSK and SHARED are deprecated.
	 * When both the Registrar and the Enrollee are using protocol version 2.0
	 * or newer, this variable can use the value 0x0022 to indicate mixed mode
	 * operation (both WPA-Personal and WPA2-Personal enabled)
	 */
	if (b_wps_version2) {
		info.authTypeFlags = (uint16)(WPS_AUTHTYPE_OPEN | WPS_AUTHTYPE_WPAPSK |
			WPS_AUTHTYPE_WPA2PSK);
	}
	else {
		info.authTypeFlags = (uint16)(WPS_AUTHTYPE_OPEN | WPS_AUTHTYPE_WPAPSK |
			WPS_AUTHTYPE_SHARED | WPS_AUTHTYPE_WPA2PSK);
	}

	/* ENCR_TYPE_FLAGS */
	/*
	 * WSC 2.0, deprecated WEP. TKIP can only be advertised on the AP when
	 * Mixed Mode is enabled (Encryption Type is 0x000c)
	 */
	if (b_wps_version2) {
		info.encrTypeFlags = (uint16)(WPS_ENCRTYPE_NONE | WPS_ENCRTYPE_TKIP |
			WPS_ENCRTYPE_AES);
	}
	else {
		info.encrTypeFlags = (uint16)(WPS_ENCRTYPE_NONE | WPS_ENCRTYPE_WEP |
			WPS_ENCRTYPE_TKIP | WPS_ENCRTYPE_AES);
	}

	info.connTypeFlags = WPS_CONNTYPE_ESS;
	info.rfBand = WPS_RFBAND_24GHZ;
	info.osVersion = 0x80000000;
	info.featureId = 0x80000000;
	/* WSC 2.0 */
	if (b_wps_version2) {
		value = wps_get_conf("wps_version2_num");
		info.version2 = (uint8)(strtoul(value, NULL, 16));
		info.settingsDelayTime = WPS_SETTING_DELAY_TIME_ROUTER;
		info.b_reqToEnroll = FALSE;
		info.b_nwKeyShareable = FALSE;
	}

	if (sta_wksp->configap == true) {
		/*
		 * Before check oob mode, we have to
		 * get ssid, akm, wep, crypto and mgmt key from config.
		 * because oob mode might change the settings.
		 */
		value = wps_safe_get_conf(strcat_r(prefix, "ssid", tmp));
		strncpy(ssid, value, MAX_SSID_LEN);

		value = wps_safe_get_conf(strcat_r(prefix, "akm", tmp));
		foreach(akmstr, value, next) {
			if (!strcmp(akmstr, "psk"))
				akm |= WPA_AUTH_PSK;

			if (!strcmp(akmstr, "psk2"))
				akm |= WPA2_AUTH_PSK;
		}

		value = wps_safe_get_conf(strcat_r(prefix, "wep", tmp));
		wsec = !strcmp(value, "enabled") ? WEP_ENABLED : 0;

		value = wps_safe_get_conf(strcat_r(prefix, "crypto", tmp));
		if (WPS_WLAKM_PSK(akm) || WPS_WLAKM_PSK2(akm)) {
			if (!strcmp(value, "tkip"))
				wsec |= TKIP_ENABLED;
			else if (!strcmp(value, "aes"))
				wsec |= AES_ENABLED;
			else if (!strcmp(value, "tkip+aes"))
				wsec |= TKIP_ENABLED|AES_ENABLED;

			/* Set PSK key */
			value = wps_safe_get_conf(strcat_r(prefix, "wpa_psk", tmp));
			strncpy(psk, value, MAX_USER_KEY_LEN);
			psk[MAX_USER_KEY_LEN] = 0;
		}

		if (wsec & WEP_ENABLED) {
			/* Key index */
			value = wps_safe_get_conf(strcat_r(prefix, "key", tmp));
			wep_index = (int)strtoul(value, NULL, 0);

			/* Key */
			sprintf(key, "key%s", value);
			wep_key = wps_safe_get_conf(strcat_r(prefix, key, tmp));
		}

		/* Caution: wps_oob will over-write akm and wsec */
		if (oob) {
			/* Generate random ssid and key */
			if (wps_gen_ssid(ssid, sizeof(ssid),
				wps_get_conf("wps_random_ssid_prefix"),
				wps_safe_get_conf("wl0_hwaddr")) == FALSE ||
			    wps_gen_key(psk, sizeof(psk)) == FALSE)
				return WPS_ERR_SYSTEM;

			/* Open */
			auth = 0;

			/* PSK, PSK2 */
			akm = WPA_AUTH_PSK | WPA2_AUTH_PSK;
			wsec = AES_ENABLED;
		}

		/*
		 * Let the user have a chance to override the credential.
		 */
		if (WPS_WLAKM_BOTH(akm))
			strcpy(dev_akm, "WPA-PSK WPA2-PSK");
		else if (WPS_WLAKM_PSK(akm))
			strcpy(dev_akm, "WPA-PSK");
		else if (WPS_WLAKM_PSK2(akm))
			strcpy(dev_akm, "WPA2-PSK");
		else
			dev_akm[0] = 0;

		/* Encryption algorithm */
		if (WPS_WLENCR_BOTH(wsec))
			strcpy(dev_crypto, "AES+TKIP");
		else if (WPS_WLENCR_TKIP(wsec))
			strcpy(dev_crypto, "TKIP");
		else if (WPS_WLENCR_AES(wsec))
			strcpy(dev_crypto, "AES");
		else
			dev_crypto[0] = 0;

		/* Do customization, and check credentials again */
		wpssta_update_custom_cred(ssid, psk, dev_akm, dev_crypto, oob,
			b_wps_version2);

		/*
		 * After doing customized credentials modification,
		 * fill ssid, psk, akm and crypto to ap_deviceinfo
		 */
		strcpy(info.ssid, ssid);

		/* Parsing return amk and crypto */
		if (strlen(dev_akm)) {
			if (!strcmp(dev_akm, "WPA-PSK WPA2-PSK"))
				akm = WPA_AUTH_PSK | WPA2_AUTH_PSK;
			else if (!strcmp(dev_akm, "WPA-PSK"))
				akm = WPA_AUTH_PSK;
			else if (!strcmp(dev_akm, "WPA2-PSK"))
				akm = WPA2_AUTH_PSK;
		}
		if (strlen(dev_crypto)) {
			if (!strcmp(dev_crypto, "AES+TKIP"))
				wsec = AES_ENABLED | TKIP_ENABLED;
			else if (!strcmp(dev_crypto, "AES"))
				wsec = AES_ENABLED;
			else if (!strcmp(dev_crypto, "TKIP"))
				wsec = TKIP_ENABLED;
		}

		/* KEY MGMT */
		/* WSC 2.0, deprecated SHARED */
		if (auth) {
			strcpy(info.keyMgmt, "SHARED");
			if (b_wps_version2 && !oob) {
				TUTRACE((TUTRACE_INFO,
					"wpssta_readConfigure: Error in configuration,"
					"Authentication type is Shared, violate WSC 2.0\n"));
				return MC_ERR_CFGFILE_CONTENT;
			}
		}
		else {
			if (WPS_WLAKM_BOTH(akm))
				strcpy(info.keyMgmt, "WPA-PSK WPA2-PSK");
			else if (WPS_WLAKM_PSK(akm))
				strcpy(info.keyMgmt, "WPA-PSK");
			else if (WPS_WLAKM_PSK2(akm))
				strcpy(info.keyMgmt, "WPA2-PSK");
			else
				info.keyMgmt[0] = 0;
		}

		/* WEP index */
		info.wep = (wsec & WEP_ENABLED) ? 1 : 0;

		/* Set crypto algorithm */
		info.crypto = 0;
		if (wsec & TKIP_ENABLED)
			info.crypto |= WPS_ENCRTYPE_TKIP;
		if (wsec & AES_ENABLED)
			info.crypto |= WPS_ENCRTYPE_AES;

		if (info.crypto == 0)
			info.crypto = WPS_ENCRTYPE_TKIP;

		/* WSC 2.0 */
		if (b_wps_version2) {			/* Version 2 */
			value = wps_get_conf("wps_version2_num");
			info.version2 = (uint8)(strtoul(value, NULL, 16));

			/* Setting Delay Time */
			info.settingsDelayTime = WPS_SETTING_DELAY_TIME_ROUTER;
		}
		ret = wps_enr_reg_config_init(&info, psk, strlen(psk), bssid);

	} /* configap == true */
예제 #5
0
int
wps_set_wsec(int ess_id, char *wps_ifname, void *credential, int mode)
{
	char prefix[] = "lanXXXXXXXXX_";
	int instance;
	char *value;
	char *oob = NULL;

	char tmp[100];
	char *wlnames = wps_ifname;
	char *next = NULL;
	char ifname[IFNAMSIZ];

	if (wps_ifname == NULL || credential == NULL) {
		TUTRACE((TUTRACE_ERR, "wps_set_wsec: Invaild argument\n"));
		return -1;
	}
#ifdef WPS_PLC
	if (strcmp(nvram_safe_get("wps_pbc_apsta"), "enabled") == 0 &&
		strcmp(wps_ifname, wps_safe_get_conf("wps_pbc_sta_ifname")) == 0) {
		char *ap_ifname = wps_safe_get_conf("wps_pbc_ap_ifname");

		/* Set wsec to ap interface */

		value = wps_get_conf("wps_pbc_ap_index");
		if (value == NULL) {
			TUTRACE((TUTRACE_ERR, "wps_set_wsec: Cannot get UPnP instance\n"));
			return -1;
		}

		instance = atoi(value);
		if (instance == 0)
			strcpy(prefix, "lan_");
		else
			sprintf(prefix, "lan%d_", instance);
		wps_osl_set_conf(strcat_r(prefix, "wps_oob", tmp),
			"disabled");

		wps_osl_set_conf(strcat_r(prefix, "wps_reg", tmp),
			"enabled");
		TUTRACE((TUTRACE_INFO, "built-in registrar enabled\n"));

		wlnames = ap_ifname;
		TUTRACE((TUTRACE_INFO, "WPS STA (%s) has finished WPS process "
			"and now is setting security to AP (%s).\n", wps_ifname, ap_ifname));
	}
	else
#endif
	if (!wps_is_wps_sta(wps_ifname)) {
		sprintf(tmp, "ess%d_ap_index", ess_id);
		value = wps_get_conf(tmp);
		if (value == NULL) {
			TUTRACE((TUTRACE_ERR, "wps_set_wsec: Cannot get UPnP instance\n"));
			return -1;
		}

		instance = atoi(value);
		if (instance == 0)
			strcpy(prefix, "lan_");
		else
			sprintf(prefix, "lan%d_", instance);

		/* Default OOB set to enabled */
		oob = nvram_get(strcat_r(prefix, "wps_oob", tmp));
		if (!oob)
			oob = "enabled";

		/* Check wether OOB is true */
		if (!strcmp(oob, "enabled")) {
			/* OOB mode, apply to all wl if */
			sprintf(tmp, "ess%d_wlnames", ess_id);
			wlnames = wps_safe_get_conf(tmp);

			TUTRACE((TUTRACE_INFO,
				"wps_set_wsec: OOB set config\n"));
		}

		/* Set OOB and built-in reg (Per-ESS) */
		if (mode == EModeApProxyRegistrar) {
			wps_osl_set_conf(strcat_r(prefix, "wps_oob", tmp),
				"disabled");
			TUTRACE((TUTRACE_INFO, "OOB state configed\n"));

			wps_osl_set_conf(strcat_r(prefix, "wps_reg", tmp),
				"enabled");
			TUTRACE((TUTRACE_INFO, "built-in registrar enabled\n"));
		} else if (mode == EModeUnconfAp) {
			wps_osl_set_conf(strcat_r(prefix, "wps_oob", tmp),
				"disabled");
			TUTRACE((TUTRACE_INFO, "OOB state configed\n"));
		}
	}
	else {
		/* STA ess interfaces */
		if (osifname_to_nvifname(wlnames, prefix, sizeof(prefix)) == 0) {
			strcat(prefix, "_");
			wps_osl_set_conf(strcat_r(prefix, "wps_oob", tmp), "disabled");
		}
		else {
			TUTRACE((TUTRACE_INFO, "Clear OOB: convert to nvname failed!\n"));
		}
	}

	/* Apply the wsec */
	foreach(ifname, wlnames, next) {
		set_wsec(ifname, credential, mode);
		TUTRACE((TUTRACE_INFO, "wps_set_wsec: Set config to %s\n", ifname));
	}