* Add BSSID connection options to PicoW

When working with a mesh or multiple APs with the same SSID, it is often
necessary to specify which of the APs to connect to in order to maximize
the WiFi strength.

Add BSSID options to the SDK's PicoW cyw43_arch_wifi_connect_XXX APIs.

Fixes #1090

Co-authored-by: Earle F. Philhower, III <earlephilhower@yahoo.com>
This commit is contained in:
Peter Harper 2023-01-29 22:56:58 +00:00 committed by GitHub
parent 5984849594
commit 0b0931a9a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 8 deletions

@ -1 +1 @@
Subproject commit 2cf328d9e41603405a037a29e081a7d30dd519e6 Subproject commit 83e0c700c252b392d33e70a5e9a241b921b166eb

View File

@ -69,15 +69,19 @@ const char* cyw43_tcpip_link_status_name(int status)
} }
#endif #endif
int cyw43_arch_wifi_connect_async(const char *ssid, const char *pw, uint32_t auth) {
int cyw43_arch_wifi_connect_bssid_async(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth) {
if (!pw) auth = CYW43_AUTH_OPEN; if (!pw) auth = CYW43_AUTH_OPEN;
// Connect to wireless // Connect to wireless
return cyw43_wifi_join(&cyw43_state, strlen(ssid), (const uint8_t *)ssid, pw ? strlen(pw) : 0, (const uint8_t *)pw, auth, NULL, CYW43_ITF_STA); return cyw43_wifi_join(&cyw43_state, strlen(ssid), (const uint8_t *)ssid, pw ? strlen(pw) : 0, (const uint8_t *)pw, auth, bssid, CYW43_CHANNEL_NONE);
} }
// Connect to wireless, return with success when an IP address has been assigned int cyw43_arch_wifi_connect_async(const char *ssid, const char *pw, uint32_t auth) {
static int cyw43_arch_wifi_connect_until(const char *ssid, const char *pw, uint32_t auth, absolute_time_t until) { return cyw43_arch_wifi_connect_bssid_async(ssid, NULL, pw, auth);
int err = cyw43_arch_wifi_connect_async(ssid, pw, auth); }
static int cyw43_arch_wifi_connect_bssid_until(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth, absolute_time_t until) {
int err = cyw43_arch_wifi_connect_bssid_async(ssid, bssid, pw, auth);
if (err) return err; if (err) return err;
int status = CYW43_LINK_UP + 1; int status = CYW43_LINK_UP + 1;
@ -86,7 +90,7 @@ static int cyw43_arch_wifi_connect_until(const char *ssid, const char *pw, uint3
// If there was no network, keep trying // If there was no network, keep trying
if (new_status == CYW43_LINK_NONET) { if (new_status == CYW43_LINK_NONET) {
new_status = CYW43_LINK_JOIN; new_status = CYW43_LINK_JOIN;
err = cyw43_arch_wifi_connect_async(ssid, pw, auth); err = cyw43_arch_wifi_connect_bssid_async(ssid, bssid, pw, auth);
if (err) return err; if (err) return err;
} }
if (new_status != status) { if (new_status != status) {
@ -111,14 +115,27 @@ static int cyw43_arch_wifi_connect_until(const char *ssid, const char *pw, uint3
} }
} }
// Connect to wireless, return with success when an IP address has been assigned
static int cyw43_arch_wifi_connect_until(const char *ssid, const char *pw, uint32_t auth, absolute_time_t until) {
return cyw43_arch_wifi_connect_bssid_until(ssid, NULL, pw, auth, until);
}
int cyw43_arch_wifi_connect_blocking(const char *ssid, const char *pw, uint32_t auth) { int cyw43_arch_wifi_connect_blocking(const char *ssid, const char *pw, uint32_t auth) {
return cyw43_arch_wifi_connect_until(ssid, pw, auth, at_the_end_of_time); return cyw43_arch_wifi_connect_until(ssid, pw, auth, at_the_end_of_time);
} }
int cyw43_arch_wifi_connect_bssid_blocking(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth) {
return cyw43_arch_wifi_connect_bssid_until(ssid, bssid, pw, auth, at_the_end_of_time);
}
int cyw43_arch_wifi_connect_timeout_ms(const char *ssid, const char *pw, uint32_t auth, uint32_t timeout_ms) { int cyw43_arch_wifi_connect_timeout_ms(const char *ssid, const char *pw, uint32_t auth, uint32_t timeout_ms) {
return cyw43_arch_wifi_connect_until(ssid, pw, auth, make_timeout_time_ms(timeout_ms)); return cyw43_arch_wifi_connect_until(ssid, pw, auth, make_timeout_time_ms(timeout_ms));
} }
int cyw43_arch_wifi_connect_bssid_timeout_ms(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth, uint32_t timeout_ms) {
return cyw43_arch_wifi_connect_bssid_until(ssid, bssid, pw, auth, make_timeout_time_ms(timeout_ms));
}
uint32_t cyw43_arch_get_country_code(void) { uint32_t cyw43_arch_get_country_code(void) {
return country_code; return country_code;
} }
@ -151,4 +168,4 @@ void cyw43_arch_poll(void)
void cyw43_arch_wait_for_work_until(absolute_time_t until) { void cyw43_arch_wait_for_work_until(absolute_time_t until) {
async_context_wait_for_work_until(async_context, until); async_context_wait_for_work_until(async_context, until);
} }

View File

@ -351,6 +351,20 @@ void cyw43_arch_enable_ap_mode(const char *ssid, const char *password, uint32_t
*/ */
int cyw43_arch_wifi_connect_blocking(const char *ssid, const char *pw, uint32_t auth); int cyw43_arch_wifi_connect_blocking(const char *ssid, const char *pw, uint32_t auth);
/*!
* \brief Attempt to connect to a wireless access point specified by SSID and BSSID, blocking until the network is joined or a failure is detected.
* \ingroup pico_cyw43_arch
*
* \param ssid the network name to connect to
* \param bssid the network BSSID to connect to or NULL if ignored
* \param password the network password or NULL if there is no password required
* \param auth the authorization type to use when the password is enabled. Values are \ref CYW43_AUTH_WPA_TKIP_PSK,
* \ref CYW43_AUTH_WPA2_AES_PSK, or \ref CYW43_AUTH_WPA2_MIXED_PSK (see \ref CYW43_AUTH_)
*
* \return 0 if the initialization is successful, an error code otherwise \see pico_error_codes
*/
int cyw43_arch_wifi_connect_bssid_blocking(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth);
/*! /*!
* \brief Attempt to connect to a wireless access point, blocking until the network is joined, a failure is detected or a timeout occurs * \brief Attempt to connect to a wireless access point, blocking until the network is joined, a failure is detected or a timeout occurs
* \ingroup pico_cyw43_arch * \ingroup pico_cyw43_arch
@ -364,6 +378,20 @@ int cyw43_arch_wifi_connect_blocking(const char *ssid, const char *pw, uint32_t
*/ */
int cyw43_arch_wifi_connect_timeout_ms(const char *ssid, const char *pw, uint32_t auth, uint32_t timeout); int cyw43_arch_wifi_connect_timeout_ms(const char *ssid, const char *pw, uint32_t auth, uint32_t timeout);
/*!
* \brief Attempt to connect to a wireless access point specified by SSID and BSSID, blocking until the network is joined, a failure is detected or a timeout occurs
* \ingroup pico_cyw43_arch
*
* \param ssid the network name to connect to
* \param bssid the network BSSID to connect to or NULL if ignored
* \param password the network password or NULL if there is no password required
* \param auth the authorization type to use when the password is enabled. Values are \ref CYW43_AUTH_WPA_TKIP_PSK,
* \ref CYW43_AUTH_WPA2_AES_PSK, or \ref CYW43_AUTH_WPA2_MIXED_PSK (see \ref CYW43_AUTH_)
*
* \return 0 if the initialization is successful, an error code otherwise \see pico_error_codes
*/
int cyw43_arch_wifi_connect_bssid_timeout_ms(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth, uint32_t timeout);
/*! /*!
* \brief Start attempting to connect to a wireless access point * \brief Start attempting to connect to a wireless access point
* \ingroup pico_cyw43_arch * \ingroup pico_cyw43_arch
@ -380,6 +408,23 @@ int cyw43_arch_wifi_connect_timeout_ms(const char *ssid, const char *pw, uint32_
*/ */
int cyw43_arch_wifi_connect_async(const char *ssid, const char *pw, uint32_t auth); int cyw43_arch_wifi_connect_async(const char *ssid, const char *pw, uint32_t auth);
/*!
* \brief Start attempting to connect to a wireless access point specified by SSID and BSSID
* \ingroup pico_cyw43_arch
*
* This method tells the CYW43 driver to start connecting to an access point. You should subsequently check the
* status by calling \ref cyw43_wifi_link_status.
*
* \param ssid the network name to connect to
* \param bssid the network BSSID to connect to or NULL if ignored
* \param password the network password or NULL if there is no password required
* \param auth the authorization type to use when the password is enabled. Values are \ref CYW43_AUTH_WPA_TKIP_PSK,
* \ref CYW43_AUTH_WPA2_AES_PSK, or \ref CYW43_AUTH_WPA2_MIXED_PSK (see \ref CYW43_AUTH_)
*
* \return 0 if the scan was started successfully, an error code otherwise \see pico_error_codes
*/
int cyw43_arch_wifi_connect_bssid_async(const char *ssid, const uint8_t *bssid, const char *pw, uint32_t auth);
/*! /*!
* \brief Set a GPIO pin on the wireless chip to a given value * \brief Set a GPIO pin on the wireless chip to a given value
* \ingroup pico_cyw43_arch * \ingroup pico_cyw43_arch