From cee80a83915e59aca69af56a9beec22d961c3847 Mon Sep 17 00:00:00 2001 From: "Sergio R. Caprile" Date: Wed, 1 Jul 2026 11:13:50 -0300 Subject: [PATCH] add tests for ATcmd driver, fix some warnings --- .github/workflows/nightly.yml | 48 +++++++++ .github/workflows/on_demand.yml | 53 +++------- mongoose.c | 14 +-- src/drivers/at_cmd.c | 12 ++- src/net_builtin.c | 2 +- test/Makefile | 18 +++- test/atcmd_test.c | 173 ++++++++++++++++++++++++++++++++ test/mip_test.c | 2 +- 8 files changed, 266 insertions(+), 56 deletions(-) create mode 100644 test/atcmd_test.c diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 2dca94bf..74487b7f 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -153,6 +153,54 @@ jobs: with: { fetch-depth: 2 } - run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test ${{ matrix.target }} IPV6=${{ matrix.ipv6 }} + atcmd: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + cc: [gcc, clang, g++, clang++] + name: ATcmd CC=${{ matrix.cc }} + env: + IPV6: 0 # makes no sense, shorten code + steps: + - uses: actions/checkout@v5 + with: { fetch-depth: 2 } + - uses: webfactory/ssh-agent@v0.10.0 + with: + ssh-private-key: ${{ secrets.HEALTH_TESTS_SSH_KEY }} + - run: make -C test atcmd_test CC=${{ matrix.cc }} > log + - if: success() || failure() + run: | + cat log + test/health.awk < log > json + scp -o "StrictHostKeyChecking=no" json "root@176.9.217.245:/data/downloads/health/ATcmd_${{ matrix.cc }}_$(date +"%Y%m%d").json" + atcmd89: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + target: [atcmd_vc98] + name: ATcmd C89 ${{ matrix.target }} + env: + IPV6: 0 # makes no sense, shorten code + steps: + - uses: actions/checkout@v5 + with: { fetch-depth: 2 } + - run: make -C test ${{ matrix.target }} + atcmdbe: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + target: [atcmd_s390] + name: ATcmd be ${{ matrix.target }} + env: + IPV6: 0 # makes no sense, shorten code + steps: + - uses: actions/checkout@v5 + with: { fetch-depth: 2 } + - run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test ${{ matrix.target }} + s390: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/on_demand.yml b/.github/workflows/on_demand.yml index 4fc23528..7e4f34ea 100644 --- a/.github/workflows/on_demand.yml +++ b/.github/workflows/on_demand.yml @@ -4,76 +4,47 @@ on: env: IPV6: 0 jobs: - mip89: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - target: [mip_vc98] - ipv6: [0, 1] - name: MIP C89 ${{ matrix.target }} IPV6=${{ matrix.ipv6 }} - steps: - - uses: actions/checkout@v5 - with: { fetch-depth: 2 } - - run: make -C test ${{ matrix.target }} IPV6=${{ matrix.ipv6 }} - mipbe: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - target: [mip_s390] - ipv6: [0, 1] - name: MIP be ${{ matrix.target }} IPV6=${{ matrix.ipv6 }} - steps: - - uses: actions/checkout@v5 - with: { fetch-depth: 2 } - - run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test ${{ matrix.target }} IPV6=${{ matrix.ipv6 }} - - l2: + atcmd: runs-on: ubuntu-latest strategy: fail-fast: false matrix: cc: [gcc, clang, g++, clang++] - target: [eth_test, ppp_test] - ipv6: [0, 1] - name: L2 ${{ matrix.target }} CC=${{ matrix.cc }} IPV6=${{ matrix.ipv6 }} + name: ATcmd CC=${{ matrix.cc }} steps: - uses: actions/checkout@v5 with: { fetch-depth: 2 } - uses: webfactory/ssh-agent@v0.10.0 with: ssh-private-key: ${{ secrets.HEALTH_TESTS_SSH_KEY }} - - run: make -C test ${{ matrix.target }} IPV6=${{ matrix.ipv6 }} CC=${{ matrix.cc }} > log + - run: make -C test atcmd_test CC=${{ matrix.cc }} > log - if: success() || failure() run: | cat log test/health.awk < log > json - scp -o "StrictHostKeyChecking=no" json "root@176.9.217.245:/data/downloads/health/${{ matrix.target }}_${{ matrix.cc }}_${{ matrix.ipv6 }}_$(date +"%Y%m%d").json" - l289: + scp -o "StrictHostKeyChecking=no" json "root@176.9.217.245:/data/downloads/health/atcmd_${{ matrix.cc }}_$(date +"%Y%m%d").json" + atcmd89: runs-on: ubuntu-latest strategy: fail-fast: false matrix: - target: [eth_vc98, ppp_vc98] - ipv6: [0, 1] - name: L2 C89 ${{ matrix.target }} IPV6=${{ matrix.ipv6 }} + target: [atcmd_vc98] + name: ATcmd C89 ${{ matrix.target }} steps: - uses: actions/checkout@v5 with: { fetch-depth: 2 } - - run: make -C test ${{ matrix.target }} IPV6=${{ matrix.ipv6 }} - l2be: + - run: make -C test ${{ matrix.target }} + atcmdbe: runs-on: ubuntu-latest strategy: fail-fast: false matrix: - target: [eth_s390, ppp_s390] - ipv6: [0, 1] - name: L2 be ${{ matrix.target }} IPV6=${{ matrix.ipv6 }} + target: [atcmd_s390] + name: ATcmd be ${{ matrix.target }} steps: - uses: actions/checkout@v5 with: { fetch-depth: 2 } - - run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test ${{ matrix.target }} IPV6=${{ matrix.ipv6 }} + - run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test ${{ matrix.target }} # macos: diff --git a/mongoose.c b/mongoose.c index 2663634c..14c14d08 100644 --- a/mongoose.c +++ b/mongoose.c @@ -8989,7 +8989,7 @@ static size_t tx_tcp_ctrlresp(struct mg_tcpip_if *ifp, struct pkt *pkt, } static size_t tx_tcp_rst(struct mg_tcpip_if *ifp, struct pkt *pkt, bool toack) { - return tx_tcp_ctrlresp(ifp, pkt, toack ? TH_RST : (TH_RST | TH_ACK), + return tx_tcp_ctrlresp(ifp, pkt, (uint8_t)(toack ? TH_RST : (TH_RST | TH_ACK)), toack ? pkt->tcp->ack : 0); } @@ -26018,7 +26018,9 @@ size_t mg_ws_wrap(struct mg_connection *c, size_t len, int op) { static size_t print_atcmd(void (*out)(char, void *), void *arg, va_list *ap) { struct mg_str s = va_arg(*ap, struct mg_str); - for (size_t i = 0; i < s.len; i++) out(s.buf[i] < 0x20 ? '.' : s.buf[i], arg); + size_t i; + for (i = 0; i < s.len; i++) + out((char) (s.buf[i] < 0x20 ? '.' : s.buf[i]), arg); return s.len; } @@ -26036,7 +26038,7 @@ static bool mg_atcmd_handle(struct mg_tcpip_if *ifp) { if (dd->script_index % 2 == 0) { // send AT command const char *cmd = dd->script[dd->script_index]; MG_DEBUG(("send AT[%d]: %M", dd->script_index, print_atcmd, mg_str(cmd))); - while (*cmd) dd->tx(dd->usart, *cmd++); + while (*cmd != '\0') dd->tx(dd->usart, (uint8_t) *cmd++); dd->script_index++; ifp->recv_queue.head = 0; } else { // check AT command response @@ -26052,7 +26054,7 @@ static bool mg_atcmd_handle(struct mg_tcpip_if *ifp) { return false; // FAIL } if ((c = dd->rx(dd->usart)) < 0) return false; // no data - q->buf[q->head++] = c; + q->buf[q->head++] = (char) c; if (mg_match(mg_str_n(q->buf, q->head), mg_str(expect), NULL)) { MG_DEBUG(("recv AT[%d]: %M", dd->script_index, print_atcmd, mg_str_n(q->buf, q->head))); @@ -26093,7 +26095,7 @@ static size_t mg_atcmd_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) { } } if (!dd->no_byte_stuff && !byte_unstuff(dd, &b)) continue; - q->buf[q->head++] = b; + q->buf[q->head++] = (char) b; } len = (q->head <= len) ? q->head : 0; memmove(buf, q->buf, len); @@ -26139,7 +26141,7 @@ struct mg_tcpip_driver mg_tcpip_driver_atcmd = {mg_atcmd_init, mg_atcmd_tx, mg_a static void byte_stuff(struct mg_tcpip_driver_atcmd_data *dd, uint8_t b) { if ((b < 0x20) || (b == MG_HDLC_ESC) || (b == MG_HDLC_FLAG)) { dd->tx(dd->usart, MG_HDLC_ESC); - dd->tx(dd->usart, b ^ 0x20); + dd->tx(dd->usart, (uint8_t) (b ^ 0x20)); } else { dd->tx(dd->usart, b); } diff --git a/src/drivers/at_cmd.c b/src/drivers/at_cmd.c index 1f413472..4cfc725b 100644 --- a/src/drivers/at_cmd.c +++ b/src/drivers/at_cmd.c @@ -9,7 +9,9 @@ static size_t print_atcmd(void (*out)(char, void *), void *arg, va_list *ap) { struct mg_str s = va_arg(*ap, struct mg_str); - for (size_t i = 0; i < s.len; i++) out(s.buf[i] < 0x20 ? '.' : s.buf[i], arg); + size_t i; + for (i = 0; i < s.len; i++) + out((char) (s.buf[i] < 0x20 ? '.' : s.buf[i]), arg); return s.len; } @@ -27,7 +29,7 @@ static bool mg_atcmd_handle(struct mg_tcpip_if *ifp) { if (dd->script_index % 2 == 0) { // send AT command const char *cmd = dd->script[dd->script_index]; MG_DEBUG(("send AT[%d]: %M", dd->script_index, print_atcmd, mg_str(cmd))); - while (*cmd) dd->tx(dd->usart, *cmd++); + while (*cmd != '\0') dd->tx(dd->usart, (uint8_t) *cmd++); dd->script_index++; ifp->recv_queue.head = 0; } else { // check AT command response @@ -43,7 +45,7 @@ static bool mg_atcmd_handle(struct mg_tcpip_if *ifp) { return false; // FAIL } if ((c = dd->rx(dd->usart)) < 0) return false; // no data - q->buf[q->head++] = c; + q->buf[q->head++] = (char) c; if (mg_match(mg_str_n(q->buf, q->head), mg_str(expect), NULL)) { MG_DEBUG(("recv AT[%d]: %M", dd->script_index, print_atcmd, mg_str_n(q->buf, q->head))); @@ -84,7 +86,7 @@ static size_t mg_atcmd_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) { } } if (!dd->no_byte_stuff && !byte_unstuff(dd, &b)) continue; - q->buf[q->head++] = b; + q->buf[q->head++] = (char) b; } len = (q->head <= len) ? q->head : 0; memmove(buf, q->buf, len); @@ -130,7 +132,7 @@ struct mg_tcpip_driver mg_tcpip_driver_atcmd = {mg_atcmd_init, mg_atcmd_tx, mg_a static void byte_stuff(struct mg_tcpip_driver_atcmd_data *dd, uint8_t b) { if ((b < 0x20) || (b == MG_HDLC_ESC) || (b == MG_HDLC_FLAG)) { dd->tx(dd->usart, MG_HDLC_ESC); - dd->tx(dd->usart, b ^ 0x20); + dd->tx(dd->usart, (uint8_t) (b ^ 0x20)); } else { dd->tx(dd->usart, b); } diff --git a/src/net_builtin.c b/src/net_builtin.c index c95a3d0a..3dfb330c 100644 --- a/src/net_builtin.c +++ b/src/net_builtin.c @@ -1278,7 +1278,7 @@ static size_t tx_tcp_ctrlresp(struct mg_tcpip_if *ifp, struct pkt *pkt, } static size_t tx_tcp_rst(struct mg_tcpip_if *ifp, struct pkt *pkt, bool toack) { - return tx_tcp_ctrlresp(ifp, pkt, toack ? TH_RST : (TH_RST | TH_ACK), + return tx_tcp_ctrlresp(ifp, pkt, (uint8_t)(toack ? TH_RST : (TH_RST | TH_ACK)), toack ? pkt->tcp->ack : 0); } diff --git a/test/Makefile b/test/Makefile index a748daee..3e93601c 100644 --- a/test/Makefile +++ b/test/Makefile @@ -29,7 +29,7 @@ COMMON_CFLAGS ?= $(C_WARN) $(WARN) $(INCS) $(DEFS) $(TFLAGS) -pthread CFLAGS ?= $(OPTS) $(ASAN) $(COMMON_CFLAGS) VALGRIND_CFLAGS ?= $(OPTS) $(COMMON_CFLAGS) VALGRIND_RUN ?= valgrind --tool=memcheck --gen-suppressions=all --leak-check=full --show-leak-kinds=all --leak-resolution=high --track-origins=yes --error-exitcode=1 --exit-on-first-error=yes --fair-sched=yes -.PHONY: tutorials mip_test eth_test ppp_test eth_vc98 ppp_vc98 eth_s390 ppp_s390 test valgrind +.PHONY: tutorials mip_test eth_test ppp_test atcmd_test eth_vc98 ppp_vc98 atcmd_vc98 eth_s390 ppp_s390 atcmd_s390 test valgrind ifeq "$(findstring ++,$(CC))" "" # $(CC) does not end with ++, i.e. we're using C. Apply C flags @@ -81,7 +81,7 @@ endif all: $(MAKE) -C ../tutorials/http/http-server -tall: mg_prefix unamalgamated test valgrind fuzz fuzz_tls vc98 vc17 vc22 mingw mingw++ arm armhf riscv s390 tutorials tutorials_win tutorials_embedded mip_test eth_test ppp_test mip_vc98 eth_vc98 ppp_vc98 eth_s390 ppp_s390 +tall: mg_prefix unamalgamated test valgrind fuzz fuzz_tls vc98 vc17 vc22 mingw mingw++ arm armhf riscv s390 tutorials tutorials_win tutorials_embedded mip_test eth_test ppp_test atcmd_test mip_vc98 eth_vc98 ppp_vc98 atcmd_vc98 eth_s390 ppp_s390 atcmd_s390 mip_test: mip_test.c mongoose.c mongoose.h packed_fs.c Makefile $(CC) mip_test.c packed_fs.c $(CFLAGS) $(LDFLAGS) -o $@ @@ -95,6 +95,10 @@ ppp_test: ppp_test.c mongoose.c mongoose.h Makefile $(CC) ppp_test.c $(CFLAGS) $(LDFLAGS) -o $@ ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./$@ +atcmd_test: atcmd_test.c mongoose.c mongoose.h Makefile + $(CC) atcmd_test.c $(CFLAGS) $(LDFLAGS) -o $@ + ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./$@ + mip_tap_test: mip_x_test.c mip_tap_test.c mongoose.c mongoose.h packed_fs.c Makefile tls_multirec/server $(CC) mip_tap_test.c packed_fs.c $(CFLAGS) $(LDFLAGS) -o $@ ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./$@ @@ -120,6 +124,10 @@ ppp_vc98: ppp_test.c driver_mock.c mongoose.c mongoose.h Makefile $(DOCKER) mdashnet/vc98 wine cl ppp_test.c $(VCFLAGS) $(DEFS) $(TFLAGS) /Fe$@.exe $(DOCKER) -e WINEPREFIX=/tmp/wineprefix mdashnet/vc98 wine $@.exe +atcmd_vc98: atcmd_test.c mongoose.c mongoose.h Makefile + $(DOCKER) mdashnet/vc98 wine cl atcmd_test.c $(VCFLAGS) $(DEFS) $(TFLAGS) /Fe$@.exe + $(DOCKER) -e WINEPREFIX=/tmp/wineprefix mdashnet/vc98 wine $@.exe + packed_fs.c: Makefile data/ssi.h fuzz.c data/a.txt data/ca.pem certs/ca.crt certs/server.crt certs/server.key $(CC) $(CFLAGS) pack.c -o pack $(RUN) ./pack Makefile data/ssi.h fuzz.c data/a.txt data/range.txt data/ca.pem certs/ca.crt certs/server.crt certs/server.key certs/client.key certs/client.crt > $@ @@ -223,6 +231,11 @@ ppp_s390: CC = $(DOCKER) mdashnet/s390 cc ppp_s390: RUN = $(DOCKER) --init mdashnet/s390 ppp_s390: ppp_test +atcmd_s390: ASAN= +atcmd_s390: CC = $(DOCKER) mdashnet/s390 cc +atcmd_s390: RUN = $(DOCKER) --init mdashnet/s390 +atcmd_s390: atcmd_test + mip_port_s390: ASAN= mip_port_s390: IPV6=0 # This test requires curl, not present in this image @@ -241,6 +254,7 @@ riscv: mongoose.h $(SRCS) mip_test.c $(DOCKER) mdashnet/riscv riscv-none-elf-gcc -march=rv32imc -mabi=ilp32 $(SRCS) $(OPTS) $(WARN) $(INCS) $(DEFS) $(TFLAGS) -o unit_test $(DOCKER) mdashnet/riscv riscv-none-elf-gcc -march=rv32imc -mabi=ilp32 mip_test.c packed_fs.c $(OPTS) $(WARN) $(INCS) $(DEFS) $(TFLAGS) -o mip_test +vc98: IPV6=0 # VC98 does NOT support IPV6 sockets vc98: Makefile mongoose.h $(SRCS) $(DOCKER) mdashnet/vc98 wine cl $(SRCS) $(VCFLAGS) $(DEFS) $(TFLAGS) /Fe$@.exe $(DOCKER) -e WINEPREFIX=/tmp/wineprefix mdashnet/vc98 wine $@.exe diff --git a/test/atcmd_test.c b/test/atcmd_test.c new file mode 100644 index 00000000..9ef14ffd --- /dev/null +++ b/test/atcmd_test.c @@ -0,0 +1,173 @@ +#define MG_ENABLE_TCPIP 1 +#define MG_ENABLE_TCPIP_DRIVER_INIT 0 +#define MG_ENABLE_DRIVER_ATCMD 1 + +#include "mongoose.c" + +static int s_num_tests = 0; +static bool s_error = false; + +#ifdef NO_ABORT +static int s_abort = 0; +#define ABORT() ++s_abort, s_error = true +#else +#ifdef NO_SLEEP_ABORT +#define ABORT() abort() +#else +#define ABORT() \ + sleep(2); /* 2s, GH print reason */ \ + abort(); +#endif +#endif + +#define ASSERT(expr) \ + do { \ + s_num_tests++; \ + if (!(expr)) { \ + printf("FAILURE %s:%d: %s\n", __FILE__, __LINE__, #expr); \ + fflush(stdout); \ + ABORT(); \ + } \ + } while (0) + +struct uart_mock { + uint8_t rx[2048]; + uint8_t tx[256]; + size_t rx_len; + size_t rx_pos; + size_t tx_len; + int reset_count; +}; + +struct test_ctx { + struct mg_tcpip_if ifp; + struct mg_tcpip_driver_atcmd_data dd; + struct uart_mock mock; + char qbuf[1506]; +}; + +static void mock_reset(void *arg) { + struct uart_mock *mock = (struct uart_mock *) arg; + mock->reset_count++; +} + +static void mock_tx(void *arg, uint8_t b) { + struct uart_mock *mock = (struct uart_mock *) arg; + ASSERT(mock->tx_len < sizeof(mock->tx)); + mock->tx[mock->tx_len++] = b; +} + +static int mock_rx(void *arg) { + struct uart_mock *mock = (struct uart_mock *) arg; + return mock->rx_pos < mock->rx_len ? mock->rx[mock->rx_pos++] : -1; +} + +static void mock_rx_add(struct uart_mock *mock, const void *buf, size_t len) { + ASSERT(mock->rx_len + len <= sizeof(mock->rx)); + memcpy(mock->rx + mock->rx_len, buf, len); + mock->rx_len += len; +} + +static void init_if(struct test_ctx *ctx) { + memset(ctx, 0, sizeof(*ctx)); + ctx->ifp.driver_data = &ctx->dd; + ASSERT(mg_atcmd_init(&ctx->ifp) == true); + ASSERT(ctx->ifp.recv_queue.size <= sizeof(ctx->qbuf)); + ctx->ifp.recv_queue.buf = ctx->qbuf; +} + +static void reset_if(struct test_ctx *ctx, const char **script, + bool no_byte_stuff) { + memset(&ctx->dd, 0, sizeof(ctx->dd)); + memset(&ctx->mock, 0, sizeof(ctx->mock)); + ctx->ifp.driver_data = &ctx->dd; + ctx->ifp.recv_queue.head = 0; + ctx->ifp.recv_queue.tail = 0; + ctx->dd.usart = &ctx->mock; + ctx->dd.reset = mock_reset; + ctx->dd.tx = mock_tx; + ctx->dd.rx = mock_rx; + ctx->dd.script = script; + ctx->dd.no_byte_stuff = no_byte_stuff; +} + +#define DASHBOARD(x) \ + printf("HEALTH_DASHBOARD\t\"%s\": %s,\n", x, s_error ? "false" : "true") + +int main(void) { + struct test_ctx ctx; + init_if(&ctx); + + s_error = false; + { // Send AT command, receive OK + static const char *script[] = {"AT\r\n", "\r\nOK\r\n", NULL}; + static const uint8_t at[] = {'A', 'T', '\r', '\n'}; + static const uint8_t ok[] = {'\r', '\n', 'O', 'K', '\r', '\n'}; + reset_if(&ctx, script, false); + + ASSERT(mg_atcmd_poll(&ctx.ifp, true) == false); + ASSERT(ctx.mock.tx_len == sizeof(at)); + ASSERT(memcmp(ctx.mock.tx, at, sizeof(at)) == 0); + ASSERT(ctx.dd.link == false); + mock_rx_add(&ctx.mock, ok, sizeof(ok)); + ASSERT(mg_atcmd_poll(&ctx.ifp, true) == true); + ASSERT(ctx.dd.link == true); + ASSERT(ctx.dd.script_index == -1); + ASSERT(ctx.mock.reset_count == 0); + } + DASHBOARD("atcmd"); + + s_error = false; + { // HDLC byte stuffing and unstuffing + static const uint8_t payload[] = {0x00, 0x01, 'A', 0x7d, 0x7e, 0x20}; + static const uint8_t frame[] = {0x7e, 0x7d, 0x20, 0x7d, 0x21, 'A', + 0x7d, 0x5d, 0x7d, 0x5e, 0x20, 0x7e}; + uint8_t buf[sizeof(payload)]; + reset_if(&ctx, NULL, false); + ASSERT(mg_atcmd_poll(&ctx.ifp, true) == true); + + ASSERT(mg_atcmd_tx(payload, sizeof(payload), &ctx.ifp) == sizeof(payload)); + ASSERT(ctx.mock.tx_len == sizeof(frame)); + ASSERT(memcmp(ctx.mock.tx, frame, sizeof(frame)) == 0); + + mock_rx_add(&ctx.mock, frame, sizeof(frame)); + ASSERT(mg_atcmd_rx(buf, sizeof(buf), &ctx.ifp) == sizeof(payload)); + ASSERT(memcmp(buf, payload, sizeof(payload)) == 0); + } + { // HDLC framing with byte stuffing disabled + static const uint8_t payload[] = {0x00, 0x01, 'A', 0x7d, 0x20}; + static const uint8_t frame[] = {0x7e, 0x00, 0x01, 'A', 0x7d, 0x20, 0x7e}; + uint8_t buf[sizeof(payload)]; + reset_if(&ctx, NULL, true); + ASSERT(mg_atcmd_poll(&ctx.ifp, true) == true); + + ASSERT(mg_atcmd_tx(payload, sizeof(payload), &ctx.ifp) == sizeof(payload)); + ASSERT(ctx.mock.tx_len == sizeof(frame)); + ASSERT(memcmp(ctx.mock.tx, frame, sizeof(frame)) == 0); + + mock_rx_add(&ctx.mock, frame, sizeof(frame)); + ASSERT(mg_atcmd_rx(buf, sizeof(buf), &ctx.ifp) == sizeof(payload)); + ASSERT(memcmp(buf, payload, sizeof(payload)) == 0); + } + { // Oversized frame is rejected + uint8_t buf[8]; + reset_if(&ctx, NULL, true); + ASSERT(mg_atcmd_poll(&ctx.ifp, true) == true); + + mock_rx_add(&ctx.mock, "\x7e", 1); + memset(ctx.mock.rx + ctx.mock.rx_len, 'A', sizeof(buf) + 1); + ctx.mock.rx_len += sizeof(buf) + 1; + mock_rx_add(&ctx.mock, "\x7e", 1); + + ASSERT(mg_atcmd_rx(buf, sizeof(buf), &ctx.ifp) == 0); + } + printf("HEALTH_DASHBOARD\t\"hdlc\": %s\n", + s_error ? "false" : "true"); + +#ifdef NO_ABORT + if (s_abort != 0) return EXIT_FAILURE; +#endif + + printf("SUCCESS. Total tests: %d\n", s_num_tests); + return EXIT_SUCCESS; +} diff --git a/test/mip_test.c b/test/mip_test.c index 908e4b8f..ba67b044 100644 --- a/test/mip_test.c +++ b/test/mip_test.c @@ -306,7 +306,7 @@ static void init_tests(struct mg_mgr *mgr, struct eth *e, struct ipp *ipp, // setting the Ethernet header memset(e, 0, sizeof(*e)); memcpy(e->dst, mif->mac, 6 * sizeof(uint8_t)); - e->type = mg_htons(ipp->ip4 != NULL ? 0x800 : 0x86dd); + e->type = mg_htons((uint16_t)(ipp->ip4 != NULL ? 0x800 : 0x86dd)); // setting the IP header #if MG_ENABLE_IPV6