📄 wps_userapi.c
字号:
/*
* WPS_USERAPI.C : WPS User Application Interface Implementation
*
* ver date author comment
* 0.0.1 08/02/21 Gao Hua First
*/
#include "wps_userapi.h"
#include "wps_wlandrv.h"
#include "wps_enrollee.h"
#include "wps_queue.h"
#include "wps_data_element.h"
#include "wps_callback.h"
typedef struct _tag_tried_pin_ap {
wps_queue link;
WPS_AP_DESC ap;
}TRIED_PIN_AP;
static WPS_THREAD_DESC wps_enrol_thread = NULL;
static WPS_SEM_DESC wps_enrol_sem = NULL;
static struct enrollee *wps_enrol_ptr = NULL;
static WPS_u8 wps_running = 0;
static wps_queue *tyied_pin_ap_queue = NULL;
static WPS_u8 wps_enrol_stop_flag;
static WPS_u32 wps_start_time;
static WPS_u32 wps_timeout_value;
static WPS_u8 wps_enrol_mode;
static WPS_char wps_enrol_pin[9];
WPS_USER_CALLBACK wps_enrol_callback;
/*---------------------------------------------------------------------------*/
struct enrollee *get_enrollee_ptr(void)
{
return wps_enrol_ptr;
}
WPS_u8 get_enrollee_mode(void)
{
return wps_enrol_mode;
}
const WPS_char *get_enrollee_pin(void)
{
return wps_enrol_pin;
}
/*---------------------------------------------------------------------------*/
static int is_pin_ap_tried(WPS_AP_DESC *ap)
{
int ret = 0;
wps_queue *temp = tyied_pin_ap_queue;
WPS_AP_DESC *temp_ap;
while (temp) {
temp_ap = &((TRIED_PIN_AP *)(temp->q_body))->ap;
if (WPS_MEM_CMP(ap->bssid, temp_ap->bssid, 6) == 0) {
ret = 1;
break;
}
temp = temp->q_forw;
}
return ret;
}
static void add_tried_pin_ap_queue(WPS_AP_DESC *ap)
{
TRIED_PIN_AP *p;
p = (TRIED_PIN_AP *)WPS_MALLOC(sizeof(TRIED_PIN_AP));
wps_init_que(&p->link, (void *)p);
p->ap = *ap;
wps_append_que(&tyied_pin_ap_queue, &p->link);
}
static void empty_tried_pin_ap_queue(void)
{
wps_queue *temp;
while (tyied_pin_ap_queue) {
temp = tyied_pin_ap_queue;
wps_remove_que(&tyied_pin_ap_queue, temp);
WPS_MFREE(get_qbody(temp));
}
}
/*
* Return value:
* 0: OK
* -1: No such ap
* -2: PBC session overlap
*/
static int wps_enrol_select_ap(WPS_u8 mode, WPS_AP_DESC *selected_ap)
{
int i;
WPS_AP_DESC ap_array[32];
WPS_AP_DESC *ap;
int ap_num, dataLen;
WPS_u8 *p;
int bConfigured, b1, b2, bDPIDExistButUnmatch;
WPS_u16 DevicePasswordID = DPID_DEFAULT;
int n = 0;
int retIndex = -1;
ap_num = Wlan_GetWpsApList(ap_array, 32);
if (ap_num == -1) {
#if ENROLLEE_DEBUG
WPS_PRINTF("%s: Found no AP that supports WPS.", __FUNCTION__);
#endif
return -1;
}
#if ENROLLEE_DEBUG
WPS_PRINTF("%s: Found %d APs that support WPS.", __FUNCTION__, ap_num);
#endif
if (mode == WPS_PIN_MODE) {
DevicePasswordID = DPID_DEFAULT;
}
else if (mode == WPS_PBC_MODE) {
DevicePasswordID = DPID_PUSHBUTTON;
}
for (i = 0; i < ap_num; i++) {
bConfigured = 0;
b1 = 0;
b2 = 0;
bDPIDExistButUnmatch = 0;
ap = &ap_array[i];
#if ENROLLEE_DEBUG
WPS_PRINTF("%s: Check AP(ssid=\"%s\")", __FUNCTION__, ap->ssid);
#endif
if (mode == WPS_PIN_MODE && is_pin_ap_tried(ap)) {
#if ENROLLEE_DEBUG
WPS_PRINTF("%s: PIN tried, can not choose.", __FUNCTION__);
#endif
continue;
}
dataLen = ap->wpsIE.length - 4;
p = ap->wpsIE.data;
#if ENROLLEE_DEBUG
PrintHex(p, 64);////Debug
#endif
if (WPS_get_word(p) != WPS_h2n16(E_Version_ID)
|| WPS_get_word(p+2) != WPS_h2n16(E_Version_Length)
|| *(p+4) != WPS_VERSION) {
#if ENROLLEE_DEBUG
WPS_PRINTF("%s: Version is invalid\n", __FUNCTION__);
#endif
continue;
}
else {
p += 2+2+E_Version_Length;
}
/* For Buffalo AP and Corega AP, the order of the following Elements is random, it's not comply with the wifi-spec */
while (((int)p - (int)&(ap->wpsIE.data[0])) < dataLen) {
if (WPS_get_word(p) == WPS_h2n16(E_SimpleConfigState_ID)
&& WPS_get_word(p+2) == WPS_h2n16(E_SimpleConfigState_Length)) {
if (*(p+4) == SIMPLE_CONFIG_STATE_CONFIGURED) {
bConfigured = 1;
}
p += 2+2+E_SimpleConfigState_Length;
}
if (WPS_get_word(p) == WPS_h2n16(E_SelectedRegistrar_ID)
&& WPS_get_word(p+2) == WPS_h2n16(E_SelectedRegistrar_Length)) {
if (*(p+4) != 1) {
#if ENROLLEE_DEBUG
WPS_PRINTF("%s: SelectedRegistrar is invalid\n", __FUNCTION__);
#endif
}
else {
b1 = 1;
}
p += 2+2+E_SelectedRegistrar_Length;
}
else if (WPS_get_word(p) == WPS_h2n16(E_DevicePasswordID_ID)
&& WPS_get_word(p+2) == WPS_h2n16(E_DevicePasswordID_Length)) {
if (WPS_get_word(p+4) != WPS_h2n16(DevicePasswordID)) {
#if ENROLLEE_DEBUG
WPS_PRINTF("%s: DevicePasswordID is invalid, 0x%x:0x%x\n", __FUNCTION__, WPS_n2h16(WPS_get_word(p+4)), DevicePasswordID);
#endif
bDPIDExistButUnmatch = 1;
}
else {
b2 = 1;
}
p += 2+2+E_DevicePasswordID_Length;
}
else {
p += 2+2+WPS_n2h16(WPS_get_word(p+2));
}
}
#if ENROLLEE_DEBUG
WPS_PRINTF("isConfigured=%d\n", bConfigured);
WPS_PRINTF("SelectedRegistrar Match: %d\n", b1);
WPS_PRINTF("DevicePasswordID Match: %d\n", b2);
#endif
if (mode == WPS_PIN_MODE && !bDPIDExistButUnmatch) {
retIndex = i;
n ++;
}
else if (b1 && b2) {
retIndex = i;
n ++;
}
}
#if ENROLLEE_DEBUG
WPS_PRINTF("%s: %d wps bss found!!!!!!\n\n", __FUNCTION__, n);
#endif
if (mode == WPS_PIN_MODE) {
if (n >= 1) {
*selected_ap = ap_array[retIndex];
add_tried_pin_ap_queue(selected_ap);
return 0;
}
else {
return -1;
}
}
else if (mode == WPS_PBC_MODE) {
if (n == 1) {
*selected_ap = ap_array[retIndex];
return 0;
}
else if (n == 0) {
return -1;
}
else {
return -2;
}
}
}
static void wps_enrol_thread_fn(void)
{
int ret;
WPS_u8 event;
WPS_AP_DESC ap;
while (1)
{
WPS_WaitSemaphore(wps_enrol_sem);
wps_running = 1;
WPS_PRINTF("Debug: %s - %s() - %d", __FILE__, __FUNCTION__, __LINE__);////Debug
for(;;) {
ret = wps_enrol_select_ap(get_enrollee_mode(), &ap);
if (ret == -2) {
event = USER_CALLBACK_EVENT_OVERLAP;
break;
}
else if (ret == 0) {
if (Wlan_IsAssociated()) {
Wlan_Disassociate();
}
Wlan_AddEapolListener(wps_eapol_callback);
wps_assoc_and_wait_completion(&ap);
for (;;) {
if (enrollee_is_regprotocol_done(wps_enrol_ptr)) {
if (enrollee_is_regprotocol_successful(wps_enrol_ptr)) {
event = USER_CALLBACK_EVENT_SUCCESS;
}
else {
event = USER_CALLBACK_EVENT_ERROR;
}
break;
}
if (wps_enrol_stop_flag) {
event = USER_CALLBACK_EVENT_STOPPED;
break;
}
WPS_Sleep(500);
}
wps_disassoc_and_wait_completion();
Wlan_RemoveEapolListener();
if (event == USER_CALLBACK_EVENT_SUCCESS || event == USER_CALLBACK_EVENT_STOPPED) {
break;
}
}
else if (ret == -1) {
if (WPS_GetSysTime() - wps_start_time >= wps_timeout_value) {
event = USER_CALLBACK_EVENT_ERROR;
break;
}
if (wps_enrol_stop_flag) {
event = USER_CALLBACK_EVENT_STOPPED;
break;
}
empty_tried_pin_ap_queue();
}
} /* for(;;) */
empty_tried_pin_ap_queue();
wps_enrol_callback(event);
wps_running = 0;
} /* while (1) */
}
int wps_enrol_initialize(void)
{ WPS_osfunc_init();
wps_enrol_mode = WPS_DISABLED;
WPS_STR_NCPY(wps_enrol_pin, "", sizeof(wps_enrol_pin));
wps_enrol_callback = NULL;
wps_enrol_sem = WPS_CreateSemaphore(1);
if (wps_enrol_sem == NULL) {
return WPS_ERROR_NO_MEM;
}
wps_enrol_thread = WPS_CreateThread(wps_enrol_thread_fn);
if (wps_enrol_thread == NULL) {
WPS_DeleteSemaphore(wps_enrol_sem);
wps_enrol_sem = NULL;
return WPS_ERROR_NO_MEM;
}
enrollee_create_instance(&wps_enrol_ptr);
if (wps_enrol_ptr == NULL) {
WPS_DeleteSemaphore(wps_enrol_sem);
wps_enrol_sem = NULL;
WPS_DeleteThread(wps_enrol_thread);
wps_enrol_thread = NULL;
return WPS_ERROR_NO_MEM;
}
return WPS_ERROR_SUCCESS;
}
int wps_enrol_set_mode(WPS_u8 mode)
{
if (mode != WPS_PIN_MODE && mode != WPS_PBC_MODE) {
return WPS_ERROR_INVALID_PARAM;
}
wps_enrol_mode = mode;
return WPS_ERROR_SUCCESS;
}
int wps_enrol_set_pin(WPS_char *pin)
{
if (pin == NULL || WPS_STR_LEN(pin) != 8) {
return WPS_ERROR_INVALID_PARAM;
}
WPS_STR_NCPY(wps_enrol_pin, pin, sizeof(wps_enrol_pin));
return WPS_ERROR_SUCCESS;
}
int wps_enrol_set_callback(WPS_USER_CALLBACK callback)
{
if (callback == NULL) {
return WPS_ERROR_INVALID_PARAM;
}
wps_enrol_callback = callback;
return WPS_ERROR_SUCCESS;
}
int wps_enrol_start(void)
{
if (wps_running != 0) {
return WPS_ERROR_ALREADY_STARTED;
}
if (wps_enrol_mode == WPS_DISABLED) {
return WPS_ERROR_MODE_NOT_SET;
}
if (wps_enrol_mode == WPS_PBC_MODE) {
WPS_STR_NCPY(wps_enrol_pin, "00000000", sizeof(wps_enrol_pin));
}
if (WPS_STR_CMP(wps_enrol_pin, "") == 0) {
return WPS_ERROR_PIN_NOT_SET;
}
if (wps_enrol_callback == NULL) {
return WPS_ERROR_CALLBACK_NOT_SET;
}
wps_start_time = WPS_GetSysTime();
wps_timeout_value = WPS_OVERALL_TIMEOUT * 1000;
wps_enrol_stop_flag = 0;
WPS_PostSemaphore(wps_enrol_sem);
return WPS_ERROR_SUCCESS;
}
int wps_enrol_stop(void)
{
if (wps_running != 1) {
return WPS_ERROR_ALREADY_STOPPED;
}
wps_enrol_stop_flag = 1;
return WPS_ERROR_SUCCESS;
}
int wps_enrol_get_wlan_param(USER_WLAN_PARAM *param)
{
ENROLLEE_CREDENTIAL *p;
if (param == NULL) {
return WPS_ERROR_INVALID_PARAM;
}
if (wps_enrol_ptr == NULL ||
!enrollee_is_regprotocol_successful(wps_enrol_ptr)) {
return WPS_ERROR_NO_WLAN_PARAM;
}
p = &wps_enrol_ptr->credential;
WPS_MEM_CPY(param->param_SSID, p->Cre_SSID, SSID_MAXLENGTH);
param->param_SSID_Length = p->Cre_SSID_Length;
param->param_AuthenticationType = p->Cre_AuthenticationType;
param->param_EncryptionType = p->Cre_EncryptionType;
param->param_NetworkKeyIndex = p->Cre_NetworkKeyIndex;
WPS_MEM_CPY(param->param_NetworkKey, p->Cre_NetworkKey, NETWORKKEY_MAXLENGTH);
param->param_NetworkKey_Length = p->Cre_NetworkKey_Length;
return WPS_ERROR_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -