The issue started when I wanted to use the W801 to detect a GPIO level change and then send a bot notification message through Telegram. However, when calling my own Telegram API reverse proxy (caddy v2.6.4 h1:2hwYqiRwk1tf3VruhMpLcYTg+11fCdr8S3jhNAdnPy8=), the serial log showed the SSL handshake error 0x7780 mentioned in the title.
The code was directly copied from the SDK example demo wm_https_demo.c. The error occurred during the handshake, specifically when calling HTTPWrapperSSLConnect, as shown:
wm_printf("step 1: ssl connect to...\r\n");
ret = HTTPWrapperSSLConnect(&ssl_p, fd, (const struct sockaddr *)&server, sizeof(server), HTTPS_DEMO_SERVER);
if (ret < 0)
{
wm_printf("https connect error\r\n");
close(fd);
break;
}
At first, the serial output only showed step 1: ssl connect to…, then immediately the 0x7780 error, followed by https connect error and request failure. After studying the mbedtls library used internally, I found that more detailed debug logs were available. You need to enable the macro define MBEDTLS_DEBUG_C in SDK src/app/mbedtls/include/mbedtls/config.h (and make sure the makefile project rebuilds the lib target. If using my previous CLion IDE setup, select the lib configuration and rebuild). After enabling it, you can see error messages similar to those mentioned here: https://forums.mbed.com/t/error-0x7780-during-handshake/6883
ssl_tls.c:6754: |2| => handshake
ssl_cli.c:3384: |2| client state: 0
ssl_tls.c:2471: |2| => flush output
ssl_tls.c:2483: |2| <= flush output
ssl_cli.c:3384: |2| client state: 1
ssl_tls.c:2471: |2| => flush output
ssl_tls.c:2483: |2| <= flush output
ssl_cli.c:0770: |2| => write client hello
ssl_cli.c:0808: |3| client hello, max version: [3:3]
ssl_cli.c:0703: |3| client hello, current time: 3
ssl_cli.c:0817: |3| dumping 'client hello, random bytes' (32 bytes)
ssl_cli.c:0817: |3| 0000: 00 00 00 00 76 a0 12 da 58 6f 48 3c 14 72 c3 aa ....v...XoH<.r..
ssl_cli.c:0817: |3| 0010: 22 ac 98 8a 5b 1b 3c 77 9f cb 78 19 16 55 0d 6c "...[.<w..x..U.l
ssl_cli.c:0870: |3| client hello, session id len.: 0
ssl_cli.c:0871: |3| dumping 'client hello, session id' (0 bytes)
ssl_cli.c:0918: |3| client hello, add ciphersuite: c02c
ssl_cli.c:0918: |3| client hello, add ciphersuite: c02b
ssl_cli.c:0925: |3| client hello, got 2 ciphersuites (excluding SCSVs)
ssl_cli.c:0934: |3| adding EMPTY_RENEGOTIATION_INFO_SCSV
ssl_cli.c:0983: |3| client hello, compress len.: 1
ssl_cli.c:0985: |3| client hello, compress alg.: 0
ssl_cli.c:0186: |3| client hello, adding signature_algorithms extension
ssl_cli.c:0271: |3| client hello, adding supported_elliptic_curves extension
ssl_cli.c:0336: |3| client hello, adding supported_point_formats extension
ssl_cli.c:1059: |3| client hello, total extension length: 30
ssl_tls.c:2764: |2| => write record
ssl_tls.c:2910: |3| output record: msgtype = 22, version = [3:1], msglen = 81
ssl_tls.c:2471: |2| => flush output
ssl_tls.c:2490: |2| message length: 86, out_left: 86
ssl_tls.c:2496: |2| ssl->f_send() returned 86 (-0xffffffaa)
ssl_tls.c:2523: |2| <= flush output
ssl_tls.c:2922: |2| <= write record
ssl_cli.c:1085: |2| <= write client hello
ssl_cli.c:3384: |2| client state: 2
ssl_tls.c:2471: |2| => flush output
ssl_tls.c:2483: |2| <= flush output
ssl_cli.c:1478: |2| => parse server hello
ssl_tls.c:3809: |2| => read record
ssl_tls.c:2252: |2| => fetch input
ssl_tls.c:2413: |2| in_left: 0, nb_want: 5
ssl_tls.c:2437: |2| in_left: 0, nb_want: 5
ssl_tls.c:2438: |2| ssl->f_recv(_timeout)() returned 5 (-0xfffffffb)
ssl_tls.c:2458: |2| <= fetch input
ssl_tls.c:3561: |3| input record: msgtype = 21, version = [3:3], msglen = 2
ssl_tls.c:2252: |2| => fetch input
ssl_tls.c:2413: |2| in_left: 5, nb_want: 7
ssl_tls.c:2437: |2| in_left: 5, nb_want: 7
ssl_tls.c:2438: |2| ssl->f_recv(_timeout)() returned 2 (-0xfffffffe)
ssl_tls.c:2458: |2| <= fetch input
ssl_tls.c:4100: |2| got an alert message, type: [2:80]
ssl_tls.c:4108: |1| is a fatal alert message (msg 80)
ssl_tls.c:3831: |1| mbedtls_ssl_handle_message_type() returned -30592 (-0x7780)
ssl_cli.c:1485: |1| mbedtls_ssl_read_record() returned -30592 (-0x7780)
ssl_tls.c:6764: |2| <= handshake
ssl_tls.c:7542: |2| => free
ssl_tls.c:7607: |2| <= free
ssl_tls.c:6754: |2| => handshake
ssl_cli.c:3384: |2| client state: 0
ssl_tls.c:2471: |2| => flush output
ssl_tls.c:2483: |2| <= flush output
ssl_cli.c:3384: |2| client state: 1
ssl_tls.c:2471: |2| => flush output
ssl_tls.c:2483: |2| <= flush output
ssl_cli.c:0770: |2| => write client hello
ssl_cli.c:0808: |3| client hello, max version: [3:3]
ssl_cli.c:0703: |3| client hello, current time: 3
ssl_cli.c:0817: |3| dumping 'client hello, random bytes' (32 bytes)
ssl_cli.c:0817: |3| 0000: 00 00 00 00 11 0f 97 2f f9 d5 13 21 14 1a 34 a1 ......./...!..4.
ssl_cli.c:0817: |3| 0010: a7 a3 94 6e e3 14 ab 22 98 15 53 98 b8 89 49 92 ...n..."..S...I.
ssl_cli.c:0870: |3| client hello, session id len.: 0
ssl_cli.c:0871: |3| dumping 'client hello, session id' (0 bytes)
ssl_cli.c:0918: |3| client hello, add ciphersuite: c02c
ssl_cli.c:0918: |3| client hello, add ciphersuite: c02b
ssl_cli.c:0925: |3| client hello, got 2 ciphersuites (excluding SCSVs)
ssl_cli.c:0934: |3| adding EMPTY_RENEGOTIATION_INFO_SCSV
ssl_cli.c:0983: |3| client hello, compress len.: 1
ssl_cli.c:0985: |3| client hello, compress alg.: 0
ssl_cli.c:0186: |3| client hello, adding signature_algorithms extension
ssl_cli.c:0271: |3| client hello, adding supported_elliptic_curves extension
ssl_cli.c:0336: |3| client hello, adding supported_point_formats extension
ssl_cli.c:1059: |3| client hello, total extension length: 30
ssl_tls.c:2764: |2| => write record
ssl_tls.c:2910: |3| output record: msgtype = 22, version = [3:1], msglen = 81
ssl_tls.c:2913: |4| dumping 'output record sent to network' (86 bytes)
ssl_tls.c:2913: |4| 0000: 16 03 01 00 51 01 00 00 4d 03 03 00 00 00 00 11 ....Q...M.......
ssl_tls.c:2913: |4| 0010: 0f 97 2f f9 d5 13 21 14 1a 34 a1 a7 a3 94 6e e3 ../...!..4....n.
ssl_tls.c:2913: |4| 0020: 14 ab 22 98 15 53 98 b8 89 49 92 00 00 06 c0 2c .."..S...I.....,
ssl_tls.c:2913: |4| 0030: c0 2b 00 ff 01 00 00 1e 00 0d 00 0a 00 08 06 03 .+..............
ssl_tls.c:2913: |4| 0040: 05 03 04 03 03 03 00 0a 00 06 00 04 00 18 00 17 ................
ssl_tls.c:2913: |4| 0050: 00 0b 00 02 01 00 ......
ssl_tls.c:2471: |2| => flush output
ssl_tls.c:2490: |2| message length: 86, out_left: 86
ssl_tls.c:2496: |2| ssl->f_send() returned 86 (-0xffffffaa)
ssl_tls.c:2523: |2| <= flush output
ssl_tls.c:2922: |2| <= write record
ssl_cli.c:1085: |2| <= write client hello
ssl_cli.c:3384: |2| client state: 2
ssl_tls.c:2471: |2| => flush output
ssl_tls.c:2483: |2| <= flush output
ssl_cli.c:1478: |2| => parse server hello
ssl_tls.c:3809: |2| => read record
ssl_tls.c:2252: |2| => fetch input
ssl_tls.c:2413: |2| in_left: 0, nb_want: 5
ssl_tls.c:2437: |2| in_left: 0, nb_want: 5
ssl_tls.c:2438: |2| ssl->f_recv(_timeout)() returned 5 (-0xfffffffb)
ssl_tls.c:2458: |2| <= fetch input
ssl_tls.c:3552: |4| dumping 'input record header' (5 bytes)
ssl_tls.c:3552: |4| 0000: 15 03 03 00 02 .....
ssl_tls.c:3561: |3| input record: msgtype = 21, version = [3:3], msglen = 2
ssl_tls.c:2252: |2| => fetch input
ssl_tls.c:2413: |2| in_left: 5, nb_want: 7
ssl_tls.c:2437: |2| in_left: 5, nb_want: 7
ssl_tls.c:2438: |2| ssl->f_recv(_timeout)() returned 2 (-0xfffffffe)
ssl_tls.c:2458: |2| <= fetch input
ssl_tls.c:3738: |4| dumping 'input record from network' (7 bytes)
ssl_tls.c:3738: |4| 0000: 15 03 03 00 02 02 50 ......P
ssl_tls.c:4100: |2| got an alert message, type: [2:80]
ssl_tls.c:4108: |1| is a fatal alert message (msg 80)
ssl_tls.c:3831: |1| mbedtls_ssl_handle_message_type() returned -30592 (-0x7780)
ssl_cli.c:1485: |1| mbedtls_ssl_read_record() returned -30592 (-0x7780)
ssl_tls.c:6764: |2| <= handshake
ssl_tls.c:7542: |2| => free
ssl_tls.c:7607: |2| <= free
Based on the forum information, the issue seemed to be caused by mismatched cipher suites during the SSL handshake. I then tested the SDK demo by requestingwww.tencent.com:443,and it worked correctly. This made me suspect that the caddy version was too new, with stricter TLS requirements, making it incompatible with older versions. I then tried connecting directly to api.telegram.org, and it produced the same 7780 error.
Next, I started studying the SSL handshake mechanism and found a very useful website: https://www.ssllabs.com/ssltest. This site can scan the target HTTPS server for supported TLS versions and cipher suites (cipher suites like RSA, MD5, etc., which can also be found in mbedtls source src/app/mbedtls/include/mbedtls/ssl_ciphersuites.h). It also shows handshake test results for common clients. I scanned Tencent, then Telegram, and my caddy reverse proxy. I found that Tencent supports many TLS versions including 1.0 and 1.1, while Telegram and caddy v2 only support TLS 1.2 and above (which also gives them high A+ ratings). Here is Telegram’s result:

