Merge branch 'feature/mbedtls'
This commit is contained in:
		
						commit
						65307aed75
					
				
					 33 changed files with 4571 additions and 822 deletions
				
			
		
							
								
								
									
										7
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
[submodule "lwip/lwip"]
 | 
			
		||||
	path = lwip/lwip
 | 
			
		||||
	url = https://github.com/SuperHouse/esp-lwip.git
 | 
			
		||||
[submodule "axtls/axtls"]
 | 
			
		||||
	path = axtls/axtls
 | 
			
		||||
	url = https://github.com/SuperHouse/axtls.git
 | 
			
		||||
 | 
			
		||||
[submodule "extras/mbedtls/mbedtls"]
 | 
			
		||||
	path = extras/mbedtls/mbedtls
 | 
			
		||||
	url = https://github.com/ARMmbed/mbedtls.git
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								README.md
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -69,18 +69,18 @@ Current status is alpha quality, actively developed. AP STATION mode (ie wifi cl
 | 
			
		|||
* `include` contains header files from Espressif RTOS SDK, relating to the binary libraries & Xtensa core.
 | 
			
		||||
* `core` contains source & headers for low-level ESP8266 functions & peripherals. `core/include/esp` contains useful headers for peripheral access, etc. Minimal to no FreeRTOS dependencies.
 | 
			
		||||
* `extras` is a directory that contains optional components that can be added to your project. Most 'extras' components will have a corresponding example in the `examples` directory. Extras include:
 | 
			
		||||
   - mbedtls - [mbedTLS](https://tls.mbed.org/) is a TLS/SSL library providing up to date secure connectivity and encryption support.
 | 
			
		||||
   - i2c - software i2c driver ([upstream project](https://github.com/kanflo/esp-open-rtos-driver-i2c))
 | 
			
		||||
   - rboot-ota - OTA support (over-the-air updates) including a TFTP server for receiving updates ([for rboot by @raburton](http://richard.burtons.org/2015/05/18/rboot-a-new-boot-loader-for-esp8266/))
 | 
			
		||||
   - bmp180 driver for digital pressure sensor ([upstream project](https://github.com/Angus71/esp-open-rtos-driver-bmp180))
 | 
			
		||||
* `FreeRTOS` contains FreeRTOS implementation, subdirectory structure is the standard FreeRTOS structure. `FreeRTOS/source/portable/esp8266/` contains the ESP8266 port.
 | 
			
		||||
* `lwip` and `axtls` contain the lwIP TCP/IP library and the axTLS TLS library ('libssl' in the esp8266 SDKs), respectively. See [Third Party Libraries](https://github.com/SuperHouse/esp-open-rtos/wiki/Third-Party-Libraries) wiki page for details.
 | 
			
		||||
* `lwip` contains the lwIP TCP/IP library. See [Third Party Libraries](https://github.com/SuperHouse/esp-open-rtos/wiki/Third-Party-Libraries) wiki page for details.
 | 
			
		||||
* `libc` contains the newlib libc. [Libc details here](https://github.com/SuperHouse/esp-open-rtos/wiki/libc-configuration).
 | 
			
		||||
 | 
			
		||||
## Open Source Components
 | 
			
		||||
 | 
			
		||||
* [FreeRTOS](http://freertos.org) V7.5.2
 | 
			
		||||
* [lwIP](http://lwip.wikia.com/wiki/LwIP_Wiki) v1.4.1, modified via the [esp-lwip project](https://github.com/kadamski/esp-lwip) by @kadamski.
 | 
			
		||||
* [axTLS](http://axtls.sourceforge.net/) compiled from development version v1.5.3, plus modifications for low memory devices.
 | 
			
		||||
* [newlib](https://github.com/projectgus/newlib-xtensa) v2.2.0, with patches for xtensa support and locking stubs for thread-safe operation on FreeRTOS.
 | 
			
		||||
 | 
			
		||||
For details of how third party libraries are integrated, [see the wiki page](https://github.com/SuperHouse/esp-open-rtos/wiki/Third-Party-Libraries).
 | 
			
		||||
| 
						 | 
				
			
			@ -91,6 +91,8 @@ Binary libraries (inside the `lib` dir) are all supplied by Espressif as part of
 | 
			
		|||
 | 
			
		||||
As part of the esp-open-rtos build process, all binary SDK symbols are prefixed with `sdk_`. This makes it easier to differentiate binary & open source code, and also prevents namespace conflicts.
 | 
			
		||||
 | 
			
		||||
Espressif's RTOS SDK provided a "libssl" based on axTLS. This has been replaced with the more up to date mbedTLS library (see below).
 | 
			
		||||
 | 
			
		||||
Some binary libraries appear to contain unattributed open source code:
 | 
			
		||||
 | 
			
		||||
* libnet80211.a & libwpa.a appear to be based on FreeBSD net80211/wpa, or forks of them. ([See this issue](https://github.com/SuperHouse/esp-open-rtos/issues/4)).
 | 
			
		||||
| 
						 | 
				
			
			@ -98,7 +100,7 @@ Some binary libraries appear to contain unattributed open source code:
 | 
			
		|||
 | 
			
		||||
## Licensing
 | 
			
		||||
 | 
			
		||||
* BSD license (as described in LICENSE) applies to original source files, [lwIP](http://lwip.wikia.com/wiki/LwIP_Wiki), and [axTLS](http://axtls.sourceforge.net/). lwIP is Copyright (C) Swedish Institute of Computer Science. axTLS is Copyright (C) Cameron Rich.
 | 
			
		||||
* BSD license (as described in LICENSE) applies to original source files, [lwIP](http://lwip.wikia.com/wiki/LwIP_Wiki). lwIP is Copyright (C) Swedish Institute of Computer Science.
 | 
			
		||||
 | 
			
		||||
* FreeRTOS is provided under the GPL with the FreeRTOS linking exception, allowing non-GPL firmwares to be produced using FreeRTOS as the RTOS core. License details in files under FreeRTOS dir. FreeRTOS is Copyright (C) Real Time Engineers Ltd.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -106,6 +108,8 @@ Some binary libraries appear to contain unattributed open source code:
 | 
			
		|||
 | 
			
		||||
* Newlib is covered by several copyrights and licenses, as per the files in the `libc` directory.
 | 
			
		||||
 | 
			
		||||
* [mbedTLS](https://tls.mbed.org/) is provided under the Apache 2.0 license as described in the file extras/mbedtls/mbedtls/apache-2.0.txt. mbedTLS is Copyright (C) ARM Limited.
 | 
			
		||||
 | 
			
		||||
Components under `extras/` may contain different licenses, please see those directories for details.
 | 
			
		||||
 | 
			
		||||
## Contributions
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
Subproject commit a4860ef68d7f5d98a8731f99787d51cc44c433c9
 | 
			
		||||
| 
						 | 
				
			
			@ -1,33 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Stub time-related functions for TLS time-related operations
 | 
			
		||||
 *
 | 
			
		||||
 * ESPTODO: Revisit these ASAP as gettimeofday() is used for entropy
 | 
			
		||||
 *
 | 
			
		||||
 * Part of esp-open-rtos
 | 
			
		||||
 * Copyright (C) 2015 Superhouse Automation Pty Ltd
 | 
			
		||||
 * BSD Licensed as described in the file LICENSE
 | 
			
		||||
 */
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
time_t time(time_t *t)
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
time_t mktime(struct tm *tm)
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int gettimeofday(struct timeval *tv, void *tz)
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void abort(void)
 | 
			
		||||
{
 | 
			
		||||
    printf("abort() was called.\r\n");
 | 
			
		||||
    while(1) {}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,22 +0,0 @@
 | 
			
		|||
# Component makefile for axTLS
 | 
			
		||||
 | 
			
		||||
# axTLS has its own configure and build system, but it's not particularly
 | 
			
		||||
# designed for embedded systems. For now we're just imposing the ESP Open RTOS
 | 
			
		||||
# build system over the top.
 | 
			
		||||
 | 
			
		||||
# We supply our own hand tweaked config.h in the external 'include' dir.
 | 
			
		||||
 | 
			
		||||
AXTLS_DIR = $(axtls_ROOT)axtls/
 | 
			
		||||
INC_DIRS += $(axtls_ROOT)include $(AXTLS_DIR)ssl $(AXTLS_DIR)crypto
 | 
			
		||||
 | 
			
		||||
# args for passing into compile rule generation
 | 
			
		||||
axtls_INC_DIR =  $(AXTLS_DIR)include $(AXTLS_DIR)
 | 
			
		||||
axtls_SRC_DIR = $(AXTLS_DIR)crypto $(AXTLS_DIR)ssl $(axtls_ROOT)
 | 
			
		||||
 | 
			
		||||
#axtls_CFLAGS = $(CFLAGS) -Wno-address
 | 
			
		||||
 | 
			
		||||
$(eval $(call component_compile_rules,axtls))
 | 
			
		||||
 | 
			
		||||
# Helpful error if git submodule not initialised
 | 
			
		||||
$(axtls_SRC_DIR):
 | 
			
		||||
	$(error "axtls git submodule not installed. Please run 'git submodule init' then 'git submodule update'")
 | 
			
		||||
| 
						 | 
				
			
			@ -1,128 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Automatically generated header file: don't edit
 | 
			
		||||
 */
 | 
			
		||||
#define HAVE_DOT_CONFIG 0
 | 
			
		||||
#undef CONFIG_PLATFORM_LINUX
 | 
			
		||||
#undef CONFIG_PLATFORM_CYGWIN
 | 
			
		||||
#undef CONFIG_PLATFORM_WIN32
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * General Configuration
 | 
			
		||||
 */
 | 
			
		||||
#define PREFIX "/usr/local"
 | 
			
		||||
#define CROSS "xtensa-lx106-elf-"
 | 
			
		||||
#undef CONFIG_DEBUG
 | 
			
		||||
#define CONFIG_STRIP_UNWANTED_SECTIONS 1
 | 
			
		||||
#undef CONFIG_VISUAL_STUDIO_7_0
 | 
			
		||||
#undef CONFIG_VISUAL_STUDIO_8_0
 | 
			
		||||
#undef CONFIG_VISUAL_STUDIO_10_0
 | 
			
		||||
#define CONFIG_VISUAL_STUDIO_7_0_BASE ""
 | 
			
		||||
#define CONFIG_VISUAL_STUDIO_8_0_BASE ""
 | 
			
		||||
#define CONFIG_VISUAL_STUDIO_10_0_BASE ""
 | 
			
		||||
#define CONFIG_EXTRA_CFLAGS_OPTIONS ""
 | 
			
		||||
#define CONFIG_EXTRA_LDFLAGS_OPTIONS ""
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Embedded System Options (added for ESP RTOS SDK, don't have config entries yetr)
 | 
			
		||||
 */
 | 
			
		||||
#define CONFIG_NO_FILESYSTEM 1
 | 
			
		||||
#define CONFIG_USE_RAND 1
 | 
			
		||||
#define CONFIG_MAX_PLAIN_LENGTH 1024
 | 
			
		||||
#define CONFIG_MAX_KEY_BYTE_SIZE 256 /* for max 2048 bit keys (untested with >1024 bit keys) */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * SSL Library
 | 
			
		||||
 */
 | 
			
		||||
#undef CONFIG_SSL_SERVER_ONLY
 | 
			
		||||
#undef CONFIG_SSL_CERT_VERIFICATION
 | 
			
		||||
#define CONFIG_SSL_ENABLE_CLIENT 1
 | 
			
		||||
#undef CONFIG_SSL_FULL_MODE
 | 
			
		||||
#undef CONFIG_SSL_SKELETON_MODE
 | 
			
		||||
#undef CONFIG_SSL_PROT_LOW
 | 
			
		||||
#define CONFIG_SSL_PROT_MEDIUM 1
 | 
			
		||||
#undef CONFIG_SSL_PROT_HIGH
 | 
			
		||||
#undef CONFIG_SSL_USE_DEFAULT_KEY
 | 
			
		||||
#define CONFIG_SSL_PRIVATE_KEY_LOCATION ""
 | 
			
		||||
#define CONFIG_SSL_PRIVATE_KEY_PASSWORD ""
 | 
			
		||||
#define CONFIG_SSL_X509_CERT_LOCATION ""
 | 
			
		||||
#undef CONFIG_SSL_GENERATE_X509_CERT
 | 
			
		||||
#define CONFIG_SSL_X509_COMMON_NAME ""
 | 
			
		||||
#define CONFIG_SSL_X509_ORGANIZATION_NAME ""
 | 
			
		||||
#define CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME ""
 | 
			
		||||
#undef CONFIG_SSL_ENABLE_V23_HANDSHAKE
 | 
			
		||||
#undef CONFIG_SSL_HAS_PEM
 | 
			
		||||
#undef CONFIG_SSL_USE_PKCS12
 | 
			
		||||
#define CONFIG_SSL_EXPIRY_TIME 24
 | 
			
		||||
#define CONFIG_X509_MAX_CA_CERTS 1
 | 
			
		||||
#define CONFIG_SSL_MAX_CERTS 3
 | 
			
		||||
#undef CONFIG_SSL_CTX_MUTEXING
 | 
			
		||||
#undef CONFIG_USE_DEV_URANDOM
 | 
			
		||||
#undef CONFIG_WIN32_USE_CRYPTO_LIB
 | 
			
		||||
#undef CONFIG_OPENSSL_COMPATIBLE
 | 
			
		||||
#undef CONFIG_PERFORMANCE_TESTING
 | 
			
		||||
#undef CONFIG_SSL_TEST
 | 
			
		||||
#undef CONFIG_AXTLSWRAP
 | 
			
		||||
#undef CONFIG_AXHTTPD
 | 
			
		||||
#undef CONFIG_HTTP_STATIC_BUILD
 | 
			
		||||
#define CONFIG_HTTP_PORT 
 | 
			
		||||
#define CONFIG_HTTP_HTTPS_PORT 
 | 
			
		||||
#define CONFIG_HTTP_SESSION_CACHE_SIZE 
 | 
			
		||||
#define CONFIG_HTTP_WEBROOT ""
 | 
			
		||||
#define CONFIG_HTTP_TIMEOUT 
 | 
			
		||||
#undef CONFIG_HTTP_HAS_CGI
 | 
			
		||||
#define CONFIG_HTTP_CGI_EXTENSIONS ""
 | 
			
		||||
#undef CONFIG_HTTP_ENABLE_LUA
 | 
			
		||||
#define CONFIG_HTTP_LUA_PREFIX ""
 | 
			
		||||
#undef CONFIG_HTTP_BUILD_LUA
 | 
			
		||||
#define CONFIG_HTTP_CGI_LAUNCHER ""
 | 
			
		||||
#undef CONFIG_HTTP_DIRECTORIES
 | 
			
		||||
#undef CONFIG_HTTP_HAS_AUTHORIZATION
 | 
			
		||||
#undef CONFIG_HTTP_HAS_IPV6
 | 
			
		||||
#undef CONFIG_HTTP_ENABLE_DIFFERENT_USER
 | 
			
		||||
#define CONFIG_HTTP_USER ""
 | 
			
		||||
#undef CONFIG_HTTP_VERBOSE
 | 
			
		||||
#undef CONFIG_HTTP_IS_DAEMON
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Language Bindings
 | 
			
		||||
 */
 | 
			
		||||
#undef CONFIG_BINDINGS
 | 
			
		||||
#undef CONFIG_CSHARP_BINDINGS
 | 
			
		||||
#undef CONFIG_VBNET_BINDINGS
 | 
			
		||||
#define CONFIG_DOT_NET_FRAMEWORK_BASE ""
 | 
			
		||||
#undef CONFIG_JAVA_BINDINGS
 | 
			
		||||
#define CONFIG_JAVA_HOME ""
 | 
			
		||||
#undef CONFIG_PERL_BINDINGS
 | 
			
		||||
#define CONFIG_PERL_CORE ""
 | 
			
		||||
#define CONFIG_PERL_LIB ""
 | 
			
		||||
#undef CONFIG_LUA_BINDINGS
 | 
			
		||||
#define CONFIG_LUA_CORE ""
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Samples
 | 
			
		||||
 */
 | 
			
		||||
#undef CONFIG_SAMPLES
 | 
			
		||||
#undef CONFIG_C_SAMPLES
 | 
			
		||||
#undef CONFIG_CSHARP_SAMPLES
 | 
			
		||||
#undef CONFIG_VBNET_SAMPLES
 | 
			
		||||
#undef CONFIG_JAVA_SAMPLES
 | 
			
		||||
#undef CONFIG_PERL_SAMPLES
 | 
			
		||||
#undef CONFIG_LUA_SAMPLES
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * BigInt Options
 | 
			
		||||
 */
 | 
			
		||||
#undef CONFIG_BIGINT_CLASSICAL
 | 
			
		||||
#undef CONFIG_BIGINT_MONTGOMERY
 | 
			
		||||
#define CONFIG_BIGINT_BARRETT 1
 | 
			
		||||
#define CONFIG_BIGINT_CRT 1
 | 
			
		||||
#undef CONFIG_BIGINT_KARATSUBA
 | 
			
		||||
#define MUL_KARATSUBA_THRESH
 | 
			
		||||
#define SQU_KARATSUBA_THRESH
 | 
			
		||||
#define CONFIG_BIGINT_SLIDING_WINDOW 1
 | 
			
		||||
#define CONFIG_BIGINT_SQUARE 1
 | 
			
		||||
#define CONFIG_BIGINT_CHECK_ON 1
 | 
			
		||||
#define CONFIG_INTEGER_32BIT 1
 | 
			
		||||
#undef CONFIG_INTEGER_16BIT
 | 
			
		||||
#undef CONFIG_INTEGER_8BIT
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
#ifndef _OS_INT_H
 | 
			
		||||
#define _OS_INT_H
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,95 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2007-2015, Cameron Rich
 | 
			
		||||
 * Modifications Copyright (c) 2015 Superhouse Automation Pty Ltd
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without 
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * * Redistributions of source code must retain the above copyright notice, 
 | 
			
		||||
 *   this list of conditions and the following disclaimer.
 | 
			
		||||
 * * Redistributions in binary form must reproduce the above copyright notice, 
 | 
			
		||||
 *   this list of conditions and the following disclaimer in the documentation 
 | 
			
		||||
 *   and/or other materials provided with the distribution.
 | 
			
		||||
 * * Neither the name of the axTLS project nor the names of its contributors 
 | 
			
		||||
 *   may be used to endorse or promote products derived from this software 
 | 
			
		||||
 *   without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | 
			
		||||
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
			
		||||
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file os_port.h
 | 
			
		||||
 *
 | 
			
		||||
 * Some stuff to minimise the differences between windows and linux/unix
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _HEADER_OS_PORT_H
 | 
			
		||||
#define _HEADER_OS_PORT_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "os_int.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <pwd.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
//#include <fcntl.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <posix/sys/socket.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <ipv4/lwip/inet.h>
 | 
			
		||||
#if defined(CONFIG_SSL_CTX_MUTEXING)
 | 
			
		||||
#include "semphr.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define SOCKET_READ(A,B,C)      read(A,B,C)
 | 
			
		||||
#define SOCKET_WRITE(A,B,C)     write(A,B,C)
 | 
			
		||||
#define SOCKET_CLOSE(A)         if (A >= 0) close(A)
 | 
			
		||||
#define TTY_FLUSH()
 | 
			
		||||
 | 
			
		||||
static inline uint64_t be64toh(uint64_t x) {
 | 
			
		||||
  return ntohl(x>>32) | ((uint64_t)(ntohl(x)) << 32);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void exit_now(const char *format, ...) __attribute((noreturn));
 | 
			
		||||
 | 
			
		||||
#define EXP_FUNC
 | 
			
		||||
#define STDCALL
 | 
			
		||||
 | 
			
		||||
/* Mutex definitions */
 | 
			
		||||
#if defined(CONFIG_SSL_CTX_MUTEXING)
 | 
			
		||||
#define SSL_CTX_MUTEX_TYPE           xSemaphoreHandle
 | 
			
		||||
#define SSL_CTX_MUTEX_INIT(A)       vSemaphoreCreateBinaryCreateMutex(A)
 | 
			
		||||
#define SSL_CTX_MUTEX_DESTROY(A)    vSemaphoreDelete(A)
 | 
			
		||||
#define SSL_CTX_LOCK(A)             xSemaphoreTakeRecursive(A, portMAX_DELAY)
 | 
			
		||||
#define SSL_CTX_UNLOCK(A)           xSemaphoreGiveRecursive(A)
 | 
			
		||||
#else
 | 
			
		||||
#define SSL_CTX_MUTEX_TYPE
 | 
			
		||||
#define SSL_CTX_MUTEX_INIT(A)
 | 
			
		||||
#define SSL_CTX_MUTEX_DESTROY(A)
 | 
			
		||||
#define SSL_CTX_LOCK(A)
 | 
			
		||||
#define SSL_CTX_UNLOCK(A)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif 
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +0,0 @@
 | 
			
		|||
/* axTLS version header
 | 
			
		||||
 | 
			
		||||
   We need this because we're using axTLS from source repo, not from a release.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _VERSION_H
 | 
			
		||||
 | 
			
		||||
#define AXTLS_VERSION "esp-open-rtos axTLS " GITSHORTREV
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										16
									
								
								common.mk
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								common.mk
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -80,7 +80,7 @@ OBJDUMP = $(CROSS)objdump
 | 
			
		|||
 | 
			
		||||
# Source components to compile and link. Each of these are subdirectories
 | 
			
		||||
# of the root, with a 'component.mk' file.
 | 
			
		||||
COMPONENTS     ?= $(EXTRA_COMPONENTS) FreeRTOS lwip axtls core
 | 
			
		||||
COMPONENTS     ?= $(EXTRA_COMPONENTS) FreeRTOS lwip core
 | 
			
		||||
 | 
			
		||||
# binary esp-iot-rtos SDK libraries to link. These are pre-processed prior to linking.
 | 
			
		||||
SDK_LIBS		?= main net80211 phy pp wpa
 | 
			
		||||
| 
						 | 
				
			
			@ -94,14 +94,25 @@ OWN_LIBC ?= 1
 | 
			
		|||
# Note: you will need a recent esp
 | 
			
		||||
ENTRY_SYMBOL ?= call_user_start
 | 
			
		||||
 | 
			
		||||
# Set this to zero if you don't want individual function & data sections
 | 
			
		||||
# (some code may be slightly slower, linking will be slighty slower,
 | 
			
		||||
# but compiled code size will come down a small amount.)
 | 
			
		||||
SPLIT_SECTIONS ?= 1
 | 
			
		||||
 | 
			
		||||
# Common flags for both C & C++_
 | 
			
		||||
C_CXX_FLAGS     = -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-literals $(CPPFLAGS)
 | 
			
		||||
# Flags for C only
 | 
			
		||||
CFLAGS		= $(C_CXX_FLAGS) -std=gnu99
 | 
			
		||||
# Flags for C++ only
 | 
			
		||||
CXXFLAGS	= $(C_CXX_FLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
LDFLAGS		= -nostdlib -Wl,--no-check-sections -Wl,-L$(BUILD_DIR)sdklib -Wl,-L$(ROOT)lib -u $(ENTRY_SYMBOL) -Wl,-static -Wl,-Map=build/${PROGRAM}.map $(EXTRA_LDFLAGS)
 | 
			
		||||
 | 
			
		||||
ifeq ($(SPLIT_SECTIONS),1)
 | 
			
		||||
  C_CXX_FLAGS += -ffunction-sections -fdata-sections
 | 
			
		||||
  LDFLAGS += -Wl,-gc-sections
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(FLAVOR),debug)
 | 
			
		||||
    C_CXX_FLAGS += -g -O0
 | 
			
		||||
    LDFLAGS += -g -O0
 | 
			
		||||
| 
						 | 
				
			
			@ -159,7 +170,7 @@ ifeq ($(OTA),0)
 | 
			
		|||
# for non-OTA, we create two different files for uploading into the flash
 | 
			
		||||
# these are the names and options to generate them
 | 
			
		||||
FW_ADDR_1	= 0x00000
 | 
			
		||||
FW_ADDR_2	= 0x40000
 | 
			
		||||
FW_ADDR_2	= 0x20000
 | 
			
		||||
FW_FILE_1    = $(addprefix $(FW_BASE),$(FW_ADDR_1).bin)
 | 
			
		||||
FW_FILE_2    = $(addprefix $(FW_BASE),$(FW_ADDR_2).bin)
 | 
			
		||||
else
 | 
			
		||||
| 
						 | 
				
			
			@ -263,6 +274,7 @@ $$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.S $$($(1)_MAKEFILE) $(wildcard $(ROOT)*
 | 
			
		|||
	$(vecho) "AS $$<"
 | 
			
		||||
	$(Q) mkdir -p $$(dir $$@)
 | 
			
		||||
	$$($(1)_CC_ARGS) -c $$< -o $$@
 | 
			
		||||
	$$($(1)_CC_ARGS) -MM -MT $$@ -MF $$(@:.o=.d) $$<
 | 
			
		||||
 | 
			
		||||
# the component is shown to depend on both obj and source files so we get a meaningful error message
 | 
			
		||||
# for missing explicitly named source files
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								core/esp_hwrand.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								core/esp_hwrand.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
/* Hardware Random Number Generator Functions
 | 
			
		||||
 *
 | 
			
		||||
 * For documentation, see http://esp8266-re.foogod.com/wiki/Random_Number_Generator
 | 
			
		||||
 *
 | 
			
		||||
 * Part of esp-open-rtos
 | 
			
		||||
 * Copyright (C) 2015 Angus Gratton
 | 
			
		||||
 * BSD Licensed as described in the file LICENSE
 | 
			
		||||
 */
 | 
			
		||||
#include <esp/hwrand.h>
 | 
			
		||||
#include <esp/wdev_regs.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
/* Return a random 32-bit number */
 | 
			
		||||
uint32_t hwrand(void)
 | 
			
		||||
{
 | 
			
		||||
    return WDEV.HWRNG;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Fill a variable size buffer with data from the Hardware RNG */
 | 
			
		||||
void hwrand_fill(uint8_t *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
    for(size_t i = 0; i < len; i+=4) {
 | 
			
		||||
        uint32_t random = WDEV.HWRNG;
 | 
			
		||||
        /* using memcpy here in case 'buf' is unaligned */
 | 
			
		||||
        memcpy(buf + i, &random, (i+4 <= len) ? 4 : (len % 4));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,256 +1,541 @@
 | 
			
		|||
/* Xtensa Exception (ie interrupt) Vectors & low-level handler code
 | 
			
		||||
 *
 | 
			
		||||
 * Core exception handler code is placed in the .vecbase section, which gets
 | 
			
		||||
 * picked up specially in the linker script and placed at beginning of IRAM.
 | 
			
		||||
 *
 | 
			
		||||
 * The actual VecBase symbol should be the first thing in .vecbase (this is not
 | 
			
		||||
 * strictly important as it gets set by symbol lookup not by hardcoded address,
 | 
			
		||||
 * but having it at 0x40100000 means that the exception vectors have memorable
 | 
			
		||||
 * offsets, which match the default Boot ROM vector offsets. So convenient for
 | 
			
		||||
 * human understanding.
 | 
			
		||||
 *
 | 
			
		||||
 * Part of esp-open-rtos
 | 
			
		||||
 * Original vector contents Copyright (C) 2014-2015 Espressif Systems
 | 
			
		||||
 * Additions Copyright (C) Superhouse Automation Pty Ltd and Angus Gratton
 | 
			
		||||
 * BSD Licensed as described in the file LICENSE
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
   Core exception handler code is placed in the .vecbase section,
 | 
			
		||||
   which gets picked up specially in the linker script and placed
 | 
			
		||||
   at beginning of IRAM.
 | 
			
		||||
#include "led_debug.s"
 | 
			
		||||
 | 
			
		||||
   The actual VecBase symbol should be the first thing in .vecbase
 | 
			
		||||
   (this is not strictly important as it gets set by symbol lookup not
 | 
			
		||||
   by hardcoded address, but having it at 0x40100000 means that the
 | 
			
		||||
   exception vectors have memorable offsets, which match the default
 | 
			
		||||
   Boot ROM vector offsets. So convenient for human understanding.
 | 
			
		||||
/* Some UserException causes, see table Table 4–64 in ISA reference */
 | 
			
		||||
 | 
			
		||||
   Part of esp-open-rtos
 | 
			
		||||
   Original vector contents Copyright (C) 2014-2015 Espressif Systems
 | 
			
		||||
   Additions Copyright (C) Superhouse Automation Pty Ltd
 | 
			
		||||
   BSD Licensed as described in the file LICENSE
 | 
			
		||||
*/
 | 
			
		||||
	.text
 | 
			
		||||
	.section .vecbase.text, "x"
 | 
			
		||||
        .align  256
 | 
			
		||||
        .global VecBase
 | 
			
		||||
        .type   VecBase, @function /* it's not really a function, but treat it like one */
 | 
			
		||||
#define CAUSE_SYSCALL 1
 | 
			
		||||
#define CAUSE_LOADSTORE 3
 | 
			
		||||
#define CAUSE_LVL1INT 4
 | 
			
		||||
 | 
			
		||||
        .section .bss
 | 
			
		||||
 | 
			
		||||
NMIHandlerStack:                # stack space for NMI handler
 | 
			
		||||
        .skip   4*0x100
 | 
			
		||||
.LNMIHandlerStackTop:
 | 
			
		||||
NMIRegisterSaved:               # register space for saving NMI registers
 | 
			
		||||
        .skip   4*(16 + 6)
 | 
			
		||||
 | 
			
		||||
LoadStoreErrorHandlerStack:
 | 
			
		||||
        .word   0       # a0
 | 
			
		||||
        .word   0       # (unused)
 | 
			
		||||
        .word   0       # a2
 | 
			
		||||
        .word   0       # a3
 | 
			
		||||
        .word   0       # a4
 | 
			
		||||
 | 
			
		||||
/***************************** Exception Vectors *****************************/
 | 
			
		||||
 | 
			
		||||
        .section .vecbase.text, "x"
 | 
			
		||||
 | 
			
		||||
/* Note: Exception vectors must be aligned on a 256-byte (0x100) boundary or
 | 
			
		||||
 * they will not function properly.  (This is taken care of in the linker
 | 
			
		||||
 * script by ensuring .vecbase.text is aligned properly, and putting VecBase
 | 
			
		||||
 * right at the beginning of .vecbase.text) */
 | 
			
		||||
        .org    0
 | 
			
		||||
VecBase:
 | 
			
		||||
	/* IMPORTANT: exception vector literals will go here, but we
 | 
			
		||||
	  can't have more than 4 otherwise we push DebugExceptionVector past
 | 
			
		||||
	  offset 0x10 relative to VecBase. There should be ways to avoid this,
 | 
			
		||||
	  and also keep the VecBase offsets easy to read, but this works for now.
 | 
			
		||||
	*/
 | 
			
		||||
	.literal_position
 | 
			
		||||
	.align 16
 | 
			
		||||
        .global VecBase
 | 
			
		||||
        /* IMPORTANT: exception vector literals will go here, but we
 | 
			
		||||
         * can't have more than 4 otherwise we push DebugExceptionVector past
 | 
			
		||||
         * offset 0x10 relative to VecBase. There should be ways to avoid this,
 | 
			
		||||
         * and also keep the VecBase offsets easy to read, but this works for
 | 
			
		||||
         * now. */
 | 
			
		||||
        .literal_position
 | 
			
		||||
 | 
			
		||||
        .org    VecBase + 0x10
 | 
			
		||||
DebugExceptionVector:
 | 
			
		||||
	wsr.excsave2 a0
 | 
			
		||||
	call0 sdk_user_fatal_exception_handler
 | 
			
		||||
	rfi 2
 | 
			
		||||
	.align 16
 | 
			
		||||
        .type   DebugExceptionVector, @function
 | 
			
		||||
 | 
			
		||||
        wsr     a0, excsave2
 | 
			
		||||
        call0   sdk_user_fatal_exception_handler
 | 
			
		||||
        rfi     2
 | 
			
		||||
 | 
			
		||||
        .org    VecBase + 0x20
 | 
			
		||||
NMIExceptionVector:
 | 
			
		||||
	wsr.excsave3 a0
 | 
			
		||||
	call0 CallNMIExceptionHandler
 | 
			
		||||
	rfi 3 /* CallNMIExceptionHandler should call rfi itself */
 | 
			
		||||
	.align 16
 | 
			
		||||
        .type   NMIExceptionVector, @function
 | 
			
		||||
 | 
			
		||||
        wsr     a0, excsave3
 | 
			
		||||
        call0   CallNMIExceptionHandler
 | 
			
		||||
        rfi     3  # Should never be reached
 | 
			
		||||
 | 
			
		||||
        .org    VecBase + 0x30
 | 
			
		||||
KernelExceptionVector:
 | 
			
		||||
	break 1, 0
 | 
			
		||||
	call0 sdk_user_fatal_exception_handler
 | 
			
		||||
	rfe
 | 
			
		||||
	.align 16
 | 
			
		||||
.L_EmptyVectorEntry:
 | 
			
		||||
	nop
 | 
			
		||||
	.align 16
 | 
			
		||||
        .type   KernelExceptionVector, @function
 | 
			
		||||
 | 
			
		||||
        break   1, 0
 | 
			
		||||
        call0   sdk_user_fatal_exception_handler
 | 
			
		||||
        rfe
 | 
			
		||||
 | 
			
		||||
        .org    VecBase + 0x50
 | 
			
		||||
UserExceptionVector:
 | 
			
		||||
	wsr.excsave1 a0
 | 
			
		||||
	call0 CallUserExceptionHandler
 | 
			
		||||
	rfe /* CallUserExceptionHandler should call rfe itself */
 | 
			
		||||
	.align 16
 | 
			
		||||
.L_EmptyVectorEntry2:
 | 
			
		||||
	nop
 | 
			
		||||
	.align 16
 | 
			
		||||
        .type   UserExceptionVector, @function
 | 
			
		||||
 | 
			
		||||
        wsr     a1, excsave1
 | 
			
		||||
        rsr     a1, exccause
 | 
			
		||||
        beqi    a1, CAUSE_LOADSTORE, LoadStoreErrorHandler
 | 
			
		||||
        j       UserExceptionHandler
 | 
			
		||||
 | 
			
		||||
        .org    VecBase + 0x70
 | 
			
		||||
DoubleExceptionVector:
 | 
			
		||||
	break 1, 4
 | 
			
		||||
	call0 sdk_user_fatal_exception_handler
 | 
			
		||||
	.align 16
 | 
			
		||||
.L_UnusedResetVector:
 | 
			
		||||
	/* reset vector slot doesn't get used, as vecbase goes back to mask ROM on reset */
 | 
			
		||||
	nop
 | 
			
		||||
        .type   DoubleExceptionVector, @function
 | 
			
		||||
 | 
			
		||||
	.section .bss
 | 
			
		||||
NMIHandlerStack: /* stack space for NMI handler */
 | 
			
		||||
	.skip 4*0x100
 | 
			
		||||
NMIRegisterSaved: /* register space for saving NMI registers */
 | 
			
		||||
	.skip 4*(0x16 + 6)
 | 
			
		||||
        break   1, 4
 | 
			
		||||
        call0   sdk_user_fatal_exception_handler
 | 
			
		||||
 | 
			
		||||
/* this symbol is _Pri_3_HandlerAddress in the RTOS SDK, appears totally
 | 
			
		||||
	unused (stays zero at all times) */
 | 
			
		||||
	.global NMIHandlerAddress
 | 
			
		||||
NMIHandlerAddress:
 | 
			
		||||
	.long 0
 | 
			
		||||
/* Reset vector at offset 0x80 is unused, as vecbase gets reset to mask ROM
 | 
			
		||||
 * vectors on chip reset. */
 | 
			
		||||
 | 
			
		||||
/*************************** LoadStoreError Handler **************************/
 | 
			
		||||
 | 
			
		||||
        .section .vecbase.text, "x"
 | 
			
		||||
 | 
			
		||||
/* Xtensa "Load/Store Exception" handler:
 | 
			
		||||
 * Completes L8/L16 load instructions from Instruction address space, for which
 | 
			
		||||
 * the architecture only supports 32-bit reads.
 | 
			
		||||
 *
 | 
			
		||||
 * Called from UserExceptionVector if EXCCAUSE is LoadStoreErrorCause
 | 
			
		||||
 *
 | 
			
		||||
 * (Fast path (no branches) is for L8UI)
 | 
			
		||||
 */
 | 
			
		||||
        .literal_position
 | 
			
		||||
 | 
			
		||||
        .balign 4
 | 
			
		||||
LoadStoreErrorHandler:
 | 
			
		||||
        .type   LoadStoreErrorHandler, @function
 | 
			
		||||
 | 
			
		||||
        /* Registers are saved in the address corresponding to their register
 | 
			
		||||
         * number times 4.  This allows a quick and easy mapping later on when
 | 
			
		||||
         * needing to store the value to a particular register number. */
 | 
			
		||||
        movi    sp, LoadStoreErrorHandlerStack
 | 
			
		||||
        s32i    a0, sp, 0
 | 
			
		||||
        s32i    a2, sp, 0x08
 | 
			
		||||
        s32i    a3, sp, 0x0c
 | 
			
		||||
        s32i    a4, sp, 0x10
 | 
			
		||||
        rsr     a0, sar         # Save SAR in a0 to restore later
 | 
			
		||||
 | 
			
		||||
        /* Examine the opcode which generated the exception */
 | 
			
		||||
        /* Note: Instructions are in this order to avoid pipeline stalls. */
 | 
			
		||||
        rsr     a2, epc1
 | 
			
		||||
        movi    a3, ~3
 | 
			
		||||
        ssa8l   a2              # sar is now correct shift for aligned read
 | 
			
		||||
        and     a2, a2, a3      # a2 now 4-byte aligned address of instruction
 | 
			
		||||
        l32i    a4, a2, 0
 | 
			
		||||
        l32i    a2, a2, 4
 | 
			
		||||
        movi    a3, 0x00700F    # opcode mask for l8ui/l16si/l16ui
 | 
			
		||||
        src     a2, a2, a4      # a2 now instruction that failed
 | 
			
		||||
        and     a3, a2, a3      # a3 is masked instruction
 | 
			
		||||
        bnei    a3, 0x000002, .LSE_check_l16
 | 
			
		||||
 | 
			
		||||
        /* Note: At this point, opcode could technically be one of two things:
 | 
			
		||||
         *   xx0xx2 (L8UI)
 | 
			
		||||
         *   xx8xx2 (Reserved (invalid) opcode)
 | 
			
		||||
         * It is assumed that we'll never get to this point from an illegal
 | 
			
		||||
         * opcode, so we don't bother to check for that case and presume this
 | 
			
		||||
         * is always an L8UI. */
 | 
			
		||||
 | 
			
		||||
        movi    a4, ~3
 | 
			
		||||
        rsr     a3, excvaddr    # read faulting address
 | 
			
		||||
        and     a4, a3, a4      # a4 now word aligned read address
 | 
			
		||||
 | 
			
		||||
        l32i    a4, a4, 0       # perform the actual read
 | 
			
		||||
        ssa8l   a3              # sar is now shift to extract a3's byte
 | 
			
		||||
        srl     a3, a4          # shift right correct distance
 | 
			
		||||
        extui   a4, a3, 0, 8    # mask off bits we need for an l8
 | 
			
		||||
 | 
			
		||||
.LSE_post_fetch:
 | 
			
		||||
        /* We jump back here after either the L8UI or the L16*I routines do the
 | 
			
		||||
         * necessary work to read the value from memory.
 | 
			
		||||
         * At this point, a2 holds the faulting instruction and a4 holds the
 | 
			
		||||
         * correctly read value.
 | 
			
		||||
 | 
			
		||||
         * Restore original SAR value (saved in a0) and update EPC so we'll
 | 
			
		||||
         * return back to the instruction following the one we just emulated */
 | 
			
		||||
 | 
			
		||||
        /* Note: Instructions are in this order to avoid pipeline stalls */
 | 
			
		||||
        rsr     a3, epc1
 | 
			
		||||
        wsr     a0, sar
 | 
			
		||||
        addi    a3, a3, 0x3
 | 
			
		||||
        wsr     a3, epc1
 | 
			
		||||
 | 
			
		||||
        /* Stupid opcode tricks: The jumptable we use later on needs 16 bytes
 | 
			
		||||
         * per entry (so we can avoid a second jump by just doing a RFE inside
 | 
			
		||||
         * each entry).  Unfortunately, however, Xtensa doesn't have an addx16
 | 
			
		||||
         * operation to make that easy for us.  Luckily, all of the faulting
 | 
			
		||||
         * opcodes we're processing are guaranteed to have bit 3 be zero, which
 | 
			
		||||
         * means if we just shift the register bits of the opcode down by 3
 | 
			
		||||
         * instead of 4, we will get the register number multiplied by 2.  This
 | 
			
		||||
         * combined with an addx8 will give us an effective addx16 without
 | 
			
		||||
         * needing any extra shift operations. */
 | 
			
		||||
        extui   a2, a2, 3, 5    # a2 is now destination register 0-15 times 2
 | 
			
		||||
 | 
			
		||||
        bgei    a2, 10, .LSE_assign_reg     # a5..a15 use jumptable
 | 
			
		||||
        beqi    a2, 2, .LSE_assign_a1       # a1 uses a special routine
 | 
			
		||||
 | 
			
		||||
        /* We're storing into a0 or a2..a4, which are all saved in our "stack"
 | 
			
		||||
         * area.  Calculate the correct address and stick the value in there,
 | 
			
		||||
         * then just do our normal restore and RFE (no jumps required, which
 | 
			
		||||
         * actually makes a0..a4 substantially faster). */
 | 
			
		||||
        addx2   a2, a2, sp
 | 
			
		||||
        s32i    a4, a2, 0
 | 
			
		||||
 | 
			
		||||
        /* Restore all regs and return */
 | 
			
		||||
        l32i    a0, sp, 0
 | 
			
		||||
        l32i    a2, sp, 0x08
 | 
			
		||||
        l32i    a3, sp, 0x0c
 | 
			
		||||
        l32i    a4, sp, 0x10
 | 
			
		||||
        rsr     a1, excsave1    # restore a1 saved by UserExceptionVector
 | 
			
		||||
        rfe
 | 
			
		||||
 | 
			
		||||
.LSE_assign_reg:
 | 
			
		||||
        /* At this point, a2 contains the register number times 2, a4 is the
 | 
			
		||||
         * read value. */
 | 
			
		||||
 | 
			
		||||
        /* Calculate the jumptable address, and restore all regs except a2 and
 | 
			
		||||
         * a4 so we have less to do after jumping. */
 | 
			
		||||
        /* Note: Instructions are in this order to avoid pipeline stalls. */
 | 
			
		||||
        movi    a3, .LSE_jumptable_base
 | 
			
		||||
        l32i    a0, sp, 0
 | 
			
		||||
        addx8   a2, a2, a3      # a2 is now the address to jump to
 | 
			
		||||
        l32i    a3, sp, 0x0c
 | 
			
		||||
 | 
			
		||||
        jx      a2
 | 
			
		||||
 | 
			
		||||
        .balign 4
 | 
			
		||||
.LSE_check_l16:
 | 
			
		||||
        /* At this point, a2 contains the opcode, a3 is masked opcode */
 | 
			
		||||
        movi    a4, 0x001002    # l16si or l16ui opcode after masking
 | 
			
		||||
        bne     a3, a4, .LSE_wrong_opcode
 | 
			
		||||
 | 
			
		||||
        /* Note: At this point, the opcode could be one of two things:
 | 
			
		||||
         *   xx1xx2 (L16UI)
 | 
			
		||||
         *   xx9xx2 (L16SI)
 | 
			
		||||
         * Both of these we can handle. */
 | 
			
		||||
 | 
			
		||||
        movi    a4, ~3
 | 
			
		||||
        rsr     a3, excvaddr    # read faulting address
 | 
			
		||||
        and     a4, a3, a4      # a4 now word aligned read address
 | 
			
		||||
 | 
			
		||||
        l32i    a4, a4, 0       # perform the actual read
 | 
			
		||||
        ssa8l   a3              # sar is now shift to extract a3's bytes
 | 
			
		||||
        srl     a3, a4          # shift right correct distance
 | 
			
		||||
        extui   a4, a3, 0, 16   # mask off bits we need for an l16
 | 
			
		||||
 | 
			
		||||
        bbci    a2, 15, .LSE_post_fetch  # Not a signed op
 | 
			
		||||
        bbci    a4, 15, .LSE_post_fetch  # Value does not need sign-extension
 | 
			
		||||
 | 
			
		||||
        movi    a3, 0xFFFF0000
 | 
			
		||||
        or      a4, a3, a4      # set 32-bit sign bits
 | 
			
		||||
        j       .LSE_post_fetch
 | 
			
		||||
 | 
			
		||||
.LSE_wrong_opcode:
 | 
			
		||||
        /* If we got here it's not an opcode we can try to fix, so bomb out.
 | 
			
		||||
         * Restore registers so any dump the fatal exception routine produces
 | 
			
		||||
         * will have correct values */
 | 
			
		||||
        wsr     a0, sar
 | 
			
		||||
        l32i    a0, sp, 0
 | 
			
		||||
        l32i    a2, sp, 0x08
 | 
			
		||||
        l32i    a3, sp, 0x0c
 | 
			
		||||
        l32i    a4, sp, 0x10
 | 
			
		||||
        rsr     a1, excsave1
 | 
			
		||||
        call0   sdk_user_fatal_exception_handler
 | 
			
		||||
 | 
			
		||||
        .balign 4
 | 
			
		||||
.LSE_assign_a1:
 | 
			
		||||
        /* a1 is saved in excsave1, so just update that with the value, */
 | 
			
		||||
        wsr     a4, excsave1
 | 
			
		||||
        /* Then restore all regs and return */
 | 
			
		||||
        l32i    a0, sp, 0
 | 
			
		||||
        l32i    a2, sp, 0x08
 | 
			
		||||
        l32i    a3, sp, 0x0c
 | 
			
		||||
        l32i    a4, sp, 0x10
 | 
			
		||||
        rsr     a1, excsave1
 | 
			
		||||
        rfe
 | 
			
		||||
 | 
			
		||||
        .balign 4
 | 
			
		||||
.LSE_jumptable:
 | 
			
		||||
        /* The first 5 entries (80 bytes) of this table are unused (registers
 | 
			
		||||
         * a0..a4 are handled separately above).  Rather than have a whole bunch
 | 
			
		||||
         * of wasted space, we just pretend that the table starts 80 bytes
 | 
			
		||||
         * earlier in memory. */
 | 
			
		||||
        .set    .LSE_jumptable_base, .LSE_jumptable - (16 * 5)
 | 
			
		||||
 | 
			
		||||
        .org    .LSE_jumptable_base + (16 * 5)
 | 
			
		||||
        mov     a5, a4
 | 
			
		||||
        l32i    a2, sp, 0x08
 | 
			
		||||
        l32i    a4, sp, 0x10
 | 
			
		||||
        rsr     a1, excsave1
 | 
			
		||||
        rfe
 | 
			
		||||
 | 
			
		||||
        .org    .LSE_jumptable_base + (16 * 6)
 | 
			
		||||
        mov     a6, a4
 | 
			
		||||
        l32i    a2, sp, 0x08
 | 
			
		||||
        l32i    a4, sp, 0x10
 | 
			
		||||
        rsr     a1, excsave1
 | 
			
		||||
        rfe
 | 
			
		||||
 | 
			
		||||
        .org    .LSE_jumptable_base + (16 * 7)
 | 
			
		||||
        mov     a7, a4
 | 
			
		||||
        l32i    a2, sp, 0x08
 | 
			
		||||
        l32i    a4, sp, 0x10
 | 
			
		||||
        rsr     a1, excsave1
 | 
			
		||||
        rfe
 | 
			
		||||
 | 
			
		||||
        .org    .LSE_jumptable_base + (16 * 8)
 | 
			
		||||
        mov     a8, a4
 | 
			
		||||
        l32i    a2, sp, 0x08
 | 
			
		||||
        l32i    a4, sp, 0x10
 | 
			
		||||
        rsr     a1, excsave1
 | 
			
		||||
        rfe
 | 
			
		||||
 | 
			
		||||
        .org    .LSE_jumptable_base + (16 * 9)
 | 
			
		||||
        mov     a9, a4
 | 
			
		||||
        l32i    a2, sp, 0x08
 | 
			
		||||
        l32i    a4, sp, 0x10
 | 
			
		||||
        rsr     a1, excsave1
 | 
			
		||||
        rfe
 | 
			
		||||
 | 
			
		||||
        .org    .LSE_jumptable_base + (16 * 10)
 | 
			
		||||
        mov     a10, a4
 | 
			
		||||
        l32i    a2, sp, 0x08
 | 
			
		||||
        l32i    a4, sp, 0x10
 | 
			
		||||
        rsr     a1, excsave1
 | 
			
		||||
        rfe
 | 
			
		||||
 | 
			
		||||
        .org    .LSE_jumptable_base + (16 * 11)
 | 
			
		||||
        mov     a11, a4
 | 
			
		||||
        l32i    a2, sp, 0x08
 | 
			
		||||
        l32i    a4, sp, 0x10
 | 
			
		||||
        rsr     a1, excsave1
 | 
			
		||||
        rfe
 | 
			
		||||
 | 
			
		||||
        .org    .LSE_jumptable_base + (16 * 12)
 | 
			
		||||
        mov     a12, a4
 | 
			
		||||
        l32i    a2, sp, 0x08
 | 
			
		||||
        l32i    a4, sp, 0x10
 | 
			
		||||
        rsr     a1, excsave1
 | 
			
		||||
        rfe
 | 
			
		||||
 | 
			
		||||
        .org    .LSE_jumptable_base + (16 * 13)
 | 
			
		||||
        mov     a13, a4
 | 
			
		||||
        l32i    a2, sp, 0x08
 | 
			
		||||
        l32i    a4, sp, 0x10
 | 
			
		||||
        rsr     a1, excsave1
 | 
			
		||||
        rfe
 | 
			
		||||
 | 
			
		||||
        .org    .LSE_jumptable_base + (16 * 14)
 | 
			
		||||
        mov     a14, a4
 | 
			
		||||
        l32i    a2, sp, 0x08
 | 
			
		||||
        l32i    a4, sp, 0x10
 | 
			
		||||
        rsr     a1, excsave1
 | 
			
		||||
        rfe
 | 
			
		||||
 | 
			
		||||
        .org    .LSE_jumptable_base + (16 * 15)
 | 
			
		||||
        mov     a15, a4
 | 
			
		||||
        l32i    a2, sp, 0x08
 | 
			
		||||
        l32i    a4, sp, 0x10
 | 
			
		||||
        rsr     a1, excsave1
 | 
			
		||||
        rfe
 | 
			
		||||
 | 
			
		||||
/****************************** call_user_start ******************************/
 | 
			
		||||
 | 
			
		||||
        .section .vecbase.text, "x"
 | 
			
		||||
 | 
			
		||||
/* This is the first entrypoint called from the ROM after loading the image
 | 
			
		||||
 * into IRAM.  It just sets up the VECBASE register to point at our own
 | 
			
		||||
 * exception vectors and then calls sdk_user_start() */
 | 
			
		||||
 | 
			
		||||
        .literal_position
 | 
			
		||||
 | 
			
		||||
        .balign 4
 | 
			
		||||
call_user_start:
 | 
			
		||||
        .global call_user_start
 | 
			
		||||
        .type   call_user_start, @function
 | 
			
		||||
 | 
			
		||||
        movi    a2, VecBase
 | 
			
		||||
        wsr     a2, vecbase
 | 
			
		||||
        call0   sdk_user_start
 | 
			
		||||
 | 
			
		||||
/*************************** NMI Exception Handler ***************************/
 | 
			
		||||
 | 
			
		||||
        .section .vecbase.text, "x"
 | 
			
		||||
 | 
			
		||||
/* Save register relative to a0 */
 | 
			
		||||
.macro SAVE_REG register, regnum
 | 
			
		||||
	s32i \register, a0, (0x20 + 4 * \regnum)
 | 
			
		||||
        s32i \register, a0, (4 * (\regnum + 6))
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
/* Load register relative to sp */
 | 
			
		||||
.macro LOAD_REG register, regnum
 | 
			
		||||
	l32i \register, sp, (0x20 + 4 * \regnum)
 | 
			
		||||
        l32i \register, sp, (4 * (\regnum + 6))
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
	.text
 | 
			
		||||
	.section .vecbase.text
 | 
			
		||||
	.literal_position
 | 
			
		||||
        .align  4
 | 
			
		||||
	.global call_user_start
 | 
			
		||||
        .type   call_user_start, @function
 | 
			
		||||
call_user_start:
 | 
			
		||||
	movi a2, VecBase
 | 
			
		||||
	wsr.vecbase a2
 | 
			
		||||
	call0 sdk_user_start
 | 
			
		||||
        .literal_position
 | 
			
		||||
 | 
			
		||||
	.literal_position
 | 
			
		||||
        .align  16
 | 
			
		||||
        .type   CallNMIExceptionHandler, @function
 | 
			
		||||
        .balign  16
 | 
			
		||||
CallNMIExceptionHandler:
 | 
			
		||||
	movi a0, NMIRegisterSaved
 | 
			
		||||
	SAVE_REG a2, 2
 | 
			
		||||
	movi a2, NMIHandlerAddress
 | 
			
		||||
	l32i a2, a2, 0
 | 
			
		||||
	SAVE_REG sp, 1
 | 
			
		||||
	SAVE_REG a3, 3
 | 
			
		||||
	xsr.excsave3 a2 /* excsave3 is now NMIHandlerAddress, a2 is former a0 */
 | 
			
		||||
	SAVE_REG a4, 4
 | 
			
		||||
	SAVE_REG a2, 0
 | 
			
		||||
	rsr.epc1 a3
 | 
			
		||||
	rsr.exccause a4
 | 
			
		||||
	SAVE_REG a3, -5
 | 
			
		||||
	SAVE_REG a4, -4
 | 
			
		||||
	rsr.excvaddr a3
 | 
			
		||||
	SAVE_REG a3, -3
 | 
			
		||||
	rsr.excsave1 a3
 | 
			
		||||
	SAVE_REG a3, -2
 | 
			
		||||
	SAVE_REG a5, 5
 | 
			
		||||
	SAVE_REG a6, 6
 | 
			
		||||
	SAVE_REG a7, 7
 | 
			
		||||
	SAVE_REG a8, 8
 | 
			
		||||
	SAVE_REG a9, 9
 | 
			
		||||
	SAVE_REG a10, 10
 | 
			
		||||
	SAVE_REG a11, 11
 | 
			
		||||
	SAVE_REG a12, 12
 | 
			
		||||
	SAVE_REG a13, 13
 | 
			
		||||
	SAVE_REG a14, 14
 | 
			
		||||
	SAVE_REG a15, 15
 | 
			
		||||
	movi sp, NMIRegisterSaved /* also top of NMIHandlerStack */
 | 
			
		||||
	movi a0, 0
 | 
			
		||||
	movi a2, 0x23 /* argument for handler */
 | 
			
		||||
	wsr.ps a2
 | 
			
		||||
	rsync
 | 
			
		||||
	rsr.sar a14
 | 
			
		||||
	s32i a14, sp, 0 /* this is also NMIRegisterSaved+0 */
 | 
			
		||||
	call0 sdk_wDev_ProcessFiq
 | 
			
		||||
	l32i a15, sp, 0
 | 
			
		||||
	wsr.sar a15
 | 
			
		||||
	movi a2, 0x33
 | 
			
		||||
	wsr.ps a2
 | 
			
		||||
	rsync
 | 
			
		||||
	LOAD_REG a4, 4
 | 
			
		||||
	LOAD_REG a5, 5
 | 
			
		||||
	LOAD_REG a6, 6
 | 
			
		||||
	LOAD_REG a7, 7
 | 
			
		||||
	LOAD_REG a8, 8
 | 
			
		||||
	LOAD_REG a9, 9
 | 
			
		||||
	LOAD_REG a10, 10
 | 
			
		||||
	LOAD_REG a11, 11
 | 
			
		||||
	LOAD_REG a12, 12
 | 
			
		||||
	LOAD_REG a13, 13
 | 
			
		||||
	LOAD_REG a14, 14
 | 
			
		||||
	LOAD_REG a15, 15
 | 
			
		||||
	LOAD_REG a2, -5
 | 
			
		||||
	LOAD_REG a3, -4
 | 
			
		||||
	wsr.epc1 a2
 | 
			
		||||
	wsr.exccause a3
 | 
			
		||||
	LOAD_REG a2, -3
 | 
			
		||||
	LOAD_REG a3, -2
 | 
			
		||||
	wsr.excvaddr a2
 | 
			
		||||
	wsr.excsave1 a3
 | 
			
		||||
	LOAD_REG a0, 0
 | 
			
		||||
	/* set dport nmi status bit 0 (wDev_ProcessFiq clears & verifies this bit stays cleared,
 | 
			
		||||
	   see http://esp8266-re.foogod.com/wiki/WDev_ProcessFiq_%28IoT_RTOS_SDK_0.9.9%29)  */
 | 
			
		||||
	movi a2, 0x3ff00000
 | 
			
		||||
	movi a3, 0x1
 | 
			
		||||
	s32i a3, a2, 0
 | 
			
		||||
	LOAD_REG a2, 2
 | 
			
		||||
	LOAD_REG a3, 3
 | 
			
		||||
	LOAD_REG a1, 1
 | 
			
		||||
	rfi 0x3
 | 
			
		||||
        .type   CallNMIExceptionHandler, @function
 | 
			
		||||
 | 
			
		||||
/* Some UserException causes, see table Table 4–64 in ISA reference */
 | 
			
		||||
#define CAUSE_SYSCALL 1
 | 
			
		||||
#define CAUSE_LVL1INT 4
 | 
			
		||||
        movi    a0, NMIRegisterSaved
 | 
			
		||||
        SAVE_REG a2, 2
 | 
			
		||||
        SAVE_REG sp, 1
 | 
			
		||||
        SAVE_REG a3, 3
 | 
			
		||||
        rsr     a2, excsave3    # a2 is now former a0
 | 
			
		||||
        SAVE_REG a4, 4
 | 
			
		||||
        SAVE_REG a2, 0
 | 
			
		||||
        rsr     a3, epc1
 | 
			
		||||
        rsr     a4, exccause
 | 
			
		||||
        SAVE_REG a3, -5
 | 
			
		||||
        SAVE_REG a4, -4
 | 
			
		||||
        rsr     a3, excvaddr
 | 
			
		||||
        SAVE_REG a3, -3
 | 
			
		||||
        rsr     a3, excsave1
 | 
			
		||||
        SAVE_REG a3, -2
 | 
			
		||||
        SAVE_REG a5, 5
 | 
			
		||||
        SAVE_REG a6, 6
 | 
			
		||||
        SAVE_REG a7, 7
 | 
			
		||||
        SAVE_REG a8, 8
 | 
			
		||||
        SAVE_REG a9, 9
 | 
			
		||||
        SAVE_REG a10, 10
 | 
			
		||||
        SAVE_REG a11, 11
 | 
			
		||||
        SAVE_REG a12, 12
 | 
			
		||||
        SAVE_REG a13, 13
 | 
			
		||||
        SAVE_REG a14, 14
 | 
			
		||||
        SAVE_REG a15, 15
 | 
			
		||||
        movi    sp, .LNMIHandlerStackTop
 | 
			
		||||
        movi    a0, 0
 | 
			
		||||
        movi    a2, 0x23        # argument for handler
 | 
			
		||||
        wsr     a2, ps
 | 
			
		||||
        rsync
 | 
			
		||||
        rsr     a14, sar
 | 
			
		||||
        s32i    a14, sp, 0      # this is also NMIRegisterSaved+0
 | 
			
		||||
        call0   sdk_wDev_ProcessFiq
 | 
			
		||||
        l32i    a15, sp, 0
 | 
			
		||||
        wsr     a15, sar
 | 
			
		||||
        movi    a2, 0x33
 | 
			
		||||
        wsr     a2, ps
 | 
			
		||||
        rsync
 | 
			
		||||
        LOAD_REG a4, 4
 | 
			
		||||
        LOAD_REG a5, 5
 | 
			
		||||
        LOAD_REG a6, 6
 | 
			
		||||
        LOAD_REG a7, 7
 | 
			
		||||
        LOAD_REG a8, 8
 | 
			
		||||
        LOAD_REG a9, 9
 | 
			
		||||
        LOAD_REG a10, 10
 | 
			
		||||
        LOAD_REG a11, 11
 | 
			
		||||
        LOAD_REG a12, 12
 | 
			
		||||
        LOAD_REG a13, 13
 | 
			
		||||
        LOAD_REG a14, 14
 | 
			
		||||
        LOAD_REG a15, 15
 | 
			
		||||
        LOAD_REG a2, -5
 | 
			
		||||
        LOAD_REG a3, -4
 | 
			
		||||
        wsr     a2, epc1
 | 
			
		||||
        wsr     a3, exccause
 | 
			
		||||
        LOAD_REG a2, -3
 | 
			
		||||
        LOAD_REG a3, -2
 | 
			
		||||
        wsr     a2, excvaddr
 | 
			
		||||
        wsr     a3, excsave1
 | 
			
		||||
        LOAD_REG a0, 0
 | 
			
		||||
        /* set dport nmi status bit 0 (wDev_ProcessFiq clears & verifies this
 | 
			
		||||
         * bit stays cleared, see
 | 
			
		||||
         * http://esp8266-re.foogod.com/wiki/WDev_ProcessFiq_%28IoT_RTOS_SDK_0.9.9%29)
 | 
			
		||||
         */
 | 
			
		||||
        movi    a2, 0x3ff00000
 | 
			
		||||
        movi    a3, 0x1
 | 
			
		||||
        s32i    a3, a2, 0
 | 
			
		||||
        LOAD_REG a2, 2
 | 
			
		||||
        LOAD_REG a3, 3
 | 
			
		||||
        LOAD_REG a1, 1
 | 
			
		||||
        rfi     3
 | 
			
		||||
 | 
			
		||||
        .type   CallUserExceptionHandler, @function
 | 
			
		||||
CallUserExceptionHandler:
 | 
			
		||||
	rsr.exccause a0
 | 
			
		||||
	beqi a0, CAUSE_SYSCALL, UserSyscallHandler
 | 
			
		||||
	mov a0, sp
 | 
			
		||||
	addi sp, sp, -0x50
 | 
			
		||||
	s32i a0, sp, 0x10
 | 
			
		||||
	rsr.ps a0
 | 
			
		||||
	s32i a0, sp, 0x08
 | 
			
		||||
	rsr.epc1 a0
 | 
			
		||||
	s32i a0, sp, 0x04
 | 
			
		||||
	rsr.excsave1 a0 /* a0 was saved in UserExceptionVector */
 | 
			
		||||
	s32i a0, sp, 0x0c
 | 
			
		||||
	movi a0, _xt_user_exit
 | 
			
		||||
	s32i a0, sp, 0x0
 | 
			
		||||
	call0 sdk__xt_int_enter
 | 
			
		||||
	movi a0, 0x23
 | 
			
		||||
	wsr.ps a0
 | 
			
		||||
	rsync
 | 
			
		||||
	rsr.exccause a2
 | 
			
		||||
	beqi a2, CAUSE_LVL1INT, UserHandleInterrupt
 | 
			
		||||
	/* Any UserException cause other than level 1 interrupt triggers a panic */
 | 
			
		||||
/*********************** General UserException Handler ***********************/
 | 
			
		||||
 | 
			
		||||
        .section .vecbase.text, "x"
 | 
			
		||||
 | 
			
		||||
/* Called by UserExceptionVector if EXCCAUSE is anything other than
 | 
			
		||||
 * LoadStoreCause. */
 | 
			
		||||
 | 
			
		||||
        .literal_position
 | 
			
		||||
 | 
			
		||||
        .balign  4
 | 
			
		||||
UserExceptionHandler:
 | 
			
		||||
        .type   UserExceptionHandler, @function
 | 
			
		||||
        xsr     a0, excsave1    # a0 now contains sp
 | 
			
		||||
        mov     sp, a0
 | 
			
		||||
        addi    sp, sp, -0x50
 | 
			
		||||
        s32i    a0, sp, 0x10
 | 
			
		||||
        rsr     a0, ps
 | 
			
		||||
        s32i    a0, sp, 0x08
 | 
			
		||||
        rsr     a0, epc1
 | 
			
		||||
        s32i    a0, sp, 0x04
 | 
			
		||||
        rsr     a0, excsave1
 | 
			
		||||
        s32i    a0, sp, 0x0c
 | 
			
		||||
        movi    a0, _xt_user_exit
 | 
			
		||||
        s32i    a0, sp, 0x0
 | 
			
		||||
        call0   sdk__xt_int_enter
 | 
			
		||||
        movi    a0, 0x23
 | 
			
		||||
        wsr     a0, ps
 | 
			
		||||
        rsync
 | 
			
		||||
        rsr     a2, exccause
 | 
			
		||||
        beqi    a2, CAUSE_LVL1INT, UserHandleInterrupt
 | 
			
		||||
        /* Any UserException cause other than level 1 interrupt should panic */
 | 
			
		||||
UserFailOtherExceptionCause:
 | 
			
		||||
	break 1, 1
 | 
			
		||||
	call0 sdk_user_fatal_exception_handler
 | 
			
		||||
        break   1, 1
 | 
			
		||||
        call0   sdk_user_fatal_exception_handler
 | 
			
		||||
UserHandleInterrupt:
 | 
			
		||||
	rsil a0, 1
 | 
			
		||||
	rsr.intenable a2
 | 
			
		||||
	rsr.interrupt a3
 | 
			
		||||
	movi a4, 0x3fff
 | 
			
		||||
	and a2, a2, a3
 | 
			
		||||
	and a2, a2, a4 /* a2 = 0x3FFF & INTENABLE & INTERRUPT */
 | 
			
		||||
        rsil    a0, 1
 | 
			
		||||
        rsr     a2, intenable
 | 
			
		||||
        rsr     a3, interrupt
 | 
			
		||||
        movi    a4, 0x3fff
 | 
			
		||||
        and     a2, a2, a3
 | 
			
		||||
        and     a2, a2, a4      # a2 = 0x3FFF & INTENABLE & INTERRUPT
 | 
			
		||||
UserHandleTimer:
 | 
			
		||||
	movi a3, 0xffbf
 | 
			
		||||
	and a3, a2, a3 /* a3 = a2 & 0xFFBF, ie remove 0x40 from a2 if set */
 | 
			
		||||
	bnez a3, UserTimerDone /* bits other than 0x40 are set */
 | 
			
		||||
	movi a3, 0x40
 | 
			
		||||
	sub a12, a2, a3 /* a12 - a2 - 0x40 - I think a12 _must_ be zero here? */
 | 
			
		||||
	call0 sdk__xt_timer_int /* tick timer interrupt */
 | 
			
		||||
	mov a2, a12 /* restore a2 from a12, ie zero */
 | 
			
		||||
	beqz a2, UserIntDone
 | 
			
		||||
        movi    a3, 0xffbf
 | 
			
		||||
        and     a3, a2, a3      # a3 = a2 with bit 6 cleared
 | 
			
		||||
        bnez    a3, UserTimerDone   # If any non-timer interrupt bits set
 | 
			
		||||
        movi    a3, 0x40
 | 
			
		||||
        sub     a12, a2, a3     # a12 = a2 - 0x40 -- Will be zero if bit 6 set
 | 
			
		||||
        call0   sdk__xt_timer_int  # tick timer interrupt
 | 
			
		||||
        mov     a2, a12         # restore a2 from a12, ie zero
 | 
			
		||||
        beqz    a2, UserIntDone
 | 
			
		||||
UserTimerDone:
 | 
			
		||||
	call0 _xt_isr_handler
 | 
			
		||||
	bnez a2, UserHandleTimer
 | 
			
		||||
        call0   _xt_isr_handler
 | 
			
		||||
        bnez    a2, UserHandleTimer
 | 
			
		||||
UserIntDone:
 | 
			
		||||
	beqz a2, UserIntExit
 | 
			
		||||
	break 1, 1 /* non-zero remnant in a2 means fail */
 | 
			
		||||
	call0 sdk_user_fatal_exception_handler
 | 
			
		||||
        beqz    a2, UserIntExit
 | 
			
		||||
        /* FIXME: this code will never be reached */
 | 
			
		||||
        break   1, 1
 | 
			
		||||
        call0   sdk_user_fatal_exception_handler
 | 
			
		||||
UserIntExit:
 | 
			
		||||
	call0 sdk__xt_int_exit /* calls rfi */
 | 
			
		||||
        call0   sdk__xt_int_exit  # jumps to _xt_user_exit. Never returns here
 | 
			
		||||
 | 
			
		||||
/* As far as I can tell, the syscall handler is basically a no-op */
 | 
			
		||||
UserSyscallHandler:
 | 
			
		||||
	addi sp, sp, -0x10
 | 
			
		||||
	s32i a2, sp, 0x08
 | 
			
		||||
	s32i a2, sp, 0x0c
 | 
			
		||||
	rsr.epc1 a2
 | 
			
		||||
	addi a3, a2, 0x3
 | 
			
		||||
	wsr.epc1 a3
 | 
			
		||||
	l32i a2, sp, 0x8
 | 
			
		||||
	l32i a3, sp, 0xc
 | 
			
		||||
	addi sp, sp, 0x10
 | 
			
		||||
	movi a0, 0x7f
 | 
			
		||||
	movnez a2, a0, a2
 | 
			
		||||
	rsr.excsave1 a0
 | 
			
		||||
	rfe
 | 
			
		||||
        .section .text
 | 
			
		||||
 | 
			
		||||
	.global _xt_user_exit
 | 
			
		||||
	.type _xt_user_exit, @function
 | 
			
		||||
/* _xt_user_exit is used to exit interrupt context. */
 | 
			
		||||
/* TODO: Find a better place for this to live. */
 | 
			
		||||
_xt_user_exit:
 | 
			
		||||
	l32i a0, sp, 0x8
 | 
			
		||||
	wsr.ps a0
 | 
			
		||||
	l32i a0, sp, 0x4
 | 
			
		||||
	wsr.epc1 a0
 | 
			
		||||
	l32i a0, sp, 0xc
 | 
			
		||||
	l32i sp, sp, 0x10
 | 
			
		||||
	rsync
 | 
			
		||||
	rfe
 | 
			
		||||
        .global _xt_user_exit
 | 
			
		||||
        .type _xt_user_exit, @function
 | 
			
		||||
 | 
			
		||||
        l32i    a0, sp, 0x8
 | 
			
		||||
        wsr     a0, ps
 | 
			
		||||
        l32i    a0, sp, 0x4
 | 
			
		||||
        wsr     a0, epc1
 | 
			
		||||
        l32i    a0, sp, 0xc
 | 
			
		||||
        l32i    sp, sp, 0x10
 | 
			
		||||
        rsync
 | 
			
		||||
        rfe
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										22
									
								
								core/include/esp/hwrand.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								core/include/esp/hwrand.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
/** esp/hwrand.h
 | 
			
		||||
 *
 | 
			
		||||
 * Hardware Random Number Generator functions.
 | 
			
		||||
 *
 | 
			
		||||
 * For documentation, see http://esp8266-re.foogod.com/wiki/Random_Number_Generator
 | 
			
		||||
 *
 | 
			
		||||
 * Part of esp-open-rtos
 | 
			
		||||
 * Copyright (C) 2015 Angus Gratton
 | 
			
		||||
 * BSD Licensed as described in the file LICENSE
 | 
			
		||||
 */
 | 
			
		||||
#ifndef _ESP_RNG_H
 | 
			
		||||
#define _ESP_RNG_H
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
/* Return a random 32-bit number */
 | 
			
		||||
uint32_t hwrand(void);
 | 
			
		||||
 | 
			
		||||
/* Fill a variable size buffer with data from the Hardware RNG */
 | 
			
		||||
void hwrand_fill(uint8_t *buf, size_t len);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -2,6 +2,9 @@
 | 
			
		|||
 *
 | 
			
		||||
 * ESP8266 register definitions for the "wdev" region (0x3FF2xxx)
 | 
			
		||||
 *
 | 
			
		||||
 * In the DPORT memory space, alongside DPORT regs. However mostly
 | 
			
		||||
 * concerned with the WiFi hardware interface.
 | 
			
		||||
 *
 | 
			
		||||
 * Not compatible with ESP SDK register access code.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -21,10 +24,19 @@
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
struct WDEV_REGS {
 | 
			
		||||
    uint32_t volatile _unknown[768];  // 0x0000 - 0x0bfc
 | 
			
		||||
    uint32_t volatile SYS_TIME;       // 0x0c00
 | 
			
		||||
    uint32_t volatile _unknown0[768];  // 0x0000 - 0x0bfc
 | 
			
		||||
    uint32_t volatile SYS_TIME;        // 0x0c00
 | 
			
		||||
    uint32_t volatile _unknown1[144];  // 0x0c04 - 0x0e40
 | 
			
		||||
    uint32_t volatile HWRNG;           // 0xe44 HW RNG, see http://esp8266-re.foogod.com/wiki/Random_Number_Generator
 | 
			
		||||
} __attribute__ (( packed ));
 | 
			
		||||
 | 
			
		||||
_Static_assert(sizeof(struct WDEV_REGS) == 0xc04, "WDEV_REGS is the wrong size");
 | 
			
		||||
_Static_assert(sizeof(struct WDEV_REGS) == 0xe48, "WDEV_REGS is the wrong size");
 | 
			
		||||
 | 
			
		||||
/* Extra paranoid check about the HWRNG address, as if this becomes
 | 
			
		||||
   wrong there will be no obvious symptoms apart from a lack of
 | 
			
		||||
   entropy.
 | 
			
		||||
*/
 | 
			
		||||
_Static_assert(&WDEV.HWRNG == (void*)0x3FF20E44, "HWRNG register is at wrong address");
 | 
			
		||||
 | 
			
		||||
#endif /* _ESP_WDEV_REGS_H */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,8 @@
 | 
			
		|||
 *
 | 
			
		||||
 * To have this work from initial reset, without needing an iomux call
 | 
			
		||||
 * first, choose a pin where iomux defaults to GPIO (ie 0,2,4,5)
 | 
			
		||||
 *
 | 
			
		||||
 * Current sets on=LOW, as the GPIO2 pin is active low
 | 
			
		||||
 */
 | 
			
		||||
LED_GPIO=2
 | 
			
		||||
GPIO_DIR_SET = 0x6000030c
 | 
			
		||||
| 
						 | 
				
			
			@ -19,11 +21,11 @@ GPIO_OUT_CLEAR = 0x60000308
 | 
			
		|||
.endm
 | 
			
		||||
 | 
			
		||||
// Turn LED on. rega, regb will be clobbered
 | 
			
		||||
.macro led_on rega, regb
 | 
			
		||||
.macro led_off rega, regb
 | 
			
		||||
	led_op \rega, \regb, GPIO_OUT_SET
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
// Turn LED off. rega, regb will be clobbered
 | 
			
		||||
.macro led_off rega, regb
 | 
			
		||||
// Turn LED on. rega, regb will be clobbered
 | 
			
		||||
.macro led_on rega, regb
 | 
			
		||||
	led_op \rega, \regb, GPIO_OUT_CLEAR
 | 
			
		||||
.endm
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -103,4 +103,4 @@ extern "C" void user_init(void)
 | 
			
		|||
    
 | 
			
		||||
    task_1.task_create("tsk1");
 | 
			
		||||
    task_2.task_create("tsk2");
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								examples/experiments/unaligned_load/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								examples/experiments/unaligned_load/Makefile
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
PROGRAM=unaligned_load
 | 
			
		||||
include ../../../common.mk
 | 
			
		||||
							
								
								
									
										432
									
								
								examples/experiments/unaligned_load/unaligned_load.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										432
									
								
								examples/experiments/unaligned_load/unaligned_load.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,432 @@
 | 
			
		|||
/* Very basic example that just demonstrates we can run at all!
 | 
			
		||||
 */
 | 
			
		||||
#include "esp/rom.h"
 | 
			
		||||
#include "esp/timer.h"
 | 
			
		||||
#include "espressif/esp_common.h"
 | 
			
		||||
#include "espressif/sdk_private.h"
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
 | 
			
		||||
#include "string.h"
 | 
			
		||||
#include "strings.h"
 | 
			
		||||
 | 
			
		||||
#define TESTSTRING "O hai there! %d %d %d"
 | 
			
		||||
 | 
			
		||||
const char *dramtest = TESTSTRING;
 | 
			
		||||
const __attribute__((section(".iram1.notrodata"))) char iramtest[] = TESTSTRING;
 | 
			
		||||
const __attribute__((section(".text.notrodata"))) char iromtest[] = TESTSTRING;
 | 
			
		||||
 | 
			
		||||
INLINED uint32_t get_ccount (void)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ccount;
 | 
			
		||||
    asm volatile ("rsr.ccount %0" : "=a" (ccount));
 | 
			
		||||
    return ccount;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef void (* test_with_fn_t)(const char *string);
 | 
			
		||||
 | 
			
		||||
char buf[64];
 | 
			
		||||
 | 
			
		||||
void test_memcpy_aligned(const char *string)
 | 
			
		||||
{
 | 
			
		||||
    memcpy(buf, string, 16);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_memcpy_unaligned(const char *string)
 | 
			
		||||
{
 | 
			
		||||
    memcpy(buf, string, 15);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_memcpy_unaligned2(const char *string)
 | 
			
		||||
{
 | 
			
		||||
    memcpy(buf, string+1, 15);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_strcpy(const char *string)
 | 
			
		||||
{
 | 
			
		||||
    strcpy(buf, string);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_sprintf(const char *string)
 | 
			
		||||
{
 | 
			
		||||
    sprintf(buf, string, 1, 2, 3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_sprintf_arg(const char *string)
 | 
			
		||||
{
 | 
			
		||||
    sprintf(buf, "%s", string);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_naive_strcpy(const char *string)
 | 
			
		||||
{
 | 
			
		||||
    char *to = buf;
 | 
			
		||||
    while((*to++ = *string++))
 | 
			
		||||
        ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_naive_strcpy_a0(const char *string)
 | 
			
		||||
{
 | 
			
		||||
    asm volatile (
 | 
			
		||||
"            mov          a8, %0    \n"
 | 
			
		||||
"            mov          a9, %1    \n"
 | 
			
		||||
"tns_loop%=: l8ui         a0, a9, 0 \n"
 | 
			
		||||
"            addi.n       a9, a9, 1 \n"
 | 
			
		||||
"            s8i          a0, a8, 0 \n"
 | 
			
		||||
"            addi.n       a8, a8, 1 \n"
 | 
			
		||||
"            bnez         a0, tns_loop%=\n"
 | 
			
		||||
        : : "r" (buf), "r" (string) : "a0", "a8", "a9");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_naive_strcpy_a2(const char *string)
 | 
			
		||||
{
 | 
			
		||||
    asm volatile (
 | 
			
		||||
"            mov          a8, %0    \n"
 | 
			
		||||
"            mov          a9, %1    \n"
 | 
			
		||||
"tns_loop%=: l8ui         a2, a9, 0 \n"
 | 
			
		||||
"            addi.n       a9, a9, 1 \n"
 | 
			
		||||
"            s8i          a2, a8, 0 \n"
 | 
			
		||||
"            addi.n       a8, a8, 1 \n"
 | 
			
		||||
"            bnez         a2, tns_loop%=\n"
 | 
			
		||||
        : : "r" (buf), "r" (string) : "a2", "a8", "a9");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_naive_strcpy_a3(const char *string)
 | 
			
		||||
{
 | 
			
		||||
    asm volatile (
 | 
			
		||||
"            mov          a8, %0    \n"
 | 
			
		||||
"            mov          a9, %1    \n"
 | 
			
		||||
"tns_loop%=: l8ui         a3, a9, 0 \n"
 | 
			
		||||
"            addi.n       a9, a9, 1 \n"
 | 
			
		||||
"            s8i          a3, a8, 0 \n"
 | 
			
		||||
"            addi.n       a8, a8, 1 \n"
 | 
			
		||||
"            bnez         a3, tns_loop%=\n"
 | 
			
		||||
        : : "r" (buf), "r" (string) : "a3", "a8", "a9");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_naive_strcpy_a4(const char *string)
 | 
			
		||||
{
 | 
			
		||||
    asm volatile (
 | 
			
		||||
"            mov          a8, %0    \n"
 | 
			
		||||
"            mov          a9, %1    \n"
 | 
			
		||||
"tns_loop%=: l8ui         a4, a9, 0 \n"
 | 
			
		||||
"            addi.n       a9, a9, 1 \n"
 | 
			
		||||
"            s8i          a4, a8, 0 \n"
 | 
			
		||||
"            addi.n       a8, a8, 1 \n"
 | 
			
		||||
"            bnez         a4, tns_loop%=\n"
 | 
			
		||||
        : : "r" (buf), "r" (string) : "a4", "a8", "a9");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_naive_strcpy_a5(const char *string)
 | 
			
		||||
{
 | 
			
		||||
    asm volatile (
 | 
			
		||||
"            mov          a8, %0    \n"
 | 
			
		||||
"            mov          a9, %1    \n"
 | 
			
		||||
"tns_loop%=: l8ui         a5, a9, 0 \n"
 | 
			
		||||
"            addi.n       a9, a9, 1 \n"
 | 
			
		||||
"            s8i          a5, a8, 0 \n"
 | 
			
		||||
"            addi.n       a8, a8, 1 \n"
 | 
			
		||||
"            bnez         a5, tns_loop%=\n"
 | 
			
		||||
        : : "r" (buf), "r" (string) : "a5", "a8", "a9");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_naive_strcpy_a6(const char *string)
 | 
			
		||||
{
 | 
			
		||||
    asm volatile (
 | 
			
		||||
"            mov          a8, %0    \n"
 | 
			
		||||
"            mov          a9, %1    \n"
 | 
			
		||||
"tns_loop%=: l8ui         a6, a9, 0 \n"
 | 
			
		||||
"            addi.n       a9, a9, 1 \n"
 | 
			
		||||
"            s8i          a6, a8, 0 \n"
 | 
			
		||||
"            addi.n       a8, a8, 1 \n"
 | 
			
		||||
"            bnez         a6, tns_loop%=\n"
 | 
			
		||||
        : : "r" (buf), "r" (string) : "a6", "a8", "a9");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_l16si(const char *string)
 | 
			
		||||
{
 | 
			
		||||
    /* This follows most of the l16si path, but as the
 | 
			
		||||
     values in the string are all 7 bit none of them get sign extended.
 | 
			
		||||
 | 
			
		||||
    See separate test_sign_extension function which validates
 | 
			
		||||
    sign extension works as expected.
 | 
			
		||||
    */
 | 
			
		||||
    int16_t *src_int16 = (int16_t *)string;
 | 
			
		||||
    int32_t *dst_int32 = (int32_t *)buf;
 | 
			
		||||
    dst_int32[0] = src_int16[0];
 | 
			
		||||
    dst_int32[1] = src_int16[1];
 | 
			
		||||
    dst_int32[2] = src_int16[2];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define TEST_REPEATS 1000
 | 
			
		||||
 | 
			
		||||
void test_noop(const char *string)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t IRAM run_test(const char *string, test_with_fn_t testfn, const char *testfn_label, uint32_t nullvalue, bool evict_cache)
 | 
			
		||||
{
 | 
			
		||||
    printf(" .. against %30s: ", testfn_label);
 | 
			
		||||
    vPortEnterCritical();
 | 
			
		||||
    uint32_t before = get_ccount();
 | 
			
		||||
    for(int i = 0; i < TEST_REPEATS; i++) {
 | 
			
		||||
        testfn(string);
 | 
			
		||||
        if(evict_cache) {
 | 
			
		||||
            Cache_Read_Disable();
 | 
			
		||||
            Cache_Read_Enable(0,0,1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    uint32_t after = get_ccount();
 | 
			
		||||
    vPortExitCritical();
 | 
			
		||||
    uint32_t instructions = (after-before)/TEST_REPEATS - nullvalue;
 | 
			
		||||
    printf("%5d instructions\r\n", instructions);
 | 
			
		||||
    return instructions;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_string(const char *string, char *label, bool evict_cache)
 | 
			
		||||
{
 | 
			
		||||
    printf("Testing %s (%p) '%s'\r\n", label, string, string);
 | 
			
		||||
    printf("Formats as: '");
 | 
			
		||||
    printf(string, 1, 2, 3);
 | 
			
		||||
    printf("'\r\n");
 | 
			
		||||
    uint32_t nullvalue = run_test(string, test_noop, "null op", 0, evict_cache);
 | 
			
		||||
    run_test(string, test_memcpy_aligned, "memcpy - aligned len", nullvalue, evict_cache);
 | 
			
		||||
    run_test(string, test_memcpy_unaligned, "memcpy - unaligned len", nullvalue, evict_cache);
 | 
			
		||||
    run_test(string, test_memcpy_unaligned2, "memcpy - unaligned start&len", nullvalue, evict_cache);
 | 
			
		||||
    run_test(string, test_strcpy, "strcpy", nullvalue, evict_cache);
 | 
			
		||||
    run_test(string, test_naive_strcpy, "naive strcpy", nullvalue, evict_cache);
 | 
			
		||||
    run_test(string, test_naive_strcpy_a0, "naive strcpy (a0)", nullvalue, evict_cache);
 | 
			
		||||
    run_test(string, test_naive_strcpy_a2, "naive strcpy (a2)", nullvalue, evict_cache);
 | 
			
		||||
    run_test(string, test_naive_strcpy_a3, "naive strcpy (a3)", nullvalue, evict_cache);
 | 
			
		||||
    run_test(string, test_naive_strcpy_a4, "naive strcpy (a4)", nullvalue, evict_cache);
 | 
			
		||||
    run_test(string, test_naive_strcpy_a5, "naive strcpy (a5)", nullvalue, evict_cache);
 | 
			
		||||
    run_test(string, test_naive_strcpy_a6, "naive strcpy (a6)", nullvalue, evict_cache);
 | 
			
		||||
    run_test(string, test_sprintf, "sprintf", nullvalue, evict_cache);
 | 
			
		||||
    run_test(string, test_sprintf_arg, "sprintf format arg", nullvalue, evict_cache);
 | 
			
		||||
    run_test(string, test_l16si, "load as l16si", nullvalue, evict_cache);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_isr();
 | 
			
		||||
static void test_sign_extension();
 | 
			
		||||
static void test_system_interaction();
 | 
			
		||||
void sanity_tests(void);
 | 
			
		||||
 | 
			
		||||
void user_init(void)
 | 
			
		||||
{
 | 
			
		||||
    sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
 | 
			
		||||
 | 
			
		||||
    gpio_enable(2, GPIO_OUTPUT); /* used for LED debug */
 | 
			
		||||
    gpio_write(2, 1); /* active low */
 | 
			
		||||
 | 
			
		||||
    printf("\r\n\r\nSDK version:%s\r\n", sdk_system_get_sdk_version());
 | 
			
		||||
    sanity_tests();
 | 
			
		||||
    test_string(dramtest, "DRAM", 0);
 | 
			
		||||
    test_string(iramtest, "IRAM", 0);
 | 
			
		||||
    test_string(iromtest, "Cached flash", 0);
 | 
			
		||||
    test_string(iromtest, "'Uncached' flash", 1);
 | 
			
		||||
 | 
			
		||||
    test_isr();
 | 
			
		||||
    test_sign_extension();
 | 
			
		||||
 | 
			
		||||
    xTaskHandle taskHandle;
 | 
			
		||||
    xTaskCreate(test_system_interaction, (signed char *)"interactionTask", 256, &taskHandle, 2, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static volatile bool frc1_ran;
 | 
			
		||||
static volatile bool frc1_finished;
 | 
			
		||||
static volatile char frc1_buf[80];
 | 
			
		||||
 | 
			
		||||
static void frc1_interrupt_handler(void)
 | 
			
		||||
{
 | 
			
		||||
    frc1_ran = true;
 | 
			
		||||
    timer_set_run(FRC1, false);
 | 
			
		||||
    strcpy((char *)frc1_buf, iramtest);
 | 
			
		||||
    frc1_finished = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_isr()
 | 
			
		||||
{
 | 
			
		||||
    printf("Testing behaviour inside ISRs...\r\n");
 | 
			
		||||
    timer_set_interrupts(FRC1, false);
 | 
			
		||||
    timer_set_run(FRC1, false);
 | 
			
		||||
    _xt_isr_attach(INUM_TIMER_FRC1, frc1_interrupt_handler);
 | 
			
		||||
    timer_set_frequency(FRC1, 1000);
 | 
			
		||||
    timer_set_interrupts(FRC1, true);
 | 
			
		||||
    timer_set_run(FRC1, true);
 | 
			
		||||
    sdk_os_delay_us(2000);
 | 
			
		||||
 | 
			
		||||
    if(!frc1_ran)
 | 
			
		||||
        printf("ERROR: FRC1 timer exception never fired.\r\n");
 | 
			
		||||
    else if(!frc1_finished)
 | 
			
		||||
        printf("ERROR: FRC1 timer exception never finished.\r\n");
 | 
			
		||||
    else if(strcmp((char *)frc1_buf, iramtest))
 | 
			
		||||
        printf("ERROR: FRC1 strcpy from IRAM failed.\r\n");
 | 
			
		||||
    else
 | 
			
		||||
        printf("PASSED\r\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const volatile __attribute__((section(".iram1.notliterals"))) int16_t unsigned_shorts[] = { -3, -4, -5, -32767, 44 };
 | 
			
		||||
 | 
			
		||||
static void test_sign_extension()
 | 
			
		||||
{
 | 
			
		||||
    /* this step seems to be necessary so the compiler will actually generate l16si */
 | 
			
		||||
    int16_t *shorts_p = (int16_t *)unsigned_shorts;
 | 
			
		||||
    if(shorts_p[0] == -3 && shorts_p[1] == -4 && shorts_p[2] == -5 && shorts_p[3] == -32767 && shorts_p[4] == 44)
 | 
			
		||||
    {
 | 
			
		||||
        printf("l16si sign extension PASSED.\r\n");
 | 
			
		||||
    } else {
 | 
			
		||||
        printf("ERROR: l16si sign extension failed. Got values %d %d %d %d %d\r\n", shorts_p[0], shorts_p[1], shorts_p[2], shorts_p[3], shorts_p[4]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* test that running unaligned loads in a running FreeRTOS system doesn't break things
 | 
			
		||||
 | 
			
		||||
   The following tests run inside a FreeRTOS task, after everything else.
 | 
			
		||||
*/
 | 
			
		||||
static void test_system_interaction()
 | 
			
		||||
{
 | 
			
		||||
    uint32_t start = xTaskGetTickCount();
 | 
			
		||||
    printf("Starting system/timer interaction test (takes approx 30 seconds)...\n");
 | 
			
		||||
    for(int i = 0; i < 200*1000; i++) {
 | 
			
		||||
        test_naive_strcpy_a0(iromtest);
 | 
			
		||||
        test_naive_strcpy_a2(iromtest);
 | 
			
		||||
        test_naive_strcpy_a3(iromtest);
 | 
			
		||||
        test_naive_strcpy_a4(iromtest);
 | 
			
		||||
        test_naive_strcpy_a5(iromtest);
 | 
			
		||||
        test_naive_strcpy_a6(iromtest);
 | 
			
		||||
        /*
 | 
			
		||||
        const volatile char *string = iromtest;
 | 
			
		||||
        volatile char *to = dest;
 | 
			
		||||
        while((*to++ = *string++))
 | 
			
		||||
            ;
 | 
			
		||||
        */
 | 
			
		||||
    }
 | 
			
		||||
    uint32_t ticks = xTaskGetTickCount() - start;
 | 
			
		||||
    printf("Timer interaction test PASSED after %dms.\n", ticks*portTICK_RATE_MS);
 | 
			
		||||
    while(1) {}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* The following "sanity tests" are designed to try to execute every code path
 | 
			
		||||
 * of the LoadStoreError handler, with a variety of offsets and data values
 | 
			
		||||
 * designed to catch any mask/shift errors, sign-extension bugs, etc */
 | 
			
		||||
 | 
			
		||||
/* (Contrary to expectations, 'mov a15, a15' in Xtensa is not technically a
 | 
			
		||||
 * no-op, but is officially "undefined and reserved for future use", so we need
 | 
			
		||||
 * a special case in the case where reg == "a15" so we don't end up generating
 | 
			
		||||
 * those opcodes.  GCC is smart enough to optimize away the whole conditional
 | 
			
		||||
 * and just insert the correct asm block, since `reg` is a static argument.) */
 | 
			
		||||
#define LOAD_VIA_REG(op, reg, addr, var) \
 | 
			
		||||
    if (strcmp(reg, "a15")) { \
 | 
			
		||||
        asm volatile ( \
 | 
			
		||||
        "mov a15, " reg "\n\t" \
 | 
			
		||||
        op " " reg ", %1, 0\n\t" \
 | 
			
		||||
        "mov %0, " reg "\n\t" \
 | 
			
		||||
        "mov " reg ", a15\n\t" \
 | 
			
		||||
        : "=r" (var) : "r" (addr) : "a15" ); \
 | 
			
		||||
    } else { \
 | 
			
		||||
        asm volatile ( \
 | 
			
		||||
        op " " reg ", %1, 0\n\t" \
 | 
			
		||||
        "mov %0, " reg "\n\t" \
 | 
			
		||||
        : "=r" (var) : "r" (addr) : "a15" ); \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#define TEST_LOAD(op, reg, addr, value) \
 | 
			
		||||
    { \
 | 
			
		||||
        int32_t result; \
 | 
			
		||||
        LOAD_VIA_REG(op, reg, addr, result); \
 | 
			
		||||
        if (result != value) sanity_test_failed(op, reg, addr, value, result); \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
void sanity_test_failed(const char *testname, const char *reg, const void *addr, int32_t value, int32_t result) {
 | 
			
		||||
    uint32_t actual_data = *(uint32_t *)((uint32_t)addr & 0xfffffffc);
 | 
			
		||||
 | 
			
		||||
    printf("*** SANITY TEST FAILED: '%s %s' from %p (underlying 32-bit value: 0x%x): Expected 0x%08x (%d), got 0x%08x (%d)\n", testname, reg, addr, actual_data, value, value, result, result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const __attribute__((section(".iram1.notrodata"))) char sanity_test_data[] = {
 | 
			
		||||
    0x01, 0x55, 0x7e, 0x2a, 0x81, 0xd5, 0xfe, 0xaa
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void sanity_test_l8ui(const void *addr, int32_t value) {
 | 
			
		||||
    TEST_LOAD("l8ui", "a0", addr, value);
 | 
			
		||||
    TEST_LOAD("l8ui", "a1", addr, value);
 | 
			
		||||
    TEST_LOAD("l8ui", "a2", addr, value);
 | 
			
		||||
    TEST_LOAD("l8ui", "a3", addr, value);
 | 
			
		||||
    TEST_LOAD("l8ui", "a4", addr, value);
 | 
			
		||||
    TEST_LOAD("l8ui", "a5", addr, value);
 | 
			
		||||
    TEST_LOAD("l8ui", "a6", addr, value);
 | 
			
		||||
    TEST_LOAD("l8ui", "a7", addr, value);
 | 
			
		||||
    TEST_LOAD("l8ui", "a8", addr, value);
 | 
			
		||||
    TEST_LOAD("l8ui", "a9", addr, value);
 | 
			
		||||
    TEST_LOAD("l8ui", "a10", addr, value);
 | 
			
		||||
    TEST_LOAD("l8ui", "a11", addr, value);
 | 
			
		||||
    TEST_LOAD("l8ui", "a12", addr, value);
 | 
			
		||||
    TEST_LOAD("l8ui", "a13", addr, value);
 | 
			
		||||
    TEST_LOAD("l8ui", "a14", addr, value);
 | 
			
		||||
    TEST_LOAD("l8ui", "a15", addr, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sanity_test_l16ui(const void *addr, int32_t value) {
 | 
			
		||||
    TEST_LOAD("l16ui", "a0", addr, value);
 | 
			
		||||
    TEST_LOAD("l16ui", "a1", addr, value);
 | 
			
		||||
    TEST_LOAD("l16ui", "a2", addr, value);
 | 
			
		||||
    TEST_LOAD("l16ui", "a3", addr, value);
 | 
			
		||||
    TEST_LOAD("l16ui", "a4", addr, value);
 | 
			
		||||
    TEST_LOAD("l16ui", "a5", addr, value);
 | 
			
		||||
    TEST_LOAD("l16ui", "a6", addr, value);
 | 
			
		||||
    TEST_LOAD("l16ui", "a7", addr, value);
 | 
			
		||||
    TEST_LOAD("l16ui", "a8", addr, value);
 | 
			
		||||
    TEST_LOAD("l16ui", "a9", addr, value);
 | 
			
		||||
    TEST_LOAD("l16ui", "a10", addr, value);
 | 
			
		||||
    TEST_LOAD("l16ui", "a11", addr, value);
 | 
			
		||||
    TEST_LOAD("l16ui", "a12", addr, value);
 | 
			
		||||
    TEST_LOAD("l16ui", "a13", addr, value);
 | 
			
		||||
    TEST_LOAD("l16ui", "a14", addr, value);
 | 
			
		||||
    TEST_LOAD("l16ui", "a15", addr, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sanity_test_l16si(const void *addr, int32_t value) {
 | 
			
		||||
    TEST_LOAD("l16si", "a0", addr, value);
 | 
			
		||||
    TEST_LOAD("l16si", "a1", addr, value);
 | 
			
		||||
    TEST_LOAD("l16si", "a2", addr, value);
 | 
			
		||||
    TEST_LOAD("l16si", "a3", addr, value);
 | 
			
		||||
    TEST_LOAD("l16si", "a4", addr, value);
 | 
			
		||||
    TEST_LOAD("l16si", "a5", addr, value);
 | 
			
		||||
    TEST_LOAD("l16si", "a6", addr, value);
 | 
			
		||||
    TEST_LOAD("l16si", "a7", addr, value);
 | 
			
		||||
    TEST_LOAD("l16si", "a8", addr, value);
 | 
			
		||||
    TEST_LOAD("l16si", "a9", addr, value);
 | 
			
		||||
    TEST_LOAD("l16si", "a10", addr, value);
 | 
			
		||||
    TEST_LOAD("l16si", "a11", addr, value);
 | 
			
		||||
    TEST_LOAD("l16si", "a12", addr, value);
 | 
			
		||||
    TEST_LOAD("l16si", "a13", addr, value);
 | 
			
		||||
    TEST_LOAD("l16si", "a14", addr, value);
 | 
			
		||||
    TEST_LOAD("l16si", "a15", addr, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sanity_tests(void) {
 | 
			
		||||
    printf("== Performing sanity tests (sanity_test_data @ %p)...\n", sanity_test_data);
 | 
			
		||||
 | 
			
		||||
    sanity_test_l8ui(sanity_test_data + 0, 0x01);
 | 
			
		||||
    sanity_test_l8ui(sanity_test_data + 1, 0x55);
 | 
			
		||||
    sanity_test_l8ui(sanity_test_data + 2, 0x7e);
 | 
			
		||||
    sanity_test_l8ui(sanity_test_data + 3, 0x2a);
 | 
			
		||||
    sanity_test_l8ui(sanity_test_data + 4, 0x81);
 | 
			
		||||
    sanity_test_l8ui(sanity_test_data + 5, 0xd5);
 | 
			
		||||
    sanity_test_l8ui(sanity_test_data + 6, 0xfe);
 | 
			
		||||
    sanity_test_l8ui(sanity_test_data + 7, 0xaa);
 | 
			
		||||
 | 
			
		||||
    sanity_test_l16ui(sanity_test_data + 0, 0x5501);
 | 
			
		||||
    sanity_test_l16ui(sanity_test_data + 2, 0x2a7e);
 | 
			
		||||
    sanity_test_l16ui(sanity_test_data + 4, 0xd581);
 | 
			
		||||
    sanity_test_l16ui(sanity_test_data + 6, 0xaafe);
 | 
			
		||||
 | 
			
		||||
    sanity_test_l16si(sanity_test_data + 0, 0x5501);
 | 
			
		||||
    sanity_test_l16si(sanity_test_data + 2, 0x2a7e);
 | 
			
		||||
    sanity_test_l16si(sanity_test_data + 4, -10879);
 | 
			
		||||
    sanity_test_l16si(sanity_test_data + 6, -21762);
 | 
			
		||||
 | 
			
		||||
    printf("== Sanity tests completed.\n");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								examples/http_get_mbedtls/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								examples/http_get_mbedtls/Makefile
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
PROGRAM=http_get_mbedtls
 | 
			
		||||
COMPONENTS = FreeRTOS lwip core extras/mbedtls
 | 
			
		||||
 | 
			
		||||
include ../../common.mk
 | 
			
		||||
							
								
								
									
										39
									
								
								examples/http_get_mbedtls/cert.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								examples/http_get_mbedtls/cert.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
/* This is the root certificate for the CA trust chain of
 | 
			
		||||
   www.howsmyssl.com in PEM format, as dumped via:
 | 
			
		||||
 | 
			
		||||
   openssl s_client -showcerts -connect www.howsmyssl.com:443 </dev/null
 | 
			
		||||
 | 
			
		||||
   The root cert is the last cert in the chain output by the server.
 | 
			
		||||
*/
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
const char *server_root_cert = "-----BEGIN CERTIFICATE-----\r\n"
 | 
			
		||||
"MIIEWTCCA0GgAwIBAgIDAjpjMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT\r\n"
 | 
			
		||||
"MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i\r\n"
 | 
			
		||||
"YWwgQ0EwHhcNMTIwODI3MjA0MDQwWhcNMjIwNTIwMjA0MDQwWjBEMQswCQYDVQQG\r\n"
 | 
			
		||||
"EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg\r\n"
 | 
			
		||||
"U1NMIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5J/lP\r\n"
 | 
			
		||||
"2Pa3FT+Pzc7WjRxr/X/aVCFOA9jK0HJSFbjJgltYeYT/JHJv8ml/vJbZmnrDPqnP\r\n"
 | 
			
		||||
"UCITDoYZ2+hJ74vm1kfy/XNFCK6PrF62+J589xD/kkNm7xzU7qFGiBGJSXl6Jc5L\r\n"
 | 
			
		||||
"avDXHHYaKTzJ5P0ehdzgMWUFRxasCgdLLnBeawanazpsrwUSxLIRJdY+lynwg2xX\r\n"
 | 
			
		||||
"HNil78zs/dYS8T/bQLSuDxjTxa9Akl0HXk7+Yhc3iemLdCai7bgK52wVWzWQct3Y\r\n"
 | 
			
		||||
"TSHUQCNcj+6AMRaraFX0DjtU6QRN8MxOgV7pb1JpTr6mFm1C9VH/4AtWPJhPc48O\r\n"
 | 
			
		||||
"bxoj8cnI2d+87FLXAgMBAAGjggFUMIIBUDAfBgNVHSMEGDAWgBTAephojYn7qwVk\r\n"
 | 
			
		||||
"DBF9qn1luMrMTjAdBgNVHQ4EFgQUEUrQcznVW2kIXLo9v2SaqIscVbwwEgYDVR0T\r\n"
 | 
			
		||||
"AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2gK4Yp\r\n"
 | 
			
		||||
"aHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwNAYIKwYB\r\n"
 | 
			
		||||
"BQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nZW90cnVzdC5jb20w\r\n"
 | 
			
		||||
"TAYDVR0gBEUwQzBBBgpghkgBhvhFAQc2MDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93\r\n"
 | 
			
		||||
"d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwKgYDVR0RBCMwIaQfMB0xGzAZ\r\n"
 | 
			
		||||
"BgNVBAMTElZlcmlTaWduTVBLSS0yLTI1NDANBgkqhkiG9w0BAQUFAAOCAQEAPOU9\r\n"
 | 
			
		||||
"WhuiNyrjRs82lhg8e/GExVeGd0CdNfAS8HgY+yKk3phLeIHmTYbjkQ9C47ncoNb/\r\n"
 | 
			
		||||
"qfixeZeZ0cNsQqWSlOBdDDMYJckrlVPg5akMfUf+f1ExRF73Kh41opQy98nuwLbG\r\n"
 | 
			
		||||
"mqzemSFqI6A4ZO6jxIhzMjtQzr+t03UepvTp+UJrYLLdRf1dVwjOLVDmEjIWE4ry\r\n"
 | 
			
		||||
"lKKbR6iGf9mY5ffldnRk2JG8hBYo2CVEMH6C2Kyx5MDkFWzbtiQnAioBEoW6MYhY\r\n"
 | 
			
		||||
"R3TjuNJkpsMyWS4pS0XxW4lJLoKaxhgVRNAuZAEVaDj59vlmAwxVG52/AECu8Egn\r\n"
 | 
			
		||||
"TOCAXi25KhV6vGb4NQ==\r\n"
 | 
			
		||||
"-----END CERTIFICATE-----\r\n";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										347
									
								
								examples/http_get_mbedtls/http_get_mbedtls.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										347
									
								
								examples/http_get_mbedtls/http_get_mbedtls.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,347 @@
 | 
			
		|||
/* http_get_mbedtls - HTTPS version of the http_get example, using mbed TLS.
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieves a JSON response from the howsmyssl.com API via HTTPS over TLS v1.2.
 | 
			
		||||
 *
 | 
			
		||||
 * Validates the server's certificate using the root CA loaded (in PEM format) in cert.c.
 | 
			
		||||
 *
 | 
			
		||||
 * Adapted from the ssl_client1 example in mbedtls.
 | 
			
		||||
 *
 | 
			
		||||
 * Original Copyright (C) 2006-2015, ARM Limited, All Rights Reserved, Apache 2.0 License.
 | 
			
		||||
 * Additions Copyright (C) 2015 Angus Gratton, Apache 2.0 License.
 | 
			
		||||
 */
 | 
			
		||||
#include "espressif/esp_common.h"
 | 
			
		||||
#include "espressif/sdk_private.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
 | 
			
		||||
#include "lwip/err.h"
 | 
			
		||||
#include "lwip/sockets.h"
 | 
			
		||||
#include "lwip/sys.h"
 | 
			
		||||
#include "lwip/netdb.h"
 | 
			
		||||
#include "lwip/dns.h"
 | 
			
		||||
#include "lwip/api.h"
 | 
			
		||||
 | 
			
		||||
#include "ssid_config.h"
 | 
			
		||||
 | 
			
		||||
/* mbedtls/config.h MUST appear before all other mbedtls headers, or
 | 
			
		||||
   you'll get the default config.
 | 
			
		||||
 | 
			
		||||
   (Although mostly that isn't a big problem, you just might get
 | 
			
		||||
   errors at link time if functions don't exist.) */
 | 
			
		||||
#include "mbedtls/config.h"
 | 
			
		||||
 | 
			
		||||
#include "mbedtls/net.h"
 | 
			
		||||
#include "mbedtls/debug.h"
 | 
			
		||||
#include "mbedtls/ssl.h"
 | 
			
		||||
#include "mbedtls/entropy.h"
 | 
			
		||||
#include "mbedtls/ctr_drbg.h"
 | 
			
		||||
#include "mbedtls/error.h"
 | 
			
		||||
#include "mbedtls/certs.h"
 | 
			
		||||
 | 
			
		||||
#define WEB_SERVER "howsmyssl.com"
 | 
			
		||||
#define WEB_PORT "443"
 | 
			
		||||
#define WEB_URL "https://www.howsmyssl.com/a/check"
 | 
			
		||||
 | 
			
		||||
#define GET_REQUEST "GET "WEB_URL" HTTP/1.1\n\n"
 | 
			
		||||
 | 
			
		||||
/* Root cert for howsmyssl.com, stored in cert.c */
 | 
			
		||||
extern const char *server_root_cert;
 | 
			
		||||
 | 
			
		||||
/* MBEDTLS_DEBUG_C disabled by default to save substantial bloating of
 | 
			
		||||
 * firmware, define it in
 | 
			
		||||
 * examples/http_get_mbedtls/include/mbedtls/config.h if you'd like
 | 
			
		||||
 * debugging output.
 | 
			
		||||
 */
 | 
			
		||||
#ifdef MBEDTLS_DEBUG_C
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Increase this value to see more TLS debug details,
 | 
			
		||||
   0 prints nothing, 1 will print any errors, 4 will print _everything_
 | 
			
		||||
*/
 | 
			
		||||
#define DEBUG_LEVEL 4
 | 
			
		||||
 | 
			
		||||
static void my_debug(void *ctx, int level,
 | 
			
		||||
                     const char *file, int line,
 | 
			
		||||
                     const char *str)
 | 
			
		||||
{
 | 
			
		||||
    ((void) level);
 | 
			
		||||
 | 
			
		||||
    /* Shorten 'file' from the whole file path to just the filename
 | 
			
		||||
 | 
			
		||||
       This is a bit wasteful because the macros are compiled in with
 | 
			
		||||
       the full _FILE_ path in each case, so the firmware is bloated out
 | 
			
		||||
       by a few kb. But there's not a lot we can do about it...
 | 
			
		||||
    */
 | 
			
		||||
    char *file_sep = rindex(file, '/');
 | 
			
		||||
    if(file_sep)
 | 
			
		||||
        file = file_sep+1;
 | 
			
		||||
 | 
			
		||||
    printf("%s:%04d: %s", file, line, str);
 | 
			
		||||
    fflush(stdout);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void http_get_task(void *pvParameters)
 | 
			
		||||
{
 | 
			
		||||
    int successes = 0, failures = 0, ret;
 | 
			
		||||
    printf("HTTP get task starting...\n");
 | 
			
		||||
 | 
			
		||||
    uint32_t flags;
 | 
			
		||||
    unsigned char buf[1024];
 | 
			
		||||
    const char *pers = "ssl_client1";
 | 
			
		||||
 | 
			
		||||
    mbedtls_entropy_context entropy;
 | 
			
		||||
    mbedtls_ctr_drbg_context ctr_drbg;
 | 
			
		||||
    mbedtls_ssl_context ssl;
 | 
			
		||||
    mbedtls_x509_crt cacert;
 | 
			
		||||
    mbedtls_ssl_config conf;
 | 
			
		||||
    mbedtls_net_context server_fd;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * 0. Initialize the RNG and the session data
 | 
			
		||||
     */
 | 
			
		||||
    mbedtls_ssl_init(&ssl);
 | 
			
		||||
    mbedtls_x509_crt_init(&cacert);
 | 
			
		||||
    mbedtls_ctr_drbg_init(&ctr_drbg);
 | 
			
		||||
    printf("\n  . Seeding the random number generator...");
 | 
			
		||||
    fflush(stdout);
 | 
			
		||||
 | 
			
		||||
    mbedtls_ssl_config_init(&conf);
 | 
			
		||||
 | 
			
		||||
    mbedtls_entropy_init(&entropy);
 | 
			
		||||
    if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
 | 
			
		||||
                                    (const unsigned char *) pers,
 | 
			
		||||
                                    strlen(pers))) != 0)
 | 
			
		||||
    {
 | 
			
		||||
        printf(" failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret);
 | 
			
		||||
        while(1) {} /* todo: replace with abort() */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf(" ok\n");
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * 0. Initialize certificates
 | 
			
		||||
     */
 | 
			
		||||
    printf("  . Loading the CA root certificate ...");
 | 
			
		||||
    fflush(stdout);
 | 
			
		||||
 | 
			
		||||
    ret = mbedtls_x509_crt_parse(&cacert, (uint8_t*)server_root_cert, strlen(server_root_cert)+1);
 | 
			
		||||
    if(ret < 0)
 | 
			
		||||
    {
 | 
			
		||||
        printf(" failed\n  !  mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
 | 
			
		||||
        while(1) {} /* todo: replace with abort() */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf(" ok (%d skipped)\n", ret);
 | 
			
		||||
 | 
			
		||||
    /* Hostname set here should match CN in server certificate */
 | 
			
		||||
    if((ret = mbedtls_ssl_set_hostname(&ssl, WEB_SERVER)) != 0)
 | 
			
		||||
    {
 | 
			
		||||
        printf(" failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret);
 | 
			
		||||
        while(1) {} /* todo: replace with abort() */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * 2. Setup stuff
 | 
			
		||||
     */
 | 
			
		||||
    printf("  . Setting up the SSL/TLS structure...");
 | 
			
		||||
    fflush(stdout);
 | 
			
		||||
 | 
			
		||||
    if((ret = mbedtls_ssl_config_defaults(&conf,
 | 
			
		||||
                                          MBEDTLS_SSL_IS_CLIENT,
 | 
			
		||||
                                          MBEDTLS_SSL_TRANSPORT_STREAM,
 | 
			
		||||
                                          MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
 | 
			
		||||
    {
 | 
			
		||||
        printf(" failed\n  ! mbedtls_ssl_config_defaults returned %d\n\n", ret);
 | 
			
		||||
        goto exit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf(" ok\n");
 | 
			
		||||
 | 
			
		||||
    /* OPTIONAL is not optimal for security, in this example it will print
 | 
			
		||||
       a warning if CA verification fails but it will continue to connect.
 | 
			
		||||
    */
 | 
			
		||||
    mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
 | 
			
		||||
    mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
 | 
			
		||||
    mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
 | 
			
		||||
#ifdef MBEDTLS_DEBUG_C
 | 
			
		||||
    mbedtls_debug_set_threshold(DEBUG_LEVEL);
 | 
			
		||||
    mbedtls_ssl_conf_dbg(&conf, my_debug, stdout);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0)
 | 
			
		||||
    {
 | 
			
		||||
        printf(" failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret);
 | 
			
		||||
        goto exit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Wait until we can resolve the DNS for the server, as an indication
 | 
			
		||||
       our network is probably working...
 | 
			
		||||
    */
 | 
			
		||||
    printf("Waiting for server DNS to resolve... ");
 | 
			
		||||
    fflush(stdout);
 | 
			
		||||
    err_t dns_err;
 | 
			
		||||
    ip_addr_t host_ip;
 | 
			
		||||
    do {
 | 
			
		||||
        vTaskDelay(500 / portTICK_RATE_MS);
 | 
			
		||||
        dns_err = netconn_gethostbyname(WEB_SERVER, &host_ip);
 | 
			
		||||
    } while(dns_err != ERR_OK);
 | 
			
		||||
    printf("done.\n");
 | 
			
		||||
 | 
			
		||||
    while(1) {
 | 
			
		||||
        mbedtls_net_init(&server_fd);
 | 
			
		||||
        printf("top of loop, free heap = %u\n", xPortGetFreeHeapSize());
 | 
			
		||||
        /*
 | 
			
		||||
         * 1. Start the connection
 | 
			
		||||
         */
 | 
			
		||||
        printf("  . Connecting to %s:%s...", WEB_SERVER, WEB_PORT);
 | 
			
		||||
        fflush(stdout);
 | 
			
		||||
 | 
			
		||||
        if((ret = mbedtls_net_connect(&server_fd, WEB_SERVER,
 | 
			
		||||
                                      WEB_PORT, MBEDTLS_NET_PROTO_TCP)) != 0)
 | 
			
		||||
        {
 | 
			
		||||
            printf(" failed\n  ! mbedtls_net_connect returned %d\n\n", ret);
 | 
			
		||||
            goto exit;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        printf(" ok\n");
 | 
			
		||||
 | 
			
		||||
        mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * 4. Handshake
 | 
			
		||||
         */
 | 
			
		||||
        printf("  . Performing the SSL/TLS handshake...");
 | 
			
		||||
        fflush(stdout);
 | 
			
		||||
 | 
			
		||||
        while((ret = mbedtls_ssl_handshake(&ssl)) != 0)
 | 
			
		||||
        {
 | 
			
		||||
            if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
 | 
			
		||||
            {
 | 
			
		||||
                printf(" failed\n  ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret);
 | 
			
		||||
                goto exit;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        printf(" ok\n");
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * 5. Verify the server certificate
 | 
			
		||||
         */
 | 
			
		||||
        printf("  . Verifying peer X.509 certificate...");
 | 
			
		||||
 | 
			
		||||
        /* In real life, we probably want to bail out when ret != 0 */
 | 
			
		||||
        if((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0)
 | 
			
		||||
        {
 | 
			
		||||
            char vrfy_buf[512];
 | 
			
		||||
 | 
			
		||||
            printf(" failed\n");
 | 
			
		||||
 | 
			
		||||
            mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), "  ! ", flags);
 | 
			
		||||
 | 
			
		||||
            printf("%s\n", vrfy_buf);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            printf(" ok\n");
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * 3. Write the GET request
 | 
			
		||||
         */
 | 
			
		||||
        printf("  > Write to server:");
 | 
			
		||||
        fflush(stdout);
 | 
			
		||||
 | 
			
		||||
        int len = sprintf((char *) buf, GET_REQUEST);
 | 
			
		||||
 | 
			
		||||
        while((ret = mbedtls_ssl_write(&ssl, buf, len)) <= 0)
 | 
			
		||||
        {
 | 
			
		||||
            if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
 | 
			
		||||
            {
 | 
			
		||||
                printf(" failed\n  ! mbedtls_ssl_write returned %d\n\n", ret);
 | 
			
		||||
                goto exit;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        len = ret;
 | 
			
		||||
        printf(" %d bytes written\n\n%s", len, (char *) buf);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * 7. Read the HTTP response
 | 
			
		||||
         */
 | 
			
		||||
        printf("  < Read from server:");
 | 
			
		||||
        fflush(stdout);
 | 
			
		||||
 | 
			
		||||
        do
 | 
			
		||||
        {
 | 
			
		||||
            len = sizeof(buf) - 1;
 | 
			
		||||
            memset(buf, 0, sizeof(buf));
 | 
			
		||||
            ret = mbedtls_ssl_read(&ssl, buf, len);
 | 
			
		||||
 | 
			
		||||
            if(ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
 | 
			
		||||
                ret = 0;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(ret < 0)
 | 
			
		||||
            {
 | 
			
		||||
                printf("failed\n  ! mbedtls_ssl_read returned %d\n\n", ret);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(ret == 0)
 | 
			
		||||
            {
 | 
			
		||||
                printf("\n\nEOF\n\n");
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            len = ret;
 | 
			
		||||
            printf(" %d bytes read\n\n%s", len, (char *) buf);
 | 
			
		||||
        } while(1);
 | 
			
		||||
 | 
			
		||||
        mbedtls_ssl_close_notify(&ssl);
 | 
			
		||||
 | 
			
		||||
    exit:
 | 
			
		||||
        mbedtls_ssl_session_reset(&ssl);
 | 
			
		||||
        mbedtls_net_free(&server_fd);
 | 
			
		||||
 | 
			
		||||
        if(ret != 0)
 | 
			
		||||
        {
 | 
			
		||||
            char error_buf[100];
 | 
			
		||||
            mbedtls_strerror(ret, error_buf, 100);
 | 
			
		||||
            printf("\n\nLast error was: %d - %s\n\n", ret, error_buf);
 | 
			
		||||
            failures++;
 | 
			
		||||
        } else {
 | 
			
		||||
            successes++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        printf("\n\nsuccesses = %d failures = %d\n", successes, failures);
 | 
			
		||||
        for(int countdown = successes ? 10 : 5; countdown >= 0; countdown--) {
 | 
			
		||||
            printf("%d... ", countdown);
 | 
			
		||||
            fflush(stdout);
 | 
			
		||||
            vTaskDelay(1000 / portTICK_RATE_MS);
 | 
			
		||||
        }
 | 
			
		||||
        printf("\nStarting again!\n");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void user_init(void)
 | 
			
		||||
{
 | 
			
		||||
    sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
 | 
			
		||||
    printf("SDK version:%s\n", sdk_system_get_sdk_version());
 | 
			
		||||
 | 
			
		||||
    struct sdk_station_config config = {
 | 
			
		||||
        .ssid = WIFI_SSID,
 | 
			
		||||
        .password = WIFI_PASS,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /* required to call wifi_set_opmode before station_set_config */
 | 
			
		||||
    sdk_wifi_set_opmode(STATION_MODE);
 | 
			
		||||
    sdk_wifi_station_set_config(&config);
 | 
			
		||||
 | 
			
		||||
    xTaskCreate(&http_get_task, (signed char *)"get_task", 2048, NULL, 2, NULL);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								examples/http_get_mbedtls/include/mbedtls/config.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								examples/http_get_mbedtls/include/mbedtls/config.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
/* Special mbedTLS config file for http_get_mbedtls example,
 | 
			
		||||
   overrides supported cipher suite list.
 | 
			
		||||
 | 
			
		||||
   Overriding the set of cipher suites saves small amounts of ROM and
 | 
			
		||||
   RAM, and is a good practice in general if you know what server(s)
 | 
			
		||||
   you want to connect to.
 | 
			
		||||
 | 
			
		||||
  However it's extra important here because the howsmyssl API sends
 | 
			
		||||
  back the list of ciphers we send it as a JSON list in the, and we
 | 
			
		||||
  only have a 4096kB receive buffer. If the server supported maximum
 | 
			
		||||
  fragment length option then we wouldn't have this problem either,
 | 
			
		||||
  but we do so this is a good workaround.
 | 
			
		||||
 | 
			
		||||
  The ciphers chosen below are common ECDHE ciphers, the same ones
 | 
			
		||||
  Firefox uses when connecting to a TLSv1.2 server.
 | 
			
		||||
*/
 | 
			
		||||
#ifndef MBEDTLS_CONFIG_H
 | 
			
		||||
 | 
			
		||||
/* include_next picks up default config from extras/mbedtls/include/mbedtls/config.h */
 | 
			
		||||
#include_next<mbedtls/config.h>
 | 
			
		||||
 | 
			
		||||
#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
 | 
			
		||||
 | 
			
		||||
/* uncomment next line to include debug output from example */
 | 
			
		||||
//#define MBEDTLS_DEBUG_C
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,2 +0,0 @@
 | 
			
		|||
PROGRAM=http_get_ssl
 | 
			
		||||
include ../../common.mk
 | 
			
		||||
| 
						 | 
				
			
			@ -1,223 +0,0 @@
 | 
			
		|||
/* http_get_ssl - HTTPS version of the http_get example.
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieves a web page over HTTPS (TLS) using GET.
 | 
			
		||||
 *
 | 
			
		||||
 * Does not validate server certificate.
 | 
			
		||||
 *
 | 
			
		||||
 * This sample code is in the public domain.,
 | 
			
		||||
 */
 | 
			
		||||
#include "espressif/esp_common.h"
 | 
			
		||||
#include "espressif/sdk_private.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
 | 
			
		||||
#include "lwip/err.h"
 | 
			
		||||
#include "lwip/sockets.h"
 | 
			
		||||
#include "lwip/sys.h"
 | 
			
		||||
#include "lwip/netdb.h"
 | 
			
		||||
#include "lwip/dns.h"
 | 
			
		||||
 | 
			
		||||
#include "ssl.h"
 | 
			
		||||
 | 
			
		||||
#include "ssid_config.h"
 | 
			
		||||
 | 
			
		||||
#define WEB_SERVER "192.168.0.18"
 | 
			
		||||
#define WEB_PORT "8000"
 | 
			
		||||
#define WEB_URL "/test"
 | 
			
		||||
 | 
			
		||||
static void display_cipher(SSL *ssl);
 | 
			
		||||
static void display_session_id(SSL *ssl);
 | 
			
		||||
 | 
			
		||||
void http_get_task(void *pvParameters)
 | 
			
		||||
{
 | 
			
		||||
    int successes = 0, failures = 0;
 | 
			
		||||
    SSL_CTX *ssl_ctx;
 | 
			
		||||
    uint32_t options = SSL_SERVER_VERIFY_LATER|SSL_DISPLAY_CERTS;
 | 
			
		||||
    printf("HTTP get task starting...\r\n");
 | 
			
		||||
 | 
			
		||||
    printf("free heap = %u\r\n", xPortGetFreeHeapSize());
 | 
			
		||||
    if ((ssl_ctx = ssl_ctx_new(options, SSL_DEFAULT_CLNT_SESS)) == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        printf("Error: SSL Client context is invalid\n");
 | 
			
		||||
        while(1) {}
 | 
			
		||||
    }
 | 
			
		||||
    printf("Got SSL context.");
 | 
			
		||||
 | 
			
		||||
    while(1) {
 | 
			
		||||
        const struct addrinfo hints = {
 | 
			
		||||
            .ai_family = AF_INET,
 | 
			
		||||
            .ai_socktype = SOCK_STREAM,
 | 
			
		||||
        };
 | 
			
		||||
        struct addrinfo *res;
 | 
			
		||||
 | 
			
		||||
        printf("top of loop, free heap = %u\r\n", xPortGetFreeHeapSize());
 | 
			
		||||
 | 
			
		||||
        printf("Running DNS lookup for %s...\r\n", WEB_SERVER);
 | 
			
		||||
        int err = getaddrinfo(WEB_SERVER, WEB_PORT, &hints, &res);
 | 
			
		||||
 | 
			
		||||
        if(err != 0 || res == NULL) {
 | 
			
		||||
            printf("DNS lookup failed err=%d res=%p\r\n", err, res);
 | 
			
		||||
            if(res)
 | 
			
		||||
                freeaddrinfo(res);
 | 
			
		||||
            vTaskDelay(1000 / portTICK_RATE_MS);
 | 
			
		||||
            failures++;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        /* Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */
 | 
			
		||||
        struct in_addr *addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
 | 
			
		||||
        printf("DNS lookup succeeded. IP=%s\r\n", inet_ntoa(*addr));
 | 
			
		||||
 | 
			
		||||
        int s = socket(res->ai_family, res->ai_socktype, 0);
 | 
			
		||||
        if(s < 0) {
 | 
			
		||||
            printf("... Failed to allocate socket.\r\n");
 | 
			
		||||
            freeaddrinfo(res);
 | 
			
		||||
            vTaskDelay(1000 / portTICK_RATE_MS);
 | 
			
		||||
            failures++;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        printf("... allocated socket\r\n");
 | 
			
		||||
 | 
			
		||||
        if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
 | 
			
		||||
            close(s);
 | 
			
		||||
            freeaddrinfo(res);
 | 
			
		||||
            printf("... socket connect failed.\r\n");
 | 
			
		||||
            vTaskDelay(4000 / portTICK_RATE_MS);
 | 
			
		||||
            failures++;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        printf("... connected. starting TLS session...\r\n");
 | 
			
		||||
        freeaddrinfo(res);
 | 
			
		||||
 | 
			
		||||
        SSL *ssl = ssl_client_new(ssl_ctx, s, NULL, 0);
 | 
			
		||||
        printf("initial status %p %d\r\n", ssl, ssl_handshake_status(ssl));
 | 
			
		||||
        if((err = ssl_handshake_status(ssl)) != SSL_OK) {
 | 
			
		||||
            ssl_free(ssl);
 | 
			
		||||
            close(s);
 | 
			
		||||
            printf("SSL handshake failed. :( %d\r\n", err);
 | 
			
		||||
            vTaskDelay(4000 / portTICK_RATE_MS);
 | 
			
		||||
            failures++;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const char *common_name = ssl_get_cert_dn(ssl,
 | 
			
		||||
                                                  SSL_X509_CERT_COMMON_NAME);
 | 
			
		||||
        if (common_name)
 | 
			
		||||
        {
 | 
			
		||||
            printf("Common Name:\t\t\t%s\n", common_name);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        display_session_id(ssl);
 | 
			
		||||
        display_cipher(ssl);
 | 
			
		||||
 | 
			
		||||
        const char *req =
 | 
			
		||||
            "GET "WEB_URL"\r\n"
 | 
			
		||||
            "User-Agent: esp-open-rtos/0.1 esp8266\r\n"
 | 
			
		||||
            "\r\n";
 | 
			
		||||
        if (ssl_write(ssl, (uint8_t *)req, strlen(req)) < 0) {
 | 
			
		||||
            printf("... socket send failed\r\n");
 | 
			
		||||
            ssl_free(ssl);
 | 
			
		||||
            close(s);
 | 
			
		||||
            vTaskDelay(4000 / portTICK_RATE_MS);
 | 
			
		||||
            failures++;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        printf("... socket send success\r\n");
 | 
			
		||||
 | 
			
		||||
        uint8_t *recv_buf;
 | 
			
		||||
        int r;
 | 
			
		||||
        do {
 | 
			
		||||
            r = ssl_read(ssl, &recv_buf);
 | 
			
		||||
            for(int i = 0; i < r; i++)
 | 
			
		||||
                printf("%c", recv_buf[i]);
 | 
			
		||||
        } while(r > 0);
 | 
			
		||||
 | 
			
		||||
        printf("... done reading from socket. Last read return=%d errno=%d\r\n", r, errno);
 | 
			
		||||
        if(r != 0)
 | 
			
		||||
            failures++;
 | 
			
		||||
        else
 | 
			
		||||
            successes++;
 | 
			
		||||
        ssl_free(ssl);
 | 
			
		||||
        close(s);
 | 
			
		||||
        printf("successes = %d failures = %d\r\n", successes, failures);
 | 
			
		||||
        for(int countdown = 10; countdown >= 0; countdown--) {
 | 
			
		||||
            printf("%d... ", countdown);
 | 
			
		||||
            vTaskDelay(1000 / portTICK_RATE_MS);
 | 
			
		||||
        }
 | 
			
		||||
        printf("\r\nStarting again!\r\n");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void user_init(void)
 | 
			
		||||
{
 | 
			
		||||
    sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
 | 
			
		||||
    printf("SDK version:%s\n", sdk_system_get_sdk_version());
 | 
			
		||||
 | 
			
		||||
    struct sdk_station_config config = {
 | 
			
		||||
        .ssid = WIFI_SSID,
 | 
			
		||||
        .password = WIFI_PASS,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /* required to call wifi_set_opmode before station_set_config */
 | 
			
		||||
    sdk_wifi_set_opmode(STATION_MODE);
 | 
			
		||||
    sdk_wifi_station_set_config(&config);
 | 
			
		||||
 | 
			
		||||
    xTaskCreate(&http_get_task, (signed char *)"get_task", 2048, NULL, 2, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Display what session id we have.
 | 
			
		||||
 */
 | 
			
		||||
static void display_session_id(SSL *ssl)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    const uint8_t *session_id = ssl_get_session_id(ssl);
 | 
			
		||||
    int sess_id_size = ssl_get_session_id_size(ssl);
 | 
			
		||||
 | 
			
		||||
    if (sess_id_size > 0)
 | 
			
		||||
    {
 | 
			
		||||
        printf("-----BEGIN SSL SESSION PARAMETERS-----\n");
 | 
			
		||||
        for (i = 0; i < sess_id_size; i++)
 | 
			
		||||
        {
 | 
			
		||||
            printf("%02x", session_id[i]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        printf("\n-----END SSL SESSION PARAMETERS-----\n");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Display what cipher we are using
 | 
			
		||||
 */
 | 
			
		||||
static void display_cipher(SSL *ssl)
 | 
			
		||||
{
 | 
			
		||||
    printf("CIPHER is ");
 | 
			
		||||
    switch (ssl_get_cipher_id(ssl))
 | 
			
		||||
    {
 | 
			
		||||
    case SSL_AES128_SHA:
 | 
			
		||||
        printf("AES128-SHA");
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case SSL_AES256_SHA:
 | 
			
		||||
        printf("AES256-SHA");
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case SSL_RC4_128_SHA:
 | 
			
		||||
        printf("RC4-SHA");
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case SSL_RC4_128_MD5:
 | 
			
		||||
        printf("RC4-MD5");
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        printf("Unknown - %d", ssl_get_cipher_id(ssl));
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("\n");
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,2 +1,3 @@
 | 
			
		|||
PROGRAM=hmac_test
 | 
			
		||||
EXTRA_COMPONENTS=extras/mbedtls
 | 
			
		||||
include ../../../common.mk
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@
 | 
			
		|||
#include "espressif/esp_common.h"
 | 
			
		||||
#include "espressif/sdk_private.h"
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "ssl.h"
 | 
			
		||||
#include "mbedtls/md.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -31,9 +31,7 @@ static const uint8_t aa_80_times[] = {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0x
 | 
			
		|||
				      0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
 | 
			
		||||
				      0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa};
 | 
			
		||||
 | 
			
		||||
/* NOTE: Vectors 6 & 7 currently cause a fault as the axTLS
 | 
			
		||||
   routines don't support keys longer than the block size. */
 | 
			
		||||
const uint8_t NUM_MD5_VECTORS = 5;
 | 
			
		||||
const uint8_t NUM_MD5_VECTORS = 7;
 | 
			
		||||
 | 
			
		||||
static const struct test_vector md5_vectors[] = {
 | 
			
		||||
    { /* vector 1*/
 | 
			
		||||
| 
						 | 
				
			
			@ -88,15 +86,30 @@ static const struct test_vector md5_vectors[] = {
 | 
			
		|||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void print_blob(const char *label, const uint8_t *data, const uint32_t len)
 | 
			
		||||
{
 | 
			
		||||
    printf("%s:", label);
 | 
			
		||||
    for(int i = 0; i < len; i++) {
 | 
			
		||||
        if(i % 16 == 0)
 | 
			
		||||
            printf("\n%02x:", i);
 | 
			
		||||
        printf(" %02x", data[i]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_md5(void)
 | 
			
		||||
{
 | 
			
		||||
    printf("\r\nTesting MD5 vectors...\r\n");
 | 
			
		||||
    uint8_t test_digest[16];
 | 
			
		||||
 | 
			
		||||
    const mbedtls_md_info_t *md5_hmac = mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
 | 
			
		||||
 | 
			
		||||
    for(int i = 0; i < NUM_MD5_VECTORS; i++) {
 | 
			
		||||
	const struct test_vector *vector = &md5_vectors[i];
 | 
			
		||||
	printf("Test case %d: ", i+1);
 | 
			
		||||
	hmac_md5(vector->data, vector->data_len, vector->key, vector->key_len, test_digest);
 | 
			
		||||
	if(memcmp(test_digest, vector->digest, 16)) {
 | 
			
		||||
 | 
			
		||||
        uint8_t test_digest[16];
 | 
			
		||||
        mbedtls_md_hmac(md5_hmac, vector->key, vector->key_len, vector->data, vector->data_len, test_digest);
 | 
			
		||||
 | 
			
		||||
	if(memcmp(vector->digest, test_digest, 16)) {
 | 
			
		||||
	    uint8_t first = 0;
 | 
			
		||||
	    for(first = 0; first < 16; first++) {
 | 
			
		||||
		if(test_digest[first] != vector->digest[first]) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										56
									
								
								extras/mbedtls/component.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								extras/mbedtls/component.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
# Component makefile for mbedtls
 | 
			
		||||
 | 
			
		||||
# mbedtls by default builds into 3 libraries not one. We just use one for now (doesn't make a huge difference when static linking)
 | 
			
		||||
 | 
			
		||||
# Config:
 | 
			
		||||
# We supply our own hand tweaked mbedtls/config.h in our 'include' dir, the rest of upstream mbedtls is not changed.
 | 
			
		||||
 | 
			
		||||
MBEDTLS_DIR = $(mbedtls_ROOT)mbedtls/
 | 
			
		||||
INC_DIRS += $(mbedtls_ROOT)include $(MBEDTLS_DIR)include
 | 
			
		||||
 | 
			
		||||
# these OBJS_xxx variables  are copied directly from mbedtls/mbedtls/Makefile,
 | 
			
		||||
# minus a few values (noted in comments)
 | 
			
		||||
#
 | 
			
		||||
# If updating to a future mbedtls version you can just copy these in.
 | 
			
		||||
OBJS_CRYPTO=	aes.o		aesni.o		arc4.o		\
 | 
			
		||||
		asn1parse.o	asn1write.o	base64.o	\
 | 
			
		||||
		bignum.o	blowfish.o	camellia.o	\
 | 
			
		||||
		ccm.o		cipher.o	cipher_wrap.o	\
 | 
			
		||||
		ctr_drbg.o	des.o		dhm.o		\
 | 
			
		||||
		ecdh.o		ecdsa.o		ecp.o		\
 | 
			
		||||
		ecp_curves.o	entropy.o	entropy_poll.o	\
 | 
			
		||||
		error.o		gcm.o		havege.o	\
 | 
			
		||||
		hmac_drbg.o	md.o		md2.o		\
 | 
			
		||||
		md4.o		md5.o		md_wrap.o	\
 | 
			
		||||
		memory_buffer_alloc.o		oid.o		\
 | 
			
		||||
		padlock.o	pem.o		pk.o		\
 | 
			
		||||
		pk_wrap.o	pkcs12.o	pkcs5.o		\
 | 
			
		||||
		pkparse.o	pkwrite.o	platform.o	\
 | 
			
		||||
		ripemd160.o	rsa.o		sha1.o		\
 | 
			
		||||
		sha256.o	sha512.o	threading.o	\
 | 
			
		||||
		timing.o	version.o			\
 | 
			
		||||
		version_features.o		xtea.o
 | 
			
		||||
# minus net.o
 | 
			
		||||
 | 
			
		||||
OBJS_X509=	certs.o		pkcs11.o	x509.o		\
 | 
			
		||||
		x509_create.o	x509_crl.o	x509_crt.o	\
 | 
			
		||||
		x509_csr.o	x509write_crt.o	x509write_csr.o
 | 
			
		||||
 | 
			
		||||
OBJS_TLS=	debug.o				ssl_cache.o	\
 | 
			
		||||
		ssl_ciphersuites.o		ssl_cli.o	\
 | 
			
		||||
		ssl_cookie.o	ssl_srv.o	ssl_ticket.o	\
 | 
			
		||||
		ssl_tls.o
 | 
			
		||||
 | 
			
		||||
# args for passing into compile rule generation
 | 
			
		||||
mbedtls_INC_DIR =
 | 
			
		||||
mbedtls_SRC_DIR = $(mbedtls_ROOT)
 | 
			
		||||
mbedtls_EXTRA_SRC_FILES = $(patsubst %.o,$(MBEDTLS_DIR)library/%.c,$(OBJS_CRYPTO) $(OBJS_X509) $(OBJS_TLS))
 | 
			
		||||
 | 
			
		||||
# depending on cipher configuration, some mbedTLS variables are unused
 | 
			
		||||
mbedtls_CFLAGS = -Wno-error=unused-but-set-variable -Wno-error=unused-variable $(CFLAGS) 
 | 
			
		||||
 | 
			
		||||
$(eval $(call component_compile_rules,mbedtls))
 | 
			
		||||
 | 
			
		||||
# Helpful error if git submodule not initialised
 | 
			
		||||
$(MBEDTLS_DIR):
 | 
			
		||||
	$(error "mbedtls git submodule not installed. Please run 'git submodule update --init'")
 | 
			
		||||
							
								
								
									
										22
									
								
								extras/mbedtls/hardware_entropy.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								extras/mbedtls/hardware_entropy.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
/* ESP8266 "Hardware RNG" (validity still being confirmed) support for ESP8266
 | 
			
		||||
 *
 | 
			
		||||
 * Based on research done by @foogod.
 | 
			
		||||
 *
 | 
			
		||||
 * Please don't rely on this too much as an entropy source, quite yet...
 | 
			
		||||
 *
 | 
			
		||||
 * Part of esp-open-rtos
 | 
			
		||||
 * Copyright (C) 2015 Angus Gratton
 | 
			
		||||
 * BSD Licensed as described in the file LICENSE
 | 
			
		||||
 */
 | 
			
		||||
#include <mbedtls/entropy_poll.h>
 | 
			
		||||
#include <esp/hwrand.h>
 | 
			
		||||
 | 
			
		||||
int mbedtls_hardware_poll( void *data,
 | 
			
		||||
                           unsigned char *output, size_t len, size_t *olen )
 | 
			
		||||
{
 | 
			
		||||
    (void)(data);
 | 
			
		||||
    hwrand_fill(output, len);
 | 
			
		||||
    if(olen)
 | 
			
		||||
        *olen = len;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2446
									
								
								extras/mbedtls/include/mbedtls/config.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2446
									
								
								extras/mbedtls/include/mbedtls/config.h
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										1
									
								
								extras/mbedtls/mbedtls
									
										
									
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								extras/mbedtls/mbedtls
									
										
									
									
									
										Submodule
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
Subproject commit 0a0c22e0efcf2f8f71d7e16712f80b8f77326f72
 | 
			
		||||
							
								
								
									
										510
									
								
								extras/mbedtls/net_lwip.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										510
									
								
								extras/mbedtls/net_lwip.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,510 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  TCP/IP or UDP/IP networking functions
 | 
			
		||||
 *  modified for LWIP support on ESP8266
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
 | 
			
		||||
 *  Additions Copyright (C) 2015 Angus Gratton
 | 
			
		||||
 *  SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
			
		||||
 *  not use this file except in compliance with the License.
 | 
			
		||||
 *  You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *  http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 *  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 *  See the License for the specific language governing permissions and
 | 
			
		||||
 *  limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 *  This file is part of mbed TLS (https://tls.mbed.org)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(MBEDTLS_CONFIG_FILE)
 | 
			
		||||
#include "mbedtls/config.h"
 | 
			
		||||
#else
 | 
			
		||||
#include MBEDTLS_CONFIG_FILE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(MBEDTLS_NET_C)
 | 
			
		||||
 | 
			
		||||
#include "mbedtls/net.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Prepare for using the sockets interface
 | 
			
		||||
 */
 | 
			
		||||
static int net_prepare( void )
 | 
			
		||||
{
 | 
			
		||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
 | 
			
		||||
    !defined(EFI32)
 | 
			
		||||
    WSADATA wsaData;
 | 
			
		||||
 | 
			
		||||
    if( wsa_init_done == 0 )
 | 
			
		||||
    {
 | 
			
		||||
        if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 )
 | 
			
		||||
            return( MBEDTLS_ERR_NET_SOCKET_FAILED );
 | 
			
		||||
 | 
			
		||||
        wsa_init_done = 1;
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
#endif
 | 
			
		||||
    return( 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Initialize a context
 | 
			
		||||
 */
 | 
			
		||||
void mbedtls_net_init( mbedtls_net_context *ctx )
 | 
			
		||||
{
 | 
			
		||||
    ctx->fd = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Initiate a TCP connection with host:port and the given protocol
 | 
			
		||||
 */
 | 
			
		||||
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto )
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
    struct addrinfo hints, *addr_list, *cur;
 | 
			
		||||
 | 
			
		||||
    if( ( ret = net_prepare() ) != 0 )
 | 
			
		||||
        return( ret );
 | 
			
		||||
 | 
			
		||||
    /* Do name resolution with both IPv6 and IPv4 */
 | 
			
		||||
    memset( &hints, 0, sizeof( hints ) );
 | 
			
		||||
    hints.ai_family = AF_UNSPEC;
 | 
			
		||||
    hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
 | 
			
		||||
    hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
 | 
			
		||||
 | 
			
		||||
    if( getaddrinfo( host, port, &hints, &addr_list ) != 0 )
 | 
			
		||||
        return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
 | 
			
		||||
 | 
			
		||||
    /* Try the sockaddrs until a connection succeeds */
 | 
			
		||||
    ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
 | 
			
		||||
    for( cur = addr_list; cur != NULL; cur = cur->ai_next )
 | 
			
		||||
    {
 | 
			
		||||
        ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
 | 
			
		||||
                            cur->ai_protocol );
 | 
			
		||||
        if( ctx->fd < 0 )
 | 
			
		||||
        {
 | 
			
		||||
            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( connect( ctx->fd, cur->ai_addr, cur->ai_addrlen ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            ret = 0;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        close( ctx->fd );
 | 
			
		||||
        ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    freeaddrinfo( addr_list );
 | 
			
		||||
 | 
			
		||||
    return( ret );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Create a listening socket on bind_ip:port
 | 
			
		||||
 */
 | 
			
		||||
int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
 | 
			
		||||
{
 | 
			
		||||
    int n, ret;
 | 
			
		||||
    struct addrinfo hints, *addr_list, *cur;
 | 
			
		||||
 | 
			
		||||
    if( ( ret = net_prepare() ) != 0 )
 | 
			
		||||
        return( ret );
 | 
			
		||||
 | 
			
		||||
    /* Bind to IPv6 and/or IPv4, but only in the desired protocol */
 | 
			
		||||
    memset( &hints, 0, sizeof( hints ) );
 | 
			
		||||
    hints.ai_family = AF_UNSPEC;
 | 
			
		||||
    hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
 | 
			
		||||
    hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
 | 
			
		||||
 | 
			
		||||
    if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 )
 | 
			
		||||
        return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
 | 
			
		||||
 | 
			
		||||
    /* Try the sockaddrs until a binding succeeds */
 | 
			
		||||
    ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
 | 
			
		||||
    for( cur = addr_list; cur != NULL; cur = cur->ai_next )
 | 
			
		||||
    {
 | 
			
		||||
        ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
 | 
			
		||||
                            cur->ai_protocol );
 | 
			
		||||
        if( ctx->fd < 0 )
 | 
			
		||||
        {
 | 
			
		||||
            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        n = 1;
 | 
			
		||||
        if( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR,
 | 
			
		||||
                        (const char *) &n, sizeof( n ) ) != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            close( ctx->fd );
 | 
			
		||||
            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( bind( ctx->fd, cur->ai_addr, cur->ai_addrlen ) != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            close( ctx->fd );
 | 
			
		||||
            ret = MBEDTLS_ERR_NET_BIND_FAILED;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Listen only makes sense for TCP */
 | 
			
		||||
        if( proto == MBEDTLS_NET_PROTO_TCP )
 | 
			
		||||
        {
 | 
			
		||||
            if( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 )
 | 
			
		||||
            {
 | 
			
		||||
                close( ctx->fd );
 | 
			
		||||
                ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* I we ever get there, it's a success */
 | 
			
		||||
        ret = 0;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    freeaddrinfo( addr_list );
 | 
			
		||||
 | 
			
		||||
    return( ret );
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
 | 
			
		||||
    !defined(EFI32)
 | 
			
		||||
/*
 | 
			
		||||
 * Check if the requested operation would be blocking on a non-blocking socket
 | 
			
		||||
 * and thus 'failed' with a negative return value.
 | 
			
		||||
 */
 | 
			
		||||
static int net_would_block( const mbedtls_net_context *ctx )
 | 
			
		||||
{
 | 
			
		||||
    ((void) ctx);
 | 
			
		||||
    return( WSAGetLastError() == WSAEWOULDBLOCK );
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
/*
 | 
			
		||||
 * Check if the requested operation would be blocking on a non-blocking socket
 | 
			
		||||
 * and thus 'failed' with a negative return value.
 | 
			
		||||
 *
 | 
			
		||||
 * Note: on a blocking socket this function always returns 0!
 | 
			
		||||
 */
 | 
			
		||||
static int net_would_block( const mbedtls_net_context *ctx )
 | 
			
		||||
{
 | 
			
		||||
    /*
 | 
			
		||||
     * Never return 'WOULD BLOCK' on a non-blocking socket
 | 
			
		||||
     */
 | 
			
		||||
    if( ( fcntl( ctx->fd, F_GETFL, 0) & O_NONBLOCK ) != O_NONBLOCK )
 | 
			
		||||
        return( 0 );
 | 
			
		||||
 | 
			
		||||
    switch( errno )
 | 
			
		||||
    {
 | 
			
		||||
#if defined EAGAIN
 | 
			
		||||
        case EAGAIN:
 | 
			
		||||
#endif
 | 
			
		||||
#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
 | 
			
		||||
        case EWOULDBLOCK:
 | 
			
		||||
#endif
 | 
			
		||||
            return( 1 );
 | 
			
		||||
    }
 | 
			
		||||
    return( 0 );
 | 
			
		||||
}
 | 
			
		||||
#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Accept a connection from a remote client
 | 
			
		||||
 */
 | 
			
		||||
int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
 | 
			
		||||
                        mbedtls_net_context *client_ctx,
 | 
			
		||||
                        void *client_ip, size_t buf_size, size_t *ip_len )
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
    int type;
 | 
			
		||||
 | 
			
		||||
    struct sockaddr_in client_addr;
 | 
			
		||||
 | 
			
		||||
    socklen_t n = (socklen_t) sizeof( client_addr );
 | 
			
		||||
    socklen_t type_len = (socklen_t) sizeof( type );
 | 
			
		||||
 | 
			
		||||
    /* Is this a TCP or UDP socket? */
 | 
			
		||||
    if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
 | 
			
		||||
                    (void *) &type, (socklen_t *) &type_len ) != 0 ||
 | 
			
		||||
        ( type != SOCK_STREAM && type != SOCK_DGRAM ) )
 | 
			
		||||
    {
 | 
			
		||||
        return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if( type == SOCK_STREAM )
 | 
			
		||||
    {
 | 
			
		||||
        /* TCP: actual accept() */
 | 
			
		||||
        ret = client_ctx->fd = (int) accept( bind_ctx->fd,
 | 
			
		||||
                                             (struct sockaddr *) &client_addr, &n );
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        /* UDP: wait for a message, but keep it in the queue */
 | 
			
		||||
        char buf[1] = { 0 };
 | 
			
		||||
 | 
			
		||||
        ret = recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
 | 
			
		||||
                        (struct sockaddr *) &client_addr, &n );
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
        if( ret == SOCKET_ERROR &&
 | 
			
		||||
            WSAGetLastError() == WSAEMSGSIZE )
 | 
			
		||||
        {
 | 
			
		||||
            /* We know buf is too small, thanks, just peeking here */
 | 
			
		||||
            ret = 0;
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if( ret < 0 )
 | 
			
		||||
    {
 | 
			
		||||
        if( net_would_block( bind_ctx ) != 0 )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_WANT_READ );
 | 
			
		||||
 | 
			
		||||
        return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* UDP: hijack the listening socket to communicate with the client,
 | 
			
		||||
     * then bind a new socket to accept new connections */
 | 
			
		||||
    if( type != SOCK_STREAM )
 | 
			
		||||
    {
 | 
			
		||||
        struct sockaddr_in local_addr;
 | 
			
		||||
        int one = 1;
 | 
			
		||||
 | 
			
		||||
        if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 )
 | 
			
		||||
            return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
 | 
			
		||||
 | 
			
		||||
        client_ctx->fd = bind_ctx->fd;
 | 
			
		||||
        bind_ctx->fd   = -1; /* In case we exit early */
 | 
			
		||||
 | 
			
		||||
        n = sizeof( struct sockaddr_in );
 | 
			
		||||
        if( getsockname( client_ctx->fd,
 | 
			
		||||
                         (struct sockaddr *) &local_addr, &n ) != 0 ||
 | 
			
		||||
            ( bind_ctx->fd = (int) socket( AF_INET,
 | 
			
		||||
                                           SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
 | 
			
		||||
            setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
 | 
			
		||||
                        (const char *) &one, sizeof( one ) ) != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            return( MBEDTLS_ERR_NET_SOCKET_FAILED );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            return( MBEDTLS_ERR_NET_BIND_FAILED );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if( client_ip != NULL )
 | 
			
		||||
    {
 | 
			
		||||
            struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
 | 
			
		||||
            *ip_len = sizeof( addr4->sin_addr.s_addr );
 | 
			
		||||
 | 
			
		||||
            if( buf_size < *ip_len )
 | 
			
		||||
                return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
 | 
			
		||||
 | 
			
		||||
            memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return( 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Set the socket blocking or non-blocking
 | 
			
		||||
 */
 | 
			
		||||
int mbedtls_net_set_block( mbedtls_net_context *ctx )
 | 
			
		||||
{
 | 
			
		||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
 | 
			
		||||
    !defined(EFI32)
 | 
			
		||||
    u_long n = 0;
 | 
			
		||||
    return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
 | 
			
		||||
#else
 | 
			
		||||
    return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL, 0 ) & ~O_NONBLOCK ) );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
 | 
			
		||||
{
 | 
			
		||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
 | 
			
		||||
    !defined(EFI32)
 | 
			
		||||
    u_long n = 1;
 | 
			
		||||
    return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
 | 
			
		||||
#else
 | 
			
		||||
    return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL, 0 ) | O_NONBLOCK ) );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Portable usleep helper
 | 
			
		||||
 */
 | 
			
		||||
void mbedtls_net_usleep( unsigned long usec )
 | 
			
		||||
{
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
    Sleep( ( usec + 999 ) / 1000 );
 | 
			
		||||
#else
 | 
			
		||||
    struct timeval tv;
 | 
			
		||||
    tv.tv_sec  = usec / 1000000;
 | 
			
		||||
#if defined(__unix__) || defined(__unix) || \
 | 
			
		||||
    ( defined(__APPLE__) && defined(__MACH__) )
 | 
			
		||||
    tv.tv_usec = (suseconds_t) usec % 1000000;
 | 
			
		||||
#else
 | 
			
		||||
    tv.tv_usec = usec % 1000000;
 | 
			
		||||
#endif
 | 
			
		||||
    select( 0, NULL, NULL, NULL, &tv );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Read at most 'len' characters
 | 
			
		||||
 */
 | 
			
		||||
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
    int fd = ((mbedtls_net_context *) ctx)->fd;
 | 
			
		||||
 | 
			
		||||
    if( fd < 0 )
 | 
			
		||||
        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
 | 
			
		||||
 | 
			
		||||
    ret = (int) read( fd, buf, len );
 | 
			
		||||
 | 
			
		||||
    if( ret < 0 )
 | 
			
		||||
    {
 | 
			
		||||
        if( net_would_block( ctx ) != 0 )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_WANT_READ );
 | 
			
		||||
 | 
			
		||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
 | 
			
		||||
    !defined(EFI32)
 | 
			
		||||
        if( WSAGetLastError() == WSAECONNRESET )
 | 
			
		||||
            return( MBEDTLS_ERR_NET_CONN_RESET );
 | 
			
		||||
#else
 | 
			
		||||
        if( errno == EPIPE || errno == ECONNRESET )
 | 
			
		||||
            return( MBEDTLS_ERR_NET_CONN_RESET );
 | 
			
		||||
 | 
			
		||||
        if( errno == EINTR )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_WANT_READ );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        return( MBEDTLS_ERR_NET_RECV_FAILED );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return( ret );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Read at most 'len' characters, blocking for at most 'timeout' ms
 | 
			
		||||
 */
 | 
			
		||||
int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
 | 
			
		||||
                      uint32_t timeout )
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
    struct timeval tv;
 | 
			
		||||
    fd_set read_fds;
 | 
			
		||||
    int fd = ((mbedtls_net_context *) ctx)->fd;
 | 
			
		||||
 | 
			
		||||
    if( fd < 0 )
 | 
			
		||||
        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
 | 
			
		||||
 | 
			
		||||
    FD_ZERO( &read_fds );
 | 
			
		||||
    FD_SET( fd, &read_fds );
 | 
			
		||||
 | 
			
		||||
    tv.tv_sec  = timeout / 1000;
 | 
			
		||||
    tv.tv_usec = ( timeout % 1000 ) * 1000;
 | 
			
		||||
 | 
			
		||||
    ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
 | 
			
		||||
 | 
			
		||||
    /* Zero fds ready means we timed out */
 | 
			
		||||
    if( ret == 0 )
 | 
			
		||||
        return( MBEDTLS_ERR_SSL_TIMEOUT );
 | 
			
		||||
 | 
			
		||||
    if( ret < 0 )
 | 
			
		||||
    {
 | 
			
		||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
 | 
			
		||||
    !defined(EFI32)
 | 
			
		||||
        if( WSAGetLastError() == WSAEINTR )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_WANT_READ );
 | 
			
		||||
#else
 | 
			
		||||
        if( errno == EINTR )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_WANT_READ );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        return( MBEDTLS_ERR_NET_RECV_FAILED );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* This call will not block */
 | 
			
		||||
    return( mbedtls_net_recv( ctx, buf, len ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Write at most 'len' characters
 | 
			
		||||
 */
 | 
			
		||||
int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
    int fd = ((mbedtls_net_context *) ctx)->fd;
 | 
			
		||||
 | 
			
		||||
    if( fd < 0 )
 | 
			
		||||
        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
 | 
			
		||||
 | 
			
		||||
    ret = (int) write( fd, buf, len );
 | 
			
		||||
 | 
			
		||||
    if( ret < 0 )
 | 
			
		||||
    {
 | 
			
		||||
        if( net_would_block( ctx ) != 0 )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_WANT_WRITE );
 | 
			
		||||
 | 
			
		||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
 | 
			
		||||
    !defined(EFI32)
 | 
			
		||||
        if( WSAGetLastError() == WSAECONNRESET )
 | 
			
		||||
            return( MBEDTLS_ERR_NET_CONN_RESET );
 | 
			
		||||
#else
 | 
			
		||||
        if( errno == EPIPE || errno == ECONNRESET )
 | 
			
		||||
            return( MBEDTLS_ERR_NET_CONN_RESET );
 | 
			
		||||
 | 
			
		||||
        if( errno == EINTR )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_WANT_WRITE );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        return( MBEDTLS_ERR_NET_SEND_FAILED );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return( ret );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Gracefully close the connection
 | 
			
		||||
 */
 | 
			
		||||
void mbedtls_net_free( mbedtls_net_context *ctx )
 | 
			
		||||
{
 | 
			
		||||
    if( ctx->fd == -1 )
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    shutdown( ctx->fd, 2 );
 | 
			
		||||
    close( ctx->fd );
 | 
			
		||||
 | 
			
		||||
    ctx->fd = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* MBEDTLS_NET_C */
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +32,7 @@ ets_printf = printf;
 | 
			
		|||
*/
 | 
			
		||||
#ifndef OTA
 | 
			
		||||
 | 
			
		||||
#define IROM0_START 0x40240000
 | 
			
		||||
#define IROM0_START 0x40220000
 | 
			
		||||
 | 
			
		||||
/* Non-OTA sizes */
 | 
			
		||||
#if FLASH_SIZE == 2 /* 256kB */
 | 
			
		||||
| 
						 | 
				
			
			@ -136,6 +136,68 @@ SECTIONS
 | 
			
		|||
    _dport0_data_end = ABSOLUTE(.);
 | 
			
		||||
  } >dport0_0_seg :dport0_0_phdr
 | 
			
		||||
 | 
			
		||||
  .text : ALIGN(4) /* IRAM */
 | 
			
		||||
  {
 | 
			
		||||
    _stext = .;
 | 
			
		||||
    _text_start = ABSOLUTE(.);
 | 
			
		||||
    . = ALIGN (16);
 | 
			
		||||
    *(.vecbase.text)
 | 
			
		||||
    *(.entry.text)
 | 
			
		||||
    *(.init.literal)
 | 
			
		||||
    *(.init)
 | 
			
		||||
    /* esp-open-rtos compiled source files use the .iram1.* section names for IRAM
 | 
			
		||||
       functions, etc. */
 | 
			
		||||
    *(.iram1.*)
 | 
			
		||||
    /* SDK libraries expect their .text sections to link to iram, not irom */
 | 
			
		||||
    *sdklib*:*(.literal .text .literal.* .text.*)
 | 
			
		||||
    /* libgcc integer functions also need to be in .text, as some are called before
 | 
			
		||||
       flash is mapped (also performance)
 | 
			
		||||
    */
 | 
			
		||||
    *libgcc.a:*i3.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    /* libc also in IRAM */
 | 
			
		||||
    *libc.a:*malloc.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*mallocr.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*freer.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*memcpy.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*memset.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*memcmp.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*memmove.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*rand.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*bzero.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*lock.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    *libc.a:*printf.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*findfp.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*fputwc.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    /* xthal_set_intset() called from PendSV in NMI context */
 | 
			
		||||
    *libhal.a:*set_intset.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
 | 
			
		||||
    *(.fini.literal)
 | 
			
		||||
    *(.fini)
 | 
			
		||||
    *(.gnu.version)
 | 
			
		||||
    _text_end = ABSOLUTE(.);
 | 
			
		||||
    _etext = .;
 | 
			
		||||
  } >iram1_0_seg :iram1_0_phdr
 | 
			
		||||
 | 
			
		||||
  .irom0.text : ALIGN(4)
 | 
			
		||||
  {
 | 
			
		||||
    _irom0_text_start = ABSOLUTE(.);
 | 
			
		||||
    /* esp-open-rtos compiled code goes into IROM by default
 | 
			
		||||
       (except for libgcc which is matched above.)
 | 
			
		||||
    */
 | 
			
		||||
    *(.literal .text .literal.* .text.*)
 | 
			
		||||
    /* mbedtls rodata */
 | 
			
		||||
    *mbedtls.a:*.o(.rodata.* .rodata)
 | 
			
		||||
    /* actual certificate in example (TEMPORARY HACK) */
 | 
			
		||||
    *:cert.o(.rodata.* .rodata)
 | 
			
		||||
    /* Anything explicitly marked as "irom" or "irom0" should go here */
 | 
			
		||||
    *(.irom.* .irom.*.* .irom0.*)
 | 
			
		||||
    _irom0_text_end = ABSOLUTE(.);
 | 
			
		||||
  } >irom0_0_seg :irom0_0_phdr
 | 
			
		||||
 | 
			
		||||
  .data : ALIGN(4)
 | 
			
		||||
  {
 | 
			
		||||
    _data_start = ABSOLUTE(.);
 | 
			
		||||
| 
						 | 
				
			
			@ -218,62 +280,6 @@ SECTIONS
 | 
			
		|||
  } >dram0_0_seg :dram0_0_bss_phdr
 | 
			
		||||
/* __stack = 0x3ffc8000; */
 | 
			
		||||
 | 
			
		||||
  .text : ALIGN(4) /* IRAM */
 | 
			
		||||
  {
 | 
			
		||||
    _stext = .;
 | 
			
		||||
    _text_start = ABSOLUTE(.);
 | 
			
		||||
    . = ALIGN (16);
 | 
			
		||||
    *(.vecbase.text)
 | 
			
		||||
    *(.entry.text)
 | 
			
		||||
    *(.init.literal)
 | 
			
		||||
    *(.init)
 | 
			
		||||
    /* esp-open-rtos compiled source files use the .iram1.* section names for IRAM
 | 
			
		||||
       functions, etc. */
 | 
			
		||||
    *(.iram1.*)
 | 
			
		||||
    /* SDK libraries expect their .text sections to link to iram, not irom */
 | 
			
		||||
    *sdklib*:*(.literal .text .literal.* .text.*)
 | 
			
		||||
    /* libgcc integer functions also need to be in .text, as some are called before
 | 
			
		||||
       flash is mapped (also performance)
 | 
			
		||||
    */
 | 
			
		||||
    *libgcc.a:*i3.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    /* libc also in IRAM */
 | 
			
		||||
    *libc.a:*malloc.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*mallocr.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*freer.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*memcpy.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*memset.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*memcmp.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*rand.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*bzero.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*lock.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    *libc.a:*printf.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*findfp.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*fputwc.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    /* xthal_set_intset() called from PendSV in NMI context */
 | 
			
		||||
    *libhal.a:*set_intset.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
 | 
			
		||||
    *(.fini.literal)
 | 
			
		||||
    *(.fini)
 | 
			
		||||
    *(.gnu.version)
 | 
			
		||||
    _text_end = ABSOLUTE(.);
 | 
			
		||||
    _etext = .;
 | 
			
		||||
  } >iram1_0_seg :iram1_0_phdr
 | 
			
		||||
 | 
			
		||||
  .irom0.text : ALIGN(4)
 | 
			
		||||
  {
 | 
			
		||||
    _irom0_text_start = ABSOLUTE(.);
 | 
			
		||||
    /* esp-open-rtos compiled code goes into IROM by default
 | 
			
		||||
       (except for libgcc which is matched above.)
 | 
			
		||||
    */
 | 
			
		||||
    *(.literal .text .literal.* .text.*)
 | 
			
		||||
    /* Anything explicitly marked as "irom" or "irom0" should go here */
 | 
			
		||||
    *(.irom.* .irom.*.* .irom0.*)
 | 
			
		||||
    _irom0_text_end = ABSOLUTE(.);
 | 
			
		||||
  } >irom0_0_seg :irom0_0_phdr
 | 
			
		||||
 | 
			
		||||
  .lit4 : ALIGN(4)
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
# Component makefile for LWIP
 | 
			
		||||
 | 
			
		||||
LWIP_DIR = $(lwip_ROOT)lwip/src/
 | 
			
		||||
INC_DIRS += $(LWIP_DIR)include $(ROOT)lwip/include $(lwip_ROOT)include $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip $(LWIP_DIR)include/lwip
 | 
			
		||||
INC_DIRS += $(LWIP_DIR)include $(ROOT)lwip/include $(lwip_ROOT)include $(LWIP_DIR)include/posix $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip $(LWIP_DIR)include/lwip
 | 
			
		||||
 | 
			
		||||
# args for passing into compile rule generation
 | 
			
		||||
lwip_INC_DIR =  # all in INC_DIRS, needed for normal operation
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue