From 1284f66d584d0ed16a3c3f3ab4e12a4f39094151 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Fri, 29 Nov 2024 17:32:29 +0100 Subject: [PATCH 1/2] fix(modem): Fix CMUX enter to ignore URC before transition Closes https://github.com/espressif/esp-protocols/issues/669 --- components/esp_modem/src/esp_modem_cmux.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/components/esp_modem/src/esp_modem_cmux.cpp b/components/esp_modem/src/esp_modem_cmux.cpp index c47e13b9db..37367715d7 100644 --- a/components/esp_modem/src/esp_modem_cmux.cpp +++ b/components/esp_modem/src/esp_modem_cmux.cpp @@ -123,7 +123,12 @@ bool CMux::data_available(uint8_t *data, size_t len) { if (data && (type & FT_UIH) == FT_UIH && len > 0 && dlci > 0) { // valid payload on a virtual term int virtual_term = dlci - 1; - if (virtual_term < MAX_TERMINALS_NUM && read_cb[virtual_term]) { + if (virtual_term < MAX_TERMINALS_NUM) { + if (read_cb[virtual_term] == nullptr) { + // ignore all virtual terminal's data before we completely establish CMUX + ESP_LOG_BUFFER_HEXDUMP("CMUX Rx before init", data, len, ESP_LOG_DEBUG); + return true; + } // Post partial data (or defragment to post on CMUX footer) #ifdef DEFRAGMENT_CMUX_PAYLOAD if (payload_start == nullptr) { @@ -142,7 +147,11 @@ bool CMux::data_available(uint8_t *data, size_t len) sabm_ack = dlci; } else if (data == nullptr && dlci > 0) { int virtual_term = dlci - 1; - if (virtual_term < MAX_TERMINALS_NUM && read_cb[virtual_term]) { + if (virtual_term < MAX_TERMINALS_NUM) { + if (read_cb[virtual_term] == nullptr) { + // silently ignore this CMUX frame (not finished entering CMUX, yet) + return true; + } #ifdef DEFRAGMENT_CMUX_PAYLOAD read_cb[virtual_term](payload_start, total_payload_size); #endif From 0cb59ff80dbc8c09c8b436af3694185f49b3fff0 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Fri, 29 Nov 2024 18:24:28 +0100 Subject: [PATCH 2/2] fix(modem): Detect serial ports properly --- .github/workflows/modem__target-test.yml | 9 +++-- .../esp_modem/test/target/pytest_pppd.py | 36 ++++++++++++++++--- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/.github/workflows/modem__target-test.yml b/.github/workflows/modem__target-test.yml index 4de01e6cbd..33917430bb 100644 --- a/.github/workflows/modem__target-test.yml +++ b/.github/workflows/modem__target-test.yml @@ -80,7 +80,12 @@ jobs: name: modem_target_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.test.app }} path: ${{ env.TEST_DIR }}/build - name: Run Example Test on target - working-directory: ${{ env.TEST_DIR }} + env: + PIP_EXTRA_INDEX_URL: "https://dl.espressif.com/pypi/" run: | - python -m pip install -r $GITHUB_WORKSPACE/ci/requirements.txt + python -m venv .venv + source .venv/bin/activate + pip install --prefer-binary cryptography pytest-embedded pytest-embedded-serial-esp pytest-embedded-idf pytest-custom_exit_code esptool + pip install -r $GITHUB_WORKSPACE/ci/requirements.txt + cd ${{ env.TEST_DIR }} python -m pytest --log-cli-level DEBUG --target=${{ matrix.idf_target }} diff --git a/components/esp_modem/test/target/pytest_pppd.py b/components/esp_modem/test/target/pytest_pppd.py index d675e3c65b..86c60ac142 100644 --- a/components/esp_modem/test/target/pytest_pppd.py +++ b/components/esp_modem/test/target/pytest_pppd.py @@ -9,6 +9,20 @@ import netifaces +def is_esp32(port): + """ + Check if the given port is connected to an ESP32 using esptool. + """ + try: + result = subprocess.run( + ['esptool.py', '--port', port, 'chip_id'], + stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, text=True + ) + return 'ESP32' in result.stdout + except subprocess.CalledProcessError: + return False + + def run_server(server_stop, port, server_ip, client_ip, auth, auth_user, auth_password): print('Starting PPP server on port: {}'.format(port)) try: @@ -66,13 +80,27 @@ def test_examples_protocol_pppos_connect(dut): ) raise - # the PPP test env uses two ttyUSB's: one for ESP32 board, another one for ppp server - # use the other port for PPP server than the DUT/ESP - port = '/dev/ttyUSB0' if dut.serial.port == '/dev/ttyUSB1' else '/dev/ttyUSB1' + # the PPP test env uses three ttyUSB's: two for ESP32 board and another one for the ppp server + # we need to detect the server_port (for PPPD) + server_port = None + for i in ['/dev/ttyUSB0', '/dev/ttyUSB1', '/dev/ttyUSB2']: + if i == dut.serial.port: + print(f'DUT port: {i}') + elif is_esp32(i): + print(f'Some other ESP32: {i}') + else: + print(f'Port for PPPD: {i}') + server_port = i + if server_port is None: + print( + 'ENV_TEST_FAILURE: Cannot locate PPPD port' + ) + raise + # Start the PPP server server_stop = Event() t = Thread(target=run_server, - args=(server_stop, port, server_ip, client_ip, auth, auth_user, auth_password)) + args=(server_stop, server_port, server_ip, client_ip, auth, auth_user, auth_password)) t.start() try: ppp_server_timeout = time.time() + 30