From 1daf7f1ae23e8e2447a15504b762b83bc9ab4e3c Mon Sep 17 00:00:00 2001 From: Takashi Kojo Date: Mon, 21 Aug 2023 10:25:32 +0900 Subject: [PATCH] Polling based TCP Client --- RPi-Pico/CMakeLists.txt | 66 ++- RPi-Pico/config/lwipopts.h | 31 ++ RPi-Pico/config/lwipopts_examples_common.h | 89 ++++ RPi-Pico/config/user_settings.h | 542 +++++++++++++++++++++ RPi-Pico/config/user_settings_asm.h | 0 RPi-Pico/include/wolf/common.h | 23 + RPi-Pico/include/wolf/tcp.h | 49 ++ RPi-Pico/include/wolf/wifi.h | 23 + RPi-Pico/src/tcp.c | 241 +++++++++ RPi-Pico/src/tcpClient_main.c | 115 +++++ RPi-Pico/src/wifi.c | 54 ++ RPi-Pico/src/wifi_main.c | 48 ++ 12 files changed, 1278 insertions(+), 3 deletions(-) create mode 100644 RPi-Pico/config/lwipopts.h create mode 100644 RPi-Pico/config/lwipopts_examples_common.h create mode 100644 RPi-Pico/config/user_settings.h create mode 100644 RPi-Pico/config/user_settings_asm.h create mode 100644 RPi-Pico/include/wolf/common.h create mode 100644 RPi-Pico/include/wolf/tcp.h create mode 100644 RPi-Pico/include/wolf/wifi.h create mode 100644 RPi-Pico/src/tcp.c create mode 100644 RPi-Pico/src/tcpClient_main.c create mode 100644 RPi-Pico/src/wifi.c create mode 100644 RPi-Pico/src/wifi_main.c diff --git a/RPi-Pico/CMakeLists.txt b/RPi-Pico/CMakeLists.txt index 7dfd7d99..097ce17e 100644 --- a/RPi-Pico/CMakeLists.txt +++ b/RPi-Pico/CMakeLists.txt @@ -58,7 +58,7 @@ target_link_libraries(benchmark ) pico_add_extra_outputs(benchmark) -if(1) +if(0) add_executable(TCPclient src/blink.c # src/TCPclient.c @@ -73,7 +73,9 @@ if(1) # CYW43_NETUTILS # PICO_CYW43_ARCH_FREERTOS - TEST_TCP_SERVER_IP="192.168.11.28" + TEST_TCP_SERVER_IP=\"${TEST_TCP_SERVER_IP}\" + WIFI_SSID=\"${WIFI_SSID}\" + WIFI_PASSWORD=\"${WIFI_PASSWORD}\" PICO_CYW43_ARCH_POLL NO_SYS=1 @@ -107,4 +109,62 @@ if(1) ) pico_add_extra_outputs(TCPclient) -endif() \ No newline at end of file +endif() + +add_executable(Wifi + src/blink.c + src/wifi.c + src/Wifi_main.c +) + +# enable usb output, disable uart output +pico_enable_stdio_usb(Wifi 1) +pico_enable_stdio_uart(Wifi 0) + +target_compile_definitions(Wifi PRIVATE + WIFI_SSID=\"${WIFI_SSID}\" + WIFI_PASSWORD=\"${WIFI_PASSWORD}\" + PICO_CYW43_ARCH_POLL + NO_SYS=1 +) + +target_link_libraries(Wifi + pico_stdlib + pico_rand + pico_lwip + pico_cyw43_arch + pico_lwip_nosys + pico_async_context_poll +) + +pico_add_extra_outputs(Wifi) + +add_executable(tcp_Client + src/blink.c + src/wifi.c + src/tcp.c + src/tcpClient_main.c +) + +# enable usb output, disable uart output +pico_enable_stdio_usb(tcp_Client 1) +pico_enable_stdio_uart(tcp_Client 0) + +target_compile_definitions(tcp_Client PRIVATE + WIFI_SSID=\"${WIFI_SSID}\" + WIFI_PASSWORD=\"${WIFI_PASSWORD}\" + TEST_TCP_SERVER_IP=\"${TEST_TCP_SERVER_IP}\" + PICO_CYW43_ARCH_POLL + NO_SYS=1 +) + +target_link_libraries(tcp_Client + pico_stdlib + pico_rand + pico_lwip + pico_cyw43_arch + pico_lwip_nosys + pico_async_context_poll +) + +pico_add_extra_outputs(tcp_Client) \ No newline at end of file diff --git a/RPi-Pico/config/lwipopts.h b/RPi-Pico/config/lwipopts.h new file mode 100644 index 00000000..b3770562 --- /dev/null +++ b/RPi-Pico/config/lwipopts.h @@ -0,0 +1,31 @@ +#ifndef _LWIPOPTS_H +#define _LWIPOPTS_H + +// Generally you would define your own explicit list of lwIP options +// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html) +// +// This example uses a common include to avoid repetition +#include "lwipopts_examples_common.h" + +#if !NO_SYS +#define TCPIP_THREAD_STACKSIZE 1024 +#define DEFAULT_THREAD_STACKSIZE 1024 +#define DEFAULT_RAW_RECVMBOX_SIZE 8 +#define TCPIP_MBOX_SIZE 8 +#define LWIP_TIMEVAL_PRIVATE 0 + +// not necessary, can be done either way +#define LWIP_TCPIP_CORE_LOCKING_INPUT 1 + +// ping_thread sets socket receive timeout, so enable this feature +#define LWIP_SO_RCVTIMEO 1 + +#endif + + +#define LWIP_TIMEVAL_PRIVATE 0 +#define LWIP_MPU_COMPATIBLE 0 +#define LWIP_PROVIDE_ERRNO +#define LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX 1 + +#endif diff --git a/RPi-Pico/config/lwipopts_examples_common.h b/RPi-Pico/config/lwipopts_examples_common.h new file mode 100644 index 00000000..891a5e38 --- /dev/null +++ b/RPi-Pico/config/lwipopts_examples_common.h @@ -0,0 +1,89 @@ +#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H +#define _LWIPOPTS_EXAMPLE_COMMONH_H + +// Common settings used in most of the pico_w examples +// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details) + +// allow override in some examples +#ifndef NO_SYS +#define NO_SYS 0 +#endif +// allow override in some examples +#ifndef LWIP_SOCKET +#define LWIP_SOCKET 0 +#endif +#if PICO_CYW43_ARCH_POLL +#define MEM_LIBC_MALLOC 1 +#else +// MEM_LIBC_MALLOC is incompatible with non polling versions +#define MEM_LIBC_MALLOC 0 +#endif +#define MEM_ALIGNMENT 4 +#define MEM_SIZE 4000 +#define MEMP_NUM_TCP_SEG 32 +#define MEMP_NUM_ARP_QUEUE 10 +#define PBUF_POOL_SIZE 24 +#define LWIP_ARP 1 +#define LWIP_ETHERNET 1 +#define LWIP_ICMP 1 +#define LWIP_RAW 1 +#define TCP_WND (8 * TCP_MSS) +#define TCP_MSS 1460 +#define TCP_SND_BUF (8 * TCP_MSS) +#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS)) +#define LWIP_NETIF_STATUS_CALLBACK 1 +#define LWIP_NETIF_LINK_CALLBACK 1 +#define LWIP_NETIF_HOSTNAME 1 +#define LWIP_NETCONN 0 +#define MEM_STATS 0 +#define SYS_STATS 0 +#define MEMP_STATS 0 +#define LINK_STATS 0 +// #define ETH_PAD_SIZE 2 +#define LWIP_CHKSUM_ALGORITHM 3 +#define LWIP_DHCP 1 +#define LWIP_IPV4 1 +#define LWIP_TCP 1 +#define LWIP_UDP 1 +#define LWIP_DNS 1 +#define LWIP_TCP_KEEPALIVE 1 +#define LWIP_NETIF_TX_SINGLE_PBUF 1 +#define DHCP_DOES_ARP_CHECK 0 +#define LWIP_DHCP_DOES_ACD_CHECK 0 + +#ifndef NDEBUG +#define LWIP_DEBUG 1 +#define LWIP_STATS 1 +#define LWIP_STATS_DISPLAY 1 +#endif + +#define ETHARP_DEBUG LWIP_DBG_OFF +#define NETIF_DEBUG LWIP_DBG_OFF +#define PBUF_DEBUG LWIP_DBG_OFF +#define API_LIB_DEBUG LWIP_DBG_OFF +#define API_MSG_DEBUG LWIP_DBG_OFF +#define SOCKETS_DEBUG LWIP_DBG_OFF +#define ICMP_DEBUG LWIP_DBG_OFF +#define INET_DEBUG LWIP_DBG_OFF +#define IP_DEBUG LWIP_DBG_OFF +#define IP_REASS_DEBUG LWIP_DBG_OFF +#define RAW_DEBUG LWIP_DBG_OFF +#define MEM_DEBUG LWIP_DBG_OFF +#define MEMP_DEBUG LWIP_DBG_OFF +#define SYS_DEBUG LWIP_DBG_OFF +#define TCP_DEBUG LWIP_DBG_OFF +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#define TCP_WND_DEBUG LWIP_DBG_OFF +#define TCP_FR_DEBUG LWIP_DBG_OFF +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#define TCP_RST_DEBUG LWIP_DBG_OFF +#define UDP_DEBUG LWIP_DBG_OFF +#define TCPIP_DEBUG LWIP_DBG_OFF +#define PPP_DEBUG LWIP_DBG_OFF +#define SLIP_DEBUG LWIP_DBG_OFF +#define DHCP_DEBUG LWIP_DBG_OFF + +#endif /* __LWIPOPTS_H__ */ diff --git a/RPi-Pico/config/user_settings.h b/RPi-Pico/config/user_settings.h new file mode 100644 index 00000000..d43aec23 --- /dev/null +++ b/RPi-Pico/config/user_settings.h @@ -0,0 +1,542 @@ +/* user_settings.h + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* Example wolfSSL user settings with #if 0/1 gates to enable/disable algorithms and features. + * This file is included with wolfssl/wolfcrypt/settings.h when WOLFSSL_USER_SETTINGS is defined. + * Based on IDE/GCC-ARM/Headers/user_settings.h + */ + +#ifndef WOLFSSL_USER_SETTINGS_H +#define WOLFSSL_USER_SETTINGS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define TARGET_EMBEDDED + +/* ------------------------------------------------------------------------- */ +/* Platform */ +/* ------------------------------------------------------------------------- */ +#define WOLFSSL_GENERAL_ALIGNMENT 4 +#define SIZEOF_LONG_LONG 8 +#if 0 +#define NO_64BIT /* disable use of 64-bit variables */ +#endif + +#ifdef TARGET_EMBEDDED +/* disable mutex locking */ +#define SINGLE_THREADED + +/* reduce stack use. For variables over 100 bytes allocate from heap */ +#define WOLFSSL_SMALL_STACK + +/* Disable the built-in socket support and use the IO callbacks. + * Set IO callbacks with wolfSSL_CTX_SetIORecv/wolfSSL_CTX_SetIOSend + */ +#define WOLFSSL_USER_IO +#endif + +/* ------------------------------------------------------------------------- */ +/* Math Configuration */ +/* ------------------------------------------------------------------------- */ +/* Wolf Single Precision Math */ +#if 1 +#define WOLFSSL_HAVE_SP_RSA +#define WOLFSSL_HAVE_SP_DH +#define WOLFSSL_HAVE_SP_ECC +// #define WOLFSSL_SP_4096 /* Enable RSA/RH 4096-bit support */ +// #define WOLFSSL_SP_384 /* Enable ECC 384-bit SECP384R1 support */ + +// #define WOLFSSL_SP_CACHE_RESISTANT +// #define WOLFSSL_SP_MATH /* only SP math - disables integer.c/tfm.c */ +#define WOLFSSL_SP_MATH_ALL /* use SP math for all key sizes and curves */ + + // #define WOLFSSL_SP_NO_MALLOC + // #define WOLFSSL_SP_DIV_32 /* do not use 64-bit divides */ + +#ifdef TARGET_EMBEDDED +/* use smaller version of code */ +//#define WOLFSSL_SP_SMALL +#else +/* SP Assembly Speedups - specific to chip type */ +#define WOLFSSL_SP_ASM +#endif + // #define WOLFSSL_SP_X86_64 + // #define WOLFSSL_SP_X86 + // #define WOLFSSL_SP_ARM32_ASM + // #define WOLFSSL_SP_ARM64_ASM + // #define WOLFSSL_SP_ARM_THUMB_ASM + // #define WOLFSSL_SP_ARM_CORTEX_M_ASM +#elif 1 +/* Fast Math (tfm.c) (stack based and timing resistant) */ +#define USE_FAST_MATH +#define TFM_TIMING_RESISTANT +#else +/* Normal (integer.c) (heap based, not timing resistant) - not recommended*/ +#define USE_INTEGER_HEAP_MATH +#endif + +/* ------------------------------------------------------------------------- */ +/* Crypto */ +/* ------------------------------------------------------------------------- */ +/* RSA */ +#undef NO_RSA +#if 0 +#ifdef USE_FAST_MATH +/* Maximum math bits (Max RSA key bits * 2) */ +#define FP_MAX_BITS 4096 +#endif + +/* half as much memory but twice as slow */ +// #define RSA_LOW_MEM + +/* Enables blinding mode, to prevent timing attacks */ +#define WC_RSA_BLINDING + +/* RSA PSS Support */ +#define WC_RSA_PSS +#else +#define NO_RSA +#endif + +/* DH */ +#undef NO_DH +#if 0 +/* Use table for DH instead of -lm (math) lib dependency */ +#if 1 +#define WOLFSSL_DH_CONST +#define HAVE_FFDHE_2048 + // #define HAVE_FFDHE_4096 + // #define HAVE_FFDHE_6144 + // #define HAVE_FFDHE_8192 +#endif +#else +#define NO_DH +#endif + +/* ECC */ +#undef HAVE_ECC +#if 1 +#define HAVE_ECC + +/* Manually define enabled curves */ +#define ECC_USER_CURVES + +#ifdef ECC_USER_CURVES +/* Manual Curve Selection */ +// #define HAVE_ECC192 +// #define HAVE_ECC224 +#undef NO_ECC256 + // #define HAVE_ECC384 + // #define HAVE_ECC521 +#endif + +/* Fixed point cache (speeds repeated operations against same private key) */ +// #define FP_ECC +#ifdef FP_ECC +/* Bits / Entries */ +#define FP_ENTRIES 2 +#define FP_LUT 4 +#endif + +/* Optional ECC calculation method */ +/* Note: doubles heap usage, but slightly faster */ +#define ECC_SHAMIR + +/* Reduces heap usage, but slower */ +#define ECC_TIMING_RESISTANT + +/* Compressed ECC Key Support */ +// #define HAVE_COMP_KEY + +/* Use alternate ECC size for ECC math */ +#ifdef USE_FAST_MATH +/* MAX ECC BITS = ROUND8(MAX ECC) * 2 */ +#if defined(NO_RSA) && defined(NO_DH) +/* Custom fastmath size if not using RSA/DH */ +#define FP_MAX_BITS (256 * 2) +#else +/* use heap allocation for ECC points */ +#define ALT_ECC_SIZE + + /* wolfSSL will compute the FP_MAX_BITS_ECC, but it can be overridden */ + // #define FP_MAX_BITS_ECC (256 * 2) +#endif + +/* Speedups specific to curve */ +#ifndef NO_ECC256 +#define TFM_ECC256 +#endif +#endif +#endif + +/* AES */ +#undef NO_AES +#if 1 +#define HAVE_AES_CBC + +/* GCM Method: GCM_TABLE_4BIT, GCM_SMALL, GCM_WORD32 or GCM_TABLE */ +#define HAVE_AESGCM +#if 0 //TARGET_EMBEDDED +#define GCM_SMALL +#else +#define GCM_TABLE_4BIT +#endif + + // #define WOLFSSL_AES_DIRECT + // #define HAVE_AES_ECB + // #define WOLFSSL_AES_COUNTER + // #define HAVE_AESCCM +#else +#define NO_AES +#endif + +/* DES3 */ +#undef NO_DES3 +#if 0 +#else +#define NO_DES3 +#endif + +/* ChaCha20 / Poly1305 */ +#undef HAVE_CHACHA +#undef HAVE_POLY1305 +#if 1 +#define HAVE_CHACHA +#define HAVE_POLY1305 + +/* Needed for Poly1305 */ +#define HAVE_ONE_TIME_AUTH +#endif + +/* Ed25519 / Curve25519 */ +#undef HAVE_CURVE25519 +#undef HAVE_ED25519 +#if 1 +#define HAVE_CURVE25519 +#define HAVE_ED25519 /* ED25519 Requires SHA512 */ + + /* Optionally use small math (less flash usage, but much slower) */ +#if 0 +#define CURVED25519_SMALL +#endif +#endif + +/* Ed448 / Curve448 */ +#undef HAVE_CURVE448 +#undef HAVE_ED448 +#if 1 +#define HAVE_CURVE448 +#define HAVE_ED448 /* ED448 Requires SHA512 */ + + /* Optionally use small math (less flash usage, but much slower) */ +#if 0 +#define CURVED448_SMALL +#endif +#endif +/* ------------------------------------------------------------------------- */ +/* Hashing */ +/* ------------------------------------------------------------------------- */ +/* Sha */ +#undef NO_SHA +#if 1 + /* 1k smaller, but 25% slower */ + // #define USE_SLOW_SHA +#else +#define NO_SHA +#endif + +/* Sha256 */ +#undef NO_SHA256 +#if 1 +/* not unrolled - ~2k smaller and ~25% slower */ +// #define USE_SLOW_SHA256 + +/* Sha224 */ +#if 0 +#define WOLFSSL_SHA224 +#endif +#else +#define NO_SHA256 +#endif + +/* Sha512 */ +#undef WOLFSSL_SHA512 +#if 1 +#define WOLFSSL_SHA512 + + /* Sha384 */ +#undef WOLFSSL_SHA384 +#if 1 +#define WOLFSSL_SHA384 +#endif + + /* over twice as small, but 50% slower */ + //#define USE_SLOW_SHA512 +#endif + +/* Sha3 */ +#undef WOLFSSL_SHA3 +#if 1 +#define WOLFSSL_SHA3 +#endif + +/* MD5 */ +#undef NO_MD5 +#if 0 + +#else +#define NO_MD5 +#endif + +/* HKDF */ +#undef HAVE_HKDF +#if 1 +#define HAVE_HKDF +#endif + +/* CMAC */ +#undef WOLFSSL_CMAC +#if 0 +#define WOLFSSL_CMAC +#endif + +/* ------------------------------------------------------------------------- */ +/* Benchmark / Test */ +/* ------------------------------------------------------------------------- */ +#ifdef TARGET_EMBEDDED +/* Use reduced benchmark / test sizes */ +#define BENCH_EMBEDDED +#endif + +/* Use test buffers from array (not filesystem) */ +#ifndef NO_FILESYSTEM +#define USE_CERT_BUFFERS_256 +#define USE_CERT_BUFFERS_2048 +#endif + + /* ------------------------------------------------------------------------- */ + /* Debugging */ + /* ------------------------------------------------------------------------- */ + +#undef DEBUG_WOLFSSL +#undef NO_ERROR_STRINGS +#if 0 +#define DEBUG_WOLFSSL +#else +#if 0 +#define NO_ERROR_STRINGS +#endif +#endif + +/* ------------------------------------------------------------------------- */ +/* Memory */ +/* ------------------------------------------------------------------------- */ + +/* Override Memory API's */ +#if 0 +#define XMALLOC_OVERRIDE + + /* prototypes for user heap override functions */ + /* Note: Realloc only required for normal math */ +#include /* for size_t */ + extern void *myMalloc(size_t n, void* heap, int type); + extern void myFree(void *p, void* heap, int type); + extern void *myRealloc(void *p, size_t n, void* heap, int type); + +#define XMALLOC(n, h, t) myMalloc(n, h, t) +#define XFREE(p, h, t) myFree(p, h, t) +#define XREALLOC(p, n, h, t) myRealloc(p, n, h, t) +#endif + +#if 0 + /* Static memory requires fast math */ +#define WOLFSSL_STATIC_MEMORY + + /* Disable fallback malloc/free */ +#define WOLFSSL_NO_MALLOC +#if 1 +#define WOLFSSL_MALLOC_CHECK /* trap malloc failure */ +#endif +#endif + +/* Memory callbacks */ +#if 0 +#undef USE_WOLFSSL_MEMORY +#define USE_WOLFSSL_MEMORY + + /* Use this to measure / print heap usage */ +#if 0 +#define WOLFSSL_TRACK_MEMORY +#define WOLFSSL_DEBUG_MEMORY +#endif +#else +#ifndef WOLFSSL_STATIC_MEMORY +#define NO_WOLFSSL_MEMORY + /* Otherwise we will use stdlib malloc, free and realloc */ +#endif +#endif + +/* ------------------------------------------------------------------------- */ +/* Port */ +/* ------------------------------------------------------------------------- */ + +/* Override Current Time */ +#if 0 + /* Allows custom "custom_time()" function to be used for benchmark */ +#define WOLFSSL_USER_CURRTIME +#define WOLFSSL_GMTIME +#define USER_TICKS + extern unsigned long my_time(unsigned long* timer); +#define XTIME my_time +#endif + +/* ------------------------------------------------------------------------- */ +/* RNG */ +/* ------------------------------------------------------------------------- */ + +/* Choose RNG method */ +#if 1 +/* Custom Seed Source */ + /* Size of returned HW RNG value */ +//#define CUSTOM_RAND_TYPE unsigned int +unsigned long get_rand_32(void); +#undef CUSTOM_RAND_GENERATE +#define CUSTOM_RAND_GENERATE get_rand_32 +#endif + +#if 1 +/* Use built-in P-RNG (SHA256 based) with HW RNG */ +/* P-RNG + HW RNG (P-RNG is ~8K) */ +#undef HAVE_HASHDRBG +#define HAVE_HASHDRBG +#else +#undef WC_NO_HASHDRBG +#define WC_NO_HASHDRBG +#endif + +#if 0 +/* Bypass P-RNG and use only HW RNG */ +extern int my_rng_gen_block(unsigned char *output, unsigned int sz); +#undef CUSTOM_RAND_GENERATE_BLOCK +#define CUSTOM_RAND_GENERATE_BLOCK my_rng_gen_block +#endif + + +/* ------------------------------------------------------------------------- */ +/* Custom Standard Lib */ +/* ------------------------------------------------------------------------- */ +/* Allows override of all standard library functions */ +#undef STRING_USER +#if 0 +#define STRING_USER + +#include + +#define USE_WOLF_STRSEP +#define XSTRSEP(s1, d) wc_strsep((s1), (d)) + +#define USE_WOLF_STRTOK +#define XSTRTOK(s1, d, ptr) wc_strtok((s1), (d), (ptr)) + +#define XSTRNSTR(s1, s2, n) mystrnstr((s1), (s2), (n)) + +#define XMEMCPY(d, s, l) memcpy((d), (s), (l)) +#define XMEMSET(b, c, l) memset((b), (c), (l)) +#define XMEMCMP(s1, s2, n) memcmp((s1), (s2), (n)) +#define XMEMMOVE(d, s, l) memmove((d), (s), (l)) + +#define XSTRLEN(s1) strlen((s1)) +#define XSTRNCPY(s1, s2, n) strncpy((s1), (s2), (n)) +#define XSTRSTR(s1, s2) strstr((s1), (s2)) + +#define XSTRNCMP(s1, s2, n) strncmp((s1), (s2), (n)) +#define XSTRNCAT(s1, s2, n) strncat((s1), (s2), (n)) +#define XSTRNCASECMP(s1, s2, n) strncasecmp((s1), (s2), (n)) + +#define XSNPRINTF snprintf +#endif + + /* ------------------------------------------------------------------------- */ + /* Enable Features */ + /* ------------------------------------------------------------------------- */ + +#define WOLFSSL_TLS13 +#define WOLFSSL_OLD_PRIME_CHECK /* Use faster DH prime checking */ +#define HAVE_TLS_EXTENSIONS +#define HAVE_SUPPORTED_CURVES +#define WOLFSSL_BASE64_ENCODE + +// #define WOLFSSL_KEY_GEN /* For RSA Key gen only */ +// #define KEEP_PEER_CERT +// #define HAVE_COMP_KEY + +/* TLS Session Cache */ +#if 0 +#define SMALL_SESSION_CACHE +#else +#define NO_SESSION_CACHE +#endif + +/* ------------------------------------------------------------------------- */ +/* Disable Features */ +/* ------------------------------------------------------------------------- */ +// #define NO_WOLFSSL_SERVER +// #define NO_WOLFSSL_CLIENT +// #define NO_CRYPT_TEST +// #define NO_CRYPT_BENCHMARK +// #define WOLFCRYPT_ONLY + +/* do not warm when file is included to be built and not required to be */ +#//define WOLFSSL_IGNORE_FILE_WARN + + /* In-lining of misc.c functions */ + /* If defined, must include wolfcrypt/src/misc.c in build */ + /* Slower, but about 1k smaller */ + // #define NO_INLINE + +#ifdef TARGET_EMBEDDED +#define NO_FILESYSTEM +#define NO_WRITEV +#define NO_MAIN_DRIVER +#define NO_DEV_RANDOM +#endif + +#define NO_OLD_TLS +#define NO_PSK + +#define NO_DSA +#define NO_RC4 +#define NO_MD4 +#define NO_PWDBASED + // #define NO_CODING + // #define NO_ASN_TIME + // #define NO_CERTS + // #define NO_SIG_WRAPPER + +#ifdef __cplusplus +} +#endif + +#endif /* WOLFSSL_USER_SETTINGS_H */ + diff --git a/RPi-Pico/config/user_settings_asm.h b/RPi-Pico/config/user_settings_asm.h new file mode 100644 index 00000000..e69de29b diff --git a/RPi-Pico/include/wolf/common.h b/RPi-Pico/include/wolf/common.h new file mode 100644 index 00000000..61520e41 --- /dev/null +++ b/RPi-Pico/include/wolf/common.h @@ -0,0 +1,23 @@ +/* wolf_common.h + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#define WOLF_SUCCESS 0 +#define WOLF_FAIL -1 \ No newline at end of file diff --git a/RPi-Pico/include/wolf/tcp.h b/RPi-Pico/include/wolf/tcp.h new file mode 100644 index 00000000..a6836988 --- /dev/null +++ b/RPi-Pico/include/wolf/tcp.h @@ -0,0 +1,49 @@ +/* tcp.c + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include +#include "pico/cyw43_arch.h" +#include "pico/stdlib.h" + +#include "lwip/ip_addr.h" + +#include "wolf/blink.h" +#include "wolf/common.h" + +#define DEBUG_printf printf +#define BUF_SIZE 2048 + +typedef struct { + struct tcp_pcb *tcp_pcb; + ip_addr_t remote_addr; + uint8_t buffer[BUF_SIZE]; + int buffer_len; + int sent_len; + bool complete; + int run_count; + bool connected; +} WOLF_SOCKET_T; + +WOLF_SOCKET_T *wolf_TCPsocket(void); +static err_t wolf_TCPfree(WOLF_SOCKET_T *); +bool wolf_TCPconnect(WOLF_SOCKET_T *, const char*, uint32_t); +size_t wolf_TCPwrite(WOLF_SOCKET_T *, const unsigned char *, uint32_t); +size_t wolf_TCPread(WOLF_SOCKET_T *, unsigned char *, uint32_t); \ No newline at end of file diff --git a/RPi-Pico/include/wolf/wifi.h b/RPi-Pico/include/wolf/wifi.h new file mode 100644 index 00000000..cabf5c5a --- /dev/null +++ b/RPi-Pico/include/wolf/wifi.h @@ -0,0 +1,23 @@ +/* wifi.h + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +int wolf_wifiConnect(const char *ssid, const char *pw, uint32_t auth, uint32_t timeout); +int wolf_wifiDisconnect(void); diff --git a/RPi-Pico/src/tcp.c b/RPi-Pico/src/tcp.c new file mode 100644 index 00000000..e160c234 --- /dev/null +++ b/RPi-Pico/src/tcp.c @@ -0,0 +1,241 @@ +/* tcp.c + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include +#include "pico/cyw43_arch.h" +#include "pico/stdlib.h" + +#include "lwip/pbuf.h" +#include "lwip/tcp.h" +//#include "lwip/ip_addr.h" +#include "wolf/tcp.h" + +#define DEBUG_printf printf +#define BUF_SIZE 2048 + +#define TEST_ITERATIONS 10 +#define POLL_TIME_S 5 + +#define TEST_TASK_PRIORITY (tskIDLE_PRIORITY + 2UL) +#define BLINK_TASK_PRIORITY (tskIDLE_PRIORITY + 1UL) + +err_t wolf_TCPclose(WOLF_SOCKET_T *sock) +{ + err_t err = ERR_OK; + if (sock->tcp_pcb != NULL) + { + tcp_arg(sock->tcp_pcb, NULL); + tcp_poll(sock->tcp_pcb, NULL, 0); + tcp_sent(sock->tcp_pcb, NULL); + tcp_recv(sock->tcp_pcb, NULL); + tcp_err(sock->tcp_pcb, NULL); + err = tcp_close(sock->tcp_pcb); + if (err != ERR_OK) + { + DEBUG_printf("close failed %d, calling abort\n", err); + tcp_abort(sock->tcp_pcb); + err = ERR_ABRT; + } + sock->tcp_pcb = NULL; + } + free(sock); + return err; +} + +// Called with results of operation +// Called with results of operation +static err_t tcp_result(WOLF_SOCKET_T *sock, int status) +{ + if (status == 0) { + DEBUG_printf("test success\n"); + } else { + DEBUG_printf("test failed %d\n", status); + } + sock->complete = true; + return 0; +} + +static err_t lwip_cb_client_sent(void *arg, struct tcp_pcb *tpcb, u16_t len) +{ + WOLF_SOCKET_T *sock = (WOLF_SOCKET_T *)arg; + DEBUG_printf("tcp_client_sent %u\n", len); + sock->sent_len += len; + + if (sock->sent_len >= BUF_SIZE) + { + + sock->run_count++; + if (sock->run_count >= TEST_ITERATIONS) + { + tcp_result(arg, 0); + return ERR_OK; + } + + // We should receive a new buffer from the server + sock->buffer_len = 0; + sock->sent_len = 0; + DEBUG_printf("Waiting for buffer from server\n"); + } + + return ERR_OK; +} + +static err_t lwip_cb_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err) +{ + char msg[] = "Hello Server"; + + WOLF_SOCKET_T *sock = (WOLF_SOCKET_T *)arg; + if (err != ERR_OK) + { + printf("connect failed %d\n", err); + return tcp_result(arg, err); + } + sock->connected = true; + DEBUG_printf("Connected.\n"); + return ERR_OK; +} + +static err_t lwip_cb_client_poll(void *arg, struct tcp_pcb *tpcb) +{ + DEBUG_printf("tcp_client_poll\n"); + return tcp_result(arg, -1); // no response is an error? +} + +static void lwip_cb_client_err(void *arg, err_t err) +{ + if (err != ERR_ABRT) + { + DEBUG_printf("tcp_client_err %d\n", err); + tcp_result(arg, err); + } +} + +static err_t lwip_cb_client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) +{ + WOLF_SOCKET_T *sock = (WOLF_SOCKET_T *)arg; + if (!p) + { + return tcp_result(arg, -1); + } + // this method is callback from lwIP, so cyw43_arch_lwip_begin is not required, however you + // can use this method to cause an assertion in debug mode, if this method is called when + // cyw43_arch_lwip_begin IS needed + cyw43_arch_lwip_check(); + if (p->tot_len > 0) + { + DEBUG_printf("recv %d err %d\n", p->tot_len, err); + // Receive the buffer + const uint16_t buffer_left = BUF_SIZE - sock->buffer_len; + sock->buffer_len += pbuf_copy_partial(p, sock->buffer + sock->buffer_len, + p->tot_len > buffer_left ? buffer_left : p->tot_len, 0); + tcp_recved(tpcb, p->tot_len); + } + pbuf_free(p); + + // If we have received the whole buffer, send it back to the server + if (sock->buffer_len == BUF_SIZE) + { + DEBUG_printf("Writing %d bytes to server\n", sock->buffer_len); + err_t err = tcp_write(tpcb, sock->buffer, sock->buffer_len, TCP_WRITE_FLAG_COPY); + if (err != ERR_OK) + { + DEBUG_printf("Failed to write data %d\n", err); + return tcp_result(arg, -1); + } + } + return ERR_OK; +} + +bool wolf_TCPconnect(WOLF_SOCKET_T *sock, const char *ip, uint32_t port) +{ + ip4addr_aton(ip, &sock->remote_addr); + + DEBUG_printf("wolf_TCPconnect: Connecting to %s port %u\n", ip4addr_ntoa(&sock->remote_addr), port); + sock->tcp_pcb = tcp_new_ip_type(IP_GET_TYPE(&sock->remote_addr)); + if (!sock->tcp_pcb) + { + DEBUG_printf("failed to create pcb\n"); + return false; + } + + tcp_arg(sock->tcp_pcb, sock); + tcp_poll(sock->tcp_pcb, lwip_cb_client_poll, POLL_TIME_S * 2); + tcp_sent(sock->tcp_pcb, lwip_cb_client_sent); + tcp_recv(sock->tcp_pcb, lwip_cb_client_recv); + tcp_err(sock->tcp_pcb, lwip_cb_client_err); + + sock->buffer_len = 0; + + // cyw43_arch_lwip_begin/end should be used around calls into lwIP to ensure correct locking. + // You can omit them if you are in a callback from lwIP. Note that when using pico_cyw_arch_poll + // these calls are a no-op and can be omitted, but it is a good practice to use them in + // case you switch the cyw43_arch type later. + cyw43_arch_lwip_begin(); + err_t err = tcp_connect(sock->tcp_pcb, &sock->remote_addr, port, lwip_cb_client_connected); + cyw43_arch_lwip_end(); + if (err == ERR_OK) + DEBUG_printf("wolf_TCPconnect: Connected"); + else + DEBUG_printf("wolf_TCPconnect: Failed"); + return err == ERR_OK; +} + +// get a new TCP client +WOLF_SOCKET_T *wolf_TCPsocket() +{ + WOLF_SOCKET_T *sock = calloc(1, sizeof(WOLF_SOCKET_T)); + if (!sock) { + DEBUG_printf("failed to allocate state\n"); + return NULL; + } + + return sock; +} + +size_t wolf_TCPwrite(WOLF_SOCKET_T *sock, const unsigned char *buff, uint32_t len) +{ + return tcp_write(sock->tcp_pcb, buff, len, TCP_WRITE_FLAG_COPY); +} + +size_t wolf_TCPread(WOLF_SOCKET_T *sock, unsigned char *buff, uint32_t len) +{ + int recv_len; + int remained; + + while(1) { + if(sock->buffer_len > 0) { + recv_len = len < sock->buffer_len ? len : sock->buffer_len; + memcpy(sock->buffer, buff,recv_len); + if(recv_len == len) { + remained = sock->buffer_len - recv_len; + sock->buffer_len = remained; + memcpy(sock->buffer, sock->buffer+recv_len, remained); + } else + sock->buffer_len = 0; + return recv_len; + } else { + printf("cyw43_arch_poll()\n"); + cyw43_arch_poll(); + cyw43_arch_wait_for_work_until(make_timeout_time_ms(1000)); + } + + } +} \ No newline at end of file diff --git a/RPi-Pico/src/tcpClient_main.c b/RPi-Pico/src/tcpClient_main.c new file mode 100644 index 00000000..8393e23c --- /dev/null +++ b/RPi-Pico/src/tcpClient_main.c @@ -0,0 +1,115 @@ +/* tcpClient_main.c + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include +#include "pico/stdlib.h" +#include "pico/cyw43_arch.h" + +#include "wolf/common.h" +#include "wolf/tcp.h" +#include "wolf/wifi.h" +#include "wolf/blink.h" +#include "lwip/tcp.h" + +#define TCP_PORT 1111 + +static void dump_bytes(const uint8_t *p, uint32_t len) +{ + for (; len; len--, p++) { + if (((unsigned long)p & 0x07) == 0) { + printf("\n"); + } + printf("%02x ", *p); + } + printf("\n"); +} + +void tcpClient_test(void) +{ + int i; + int err; + #define BUFF_SIZE 2048 + char buffer[BUFF_SIZE]; + #define SIZE_OF_CLIENT_HELLO 815 + char msg[SIZE_OF_CLIENT_HELLO] = "\026\003\003\003\052\001\000\003\046 Fake Client Hello"; + + WOLF_SOCKET_T *sock = wolf_TCPsocket(); + if (!sock) + { + printf("ERROR:wolf_TCPsocke()\n"); + return; + } + if (!wolf_TCPconnect(sock, TEST_TCP_SERVER_IP, TCP_PORT)) { + printf("ERROR:wolf_TCPconnect()\n"); + goto exit; + } + + DEBUG_printf("Writing to server: %s\n", msg); + err = wolf_TCPwrite(sock, msg, sizeof(msg)); + if (err < 0) { + DEBUG_printf("Failed to write data. err=%d\n", err); + goto exit; + } + DEBUG_printf("Writen data %d bytes\n", err); + + err = wolf_TCPread(sock, buffer, BUFF_SIZE); + if (err < 0) { + DEBUG_printf("Failed to read data. err=%d\n", err); + goto exit; + } + DEBUG_printf("Read data %d bytes\n", err); + dump_bytes(buffer, err); + +exit: + free(sock); +} + +void main(void) +{ + blink(20, 1); + printf("Started main_task\n"); + + cyw43_arch_enable_sta_mode(); + printf("Connecting to Wi-Fi...\n"); + printf("WIFI_SSID=%s, WIFI_PASSWORD=%s\n", WIFI_SSID, WIFI_PASSWORD); + if(wolf_wifiConnect(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000)) { + printf("failed to connect.\n"); + return; + } else { + printf("Connected.\n"); + } + cyw43_arch_lwip_begin(); + printf("\nReady, running iperf client\n"); + + tcpClient_test(); + + cyw43_arch_lwip_end(); + cyw43_arch_deinit(); + + printf("End of iperf client\n"); +} + +void lwip_example_app_platform_assert(const char *msg, int line, const char *file) +{ + printf("Assertion \"%s\" failed at line %d in %s\n", msg, line, file); + fflush(NULL); +} + diff --git a/RPi-Pico/src/wifi.c b/RPi-Pico/src/wifi.c new file mode 100644 index 00000000..f0009e5f --- /dev/null +++ b/RPi-Pico/src/wifi.c @@ -0,0 +1,54 @@ +/* wifi.c + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include +#include "pico/stdlib.h" +#include "pico/cyw43_arch.h" + +#include "wolf/common.h" + +int wolf_wifiConnect(const char *ssid, const char *pw, uint32_t auth, uint32_t timeout) +{ + int retry; + #define MAX_RETRY 5 + printf("Initializing Wi-Fi...\n"); + cyw43_arch_enable_sta_mode(); + + for(retry = 0; retry < MAX_RETRY; retry++) { + if (cyw43_arch_wifi_connect_timeout_ms(ssid, pw, auth, timeout)) { + fprintf(stderr, "failed to connect. Retrying\n"); + } else { + printf("Wifi Connected\n"); + return WOLF_SUCCESS; + } + sleep_ms(1000); + } + return WOLF_FAIL; +} + +int wolf_wifiDisconnect(void) +{ + cyw43_arch_deinit(); + printf("Wifi disconnected\n"); + + return 0; +} + diff --git a/RPi-Pico/src/wifi_main.c b/RPi-Pico/src/wifi_main.c new file mode 100644 index 00000000..c5bc0c62 --- /dev/null +++ b/RPi-Pico/src/wifi_main.c @@ -0,0 +1,48 @@ +/* wifi_main.c + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include +#include "pico/stdlib.h" +#include "pico/cyw43_arch.h" + +#include "wolf/common.h" +#include "wolf/wifi.h" +#include "wolf/blink.h" + +void lwip_example_app_platform_assert(const char *msg, int line, const char *file) +{ + printf("Assertion \"%s\" failed at line %d in %s\n", msg, line, file); + fflush(NULL); + abort(); +} + +int main(int argc, char **argv) +{ + stdio_init_all(); + + blink(10, WOLF_BLINK_INIT); + wolf_wifiConnect(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000); + + blink(10, 0); + wolf_wifiDisconnect(); + + return 0; +} \ No newline at end of file