/* * Copyright 2008-2024 NXP * * SPDX-License-Identifier: BSD-3-Clause * */ /** @file wifi_nxp_wps.h * * @brief WPS - WiFi Protected Setup * * Wi-Fi Protected Setup (WPS) is a standard for easy and secure wireless * network set up and connections. Using this standard, wireless clients * can associate with the WPS enabled access point by entering the same * PIN at client and AP end or by pushing a pushbutton on both. This eliminates * the need for manually entering the security configuration on the client side. * * Two methods that are supported by SDK are: * * \li PIN Method: In this method the same PIN (Personal Identification Number) * is entered on the wireless client and access point. The PIN can be static * or dynamically generated on any of the AP or wireless client. * \li PBC Method: in which the user simply has to push a button, either * an actual or virtual one, on both the AP and wireless client. * * \section wps_usage Usage * In a typical implementation WPS thread is started by calling \ref wps_start. * A valid initialized \ref wps_config structure needs to be passed to this * function. This structure contains a callback handler which is invoked by the * WPS thread on occurrence of various events. Once the WPS thread is started, * commands can be sent to it using \ref wps_connect function. Typically * these commands can be start PIN session, or start a pushbutton session. This * requires passing \ref wps_session_command structure that contains a valid * \ref wlan_scan_result that contains network information for a WPS enabled * wireless network. On successful WPS session, callback handler is invoked with * \ref WPS_SESSION_SUCCESSFUL event with \ref wlan_network structure that * contains all the security information for the network with which WPS * session was attempted. After this \ref wps_stop should be called to * terminate the WPS thread. * * \note WPS implementation lets application decide PIN policy. PIN could either * be generated by the application, or by the access point or can be statically * generated at device manufacturing time. \ref wps_generate_pin and \ref * wps_validate_pin utility functions can be used by the application to generate * and validate PIN. * * \note WPS thread internally uses multiple dynamic allocations. Please do not * reduce the heap size below 64KB if the application wishes to use WPS. * */ #ifndef WPS_H #define WPS_H #include #include #if (CONFIG_WPA2_ENTP) && !(CONFIG_WPS2) #error "CONFIG_WPA2_ENTP is enabled, but CONFIG_WPS2 is not, enable it from wifi_config.h" #endif #if CONFIG_WPS_DEBUG #define wps_d(...) wmlog("wps", ##__VA_ARGS__) #else #define wps_d(...) #endif /** MAC to string */ #ifndef MAC2STR #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] #endif /** MAC string */ #ifndef MACSTR #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" #endif #if CONFIG_WPS_DEBUG /** ENTER */ #ifndef ENTER #define ENTER() PRINTF("Enter: %s : %i\r\n", __FUNCTION__, __LINE__) // #define ENTER() PRINTF("Enter: %s, %s:%i\r\n", __FUNCTION__, __FILE__, __LINE__) #endif /** LEAVE */ #ifndef LEAVE #define LEAVE() PRINTF("Leave: %s : %i\r\n", __FUNCTION__, __LINE__) // #define LEAVE() PRINTF("Leave: %s, %s:%i\r\n", __FUNCTION__, __FILE__, __LINE__) #endif #else #ifndef ENTER #define ENTER() #endif #ifndef LEAVE #define LEAVE() #endif #endif #ifndef BIT #define BIT(x) (1 << (x)) #endif #define PROV_NON_SESSION_ATTEMPT 0 #define PROV_WPS_SESSION_ATTEMPT 1 #define PROV_ENTP_SESSION_ATTEMPT 2 #if CONFIG_WPS_DEBUG static inline void wps_hexdump(const char *title, const unsigned char *data, size_t len) { int i, j; unsigned char *offset; // #ifndef ENTER offset = (unsigned char *)data; PRINTF("[wps] %s - hexdump(len=%lu):\r\n", title, (unsigned long)len); // #define ENTER() PRINTF("Enter: %s : %i\r\n", __FUNCTION__, __LINE__) for (i = 0; i < len / 16; i++) { for (j = 0; j < 16; j++) PRINTF("%02x ", offset[j]); PRINTF("\r\n"); offset += 16; } i = len % 16; for (j = 0; j < i; j++) PRINTF("%02x ", offset[j]); PRINTF("\r\n"); } #else static inline void wps_hexdump(const char *title, const unsigned char *data, size_t len) { } #endif #define PM3_BSS #if defined(__arm__) #if defined(__ARMCC_VERSION) #define LWIP_TIMEVAL_PRIVATE 1 #else #define LWIP_TIMEVAL_PRIVATE 0 #endif #ifndef LWIP_SOCKET_SELECT #define LWIP_SOCKET_SELECT 0 #endif #endif /** enum : WPS session commands */ enum wps_session_command { /** Command to start WPS PIN session */ CMD_WPS_PIN = 0, /** Command to start WPS PBC session */ CMD_WPS_PBC }; /** enum : WPS events */ enum wps_event { /** WPS thread started */ WPS_STARTED = 0, /** WPS PBC/PIN Session started */ WPS_SESSION_STARTED, /** WPS PIN checksum failed */ WPS_SESSION_PIN_CHKSUM_FAILED, /** WPS Session aborted */ WPS_SESSION_ABORTED, /** WPS Session registration timeout */ WPS_SESSION_TIMEOUT, /** WPS Session attempt successful */ WPS_SESSION_SUCCESSFUL, /** WPS Session failed */ WPS_SESSION_FAILED, /** WPS thread stopped */ WPS_FINISHED }; /** Enum that indicates type of WPS session * either a push button or a PIN based session is * determined by value fo this enum */ enum wps_session_types { /** WPS session is not active */ WPS_SESSION_INACTIVE = 0xffff, /** WPS Push Button session active */ WPS_SESSION_PBC = 0x0004, /** WPS PIN session active */ WPS_SESSION_PIN = 0x0000, }; /** * This struct is passed to wps_start(). The user must initialize it * with parameters as described inline. */ struct wps_config { /** Enrollee: 1, Registrar: 2, WiFi Direct mode:4 */ uint8_t role; /** PIN Generator - Enrollee or Registrar */ uint8_t pin_generator; /** version */ uint8_t version; /** version */ uint8_t version2; /** Device name */ uint8_t device_name[32]; /** Manufacture */ uint8_t manufacture[64]; /** Model name */ uint8_t model_name[32]; /** Model number */ uint8_t model_number[32]; /** Serial number */ uint8_t serial_number[32]; /** Config methods */ uint16_t config_methods; /** Primary Device category*/ uint16_t primary_dev_category; /** Primary Device subcategory*/ uint16_t primary_dev_subcategory; /** RF bands */ uint8_t rf_bands; /** OS Version */ uint32_t os_version; /** WPS message max retry */ uint8_t wps_msg_max_retry; /** WPS message timeout */ uint32_t wps_msg_timeout; /** PIN length */ uint16_t pin_len; /** WPS callback */ int (*wps_callback)(enum wps_event event, void *data, uint16_t len); /** session attempt PROV_NON_SESSION_ATTEMPT/PROV_WPS_SESSION_ATTEMPT/PROV_ENTP_SESSION_ATTEMPT */ uint8_t prov_session; }; /** Starts WPS thread and enables commands delivery * * \param wps_conf A pointer to WPS custom configuration * * \returns WM_SUCCESS if successful, -WM_FAIL otherwise */ int wps_start(struct wps_config *wps_conf); /** Connect to WPS enabled AP * * Connect to a WPS enabled AP. This function is typically called whenever * the users pushes the wps button or enters wps pin. * * \param pbc Set to 1 if Push-button session is desired * \param pin Ignore if pbc is 1. If pbc is 0, this indicates the pin that * should be used. The pin can be 4 or 8 digits. * \param res The WPS enabled AP to connect to. * * \returns WM_SUCCESS if successful, -WM_FAIL otherwise */ int wps_connect(enum wps_session_command pbc, uint32_t pin, struct wlan_scan_result *res); /** Generate 8 digit WPS PIN value with random number generator * * \param wps_pin Generated 8 digit WPS PIN value * * \returns WM_SUCCESS if successful, -WM_FAIL otherwise */ int wps_generate_pin(uint32_t *wps_pin); /**Validate checksum of PIN * * \param wps_pin WPS PIN value * * \returns WM_SUCCESS if successful, -WM_FAIL otherwise **/ int wps_validate_pin(uint32_t wps_pin); /** Deletes WPS thread and message queue * * \returns WM_SUCCESS if successful, -WM_FAIL otherwise */ int wps_stop(); #endif