It shows that only TLS 1.2 and above are allowed, and the permitted cipher suites are limited. Initially I thought the W801 SDK’s mbedtls version was too old and did not support TLS 1.2. But checking the SDK, I found it uses version 2.7.10 (src/app/mbedtls/include/mbedtls/version.h). Looking at the key code, TLS 1.2 is supported. To confirm, I downloaded the official mbedtls 2.7.10 source from GitHub and tested it on Windows (without CKLink, and debugging on the MCU would be inconvenient anyway). Version 2.7.10 is old and still includes a VS2010 project, but the code compiled fine after upgrading to VS2022. Running the ssl_client1.c handshake test program, I was surprised to find that both Telegram and my caddy worked fine. This made things clearer. I used a diff tool to compare the W801 SDK’s mbedtls with the official version. After a long time comparing and testing, I found that in src/app/mbedtls/include/mbedtls/config.h, many suites and features were disabled, likely due to embedded hardware resource limitations. After enabling define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED, the Telegram API handshake worked and HTTP requests succeeded. I thought the issue was solved, but testing my caddy still produced 7780.
After more comparison and testing, I finally discovered that the caddy handshake failure was not due to cipher suite mismatch, but because of this: define MBEDTLS_SSL_SERVER_NAME_INDICATION. In my caddy reverse proxy configuration, I had written:
"tls_connection_policies": [{
"match": {
"sni": [
"xxx.xxx.com"
]
}
}],
This caused the server to enable SNI verification. Since the W801 SDK’s mbedtls did not enable SNI, the handshake did not include a valid SNI field, so caddy could not match the request, resulting in the 7780 handshake error. After enabling the define mentioned above, the issue was resolved.
PS: One more note. In the W801 SDK, the Makefile builds the main program and the dependent libraries separately. This means that modifying mbedtls source code and running make will not automatically rebuild the library. You must manually run make lib to trigger the rebuild, then run make again. The generated firmware fls will then include the updated mbedtls.
博主友情提示:
如您在评论中需要提及如QQ号、电子邮件地址或其他隐私敏感信息,欢迎使用>>博主专用加密工具v3<<处理后发布,原文只有博主可以看到。