micropython / micropython/micropython

ESP32-C3-MINI-1(DK):network.WLAN can not connect success anymore if 201 status appears

Open
#14,382 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug needs-info port-esp32 proposed-close
Dominant language
C
Stars
22.1k
Forks
9k
Avg merge
6d 4h
Merged PRs (30d)
16

Description

Checks
  • I agree to follow the MicroPython Code of Conduct to ensure a safe and respectful space for everyone.

  • I've searched for existing issues matching this bug, and didn't find any.

Port, board and/or hardware

ESP32-C3-MINI-1(DK) ESP-ROM:esp32c3-api1-20210207

MicroPython version

MicroPython v1.22.2 on 2024-02-22; ESP32C3 module with ESP32C3

Reproduction

run code:

'''
如果先激活WLAN再激活AP, 则会出错 OSError: Wifi Invalid Mode
'''
import network, time, json, machine
import uasyncio as asyncio

# 先开AP
ap = network.WLAN(network.AP_IF)
ap.config(essid='ESP32-C3', password='12345678')
ap.config(max_clients=3)
ap.active(False)
ap.active(True)
print('AP信息:', ap.ifconfig())


wlan = network.WLAN(network.STA_IF)
wlan.active(False)
wlan.active(True)

connect_wifi_task = ''

async def run_connect_wifi_task(ssid, password):
    while True:
        try:
            wlan.active(False)
            wlan.active(True)
            wlan.connect(ssid, password)
            print('开始连接', ssid, password)

            count = 0
            while not wlan.isconnected():
                count += 1
                print('连接重试:', count, wlan.status())

                if count == 10:
                    raise Exception('超时')

                if wlan.status() == 201:
                    raise Exception('没有找到网络')

                await asyncio.sleep(1)
            pass
        except Exception as e:
            print('连接出错', e)
            # 立即关闭WLAN, 防止造成AP异常
            wlan.active(False)
            await asyncio.sleep(6)
    pass

    print('WLAN信息:', wlan.ifconfig())

def connect_wifi(ssid, password):
    print('连接', ssid, password)

    global connect_wifi_task
    if connect_wifi_task != '':
        connect_wifi_task.cancel()
        connect_wifi_task = ''
    pass

    connect_wifi_task = asyncio.create_task(run_connect_wifi_task(ssid, password))
pass

# 处理HTTP请求
async def http_handle(reader, writer):
    client = writer.get_extra_info('peername')
    print(f'HTTP客户端连接 {client}')

    # 读取方法路径协议行
    line_path = await reader.readline()
    line_path_text = str(line_path)
    print(f'HTTP方法路径协议行 {line_path_text}')

    # 读取Headers
    # https://github.com/micropython/micropython/blob/d11ca092f75d2652df403dda7448fe1bc8f98cf7/tests/net_inet/asyncio_tcp_read_headers.py#L10
    print('Headers 如下:')
    while True:
        line = await reader.readline()
        line = line.strip()
        if not line:
            break
        print(str(line, 'utf-8'))
    pass
    print('Headers ----')

    if line_path_text.find("b'GET /") != -1:
        print('HTTP客户端GET请求')
        writer.write('HTTP/1.1 200 OK\r\nContent-type: text/html; charset=utf-8\r\n\r\n')
        writer.write(f"""<!DOCTYPE html>
<html>
    <head> <title>里路微控</title> </head>
    <body>
        <h1>里路微控</h1>
        <p>{time.localtime()}</p>
        <p>来自 <a href="https://lilu.red">里路</a></p>
    </body>
</html>
""")
        pass

    if line_path_text.find("b'POST /") != -1:
        print('HTTP客户端POST请求')

        # 读取Body
        body_data = await reader.read(512)
        body_text = str(body_data, 'utf-8')
        print('Body 如下:')
        print(body_text)
        print('Body ----')

        # 解析数据
        post_data = json.loads(body_text)

        # 按逻辑处理
        if line_path_text.find("b'POST /wifi ") != -1: # 设置WIFI
            print(f'HTTP客户端POST请求设置WIFI')
            if 'wifi_ssid' not in post_data or post_data['wifi_ssid'] == '' or 'wifi_password' not in post_data or post_data['wifi_password'] == '':
                print('HTTP设置WIFI数据无效')
                writer.write('HTTP/1.1 400 Bad Request\r\n\r\n')
                pass
            else:
                connect_wifi(post_data['wifi_ssid'], post_data['wifi_password'])
                writer.write('HTTP/1.1 200 OK\r\n\r\n')
                pass
        else:
            print(f'HTTP客户端POST请求不在预期范围 {line_path_text}')
            writer.write('HTTP/1.1 400 Bad Request\r\n\r\n')
        pass
    pass

    # 发送响应内容
    await writer.drain()

    # 关闭
    writer.close()
    await writer.wait_closed()
    print('HTTP客户端断开')
pass

async def main():
    asyncio.create_task(asyncio.start_server(http_handle, "0.0.0.0", 80))

    # asyncio.create_task(connect_wifi('a', '12345678'))

    while True:
        await asyncio.sleep(1)
pass

try:
    asyncio.run(main())
except KeyboardInterrupt:
    print("主动关闭")
finally:
    asyncio.new_event_loop()

Post not exists SSID {"wifi_password": "wrong12345678", "wifi_ssid": "kmx"} to http://192.168.4.1/wifi :

连接 kmx wrong12345678
开始连接 kmx wrong12345678
连接重试: 1 1001
HTTP客户端断开
连接重试: 2 1001
连接重试: 3 1001
连接重试: 4 201
连接出错 没有找到网络

if wlan.status() == 201 , Post right SSID {"wifi_password": "wrong12345678", "wifi_ssid": "km"} to http://192.168.4.1/wifi :

连接 km wrong12345678
开始连接 km wrong12345678
连接重试: 1 201
连接出错 没有找到网络
HTTP客户端断开
开始连接 km wrong12345678
连接重试: 1 201
连接出错 没有找到网络

wlan.status() always 201...

Expected behaviour
  1. The 201 status should not remain when reconnecting to an right network again.
  2. Regardless of whether it was 201 or 202 status before, network should be reset when reconnecting.
  3. WLAN connection failure should not cause the AP to disconnect.
Observed behaviour

When reconnect to right SSID with wrong password, the wlan.status() should be 202. After testing, it was found that the board may still be connected to the previous SSID(kmx).

When wlan.status() is 201 , I must call wlan.active(False) immediately. If not do this, the AP will shutdown automatic. But after call wlan.active(False) , the AP can continue to work.

And if connect to right SSID with wrong password at first time(wlan.status() is 202), Then post right SSID and right password, The board can connect successful.

Additional Information

The user's situation is much more complicated when distributing the network. Hope the API behaves as expected. Thanks very much.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the provided network.WLAN reproduction on an ESP32-C3-MINI-1(DK) with the stated MicroPython v1.22.2 version, focusing on reconnects after status 201 or 202. Done means reconnecting resets the prior failure state, a valid network can connect afterward, and WLAN failure does not disconnect the AP.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
embedded-iot, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.