Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for esp32 network driver scanning for access points #1165

Open
wants to merge 3 commits into
base: release-0.6
Choose a base branch
from

Conversation

UncleGrumpy
Copy link
Collaborator

@UncleGrumpy UncleGrumpy commented May 24, 2024

Add network:wifi_scan/0,1 to esp32 network driver, giving the ability for devices configured for "station mode" (or with "station + access point mode") to scan for available access points.

note: these changes depend on PR #1181

These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later

@UncleGrumpy UncleGrumpy changed the base branch from main to release-0.6 May 24, 2024 00:58
@UncleGrumpy UncleGrumpy force-pushed the esp32_wifi_scan branch 2 times, most recently from 58cf1f8 to cdadc33 Compare June 6, 2024 01:14
@petermm
Copy link
Contributor

petermm commented Jun 11, 2024

I struggled here:

I started out empty example and tried:

    scan = :network.wifi_scan()
    IO.inspect(scan)

This crashes with: {noproc,{gen_server,call,[network,get_config]}} - looks like there is a code path for handling the error but it's never reached

Then I read docs, about having to start the network, and tried:

 config = [
      {:sta,
       [
         {:ssid, "Wokwi-GUEST"},
         {:psk, ""},
         {:connected,
          fn ->
            IO.inspect("network CONNECTED")
            :ok
          end}
       ]}
    ]

    case :network.start(config) do
      {:ok, _pid} ->
        IO.inspect("network started")
      error ->
        :io.put_chars("\nAn error occurred starting network:")
        :erlang.display(error)
    end

    scan = :network.wifi_scan()
    IO.inspect(scan)

which crashed with: wifi:sta_scan: STA is connecting, scan are not allowed!

delaying things and scanning after connection is done made it further to a crash:

CRASH 
======
pid: <0.1.0>

Stacktrace:
undefined

cp: #CP<module: 11, label: 31, offset: 26>

x[0]: error
x[1]: badarg
x[2]: error

Stack 
------

#CP<module: 11, label: 32, offset: 26>
<<"0">>
#CP<module: 11, label: 24, offset: 20>
#CP<module: 10, label: 11, offset: 11>
{0,[{none,[{rssi,undefined},{authmode,undefined},{channel,undefined}]}]}

It also seems that connecting to a network not available, disallows scanning with: wifi:sta_scan: STA is connecting, scan are not allowed!

Would be great seeing an example that could be used in CI eg:

  1. scan with no network configured
  2. connect known good network - scan
  3. config known unavailable network - scan
  4. probably some ap stuff
    etc.

I'll work on getting wokwi CI going so this can be covered by CI.

@UncleGrumpy
Copy link
Collaborator Author

UncleGrumpy commented Jun 11, 2024

I did not add an example yet, my plan was to write a demonstration of “roaming” for atomvm_examples. It is a little difficult to use until #1181 is merged, that will allow starting WiFi without immediately starting a connection. Scans will always fail when a connection is in progress, so your application will need to start a scan after obtaining an IP address, or before any connection is started (which is not possible until after #1181).

@UncleGrumpy
Copy link
Collaborator Author

I wish your second example had a stacktrace! You can see the scan result did come back with no networks found… this can happen with default scans (the dwell time is very short by default - and can easily miss networks, in my experience). I think it’s just a bad match in your test that is crashing there.

@petermm
Copy link
Contributor

petermm commented Jun 11, 2024

I wish your second example had a stacktrace! You can see the scan result did come back with no networks found… this can happen with default scans (the dwell time is very short by default - and can easily miss networks, in my experience). I think it’s just a bad match in your test that is crashing there.

ohh the embarrassment lol - it's the IO.inspect call that crashes, will look into it - used to throwing anything at IO.inspect..

Makes sense with the other stuff, suppose some kind of WifiManager GenServer will materialize, while this PR is on driver primitives level..

I'll test #1181 and help land that first..

@UncleGrumpy
Copy link
Collaborator Author

My plan precisely! The PRs I have already submitted will provide all the necessary low level functionality, but I would like to create a higher level network_manager module that can simplify configuration and orchestration.

@UncleGrumpy
Copy link
Collaborator Author

As far as “dwell” time for the scan, I have found between 300-500ms will find all of the available networks, with the default (120ms) I do notice networks being frequently missed.

@UncleGrumpy
Copy link
Collaborator Author

it's the IO.inspect call that crashes, will look into it - used to throwing anything at IO.inspect..

That does sound like a bug, from my limmited understanding of Elixir you should be able to give it just about anything, much like erlang:display/1.

@UncleGrumpy
Copy link
Collaborator Author

{0,[{none,[{rssi,undefined},{authmode,undefined},{channel,undefined}]}]}

You did point me to a problem here, I started testing more boards and realized that even with maximum dwell time no network are being found. I cherry-picked these commits from a different local branch and must have missed something.

@UncleGrumpy UncleGrumpy marked this pull request as draft June 13, 2024 15:10
Corrects the type name db() to the more correct `dbm()`, and adds a brief
edoc explanation for the value.

Signed-off-by: Winford <winford@object.stream>
@UncleGrumpy UncleGrumpy force-pushed the esp32_wifi_scan branch 2 times, most recently from 480b056 to 50a78c7 Compare August 19, 2024 19:18
@UncleGrumpy
Copy link
Collaborator Author

When I split up the working branch I was testing new network features on I mistakenly submitted this PR first, but in order to use the scan function PR #1181 needs to be merged first, and this will need to be rebased.

@UncleGrumpy
Copy link
Collaborator Author

UncleGrumpy commented Aug 19, 2024

{0,[{none,[{rssi,undefined},{authmode,undefined},{channel,undefined}]}]}

I did find a bug that would cause the results to be empty if only a single network was found, during most of my testing I had multiple networks, so this didn't get caught. @petermm, thanks for testing and helping me correct this!

@UncleGrumpy UncleGrumpy marked this pull request as ready for review August 19, 2024 19:43
Adds the ability for devices configured for sta or ap+sta to scan for available access points. With
no arguments the default maximum results returned is 6. All default options can be configured in the
`sta_config()` section of the configuration used to start the network driver, or set in the
configuration parameter of `network:wifi_scan/1`.

Signed-off-by: Winford <winford@object.stream>
Adds documentation for `network:wifi_scan/0,1` and updates details for
`network:sta_rssi/0`, as well as better organizing the sub sections that these
commands are documented in.

Signed-off-by: Winford <winford@object.stream>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants