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

[Fixed backport]: Add WPS and netstatus #4464

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

volodymyrlut
Copy link

This PR is basically a fixed version of @mactijn port of @jhgoebbert PR#218 which had conflicts with master and haven't passed the CI check.

We've fixed issues, merged code and tested functionality on our ESP-32 boards, but I would kindly ask maintainers to properly review the code.

It can be used as follows:

import machine
import time
import network

button = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_UP)
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
while True:
    if button.value() == 0:
        wlan.start_wps()
        print('start_wps')
        while wlan.status() == network.STA_WPS_PROBING:
            print("probing with WPS")
            time.sleep(0.5)

        if wlan.status() == network.STA_WPS_SUCCESS:
            print("WPS successful")
            print("   ESSID:    ", wlan.config('essid'))
            print("   Password: ", wlan.config('password'))
            wlan.connect(wlan.config('essid'), wlan.config('password'))
            print("Waiting for connection...")
            while not wlan.isconnected():
                machine.idle()
            print("Connected.")

        elif wlan.status() == network.STA_WPS_FAILED:
            print("WPS failed")

        elif wlan.status() == network.STA_WPS_TIMEOUT:
            print("WPS timeout")

// This function is called by the system-event task and so runs in a different
// thread to the main MicroPython task. It must not raise any Python exceptions.
static esp_err_t event_handler(void *ctx, system_event_t *event) {
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
ESP_LOGI("wifi", "STA_START");
break;
case SYSTEM_EVENT_STA_GOT_IP:
wifi_sta_status = STATION_GOT_IP;
Copy link
Sponsor Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(formatting) Inconsistent indentation; just drop four spaces.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed:)

@mattytrentini
Copy link
Sponsor Contributor

The code looks really good, thanks for your efforts! WPS is actually a neat solution for establishing connectivity in the IoT space so I think this feature could be quite useful.

This weekend I'll build and test it against my router.

@volodymyrlut
Copy link
Author

@mattytrentini thank you!

You can use the code example I've attached to the first comment here to test it (it worked on my ESP32 perfectly). I would like to see it merged someday.

Have a good day!

@mattytrentini
Copy link
Sponsor Contributor

Pulled code into a checkout of master:head, rebuilt and tried your example code (changing the pin to something more convenient on my board)...and it appears to work!

True
I (264939) wpa: manufacturer: ESPRESSIF, model number: ESP32, model name: ESPRESSIF IOT, device name: ESP STATION
I (264939) wpa: wifi_wps_enable

start_wps
probing with WPS
probing with WPS
probing with WPS
probing with WPS
probing with WPS
probing with WPS
I (268359) wifi: new:<1,1>, old:<1,0>, ap:<255,255>, sta:<1,1>, prof:1
I (268999) wifi: state: init -> auth (b0)
I (269009) wifi: state: auth -> assoc (0)
probing with WPS
I (269019) wifi: state: assoc -> run (10)
probing with WPS
probing with WPS
probing with WPS
probing with WPS
probing with WPS
probing with WPS
probing with WPS
probing with WPS
probing with WPS
I (274349) wifi: STA_WPS_ER_SUCCESS
I (274349) wpa: wifi_wps_disable

I (274349) wifi: state: run -> init (0)
I (274349) wifi: new:<1,0>, old:<1,1>, ap:<255,255>, sta:<1,1>, prof:1
I (274359) wifi: STA_DISCONNECTED, reason:8
WPS successful
   ESSID:     TrentNet3
   Password:  xxxxxxxx
Waiting for connection...
I (274949) wifi: new:<1,1>, old:<1,0>, ap:<255,255>, sta:<1,1>, prof:1
I (275599) wifi: state: init -> auth (b0)
I (275599) wifi: state: auth -> assoc (0)
I (275609) wifi: state: assoc -> run (10)
I (275849) wifi: connected with TrentNet3, channel 1, bssid = 00:04:ed:8a:39:6f
I (275849) wifi: pm start, type: 1

I (275859) network: CONNECTED
I (277899) event: sta ip: 192.168.1.114, mask: 255.255.255.0, gw: 192.168.1.254
I (277899) network: GOT_IP
Connected.
Traceback (most recent call last):
  File "<stdin>", line 30, in <module>
KeyboardInterrupt: 
>>> wlan.isconnected()
True
>>> wlan.ifconfig()
('192.168.1.114', '255.255.255.0', '192.168.1.254', '192.168.1.254')

Nice job! The only thing that remains is some documentation. A WPS entry in the QuickStart would be the way to go...I could add it but would certainly appreciate it if you were able to make a first-pass!

@volodymyrlut
Copy link
Author

@mattytrentini ok, for sure.
I'll take care of docs:)

@volodymyrlut
Copy link
Author

@mattytrentini I've added docs under the networking part of quickref:
https://github.com/odditive/micropython/blob/add-wps-and-netstatus/docs/esp32/quickref.rst

Can you please read it through and tell me whether it is ok?
Thank you.

@volodymyrlut
Copy link
Author

Hello, @mattytrentini!

How can I help you to make this PR merged?

@dpgeorge
Copy link
Member

Thanks @volodymyrlut for the contribution. I agree with @mattytrentini that this would be a nice addition, but we should think a bit how the user facing API looks in Python so that it can be made the same on other ports (eg esp8266).

At first thought WPS (enrollee) is just another way to connect to an AP, so could simply be exposed as wlan.connect(wps=True). Then connection would proceed as if you provided an SSID and password, and status can be checked via wlan.status() using the existing status codes.

So you could reconnect next time without using WPS there would need to be a way to get the SSID and password (from the successful WPS connection), to save them, to reuse them. Exposing them through wlan.config() makes sense (as you've done here).

The other way to think about it is with WPS as a completely separate, independent feature which is used to retrieve the SSID and password of the AP. This could be exposed using the existing config method like wlan.config(wps=True) which turns on WPS. And its status (eg success, timeout) obtained via wlan.status('wps'). Once successful, the SSID and password could be obtained using wlan.config() again.

What is done in this PR seems to be a bit of both of the above, adding a new method start_wps() and coupling in the status results to the connection status codes. I'd rather keep those codes separated because they are difficult to get right, see eg the recent commit 21f9329

@gmli
Copy link

gmli commented Apr 11, 2020

Any update about WPS support ?

@volodymyrlut
Copy link
Author

@gmli unfortunately I cannot currently help with this issue. If the problems mentioned by @mattytrentini would be resolved by someone, I think it could be merged.

Anyways, there is no technical limitations to make it work.

@tialm
Copy link

tialm commented May 17, 2020

This would be awesome to have straight out of the box! Any news? What does need to be solved?

@FabriSku
Copy link

Thanks so much for your valuable work. I wanted to ask you about this code example for WPS which is followed by an error "AttributeError: 'WLAN' object has no attribute 'start_wps'".
do the files named modnetwork.c and makefile do something? what are they and what are they for? Thanks in advance for the answer.

tannewt added a commit to tannewt/circuitpython that referenced this pull request Mar 23, 2021
update logic for displayio.TileGrid's transform_xy
@dpgeorge dpgeorge mentioned this pull request May 11, 2021
@eydam-prototyping
Copy link
Contributor

Hello,
I started a new PR #7452, since this one wasn't merged.
It would be great, if some of you have time to test it and report the results, so we could merge it this time.

@big-vl
Copy link

big-vl commented Oct 16, 2022

The branch is outdated, I would like to see this update.

@projectgus
Copy link
Contributor

This is an automated heads-up that we've just merged a Pull Request
that removes the STATIC macro from MicroPython's C API.

See #13763

A search suggests this PR might apply the STATIC macro to some C code. If it
does, then next time you rebase the PR (or merge from master) then you should
please replace all the STATIC keywords with static.

Although this is an automated message, feel free to @-reply to me directly if
you have any questions about this.

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.

None yet

9 participants