mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-25 12:04:47 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32406b678b | ||
|
|
55e2077a46 | ||
|
|
a771d6a19d | ||
|
|
0d5d7bb26f | ||
|
|
3808dd3222 | ||
|
|
8fc94e12af | ||
|
|
824e33ef8a | ||
|
|
655f9a9f79 | ||
|
|
6ac6aa521c | ||
|
|
3982e065c8 | ||
|
|
497b8027f5 | ||
|
|
89757388c7 | ||
|
|
77fae5c562 | ||
|
|
80fcba91c8 | ||
|
|
39d64be581 | ||
|
|
2bfd30ab4b | ||
|
|
60004eb209 | ||
|
|
db11897d71 | ||
|
|
5e466f9037 | ||
|
|
6b2698a503 | ||
|
|
4788db7e00 | ||
|
|
d9680df510 | ||
|
|
f20ee1f305 | ||
|
|
302bf865f9 | ||
|
|
03929dcdaa | ||
|
|
89af2e9638 | ||
|
|
015586950f | ||
|
|
9df261a0eb | ||
|
|
a2a3c84450 | ||
|
|
6611348ebf | ||
|
|
e69ee90acf | ||
|
|
8f3554d08a | ||
|
|
b6ee9e637b | ||
|
|
f46453f80f | ||
|
|
3deafaea7f | ||
|
|
a15d518571 | ||
|
|
886a29d659 | ||
|
|
e69de57def | ||
|
|
9d68e20dcc | ||
|
|
c0a8546330 | ||
|
|
4c0002e28a | ||
|
|
7c37d75bf4 | ||
|
|
879261981f | ||
|
|
838b0bcd27 | ||
|
|
736b8ad7b7 | ||
|
|
db27fae40e | ||
|
|
594111a255 | ||
|
|
53a46a2739 | ||
|
|
eef7a55904 | ||
|
|
a68fa5e6e0 | ||
|
|
7c0d126edc | ||
|
|
1a5e3d3151 | ||
|
|
95ff6c56af | ||
|
|
e2ef392633 | ||
|
|
dbc2356768 | ||
|
|
47e5e984df | ||
|
|
0f32f50c50 | ||
|
|
606cc1f538 | ||
|
|
2bb11888d5 | ||
|
|
09b1d6aa72 | ||
|
|
72f0489ec2 | ||
|
|
7b39973065 | ||
|
|
30b64483fd | ||
|
|
5369fb0376 | ||
|
|
5fe34fd6c3 | ||
|
|
0fbdda4d2e | ||
|
|
a98e980c8f | ||
|
|
2b836504ab | ||
|
|
0de3f0d985 | ||
|
|
151e375091 | ||
|
|
c44549bfa5 | ||
|
|
d6852f5e74 | ||
|
|
9173034b96 | ||
|
|
2888ab1f52 | ||
|
|
26b5416641 | ||
|
|
8bcac7e955 | ||
|
|
ea25e8129c | ||
|
|
26cb44f9d9 | ||
|
|
7a37a44433 | ||
|
|
a752f3f8c7 | ||
|
|
946e07644c | ||
|
|
497b26a249 | ||
|
|
79aad7fabf | ||
|
|
7851930ac3 | ||
|
|
758572872d | ||
|
|
111551477a | ||
|
|
31c9e3fb7e | ||
|
|
7061b7202f | ||
|
|
d88b6a3c95 | ||
|
|
cea2a62ee0 | ||
|
|
35a8b8e8e8 | ||
|
|
1b8624f135 | ||
|
|
e217066bf6 | ||
|
|
5430408218 | ||
|
|
d2744063a0 | ||
|
|
03356616ef | ||
|
|
6ce2e48dd3 | ||
|
|
16a7ba6bf0 | ||
|
|
e9d122f231 | ||
|
|
0ae5c61759 | ||
|
|
691460c5fc | ||
|
|
ab1c924388 | ||
|
|
05050eba38 | ||
|
|
912dd518bf | ||
|
|
e0395a9907 | ||
|
|
0051f23e12 | ||
|
|
a9bb8fa9fc | ||
|
|
09f5d2fdae | ||
|
|
006a9d914c | ||
|
|
9009cbc528 | ||
|
|
a1862986b8 | ||
|
|
cc2989a848 | ||
|
|
4deb95776f | ||
|
|
f195b27884 | ||
|
|
5036a71334 | ||
|
|
531c47b47c | ||
|
|
4dbb2da78f | ||
|
|
41c1e0f08d | ||
|
|
e7b1905e49 | ||
|
|
e00265f855 | ||
|
|
cd36708b6d | ||
|
|
5bd22cb5e4 | ||
|
|
bc00d5159a | ||
|
|
bcb0874477 | ||
|
|
5326e8d212 | ||
|
|
4528cc28ef | ||
|
|
381d7cce54 | ||
|
|
2594e7b37a | ||
|
|
4356b953ca | ||
|
|
e788853156 | ||
|
|
91ed6de166 | ||
|
|
cf3aafc32e | ||
|
|
c2d7ff8179 | ||
|
|
e5eaa1c633 | ||
|
|
6366c832b0 | ||
|
|
f326cbedbe | ||
|
|
5b272c2b5c | ||
|
|
452bcc68a4 | ||
|
|
829827d46f | ||
|
|
ff9d0e462e | ||
|
|
e84ea91a4a | ||
|
|
2dcb10ef36 | ||
|
|
99fa7f0851 | ||
|
|
1b5cc341a5 | ||
|
|
d50dc288cd | ||
|
|
060bb29cdc | ||
|
|
366426e8bb | ||
|
|
e710df4c80 | ||
|
|
79e5841483 | ||
|
|
374ab4ecf0 | ||
|
|
56980be48c | ||
|
|
602c5c0866 | ||
|
|
7ce5009de1 | ||
|
|
51e3a1304b | ||
|
|
d5a1d5a5e8 | ||
|
|
ae5f6c0920 | ||
|
|
0a9303bb07 | ||
|
|
42bc7b1f47 | ||
|
|
4844ed60bd | ||
|
|
41f5daeb47 | ||
|
|
a3f8f33d50 | ||
|
|
fd8db5c53a | ||
|
|
a2f027e798 | ||
|
|
dad5c8fe87 | ||
|
|
98783a41ba | ||
|
|
1517d2985a | ||
|
|
acc0564957 | ||
|
|
421bc126b5 | ||
|
|
ed1a98c381 | ||
|
|
457d76b049 | ||
|
|
6827972f71 | ||
|
|
7eb998891e | ||
|
|
582fde5c6e | ||
|
|
d327ee9834 | ||
|
|
31cf6f8969 | ||
|
|
86b1053678 | ||
|
|
6678e36278 | ||
|
|
5118355732 | ||
|
|
5b4b7f7dc5 | ||
|
|
7614a8101f | ||
|
|
3c851bcfc3 | ||
|
|
01691dafa0 |
No files matched your search
@@ -0,0 +1,11 @@
|
|||||||
|
- My goal is: _describe_
|
||||||
|
- My actions were: _describe_
|
||||||
|
- My expectation was: _describe_
|
||||||
|
- The result I saw: _provide logs or description_
|
||||||
|
- My question is: _your question_
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
|
||||||
|
- mongoose version: _X.Y_
|
||||||
|
- OS: _?_
|
||||||
|
- Compiler/IDE: _?_
|
||||||
@@ -11,6 +11,12 @@ jobs:
|
|||||||
run: make test test++ IPV6=0
|
run: make test test++ IPV6=0
|
||||||
- name: openssl
|
- name: openssl
|
||||||
run: make test SSL=OPENSSL IPV6=0
|
run: make test SSL=OPENSSL IPV6=0
|
||||||
|
examples:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install packages
|
||||||
|
run: sudo apt-get install libmbedtls-dev
|
||||||
- name: examples
|
- name: examples
|
||||||
run: make ex
|
run: make ex
|
||||||
macos:
|
macos:
|
||||||
@@ -22,7 +28,7 @@ jobs:
|
|||||||
- name: make
|
- name: make
|
||||||
run: make test++ upload-coverage IPV6=0
|
run: make test++ upload-coverage IPV6=0
|
||||||
- name: openssl
|
- name: openssl
|
||||||
run: make test SSL=OPENSSL IPV6=0
|
run: make test SSL=OPENSSL IPV6=0 OPENSSL=`echo /usr/local/Cellar/openssl*/*`
|
||||||
- name: exports
|
- name: exports
|
||||||
run: make mg_prefix
|
run: make mg_prefix
|
||||||
windows:
|
windows:
|
||||||
@@ -37,4 +43,9 @@ jobs:
|
|||||||
run: make mingw
|
run: make mingw
|
||||||
- name: mingw++
|
- name: mingw++
|
||||||
run: make mingw++
|
run: make mingw++
|
||||||
|
arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: arm
|
||||||
|
run: make arm
|
||||||
@@ -1,33 +1,35 @@
|
|||||||
SRCS = $(wildcard src/*.c)
|
SRCS = $(wildcard src/*.c)
|
||||||
HDRS = $(wildcard src/*.h)
|
HDRS = $(wildcard src/*.h)
|
||||||
DEFS ?= -DMG_MAX_HTTP_HEADERS=5 -DMG_ENABLE_LINES -DMG_ENABLE_HTTP_DEBUG_ENDPOINT=1 -DMG_ENABLE_DIRECTORY_LISTING=1 -DMG_ENABLE_SSI=1
|
DEFS ?= -DMG_MAX_HTTP_HEADERS=5 -DMG_ENABLE_LINES -DMG_ENABLE_DIRECTORY_LISTING=1 -DMG_ENABLE_SSI=1
|
||||||
CFLAGS ?= -W -Wall -Werror -Isrc -I. -O0 -g $(DEFS) $(TFLAGS) $(EXTRA)
|
WARN ?= -W -Wall -Werror -Wshadow -Wdouble-promotion -fno-common -Wconversion
|
||||||
|
OPTS ?= -O3 -g3
|
||||||
|
INCS ?= -Isrc -I.
|
||||||
|
CFLAGS ?= $(OPTS) $(WARN) $(INCS) $(DEFS) $(TFLAGS) $(EXTRA)
|
||||||
SSL ?= MBEDTLS
|
SSL ?= MBEDTLS
|
||||||
CDIR ?= $(realpath $(CURDIR))
|
CDIR ?= $(realpath $(CURDIR))
|
||||||
VC98 = docker run --rm -e WINEDEBUG=-all -v $(CDIR):$(CDIR) -w $(CDIR) docker.io/mdashnet/vc98
|
VC98 = docker run --rm -e WINEDEBUG=-all -v $(CDIR):$(CDIR) -w $(CDIR) docker.io/mdashnet/vc98
|
||||||
VC2017 = docker run --rm -e WINEDEBUG=-all -v $(CDIR):$(CDIR) -w $(CDIR) docker.io/mdashnet/vc2017
|
VC2017 = docker run --rm -e WINEDEBUG=-all -v $(CDIR):$(CDIR) -w $(CDIR) docker.io/mdashnet/vc2017
|
||||||
MINGW = docker run --rm -v $(CDIR):$(CDIR) -w $(CDIR) docker.io/mdashnet/mingw
|
MINGW = docker run --rm -v $(CDIR):$(CDIR) -w $(CDIR) docker.io/mdashnet/mingw
|
||||||
GCC = docker run --rm -v $(CDIR):$(CDIR) -w $(CDIR) mdashnet/cc2
|
GCC = docker run --rm -v $(CDIR):$(CDIR) -w $(CDIR) mdashnet/cc2
|
||||||
|
ARM = docker run -v $(CDIR):$(CDIR) -w $(CDIR) mdashnet/armgcc
|
||||||
VCFLAGS = /nologo /W3 /O2 /I. $(DEFS) $(TFLAGS)
|
VCFLAGS = /nologo /W3 /O2 /I. $(DEFS) $(TFLAGS)
|
||||||
CLANG ?= clang # /usr/local/opt/llvm\@9/bin/clang
|
CLANG ?= clang # /usr/local/opt/llvm\@9/bin/clang
|
||||||
IPV6 ?= 1
|
IPV6 ?= 1
|
||||||
ASAN_OPTIONS ?=
|
ASAN_OPTIONS ?=
|
||||||
EXAMPLES := $(wildcard examples/*)
|
EXAMPLES := $(wildcard examples/*)
|
||||||
EXAMPLE_TARGET ?= example
|
EXAMPLE_TARGET ?= example
|
||||||
|
PREFIX ?= /usr/local
|
||||||
|
SOVERSION = 7.2
|
||||||
.PHONY: ex test
|
.PHONY: ex test
|
||||||
|
|
||||||
ifeq "$(SSL)" "MBEDTLS"
|
ifeq "$(SSL)" "MBEDTLS"
|
||||||
MBEDTLS_DIR ?= $(shell brew --cellar mbedtls)
|
MBEDTLS ?= /usr
|
||||||
MBEDTLS_VER ?= $(shell brew info mbedtls --json | jq -j .[0].installed[0].version)
|
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS)/include -I/usr/include
|
||||||
MBEDTLS ?= $(MBEDTLS_DIR)/$(MBEDTLS_VER)
|
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS)/include -I/usr/include
|
|
||||||
LDFLAGS ?= -L$(MBEDTLS)/lib -lmbedtls -lmbedcrypto -lmbedx509
|
LDFLAGS ?= -L$(MBEDTLS)/lib -lmbedtls -lmbedcrypto -lmbedx509
|
||||||
endif
|
endif
|
||||||
ifeq "$(SSL)" "OPENSSL"
|
ifeq "$(SSL)" "OPENSSL"
|
||||||
OPENSSL_DIR ?= $(shell brew --cellar openssl)
|
OPENSSL ?= /usr
|
||||||
OPENSSL_VER ?= $(shell brew info openssl --json | jq -j .[0].installed[0].version)
|
CFLAGS += -DMG_ENABLE_OPENSSL=1 -I$(OPENSSL)/include
|
||||||
OPENSSL ?= $(OPENSSL_DIR)/$(OPENSSL_VER)
|
|
||||||
CFLAGS += -DMG_ENABLE_OPENSSL=1 -I$(OPENSSL)/include
|
|
||||||
LDFLAGS ?= -L$(OPENSSL)/lib -lssl -lcrypto
|
LDFLAGS ?= -L$(OPENSSL)/lib -lssl -lcrypto
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -41,13 +43,13 @@ mg_prefix: mongoose.c mongoose.h
|
|||||||
$(CLANG) mongoose.c $(CFLAGS) -c -o /tmp/x.o && nm /tmp/x.o | grep ' T' | grep -v 'mg_' ; test $$? = 1
|
$(CLANG) mongoose.c $(CFLAGS) -c -o /tmp/x.o && nm /tmp/x.o | grep ' T' | grep -v 'mg_' ; test $$? = 1
|
||||||
|
|
||||||
# C++ build
|
# C++ build
|
||||||
test++: CLANG = g++ -Wno-deprecated -Wno-missing-field-initializers
|
test++: CLANG = g++
|
||||||
test++: unamalgamated
|
test++: WARN += -Wno-shadow -Wno-missing-field-initializers -Wno-deprecated
|
||||||
|
test++: test
|
||||||
|
|
||||||
# Make sure we can build from an unamalgamated sources
|
# Make sure we can build from an unamalgamated sources
|
||||||
unamalgamated: $(SRCS) $(HDRS) Makefile
|
unamalgamated: $(SRCS) $(HDRS) Makefile
|
||||||
$(CLANG) src/*.c test/unit_test.c $(CFLAGS) $(LDFLAGS) -g -o unit_test
|
$(CLANG) src/*.c test/unit_test.c $(CFLAGS) $(LDFLAGS) -g -o unit_test
|
||||||
|
|
||||||
fuzz: mongoose.c mongoose.h Makefile test/fuzz.c
|
fuzz: mongoose.c mongoose.h Makefile test/fuzz.c
|
||||||
$(CLANG) mongoose.c test/fuzz.c $(CFLAGS) -DMG_ENABLE_LINES -DMG_ENABLE_LOG=0 -fsanitize=fuzzer,signed-integer-overflow,address $(LDFLAGS) -g -o fuzzer
|
$(CLANG) mongoose.c test/fuzz.c $(CFLAGS) -DMG_ENABLE_LINES -DMG_ENABLE_LOG=0 -fsanitize=fuzzer,signed-integer-overflow,address $(LDFLAGS) -g -o fuzzer
|
||||||
$(DEBUGGER) ./fuzzer
|
$(DEBUGGER) ./fuzzer
|
||||||
@@ -92,14 +94,31 @@ linux: Makefile mongoose.c mongoose.h test/unit_test.c
|
|||||||
$(GCC) $(CC) mongoose.c test/unit_test.c $(CFLAGS) $(LDFLAGS) -o unit_test_gcc
|
$(GCC) $(CC) mongoose.c test/unit_test.c $(CFLAGS) $(LDFLAGS) -o unit_test_gcc
|
||||||
$(GCC) ./unit_test_gcc
|
$(GCC) ./unit_test_gcc
|
||||||
|
|
||||||
linux++: CC = g++ -Wno-missing-field-initializers
|
linux++: CC = g++
|
||||||
|
linux++: WARN += -Wno-missing-field-initializers
|
||||||
linux++: linux
|
linux++: linux
|
||||||
|
|
||||||
|
linux-libs: CFLAGS += -fPIC
|
||||||
|
linux-libs: mongoose.o
|
||||||
|
$(CC) mongoose.o $(LDFLAGS) -shared -o libmongoose.so.$(SOVERSION)
|
||||||
|
$(AR) rcs libmongoose.a mongoose.o
|
||||||
|
|
||||||
|
install: linux-libs
|
||||||
|
install -Dm644 libmongoose.a libmongoose.so.$(SOVERSION) $(DESTDIR)$(PREFIX)/lib
|
||||||
|
ln -s libmongoose.so.$(SOVERSION) $(DESTDIR)$(PREFIX)/lib/libmongoose.so
|
||||||
|
install -Dm644 mongoose.h $(DESTDIR)$(PREFIX)/include/mongoose.h
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm -rf $(DESTDIR)$(PREFIX)/lib/libmongoose.a $(DESTDIR)$(PREFIX)/lib/libmongoose.so.$(SOVERSION) $(DESTDIR)$(PREFIX)/include/mongoose.h $(DESTDIR)$(PREFIX)/lib/libmongoose.so
|
||||||
|
|
||||||
|
arm: Makefile mongoose.c mongoose.h test/unit_test.c
|
||||||
|
$(ARM) arm-none-eabi-gcc mongoose.c -c -Itest -DMG_ARCH=MG_ARCH_CUSTOM $(OPTS) $(WARN) $(INCS) -DMG_MAX_HTTP_HEADERS=5 -DMG_ENABLE_LINES -DMG_ENABLE_DIRECTORY_LISTING=0 -DMG_ENABLE_SSI=1
|
||||||
|
|
||||||
mongoose.c: $(SRCS) Makefile
|
mongoose.c: $(SRCS) Makefile
|
||||||
(cat src/license.h; echo; echo '#include "mongoose.h"' ; (for F in src/private.h src/*.c ; do echo; echo '#ifdef MG_ENABLE_LINES'; echo "#line 1 \"$$F\""; echo '#endif'; cat $$F | sed -e 's,#include ".*,,'; done))> $@
|
(cat src/license.h; echo; echo '#include "mongoose.h"' ; (for F in src/private.h src/*.c ; do echo; echo '#ifdef MG_ENABLE_LINES'; echo "#line 1 \"$$F\""; echo '#endif'; cat $$F | sed -e 's,#include ".*,,'; done))> $@
|
||||||
|
|
||||||
mongoose.h: $(HDRS) Makefile
|
mongoose.h: $(HDRS) Makefile
|
||||||
(cat src/license.h src/version.h ; cat src/arch.h src/arch_*.h src/config.h src/str.h src/log.h src/timer.h src/util.h src/url.h src/iobuf.h src/base64.h src/md5.h src/sha1.h src/event.h src/net.h src/http.h src/ssi.h src/tls.h src/ws.h src/sntp.h src/mqtt.h src/dns.h | sed -e 's,#include ".*,,' -e 's,^#pragma once,,')> $@
|
(cat src/license.h src/version.h ; cat src/arch.h src/arch_*.h src/config.h src/str.h src/log.h src/timer.h src/util.h src/url.h src/iobuf.h src/base64.h src/md5.h src/sha1.h src/event.h src/net.h src/http.h src/ssi.h src/tls.h src/ws.h src/sntp.h src/mqtt.h src/dns.h | sed -e 's,#include ".*,,' -e 's,^#pragma once,,'; echo; echo '#ifdef __cplusplus'; echo '}'; echo '#endif'; echo '#endif // MONGOOSE_H')> $@
|
||||||
|
|
||||||
clean: EXAMPLE_TARGET = clean
|
clean: EXAMPLE_TARGET = clean
|
||||||
clean: ex
|
clean: ex
|
||||||
|
|||||||
@@ -1,74 +1,93 @@
|
|||||||
# Mongoose - Embedded Web Server / Embedded Networking Library
|
# Mongoose - Embedded Web Server / Embedded Networking Library
|
||||||
|
|
||||||

|
[](https://opensource.org/licenses/gpl-2.0.php)
|
||||||
[](https://github.com/cesanta/mongoose/actions)
|
[](https://github.com/cesanta/mongoose/actions)
|
||||||
[](https://codecov.io/gh/cesanta/mongoose)
|
[](https://codecov.io/gh/cesanta/mongoose)
|
||||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:mongoose)
|
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:mongoose)
|
||||||
|
|
||||||
Mongoose is a networking library for C/C++. It implements event-driven
|
Mongoose is a networking library for C/C++. It implements event-driven
|
||||||
non-blocking APIs for TCP, UDP, HTTP, WebSocket, MQTT. It has been designed
|
non-blocking APIs for TCP, UDP, HTTP, WebSocket, MQTT. It is designed for
|
||||||
for connecting devices and bringing them online. On the market since 2004, used
|
connecting devices and bringing them online. On the market since 2004, used by
|
||||||
by vast number of open source and commercial products - it even runs on the
|
vast number of open source and commercial products - it even runs on the
|
||||||
International Space Station! Mongoose makes embedded network programming fast,
|
International Space Station! Mongoose makes embedded network programming fast,
|
||||||
robust, and easy.
|
robust, and easy. Features include:
|
||||||
|
|
||||||
- [Download Mongoose Source Code here](https://www.cesanta.com/download.html)
|
- Cross-platform: works on Linux/UNIX, MacOS, Windows, Android, FreeRTOS, etc.
|
||||||
- [Read Mongoose documentation](https://cesanta.com/docs/)
|
- Supported embedded architectures: ESP32, NRF52, STM32, NXP, and more
|
||||||
|
- Built-in protocols: plain TCP/UDP, HTTP, MQTT, Websocket
|
||||||
|
- SSL/TLS support: mbedTLS, OpenSSL or custom (via API)
|
||||||
|
- Asynchronous DNS resolver
|
||||||
|
- Tiny static and run-time footprint
|
||||||
|
- Source code is both ISO C and ISO C++ compliant
|
||||||
|
- Works with any network stack with socket API, like LwIP or FreeRTOS-Plus-TCP
|
||||||
|
- Very easy to integrate: just copy `mongoose.c` and `mongoose.h` files to your build tree
|
||||||
|
- Detailed [documentation](https://cesanta.com/docs/)
|
||||||
|
|
||||||
Connectivity is vital for software and embedded devices, but there are many
|
|
||||||
pitfalls to consider when embedding a web server. This white paper breaks down
|
|
||||||
on the top 9 things to avoid when embedding a web server.
|
|
||||||
|
|
||||||
- [Download “9 Things NOT to do when embedding a web server” white paper here](https://www.cesanta.com/whitepaper.html)
|
# Commercial use
|
||||||
|
- Mongoose is used by hundreds of businesses, from Fortune500 giants like
|
||||||
|
Siemens, Schneider Electric, Broadcom, Bosch, Google, Samsung, Qualcomm, Caterpillar to the small businesses
|
||||||
|
- Used to solve a wide range of business needs, like implementing Web UI
|
||||||
|
interface on devices, RESTful API services, telemetry data exchange, remote
|
||||||
|
control for a product, remote software updates, remote monitoring, and others
|
||||||
|
- Deployed to hundreds of millions devices in production environment worldwide
|
||||||
|
- See [Case Studies](https://cesanta.com/case-studies.html) from our respected
|
||||||
|
customers like Schneider Electric (industrial automation), Broadcom (semiconductors), Schenck Process
|
||||||
|
(industrial engineering), and others
|
||||||
|
- See [Testimonials](https://cesanta.com/testimonials.html) from engineers that
|
||||||
|
integrated Mongoose in their commercial products
|
||||||
|
- We provide [commercial licensing](https://cesanta.com/licensing.html),
|
||||||
|
[support](https://cesanta.com/support.html), consultancy and integration
|
||||||
|
assistance - don't hesitate to
|
||||||
|
[contact us](https://www.cesanta.com/contact.html)
|
||||||
|
|
||||||
Looking for a complete IoT solution? Check out
|
|
||||||
- [VCON](https://vcon.io) - Arduino compatible MCU modules with built-in firmware OTA updates
|
|
||||||
- [Mongoose OS](https://mongoose-os.com) - open source embedded operating system for low-power connected microcontrollers. Secure, designed for commercial Internet of Things products
|
|
||||||
|
|
||||||
# Support
|
# Security
|
||||||
- [Study Mongoose examples](https://github.com/cesanta/mongoose/tree/master/examples)
|
|
||||||
- [Support Forum - ask your technical questions here](https://forum.cesanta.com/c/mongoose-library/6)
|
|
||||||
- [Commercial licensing and support available](https://www.cesanta.com/licensing.html)
|
|
||||||
- [Check out latest releases](https://github.com/cesanta/mongoose/releases)
|
|
||||||
|
|
||||||
# Features
|
We take security seriously:
|
||||||
|
1. Mongoose repository runs a
|
||||||
|
[continuous integration test powered by GitHub](https://github.com/cesanta/mongoose/actions),
|
||||||
|
which runs through hundreds of unit tests on every commit to the repository.
|
||||||
|
Our [unit tests](https://github.com/cesanta/mongoose/tree/master/test)
|
||||||
|
are built with modern address sanitizer technologies, which help to find
|
||||||
|
security vulnerabilities early
|
||||||
|
2. Mongoose repository is integrated into Google's
|
||||||
|
[oss-fuzz continuous fuzzer](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:mongoose)
|
||||||
|
which scans for potential vulnerabilities continuously
|
||||||
|
3. We receive periodic vulnerability reports from the independent security
|
||||||
|
groups like
|
||||||
|
[Cisco Talos](https://www.cisco.com/c/en/us/products/security/talos.html),
|
||||||
|
[Microsoft Security Response Center](https://www.microsoft.com/en-us/msrc),
|
||||||
|
[MITRE Corporation](https://www.mitre.org/),
|
||||||
|
[Compass Security](https://www.compass-security.com/en/) and others.
|
||||||
|
In case of the vulnerability found, we act according to the industry best
|
||||||
|
practice: hold on to the publication, fix the software and notify all our
|
||||||
|
customers that have an appropriate subscription
|
||||||
|
4. Some of our customers (for example NASA)
|
||||||
|
have specific security requirements and run independent security audits,
|
||||||
|
of which we get notified and in case of any issue, act similar to (3).
|
||||||
|
|
||||||
* Cross-platform: works on Linux/UNIX, MacOS, QNX, eCos, Windows, Android,
|
# Supplement software
|
||||||
iPhone, FreeRTOS, etc
|
|
||||||
* Supported embedded architectures: ESP32, ESP8266, TI CC3200, TI MSP432, NRF52, STM32, PIC32, NXP, and more
|
|
||||||
* Builtin protocols: plain TCP/UDP, HTTP, MQTT, Websocket
|
|
||||||
* SSL/TLS support: mbedTLS, OpenSSL or custom via API
|
|
||||||
* Asynchronous DNS resolver
|
|
||||||
* Tiny static and run-time footprint
|
|
||||||
* Source code is both ISO C and ISO C++ compliant
|
|
||||||
* Very easy to integrate: just copy
|
|
||||||
[mongoose.c](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.c) and
|
|
||||||
[mongoose.h](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.h)
|
|
||||||
files to your build tree
|
|
||||||
|
|
||||||
# Licensing
|
This software is often used together with Mongoose:
|
||||||
|
- [mjson](https://github.com/cesanta/mjson) - a JSON parser. Used to implement
|
||||||
|
RESTful APIs that use JSON, or implement data exchange (e.g. over MQTT
|
||||||
|
or Websocket) that use JSON for data encapsulation
|
||||||
|
- [elk](https://github.com/cesanta/elk) - a tiny JavaScript interpreter.
|
||||||
|
Used to implement scripting support for customers
|
||||||
|
|
||||||
Mongoose is released under Commercial and [GNU GPL v.2](http://www.gnu.org/licenses/old-licenses/gpl-2.0.html) open source licenses.
|
|
||||||
|
|
||||||
Commercial Projects: [Contact us for commercial license.](https://www.cesanta.com/contact.html)
|
# Precompiled web server binary
|
||||||
|
|
||||||
# Dashboard Example
|
We have built a ready-to-go, precompiled web server binary for Windows
|
||||||
|
and Mac. It is a great tool for sharing your files or website. It has
|
||||||
|
a unique feature - an ability to share your local files via a global URL.
|
||||||
|
|
||||||
Mongoose is often used to implement device dashboards and real-time
|
Interested? Go to [download](https://mongoose.ws/)
|
||||||
data exchange over Websocket. Here is a dashboard example that illustrates
|
|
||||||
the functionality:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
[Developing a new product? Contact us today to discuss how Mongoose can help.](https://www.cesanta.com/contact.html)
|
|
||||||
|
|
||||||
# Contributions
|
# Contributions
|
||||||
|
|
||||||
Contributions are welcome! Please follow the guidelines below:
|
Contributions are welcome! Please follow the guidelines below:
|
||||||
|
|
||||||
- Sign [Cesanta CLA](https://cesanta.com/cla.html) and send GitHub pull request
|
- Sign [Cesanta CLA](https://cesanta.com/cla.html) and send GitHub pull request
|
||||||
- When making pull requests, please make sure that it has only one commit,
|
- Make sure that PRs have only one commit, and deal with one issue only
|
||||||
and imlements/fixes only one piece of functionality
|
|
||||||
|
|
||||||
# Looking for a pre-compiled Mongoose web server Windows or Mac binary?
|
|
||||||
- [Download pre-compiled Mongoose web server binary.](https://www.cesanta.com/binary.html)
|
|
||||||
+186
-91
@@ -6,24 +6,23 @@
|
|||||||
Mongoose is a networking library for C/C++. It implements an event-driven,
|
Mongoose is a networking library for C/C++. It implements an event-driven,
|
||||||
non-blocking APIs for TCP, UDP, HTTP, WebSocket, MQTT. It has been designed
|
non-blocking APIs for TCP, UDP, HTTP, WebSocket, MQTT. It has been designed
|
||||||
for connecting devices and bringing them online. On the market since 2004, used
|
for connecting devices and bringing them online. On the market since 2004, used
|
||||||
by vast number of open source and commercial products - it even runs on the
|
by a vast number of open source and commercial products - it even runs on the
|
||||||
International Space Station! Mongoose makes embedded network programming fast,
|
International Space Station! Mongoose makes embedded network programming fast,
|
||||||
robust, and easy.
|
robust, and easy.
|
||||||
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* Cross-platform: works on Linux/UNIX, MacOS, QNX, eCos, Windows, Android,
|
* Works on Linux/UNIX, MacOS, Windows, QNX, eCos, Android and other
|
||||||
iPhone, FreeRTOS, etc
|
* Works on embedded hardware: STM32, ESP32, NXP, Xilinx, and other
|
||||||
* Supported hardware platforms: TI CC3200, TI MSP432, NRF52, STM32, PIC32, ESP8266, ESP32 and more
|
* Built-in protocols:
|
||||||
* Builtin protocols:
|
|
||||||
- plain TCP, plain UDP, SSL/TLS (over TCP, one-way or two-way)
|
- plain TCP, plain UDP, SSL/TLS (over TCP, one-way or two-way)
|
||||||
- HTTP client, HTTP server
|
- HTTP client, HTTP server
|
||||||
- WebSocket client, WebSocket server
|
- WebSocket client, WebSocket server
|
||||||
- MQTT client
|
- MQTT client, MQTT server
|
||||||
- DNS client, async DNS resolver
|
- DNS client, async DNS resolver
|
||||||
* Single-threaded, asynchronous, non-blocking core with simple event-based API
|
* Single-threaded, asynchronous, non-blocking core with simple event-based API
|
||||||
* Native support for [LWIP embedded TCP/IP stack](https://en.wikipedia.org/wiki/LwIP)
|
* Support for LWIP and FreeRTOS-Plus-TCP stacks
|
||||||
* Tiny static and run-time footprint
|
* Tiny static and run-time footprint
|
||||||
* Source code is both ISO C and ISO C++ compliant
|
* Source code is both ISO C and ISO C++ compliant
|
||||||
* Very easy to integrate: just copy
|
* Very easy to integrate: just copy
|
||||||
@@ -50,7 +49,7 @@ Mongoose's internals.
|
|||||||
An application that uses mongoose should follow a standard pattern of
|
An application that uses mongoose should follow a standard pattern of
|
||||||
event-driven application:
|
event-driven application:
|
||||||
|
|
||||||
1. Declare and initialise an event manager:
|
1. Declare and initialize an event manager:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
struct mg_mgr mgr;
|
struct mg_mgr mgr;
|
||||||
@@ -90,7 +89,7 @@ Each connection has a send and receive buffer:
|
|||||||
- `struct mg_connection::recv` - data received from a peer
|
- `struct mg_connection::recv` - data received from a peer
|
||||||
|
|
||||||
When data arrives, Mongoose appends received data to the `recv` and triggers an
|
When data arrives, Mongoose appends received data to the `recv` and triggers an
|
||||||
`MG_EV_RECV` event. The user may send data back by calling one of the output
|
`MG_EV_READ` event. The user may send data back by calling one of the output
|
||||||
functions, like `mg_send()` or `mg_printf()`. Output functions append data to
|
functions, like `mg_send()` or `mg_printf()`. Output functions append data to
|
||||||
the `send` buffer. When Mongoose successfully writes data to the socket, it
|
the `send` buffer. When Mongoose successfully writes data to the socket, it
|
||||||
discards data from struct `mg_connection::send` and sends an `MG_EV_SEND`
|
discards data from struct `mg_connection::send` and sends an `MG_EV_SEND`
|
||||||
@@ -106,7 +105,7 @@ what an event handler function looks like:
|
|||||||
```c
|
```c
|
||||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||||
switch (ev) {
|
switch (ev) {
|
||||||
/* Event handler code that defines behavior of the connection */
|
/* Event handler code that defines behaviour of the connection */
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,9 +113,9 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
|
|
||||||
- `struct mg_connection *c` - a connection that received an event
|
- `struct mg_connection *c` - a connection that received an event
|
||||||
- `int ev` - an event number, defined in mongoose.h. For example, when data
|
- `int ev` - an event number, defined in mongoose.h. For example, when data
|
||||||
arrives on an inbound connection, ev would be `MG_EV_RECV`
|
arrives on an inbound connection, ev would be `MG_EV_READ`
|
||||||
- `void *ev_data` - points to the event-specific data, and it has a different
|
- `void *ev_data` - points to the event-specific data, and it has a different
|
||||||
meaning for different events. For example, for an `MG_EV_RECV` event,
|
meaning for different events. For example, for an `MG_EV_READ` event,
|
||||||
`ev_data`
|
`ev_data`
|
||||||
is an `int *` pointing to the number of bytes received from a remote
|
is an `int *` pointing to the number of bytes received from a remote
|
||||||
peer and saved into the `c->recv` IO buffer. The exact meaning of `ev_data` is
|
peer and saved into the `c->recv` IO buffer. The exact meaning of `ev_data` is
|
||||||
@@ -127,7 +126,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
|
|
||||||
## Events
|
## Events
|
||||||
|
|
||||||
Below is the list of events trigged by Mongoose, taken as-is from `mongoose.h`.
|
Below is the list of events triggered by Mongoose, taken as-is from `mongoose.h`.
|
||||||
For each event, a comment describes a meaning of the `ev_data` pointer passed
|
For each event, a comment describes a meaning of the `ev_data` pointer passed
|
||||||
to an event handler:
|
to an event handler:
|
||||||
|
|
||||||
@@ -159,10 +158,10 @@ enum {
|
|||||||
they can be either 0 or 1. Some flags are set by Mongoose and must be not
|
they can be either 0 or 1. Some flags are set by Mongoose and must be not
|
||||||
changed by an application code, for example `is_udp` flag tells application if
|
changed by an application code, for example `is_udp` flag tells application if
|
||||||
that connection is UDP or not. Some flags can be changed by application, for
|
that connection is UDP or not. Some flags can be changed by application, for
|
||||||
example, `is_drainig` flag, if set by an application, tells Mongoose to send
|
example, `is_draining` flag, if set by an application, tells Mongoose to send
|
||||||
the remaining data to peer, and when everything is sent, close the connection.
|
the remaining data to peer, and when everything is sent, close the connection.
|
||||||
|
|
||||||
User-changeable flags are: `is_hexdumping`, `is_drainig`, `is_closing`.
|
User-changeable flags are: `is_hexdumping`, `is_draining`, `is_closing`.
|
||||||
|
|
||||||
This is taken from `mongoose.h` as-is:
|
This is taken from `mongoose.h` as-is:
|
||||||
|
|
||||||
@@ -193,42 +192,62 @@ Mongoose source code ships in two files:
|
|||||||
- [mongoose.c](https://github.com/cesanta/mongoose/blob/master/mongoose.c) - implementation
|
- [mongoose.c](https://github.com/cesanta/mongoose/blob/master/mongoose.c) - implementation
|
||||||
|
|
||||||
Therefore to integrate Mongoose into an application, simply copy these two
|
Therefore to integrate Mongoose into an application, simply copy these two
|
||||||
files to the application's source tree.
|
files to the application's source tree. The `mongoose.c` and `mongoose.h` files
|
||||||
|
are, actually, an amalgamation - a non-amalgamated sources can be found at
|
||||||
|
https://github.com/cesanta/mongoose/tree/master/src
|
||||||
|
|
||||||
The `mongoose.c` and `mongoose.h` files are, actually, an amalgamation -
|
Mongoose have two types of build constants (preprocessor definitions) that
|
||||||
a non-amalgamated sources can be found at https://github.com/cesanta/mongoose/tree/master/src
|
affect the build: a target architecture, and tunables. In order to set the
|
||||||
|
option during build time, use the `-D OPTION` compiler flag:
|
||||||
Mongoose source code uses a bunch of build constants defined at
|
|
||||||
https://github.com/cesanta/mongoose/blob/master/src/config.h, together with
|
|
||||||
their default values.
|
|
||||||
|
|
||||||
In order to change the constant during build time, use the `-D
|
|
||||||
<PREPROCESSOR_FLAG>` compiler option. For example, to disable both MQTT,
|
|
||||||
compile the application `my_app.c` like this (assumed UNIX system):
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ cc my_app.c mongoose.c -D MG_MQTT_ENABLE=0
|
$ cc app0.c mongoose.c # Use defaults!
|
||||||
|
$ cc app1.c mongoose.c -D MG_ENABLE_IPV6=1 # Build with IPv6 enabled
|
||||||
|
$ cc app2.c mongoose.c -D MG_ARCH=MG_ARCH_FREERTOS_LWIP # Set architecture
|
||||||
|
$ cc app3.c mongoose.c -D MG_ENABLE_FS=0 -D MG_ENABLE_LOG=0 # Multiple options
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The list of supported
|
||||||
|
architectures is defined in the
|
||||||
|
[arch.h](https://github.com/cesanta/mongoose/blob/master/src/arch.h) header
|
||||||
|
file. Normally, there is no need to explicitly specify the architecture. The
|
||||||
|
architecture is guessed during the build, so setting it is not usually required.
|
||||||
|
|
||||||
|
| Name | Description |
|
||||||
|
| ---- | ----------- |
|
||||||
|
|MG_ARCH_UNIX | All UNIX-like systems like Linux, MacOS, FreeBSD, etc |
|
||||||
|
|MG_ARCH_WIN32 | Windows systems |
|
||||||
|
|MG_ARCH_ESP32 | Espressif's ESP32 |
|
||||||
|
|MG_ARCH_ESP8266 | Espressif's ESP8266 |
|
||||||
|
|MG_ARCH_FREERTOS_LWIP | All systems with FreeRTOS kernel and LwIP IP stack |
|
||||||
|
|MG_ARCH_FREERTOS_TCP | All systems with FreeRTOS kernel and FreeRTOS-Plus-TCP IP stack |
|
||||||
|
|MG_ARCH_CUSTOM | A custom architecture, discussed in the next section |
|
||||||
|
|
||||||
|
|
||||||
|
The other class of build constants is defined in
|
||||||
|
[src/config.h](https://github.com/cesanta/mongoose/blob/master/src/config.h)
|
||||||
|
together with their default values. They are tunables that include/exclude
|
||||||
|
a certain functionality or change relevant parameters.
|
||||||
|
|
||||||
|
|
||||||
Here is a list of build constants and their default values:
|
Here is a list of build constants and their default values:
|
||||||
|
|
||||||
| Name | Default | Description |
|
| Name | Default | Description |
|
||||||
| ---- | ------- | ----------- |
|
| ---- | ------- | ----------- |
|
||||||
|`MG_ENABLE_LWIP` | 0 | Use LWIP low-level API instead of BSD sockets |
|
|MG_ENABLE_SOCKET | 1 | Use BSD socket low-level API |
|
||||||
|`MG_ENABLE_SOCKET` | 1 | Use BSD socket low-level API |
|
|MG_ENABLE_MBEDTLS | 0 | Enable Mbed TLS library |
|
||||||
|`MG_ENABLE_MBEDTLS` | 0 | Enable Mbed TLS library |
|
|MG_ENABLE_OPENSSL | 0 | Enable OpenSSL library |
|
||||||
|`MG_ENABLE_OPENSSL` | 0 | Enable OpenSSL library |
|
|MG_ENABLE_FS | 1 | Enable API that use filesystem, like `mg_http_send_file()` |
|
||||||
|`MG_ENABLE_FS` | 1 | Enable API that use filesystem, like `mg_http_send_file()` |
|
|MG_ENABLE_IPV6 | 0 | Enable IPv6 |
|
||||||
|`MG_ENABLE_IPV6` | 0 | Enable IPv6 |
|
|MG_ENABLE_LOG | 1 | Enable `LOG()` macro |
|
||||||
|`MG_ENABLE_LOG` | 1 | Enable `LOG()` macro |
|
|MG_ENABLE_MD5 | 0 | Use native MD5 implementation |
|
||||||
|`MG_ENABLE_MD5` | 0 | Use native MD5 implementation |
|
|MG_ENABLE_DIRECTORY_LISTING | 0 | Enable directory listing for HTTP server |
|
||||||
|`MG_ENABLE_DIRECTORY_LISTING` | 0 | Enable directory listing for HTTP server |
|
|MG_ENABLE_SOCKETPAIR | 0 | Enable `mg_socketpair()` for multi-threading |
|
||||||
|`MG_ENABLE_HTTP_DEBUG_ENDPOINT` | 0 | Enable `/debug/info` debug URI |
|
|MG_ENABLE_SSI | 0 | Enable serving SSI files by `mg_http_serve_dir()` |
|
||||||
|`MG_ENABLE_SOCKETPAIR` | 0 | Enable `mg_socketpair()` for multi-threading |
|
|MG_IO_SIZE | 512 | Granularity of the send/recv IO buffer growth |
|
||||||
|`MG_ENABLE_SSI` | 0 | Enable serving SSI files by `mg_http_serve_dir()` |
|
|MG_MAX_RECV_BUF_SIZE | (3 * 1024 * 1024) | Maximum recv buffer size |
|
||||||
|`MG_IO_SIZE` | 512 | Granularity of the send/recv IO buffer growth |
|
|MG_MAX_HTTP_HEADERS | 40 | Maximum number of HTTP headers |
|
||||||
|`MG_MAX_RECV_BUF_SIZE` | (3 * 1024 * 1024) | Maximum recv buffer size |
|
|
||||||
|`MG_MAX_HTTP_HEADERS` | 40 | Maximum number of HTTP headers |
|
|
||||||
|
|
||||||
NOTE: `MG_IO_SIZE` controls the maximum UDP message size, see
|
NOTE: `MG_IO_SIZE` controls the maximum UDP message size, see
|
||||||
https://github.com/cesanta/mongoose/issues/907 for details. If application
|
https://github.com/cesanta/mongoose/issues/907 for details. If application
|
||||||
@@ -236,25 +255,27 @@ uses large UDP messages, increase the `MG_IO_SIZE` limit accordingly.
|
|||||||
|
|
||||||
## Custom build
|
## Custom build
|
||||||
|
|
||||||
It is possible to use Mongoose on an architecture that is not yet supported
|
A custom build should be used for cases which is not covered by the
|
||||||
by the current codebase. In order to do so, follow these steps:
|
existing architecture options. For example, an embedded architecture that
|
||||||
|
uses some proprietary RTOS and network stack. In order to build on such
|
||||||
|
systems, follow the guideline outlined below:
|
||||||
|
|
||||||
1. Create a file called `mongoose_custom.h`, with defines and includes that
|
1. Add `-DMG_ARCH=MG_ARCH_CUSTOM` to your build flags.
|
||||||
|
|
||||||
|
2. Create a file called `mongoose_custom.h`, with defines and includes that
|
||||||
are relevant to your platform. Mongoose uses `bool` type, `MG_DIRSEP` define,
|
are relevant to your platform. Mongoose uses `bool` type, `MG_DIRSEP` define,
|
||||||
and optionally other structures like `DIR *` depending on the functionality
|
and optionally other structures like `DIR *` depending on the functionality
|
||||||
you have enabled - see previous section. Below is an example:
|
you have enabled - see previous section. Below is an example:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#include <dirent.h> // For DIR *
|
|
||||||
#include <stdbool.h> // For bool
|
#include <stdbool.h> // For bool
|
||||||
#include <sys/time.h> // For gettimeofday()
|
#include <stdarg.h>
|
||||||
#include <unistd.h> // For usleep()
|
|
||||||
#define MG_DIRSEP '/'
|
#define MG_DIRSEP '/'
|
||||||
|
#define MG_INT64_FMT "%lld"
|
||||||
#define MG_ENABLE_SOCKET 0 // Disable BSD socket API, implement your own
|
#define MG_ENABLE_SOCKET 0 // Disable BSD socket API, implement your own
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Add `-DMG_ARCH=MG_ARCH_CUSTOM` to your build flags.
|
|
||||||
|
|
||||||
3. This step is optional. If you have disabled BSD socket API, your build is
|
3. This step is optional. If you have disabled BSD socket API, your build is
|
||||||
going to fail due to several undefined symbols. Create `mongoose_custom.c`
|
going to fail due to several undefined symbols. Create `mongoose_custom.c`
|
||||||
and implement the following functions (take a look at `src/sock.c` for the
|
and implement the following functions (take a look at `src/sock.c` for the
|
||||||
@@ -321,7 +342,7 @@ This example is a simple TCP echo server that listens on port 1234:
|
|||||||
static const char *s_listening_address = "tcp://0.0.0.0:1234";
|
static const char *s_listening_address = "tcp://0.0.0.0:1234";
|
||||||
|
|
||||||
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||||
if (ev == MG_EV_RECV) {
|
if (ev == MG_EV_READ) {
|
||||||
mg_send(c, c->recv.buf, c->recv.len); // Echo received data back
|
mg_send(c, c->recv.buf, c->recv.len); // Echo received data back
|
||||||
mg_iobuf_delete(&c->recv, c->recv.len); // And discard it
|
mg_iobuf_delete(&c->recv, c->recv.len); // And discard it
|
||||||
}
|
}
|
||||||
@@ -362,20 +383,21 @@ with some housekeeping information.
|
|||||||
struct mg_connection {
|
struct mg_connection {
|
||||||
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
||||||
struct mg_mgr *mgr; // Our container
|
struct mg_mgr *mgr; // Our container
|
||||||
struct mg_addr peer; // Remote peer address
|
struct mg_addr peer; // Remote address. For listeners, local address
|
||||||
void *fd; // Connected socket, or LWIP data
|
void *fd; // Connected socket, or LWIP data
|
||||||
|
unsigned long id; // Auto-incrementing unique connection ID
|
||||||
struct mg_iobuf recv; // Incoming data
|
struct mg_iobuf recv; // Incoming data
|
||||||
struct mg_iobuf send; // Outgoing data
|
struct mg_iobuf send; // Outgoing data
|
||||||
mg_event_handler_t fn; // User-specified event handler function
|
mg_event_handler_t fn; // User-specified event handler function
|
||||||
void *fn_data; // User-speficied function parameter
|
void *fn_data; // User-specified function parameter
|
||||||
mg_event_handler_t pfn; // Protocol-specific handler function
|
mg_event_handler_t pfn; // Protocol-specific handler function
|
||||||
void *pfn_data; // Protocol-specific function parameter
|
void *pfn_data; // Protocol-specific function parameter
|
||||||
char label[32]; // Arbitrary label
|
char label[50]; // Arbitrary label
|
||||||
void *tls; // TLS specific data
|
void *tls; // TLS specific data
|
||||||
unsigned is_listening : 1; // Listening connection
|
unsigned is_listening : 1; // Listening connection
|
||||||
unsigned is_client : 1; // Outbound (client) connection
|
unsigned is_client : 1; // Outbound (client) connection
|
||||||
unsigned is_accepted : 1; // Accepted (server) connection
|
unsigned is_accepted : 1; // Accepted (server) connection
|
||||||
unsigned is_resolving : 1; // Non-blocking DNS resolv is in progress
|
unsigned is_resolving : 1; // Non-blocking DNS resolve is in progress
|
||||||
unsigned is_connecting : 1; // Non-blocking connect is in progress
|
unsigned is_connecting : 1; // Non-blocking connect is in progress
|
||||||
unsigned is_tls : 1; // TLS-enabled connection
|
unsigned is_tls : 1; // TLS-enabled connection
|
||||||
unsigned is_tls_hs : 1; // TLS handshake is in progress
|
unsigned is_tls_hs : 1; // TLS handshake is in progress
|
||||||
@@ -390,7 +412,7 @@ struct mg_connection {
|
|||||||
```
|
```
|
||||||
|
|
||||||
A connection - either a listening connection, or an accepted connection,
|
A connection - either a listening connection, or an accepted connection,
|
||||||
or an outbout connection.
|
or an outbound connection.
|
||||||
|
|
||||||
### mg\_mgr_init()
|
### mg\_mgr_init()
|
||||||
|
|
||||||
@@ -398,7 +420,7 @@ or an outbout connection.
|
|||||||
void mg_mgr_init(struct mg_mgr *);
|
void mg_mgr_init(struct mg_mgr *);
|
||||||
```
|
```
|
||||||
|
|
||||||
Initialise event manager structure: set a list of active connections to NULL,
|
Initialize event manager structure: set a list of active connections to NULL,
|
||||||
set DNS server and timeout to their default values, etc.
|
set DNS server and timeout to their default values, etc.
|
||||||
|
|
||||||
|
|
||||||
@@ -409,7 +431,7 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms);
|
|||||||
```
|
```
|
||||||
|
|
||||||
Perform a single poll iteration. For each connection in the `mgr->conns` list,
|
Perform a single poll iteration. For each connection in the `mgr->conns` list,
|
||||||
- See if there is incoming data. If it is, read it into the `c->recv` buffer, send `MG_EV_RECV` event
|
- See if there is incoming data. If it is, read it into the `c->recv` buffer, send `MG_EV_READ` event
|
||||||
- See if there is data in the `c->send` buffer, and write it, send `MG_EV_WRITE` event
|
- See if there is data in the `c->send` buffer, and write it, send `MG_EV_WRITE` event
|
||||||
- If a connection is listening, accept an incoming connection if any, and send `MG_EV_ACCEPT` event to it
|
- If a connection is listening, accept an incoming connection if any, and send `MG_EV_ACCEPT` event to it
|
||||||
- Send `MG_EV_POLL` event
|
- Send `MG_EV_POLL` event
|
||||||
@@ -455,7 +477,7 @@ struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url,
|
|||||||
mg_event_handler_t fn, void *fn_data);
|
mg_event_handler_t fn, void *fn_data);
|
||||||
```
|
```
|
||||||
|
|
||||||
Create an outbout connection, append this connection to `mgr->conns`.
|
Create an outbound connection, append this connection to `mgr->conns`.
|
||||||
- `url` - specifies remote IP address/port to connect to, e.g. `http://a.com`
|
- `url` - specifies remote IP address/port to connect to, e.g. `http://a.com`
|
||||||
- `fn` - an event handler function
|
- `fn` - an event handler function
|
||||||
- `fn_data` - an arbitrary pointer, which will be passed as `fn_data` when an
|
- `fn_data` - an arbitrary pointer, which will be passed as `fn_data` when an
|
||||||
@@ -528,21 +550,23 @@ by `buf`, and `len` specifies number of bytes currently stored.
|
|||||||
### mg\_iobuf\_init()
|
### mg\_iobuf\_init()
|
||||||
|
|
||||||
```c
|
```c
|
||||||
void mg_iobuf_init(struct mg_iobuf *io, size_t size);
|
int mg_iobuf_init(struct mg_iobuf *io, size_t size);
|
||||||
```
|
```
|
||||||
|
|
||||||
Initialise IO buffer, allocate `size` bytes.
|
Initialize IO buffer, allocate `size` bytes. Return 1 on success,
|
||||||
|
0 on allocation failure.
|
||||||
|
|
||||||
|
|
||||||
### mg\_iobuf\_resize()
|
### mg\_iobuf\_resize()
|
||||||
|
|
||||||
```c
|
```c
|
||||||
void mg_iobuf_resize(struct mg_iobuf *io, size_t size);
|
int mg_iobuf_resize(struct mg_iobuf *io, size_t size);
|
||||||
```
|
```
|
||||||
|
|
||||||
Resize IO buffer, set the new size to `size`. The `io->buf` pointer could
|
Resize IO buffer, set the new size to `size`. The `io->buf` pointer could
|
||||||
change after this, for example if the buffer grows. If `size` is 0, then the
|
change after this, for example if the buffer grows. If `size` is 0, then the
|
||||||
`io->buf` is freed and set to NULL, and both `size` and `len` are set to 0.
|
`io->buf` is freed and set to NULL, and both `size` and `len` are set to 0.
|
||||||
|
Return 1 on success, 0 on allocation failure.
|
||||||
|
|
||||||
|
|
||||||
### mg\_iobuf\_free()
|
### mg\_iobuf\_free()
|
||||||
@@ -685,8 +709,9 @@ Write a chunk of data in chunked encoding format.
|
|||||||
|
|
||||||
```c
|
```c
|
||||||
struct mg_http_serve_opts {
|
struct mg_http_serve_opts {
|
||||||
const char *root_dir; // Web root directory, must be non-NULL
|
const char *root_dir; // Web root directory, must be non-NULL
|
||||||
const char *ssi_pattern; // SSI filename pattern, e.g. #.shtml
|
const char *ssi_pattern; // SSI file name pattern, e.g. #.shtml
|
||||||
|
const char *extra_headers; // Extra HTTP headers to add in responses
|
||||||
};
|
};
|
||||||
void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm,
|
void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm,
|
||||||
const struct mg_http_serve_opts *opts);
|
const struct mg_http_serve_opts *opts);
|
||||||
@@ -729,7 +754,7 @@ parameter.
|
|||||||
- `fmt` - a format string for the HTTP body, in a printf semantics
|
- `fmt` - a format string for the HTTP body, in a printf semantics
|
||||||
|
|
||||||
|
|
||||||
### mg\_http\_header()
|
### mg\_http\_get\_header()
|
||||||
|
|
||||||
```c
|
```c
|
||||||
struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
|
struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
|
||||||
@@ -827,6 +852,25 @@ void mg_http_bauth(struct mg_connection *, const char *user, const char *pass);
|
|||||||
|
|
||||||
Write a Basic `Authorization` header to the output buffer.
|
Write a Basic `Authorization` header to the output buffer.
|
||||||
|
|
||||||
|
### mg\_http\_next_\multipart()
|
||||||
|
|
||||||
|
```c
|
||||||
|
// Parameter for mg_http_next_multipart
|
||||||
|
struct mg_http_part {
|
||||||
|
struct mg_str name; // Form field name
|
||||||
|
struct mg_str filename; // Filename for file uploads
|
||||||
|
struct mg_str body; // Part contents
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t mg_http_next_multipart(struct mg_str body, size_t offset, struct mg_http_part *part);
|
||||||
|
```
|
||||||
|
|
||||||
|
Parse the multipart chunk in the `body` at a given `offset`. An initial
|
||||||
|
`offset` should be 0. Fill up parameters in the provided `part`, which could be
|
||||||
|
NULL. Return offset to the next chunk, or 0 if there are no more chunks.
|
||||||
|
|
||||||
|
See `form-upload` example for a usage example.
|
||||||
|
|
||||||
|
|
||||||
## Websocket
|
## Websocket
|
||||||
|
|
||||||
@@ -933,24 +977,56 @@ Create client MQTT connection.
|
|||||||
|
|
||||||
```c
|
```c
|
||||||
void mg_mqtt_pub(struct mg_connection *, struct mg_str *topic,
|
void mg_mqtt_pub(struct mg_connection *, struct mg_str *topic,
|
||||||
struct mg_str *data);
|
struct mg_str *data, int qos, bool retain);
|
||||||
```
|
```
|
||||||
|
|
||||||
Publish message `data` to the topic `topic`.
|
Publish message `data` to the topic `topic` with given QoS and retain flag.
|
||||||
|
|
||||||
|
|
||||||
### mg\_mqtt\_sub()
|
### mg\_mqtt\_sub()
|
||||||
|
|
||||||
```c
|
```c
|
||||||
void mg_mqtt_sub(struct mg_connection *, struct mg_str *topic);
|
void mg_mqtt_sub(struct mg_connection *, struct mg_str *topic, int qos);
|
||||||
```
|
```
|
||||||
|
|
||||||
Subscribe to topic `topic`.
|
Subscribe to topic `topic` with given QoS.
|
||||||
|
|
||||||
|
### mg\_mqtt\_next\_sub()
|
||||||
|
|
||||||
|
```c
|
||||||
|
size_t mg_mqtt_next_sub(struct mg_mqtt_message *msg, struct mg_str *topic, uint8_t *qos, size_t pos);
|
||||||
|
```
|
||||||
|
|
||||||
|
Traverse list of subscribed topics.
|
||||||
|
Used to implement MQTT server when `MQTT_CMD_SUBSCRIBE` is received.
|
||||||
|
Return next position, or 0 when done. Initial position `pos` should be 4. Example:
|
||||||
|
|
||||||
|
```c
|
||||||
|
if (ev == MG_EV_MQTT_CMD) {
|
||||||
|
struct mg_mqtt_message *mm = (struct mg_mqtt_message *) ev_data;
|
||||||
|
if (mm->cmd == MQTT_CMD_SUBSCRIBE) {
|
||||||
|
size_t pos = 4;
|
||||||
|
uint8_t qos;
|
||||||
|
struct mg_str topic;
|
||||||
|
while ((pos = mg_mqtt_next_sub(mm, &topic, &qos, pos)) > 0) {
|
||||||
|
LOG(LL_INFO, ("SUB [%.*s]", (int) topic.len, topic.ptr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### mg\_mqtt\_next\_unsub()
|
||||||
|
|
||||||
|
```c
|
||||||
|
size_t mg_mqtt_next_unsub(struct mg_mqtt_message *msg, struct mg_str *topic, size_t pos);
|
||||||
|
```
|
||||||
|
|
||||||
|
Same as `mg_mqtt_next_sub()`, but for unsubscribed topics. The difference
|
||||||
|
is that there is no QoS in unsubscribe request.
|
||||||
|
|
||||||
|
|
||||||
## TLS
|
## TLS
|
||||||
|
|
||||||
### struct mg\_tls\_opts
|
### mg\_tls\_init()
|
||||||
|
|
||||||
```c
|
```c
|
||||||
struct mg_tls_opts {
|
struct mg_tls_opts {
|
||||||
@@ -958,20 +1034,17 @@ struct mg_tls_opts {
|
|||||||
const char *cert; // Certificate
|
const char *cert; // Certificate
|
||||||
const char *certkey; // Certificate key
|
const char *certkey; // Certificate key
|
||||||
const char *ciphers; // Cipher list
|
const char *ciphers; // Cipher list
|
||||||
const char *srvname; // If not NULL, enables server name verification
|
struct mg_str srvname; // If not empty, enables server name verification
|
||||||
};
|
};
|
||||||
```
|
|
||||||
|
|
||||||
Describes TLS parameters
|
|
||||||
|
|
||||||
|
|
||||||
### mg\_tls\_init()
|
|
||||||
|
|
||||||
```c
|
|
||||||
int mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts);
|
int mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts);
|
||||||
```
|
```
|
||||||
|
|
||||||
Turns on TLS on a given connection.
|
Initialise TLS on a given connection.
|
||||||
|
|
||||||
|
IMPORTANT: mbedTLS implementation uses `mg_random` as RNG. The `mg_random`
|
||||||
|
is defined as weak, therefore it is possible to override Mongoose's `mg_random`
|
||||||
|
with a custom implementation. Just create your own `mg_random` function:
|
||||||
|
`void mg_random(void *buf, size_t len)`.
|
||||||
|
|
||||||
|
|
||||||
## Timers
|
## Timers
|
||||||
@@ -986,7 +1059,7 @@ struct mg_timer {
|
|||||||
#define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once
|
#define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once
|
||||||
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
|
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
|
||||||
void (*fn)(void *); // Function to call
|
void (*fn)(void *); // Function to call
|
||||||
void *arg; // Function agrument
|
void *arg; // Function argument
|
||||||
unsigned long expire; // Expiration timestamp in milliseconds
|
unsigned long expire; // Expiration timestamp in milliseconds
|
||||||
struct mg_timer *next; // Linkage in g_timers list
|
struct mg_timer *next; // Linkage in g_timers list
|
||||||
};
|
};
|
||||||
@@ -1006,7 +1079,7 @@ Setup a timer.
|
|||||||
- `fn` - function to invoke
|
- `fn` - function to invoke
|
||||||
- `fn_data` - function argument
|
- `fn_data` - function argument
|
||||||
|
|
||||||
A timer gets initialised and linked into the `g_timers` list:
|
A timer gets initialized and linked into the `g_timers` list:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
struct mg_timer *g_timers;
|
struct mg_timer *g_timers;
|
||||||
@@ -1035,11 +1108,12 @@ past the timer's expiration time.
|
|||||||
### mg\_file\_read()
|
### mg\_file\_read()
|
||||||
|
|
||||||
```c
|
```c
|
||||||
char *mg_file_read(const char *path);
|
char *mg_file_read(const char *path, size_t *sizep);
|
||||||
```
|
```
|
||||||
|
|
||||||
Read file contents into a nul-terminated malloc-ed string. It is a caller's
|
Read file contents into a nul-terminated malloc-ed string. It is a caller's
|
||||||
responsibility to free() a returned pointer.
|
responsibility to free() a returned pointer. If `sizep` is not NULL, it will
|
||||||
|
return a file size in bytes.
|
||||||
|
|
||||||
### mg\_file\_size()
|
### mg\_file\_size()
|
||||||
|
|
||||||
@@ -1049,14 +1123,26 @@ size_t mg_file_size(const char *path);
|
|||||||
|
|
||||||
Return file size, or 0 on failure. Empty files also report 0 length.
|
Return file size, or 0 on failure. Empty files also report 0 length.
|
||||||
|
|
||||||
|
|
||||||
### mg\_file\_write()
|
### mg\_file\_write()
|
||||||
|
|
||||||
```c
|
```c
|
||||||
int mg_file_write(const char *path, const char *fmt, ...);
|
bool mg_file_write(const char *path, const void *buf, size_t len);
|
||||||
```
|
```
|
||||||
|
|
||||||
Write into a file `path` using `printf()` semantics. Return number of bytes written.
|
Write data to a file, return `true` if written, `false` otherwise.
|
||||||
|
The write is atomic, i.e. data gets written to a temporary file first,
|
||||||
|
then `rename()-ed` to a destination file name.
|
||||||
|
|
||||||
|
|
||||||
|
### mg\_file\_printf()
|
||||||
|
|
||||||
|
```c
|
||||||
|
int mg_file_printf(const char *path, const char *fmt, ...);
|
||||||
|
```
|
||||||
|
|
||||||
|
Write into a file `path` using `printf()` semantics.
|
||||||
|
Return `true` on success, `false` otherwise. This function prints data to
|
||||||
|
a temporary in-memory buffer first, then calls `mg_file_write()`.
|
||||||
|
|
||||||
|
|
||||||
### mg\_random()
|
### mg\_random()
|
||||||
@@ -1080,7 +1166,7 @@ The glob pattern matching rules are as follows:
|
|||||||
- `?` matches any single character
|
- `?` matches any single character
|
||||||
- `*` matches zero or more characters except `/`
|
- `*` matches zero or more characters except `/`
|
||||||
- `#` matches zero or more characters
|
- `#` matches zero or more characters
|
||||||
- any other caracter matches itself
|
- any other character matches itself
|
||||||
|
|
||||||
|
|
||||||
### mg\_next\_comma\_entry()
|
### mg\_next\_comma\_entry()
|
||||||
@@ -1138,7 +1224,7 @@ char *mg_hex(const void *buf, int len, char *dst);
|
|||||||
|
|
||||||
Hex-encode binary data `buf`, `len` into a buffer `dst` and nul-terminate it.
|
Hex-encode binary data `buf`, `len` into a buffer `dst` and nul-terminate it.
|
||||||
The output buffer must be at least 2 x `len` + 1 big.
|
The output buffer must be at least 2 x `len` + 1 big.
|
||||||
Return value: `dst` pointer. The encoded characters are lowecase,
|
Return value: `dst` pointer. The encoded characters are lowercase,
|
||||||
for example `mg_hex("hi", 2, buf)` outputs `6869` and 0 byte, 5 bytes overall.
|
for example `mg_hex("hi", 2, buf)` outputs `6869` and 0 byte, 5 bytes overall.
|
||||||
|
|
||||||
|
|
||||||
@@ -1235,3 +1321,12 @@ void mg_usleep(unsigned long usecs);
|
|||||||
```
|
```
|
||||||
|
|
||||||
Block for a given number of microseconds.
|
Block for a given number of microseconds.
|
||||||
|
|
||||||
|
### mg\_crc32()
|
||||||
|
|
||||||
|
```c
|
||||||
|
uint32_t mg_crc32(uint32_t crc, const uint8_t *buf, size_t len);
|
||||||
|
```
|
||||||
|
|
||||||
|
Calculate CRC32 checksum for a given buffer. An initial `crc` value should
|
||||||
|
be `0`.
|
||||||
@@ -143,8 +143,8 @@ static void broadcast_mjpeg_frame(struct mg_mgr *mgr) {
|
|||||||
size_t nfiles = sizeof(files) / sizeof(files[0]);
|
size_t nfiles = sizeof(files) / sizeof(files[0]);
|
||||||
static size_t i;
|
static size_t i;
|
||||||
const char *path = files[i++ % nfiles];
|
const char *path = files[i++ % nfiles];
|
||||||
size_t size = mg_file_size(path);
|
size_t size = 0;
|
||||||
char *data = mg_file_read(path); // Read next file
|
char *data = mg_file_read(path, &size); // Read next file
|
||||||
struct mg_connection *c;
|
struct mg_connection *c;
|
||||||
for (c = mgr->conns; c != NULL; c = c->next) {
|
for (c = mgr->conns; c != NULL; c = c->next) {
|
||||||
if (c->label[0] != 'S') continue; // Skip non-stream connections
|
if (c->label[0] != 'S') continue; // Skip non-stream connections
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ example: main/main.c Makefile
|
|||||||
COMPORT ?= /dev/cu.SLAB_USBtoUART
|
COMPORT ?= /dev/cu.SLAB_USBtoUART
|
||||||
ESPTOOL ?= esptool.py
|
ESPTOOL ?= esptool.py
|
||||||
flash:
|
flash:
|
||||||
cd build && $(ESPTOOL) --chip esp32 -p $(COMPORT) -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 2MB 0x8000 partition_table/partition-table.bin 0x1000 bootloader/bootloader.bin 0x10000 mongoose-esp32-example.bin
|
cd build && $(ESPTOOL) --chip esp32 -p $(COMPORT) -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 2MB 0x8000 partition_table/partition-table.bin 0x1000 bootloader/bootloader.bin 0x100000 mongoose-esp32-example.bin
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb mongoose mongoose_* mongoose.* build sdkconfig
|
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb mongoose mongoose_* mongoose.* build sdkconfig
|
||||||
@@ -2,3 +2,4 @@ idf_component_register(SRCS "main.c"
|
|||||||
"wifi.c"
|
"wifi.c"
|
||||||
"../../../mongoose.c"
|
"../../../mongoose.c"
|
||||||
INCLUDE_DIRS "../../..")
|
INCLUDE_DIRS "../../..")
|
||||||
|
component_compile_options(-DMG_ENABLE_DIRECTORY_LISTING=1 -DMG_ENABLE_LINES)
|
||||||
+31
-32
@@ -1,54 +1,53 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
// Copyright (c) 2020 Cesanta Software Limited
|
||||||
// All rights reserved
|
// All rights reserved
|
||||||
|
|
||||||
|
#include "esp_spiffs.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
|
||||||
#define WIFI_SSID "WIFI_NETWORK" // SET THIS!
|
#define WIFI_SSID "WIFI_NETWORK" // SET THIS!
|
||||||
#define WIFI_PASS "WIFI_PASSWORD" // SET THIS!
|
#define WIFI_PASS "WIFI_PASSWORD" // SET THIS!
|
||||||
|
#define FS_ROOT "/spiffs"
|
||||||
|
|
||||||
#define SERVER_URL "http://0.0.0.0:80"
|
// Event handler for an server (accepted) connection. Implemented endpoints:
|
||||||
#define CLIENT_URL "http://info.cern.ch"
|
// /api/stats - return JSON object with ESP32 stats (free RAM)
|
||||||
|
// any other - serve files from the filesystem
|
||||||
// Event handler for an server (accepted) connection
|
|
||||||
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||||
if (ev == MG_EV_HTTP_MSG) {
|
if (ev == MG_EV_HTTP_MSG) {
|
||||||
mg_http_reply(c, 200, "", "Hello from ESP!\n");
|
struct mg_http_message *hm = ev_data;
|
||||||
|
if (mg_http_match_uri(hm, "/api/stats")) {
|
||||||
|
mg_http_reply(c, 200, "", "{\"ram\": %lu}\n", xPortGetFreeHeapSize());
|
||||||
|
} else {
|
||||||
|
struct mg_http_serve_opts opts = {.root_dir = FS_ROOT};
|
||||||
|
mg_http_serve_dir(c, hm, &opts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event handler for a client connection - fetch the first web page in history
|
// SPIFFS is flat, so tell Mongoose that the FS root is a directory
|
||||||
// To enable TLS for HTTP,
|
// This cludge is not required for filesystems with directory support
|
||||||
// 1. Copy "ca.pem" file to the ESP32 flash FS
|
bool mg_is_dir(const char *path) {
|
||||||
// 2. Add TLS init snippet for the connection, see examples/http-client
|
return strcmp(path, FS_ROOT) == 0;
|
||||||
static void cb2(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|
||||||
if (ev == MG_EV_CONNECT) {
|
|
||||||
struct mg_str s = mg_url_host(CLIENT_URL);
|
|
||||||
mg_printf(c, "GET / HTTP/1.0\r\nHost: %.*s\r\n\r\n", (int) s.len, s.ptr);
|
|
||||||
} else if (ev == MG_EV_HTTP_MSG) {
|
|
||||||
struct mg_http_message *hm = ev_data; // Print HTTP response
|
|
||||||
LOG(LL_INFO, ("Fetched:\n%.*s", (int) hm->message.len, hm->message.ptr));
|
|
||||||
c->is_closing = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called after we're connected to WiFi network
|
|
||||||
static void run_mongoose(void) {
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
mg_log_set("3");
|
|
||||||
mg_mgr_init(&mgr);
|
|
||||||
mg_http_listen(&mgr, SERVER_URL, cb, &mgr); // Listening server
|
|
||||||
mg_http_connect(&mgr, CLIENT_URL, cb2, &mgr); // Example client
|
|
||||||
LOG(LL_INFO, ("Starting Mongoose web server v%s", MG_VERSION));
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 1000);
|
|
||||||
mg_mgr_free(&mgr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void app_main(void) {
|
void app_main(void) {
|
||||||
|
// Mount filesystem
|
||||||
|
esp_vfs_spiffs_conf_t conf = {
|
||||||
|
.base_path = FS_ROOT, .max_files = 20, .format_if_mount_failed = true};
|
||||||
|
int res = esp_vfs_spiffs_register(&conf);
|
||||||
|
LOG(res == ESP_OK ? LL_INFO : LL_ERROR, ("FS %s, %d", conf.base_path, res));
|
||||||
|
mg_file_printf(FS_ROOT "/hello.txt", "%s", "hello from ESP");
|
||||||
|
|
||||||
// Setup wifi. This function is implemented in wifi.c
|
// Setup wifi. This function is implemented in wifi.c
|
||||||
// It blocks until connected to the configured WiFi network
|
// It blocks until connected to the configured WiFi network
|
||||||
void wifi_init(const char *ssid, const char *pass);
|
void wifi_init(const char *ssid, const char *pass);
|
||||||
wifi_init(WIFI_SSID, WIFI_PASS);
|
wifi_init(WIFI_SSID, WIFI_PASS);
|
||||||
|
|
||||||
// Done connecting to WiFi, now start HTTP server
|
// Connected to WiFi, now start HTTP server
|
||||||
run_mongoose();
|
struct mg_mgr mgr;
|
||||||
|
mg_log_set("3");
|
||||||
|
mg_mgr_init(&mgr);
|
||||||
|
mg_http_listen(&mgr, "http://0.0.0.0:80", cb, &mgr); // Listening server
|
||||||
|
LOG(LL_INFO, ("Starting Mongoose web server v%s", MG_VERSION));
|
||||||
|
for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
nvs, data, nvs, 0x9000, 0x6000,
|
||||||
|
phy_init, data, phy, 0xf000, 0x1000,
|
||||||
|
storage, data, spiffs, 0x10000, 0x10000,
|
||||||
|
factory, app, factory, 0x100000, 1M,
|
||||||
|
@@ -0,0 +1,3 @@
|
|||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
PROG ?= example
|
||||||
|
|
||||||
|
all: $(PROG)
|
||||||
|
$(DEBUGGER) ./$(PROG)
|
||||||
|
|
||||||
|
$(PROG):
|
||||||
|
$(CC) ../../mongoose.c -I../.. $(CFLAGS) $(EXTRA) -o $(PROG) main.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
// Copyright (c) 2021 Cesanta Software Limited
|
||||||
|
// All rights reserved
|
||||||
|
|
||||||
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
// HTTP request handler function. It implements the following endpoints:
|
||||||
|
// /upload - prints all submitted form elements
|
||||||
|
// all other URI - serves web_root/ directory
|
||||||
|
//
|
||||||
|
// ///////////////// IMPORTANT //////////////////////////
|
||||||
|
//
|
||||||
|
// Mongoose has a limit on input buffer, which also limits maximum upload size.
|
||||||
|
// It is controlled by the MG_MAX_RECV_BUF_SIZE constant, which is set by
|
||||||
|
// default to (3 * 1024 * 1024), i.e. 3 megabytes.
|
||||||
|
// Use -DMG_MAX_RECV_BUF_SIZE=NEW_LIMIT to override it.
|
||||||
|
//
|
||||||
|
// Also, consider changing -DMG_IO_SIZE=SOME_BIG_VALUE to increase IO buffer
|
||||||
|
// increment when reading data.
|
||||||
|
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||||
|
if (ev == MG_EV_HTTP_MSG) {
|
||||||
|
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||||
|
LOG(LL_INFO, ("New request to: [%.*s], body size: %lu", (int) hm->uri.len,
|
||||||
|
hm->uri.ptr, (unsigned long) hm->body.len));
|
||||||
|
if (mg_http_match_uri(hm, "/upload")) {
|
||||||
|
struct mg_http_part part;
|
||||||
|
size_t ofs = 0;
|
||||||
|
while ((ofs = mg_http_next_multipart(hm->body, ofs, &part)) > 0) {
|
||||||
|
LOG(LL_INFO,
|
||||||
|
("Chunk name: [%.*s] filename: [%.*s] length: %lu bytes",
|
||||||
|
(int) part.name.len, part.name.ptr, (int) part.filename.len,
|
||||||
|
part.filename.ptr, (unsigned long) part.body.len));
|
||||||
|
}
|
||||||
|
mg_http_reply(c, 200, "", "Thank you!");
|
||||||
|
} else {
|
||||||
|
struct mg_http_serve_opts opts = {.root_dir = "web_root"};
|
||||||
|
mg_http_serve_dir(c, ev_data, &opts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
struct mg_mgr mgr;
|
||||||
|
struct mg_timer t1;
|
||||||
|
|
||||||
|
mg_mgr_init(&mgr);
|
||||||
|
mg_log_set("3");
|
||||||
|
mg_http_listen(&mgr, "http://localhost:8000", cb, NULL);
|
||||||
|
|
||||||
|
for (;;) mg_mgr_poll(&mgr, 50);
|
||||||
|
mg_mgr_free(&mgr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>example</title>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<style>
|
||||||
|
#container { margin-right: auto; margin-left: auto; max-width: 480px; }
|
||||||
|
#info { background: #e0f0f0; border-radius: .5em; padding: 2em; }
|
||||||
|
#wrapper { margin-top: 1em; }
|
||||||
|
form * { margin: 0.2em 0; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="container">
|
||||||
|
<div id="info">
|
||||||
|
Mongoose always buffers a full HTTP message before invoking
|
||||||
|
MG_EV_HTTP_MSG event. Big POST request require of lot
|
||||||
|
of RAM to buffer everything. Therefore, standard form uploads
|
||||||
|
should be used only when Mongoose runs on a system with lots of RAM.
|
||||||
|
Otherwise, please see <code>file-updload</code> example, how
|
||||||
|
a big file could be uploaded to a device with little RAM.
|
||||||
|
<br/><br/>
|
||||||
|
In this example, a standard HTML form upload is used, which uses
|
||||||
|
<code>multipart-form-data</code> encoding with
|
||||||
|
several variables and file upload. On a server side, a
|
||||||
|
<code>mg_http_next_multipart()</code> API is used to iterate over
|
||||||
|
all submitted form elements and print their payload.
|
||||||
|
</div>
|
||||||
|
<div id="wrapper">
|
||||||
|
<form action="/upload" method="post" enctype="multipart/form-data">
|
||||||
|
<input type="text" name="field1" value="type some text here" /> <br/>
|
||||||
|
<input type="file" name="file1" /> </br>
|
||||||
|
<button type="submit">submit form</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,19 +1,28 @@
|
|||||||
PROG ?= example
|
PROG ?= example
|
||||||
CFLAGS ?= -DMG_ENABLE_LINES $(CFLAGS_EXTRA)
|
CFLAGS ?= -DMG_ENABLE_LINES $(EXTRA)
|
||||||
MBEDTLS_DIR ?=
|
ROOT ?= $(realpath $(CURDIR)/../..)
|
||||||
|
LIN = docker run -it --rm -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/cc2
|
||||||
|
|
||||||
ifeq "$(MBEDTLS_DIR)" ""
|
ifneq ($(MBEDTLS),)
|
||||||
else
|
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS)/include -I/usr/include
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS_DIR)/include -I/usr/include
|
CFLAGS += -L$(MBEDTLS)/lib -lmbedtls -lmbedcrypto -lmbedx509
|
||||||
CFLAGS += -L$(MBEDTLS_DIR)/lib -lmbedtls -lmbedcrypto -lmbedx509
|
endif
|
||||||
|
|
||||||
|
ifneq ($(OPENSSL),)
|
||||||
|
CFLAGS += -DMG_ENABLE_OPENSSL=1 -I$(OPENSSL)/include
|
||||||
|
CFLAGS += -L$(OPENSSL)/lib -lssl -lcrypto
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all: $(PROG)
|
all: $(PROG)
|
||||||
$(DEBUGGER) ./$(PROG) $(ARGS)
|
$(DEBUGGER) ./$(PROG) $(ARGS)
|
||||||
|
|
||||||
|
|
||||||
$(PROG): main.c
|
$(PROG): main.c
|
||||||
$(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) -o $(PROG) main.c
|
$(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) -o $(PROG) main.c
|
||||||
|
|
||||||
|
linux: all
|
||||||
|
linux: CFLAGS += -O2 -g -fsanitize=address,undefined,shift,null,return,bounds,alignment,object-size,bool,enum -static-libasan
|
||||||
|
linux: CC = $(LIN) cc
|
||||||
|
linux: DEBUGGER = $(LIN)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
||||||
+19
-10
@@ -1,43 +1,52 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
// Copyright (c) 2021 Cesanta Software Limited
|
||||||
// All rights reserved
|
// All rights reserved
|
||||||
//
|
//
|
||||||
// Example HTTP client. Connect to `s_url`, send request, wait for a response,
|
// Example HTTP client. Connect to `s_url`, send request, wait for a response,
|
||||||
// print the response and exit.
|
// print the response and exit.
|
||||||
|
// You can change `s_url` from the command line by executing: ./example YOUR_URL
|
||||||
//
|
//
|
||||||
// To enable SSL/TLS for this client, build it like this:
|
// To enable SSL/TLS for this client, build it like this:
|
||||||
// make MBEDTLS_DIR=/path/to/your/mbedtls/installation
|
// make MBEDTLS=/path/to/your/mbedtls/installation
|
||||||
|
// make OPENSSL=/path/to/your/openssl/installation
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
|
||||||
// The very first web page in history
|
// The very first web page in history. You can replace it from command line
|
||||||
static const char *s_url = "http://info.cern.ch";
|
static const char *s_url = "http://info.cern.ch//foo";
|
||||||
|
|
||||||
// Print HTTP response and signal that we're done
|
// Print HTTP response and signal that we're done
|
||||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||||
if (ev == MG_EV_CONNECT) {
|
if (ev == MG_EV_CONNECT) {
|
||||||
// Connected to server
|
// Connected to server. Extract host name from URL
|
||||||
struct mg_str host = mg_url_host(s_url);
|
struct mg_str host = mg_url_host(s_url);
|
||||||
|
|
||||||
|
// If s_url is https://, tell client connection to use TLS
|
||||||
if (mg_url_is_ssl(s_url)) {
|
if (mg_url_is_ssl(s_url)) {
|
||||||
// If s_url is https://, tell client connection to use TLS
|
struct mg_tls_opts opts = {.ca = "ca.pem", .srvname = host};
|
||||||
struct mg_tls_opts opts = {.ca = "ca.pem"};
|
|
||||||
mg_tls_init(c, &opts);
|
mg_tls_init(c, &opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send request
|
// Send request
|
||||||
mg_printf(c, "GET %s HTTP/1.0\r\nHost: %.*s\r\n\r\n", mg_url_uri(s_url),
|
mg_printf(c,
|
||||||
(int) host.len, host.ptr);
|
"GET %s HTTP/1.0\r\n"
|
||||||
|
"Host: %.*s\r\n"
|
||||||
|
"\r\n",
|
||||||
|
mg_url_uri(s_url), (int) host.len, host.ptr);
|
||||||
} else if (ev == MG_EV_HTTP_MSG) {
|
} else if (ev == MG_EV_HTTP_MSG) {
|
||||||
// Response is received. Print it
|
// Response is received. Print it
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||||
printf("%.*s", (int) hm->message.len, hm->message.ptr);
|
printf("%.*s", (int) hm->message.len, hm->message.ptr);
|
||||||
c->is_closing = 1; // Tell mongoose to close this connection
|
c->is_closing = 1; // Tell mongoose to close this connection
|
||||||
*(bool *) fn_data = true; // Tell event loop to stop
|
*(bool *) fn_data = true; // Tell event loop to stop
|
||||||
|
} else if (ev == MG_EV_ERROR) {
|
||||||
|
*(bool *) fn_data = true; // Error, tell event loop to stop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(int argc, char *argv[]) {
|
||||||
struct mg_mgr mgr; // Event manager
|
struct mg_mgr mgr; // Event manager
|
||||||
bool done = false; // Event handler flips it to true
|
bool done = false; // Event handler flips it to true
|
||||||
|
if (argc > 1) s_url = argv[1]; // Use URL from command line
|
||||||
mg_log_set("3"); // Set to 0 to disable debug
|
mg_log_set("3"); // Set to 0 to disable debug
|
||||||
mg_mgr_init(&mgr); // Initialise event manager
|
mg_mgr_init(&mgr); // Initialise event manager
|
||||||
mg_http_connect(&mgr, s_url, fn, &done); // Create client connection
|
mg_http_connect(&mgr, s_url, fn, &done); // Create client connection
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
PROG ?= example
|
PROG ?= example
|
||||||
|
|
||||||
ifeq "$(MBEDTLS_DIR)" ""
|
ifneq ($(MBEDTLS_DIR),)
|
||||||
else
|
|
||||||
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS_DIR)/include -I/usr/include
|
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS_DIR)/include -I/usr/include
|
||||||
CFLAGS += -L$(MBEDTLS_DIR)/lib -lmbedtls -lmbedcrypto -lmbedx509
|
CFLAGS += -L$(MBEDTLS_DIR)/lib -lmbedtls -lmbedcrypto -lmbedx509
|
||||||
|
else ifneq ($(OPENSSL_DIR),)
|
||||||
|
CFLAGS += -DMG_ENABLE_OPENSSL=1 -I$(OPENSSL_DIR)/include
|
||||||
|
CFLAGS += -L$(OPENSSL_DIR)/lib -lssl -lcrypto
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all: $(PROG)
|
all: $(PROG)
|
||||||
|
|||||||
@@ -2,24 +2,26 @@
|
|||||||
// All rights reserved
|
// All rights reserved
|
||||||
//
|
//
|
||||||
// HTTP server example. This server serves both static and dynamic content.
|
// HTTP server example. This server serves both static and dynamic content.
|
||||||
|
// It opens two ports: plain HTTP on port 8000 and HTTP on port 8443.
|
||||||
// It implements the following endpoints:
|
// It implements the following endpoints:
|
||||||
// /api/f1 - respond with JSON string {"result": 123}
|
// /api/f1 - respond with JSON string {"result": 123}
|
||||||
// /api/f2/:id - wildcard example, respond with JSON string {"result": "URI"}
|
// /api/f2/:id - wildcard example, respond with JSON string {"result": "URI"}
|
||||||
// any other URI serves static files from s_web_directory
|
// any other URI serves static files from s_root_dir
|
||||||
//
|
//
|
||||||
// To enable SSL/TLS (using self-signed certificates in PEM files),
|
// To enable SSL/TLS (using self-signed certificates in PEM files),
|
||||||
// 1. Change s_listen_on from http:// to https://
|
// 1. make MBEDTLS_DIR=/path/to/your/mbedtls/installation
|
||||||
// 2. make MBEDTLS_DIR=/path/to/your/mbedtls/installation
|
// 2. curl -k https://127.0.0.1:8443
|
||||||
// 3. curl -k https://127.0.0.1:8000
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
|
||||||
static const char *s_listen_on = "https://localhost:8000";
|
static const char *s_http_addr = "http://0.0.0.0:8000"; // HTTP port
|
||||||
static const char *s_web_directory = ".";
|
static const char *s_https_addr = "https://0.0.0.0:8443"; // HTTPS port
|
||||||
|
static const char *s_root_dir = ".";
|
||||||
|
|
||||||
|
// We use the same event handler function for HTTP and HTTPS connections
|
||||||
|
// fn_data is NULL for plain HTTP, and non-NULL for HTTPS
|
||||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||||
if (ev == MG_EV_ACCEPT && mg_url_is_ssl(s_listen_on)) {
|
if (ev == MG_EV_ACCEPT && fn_data != NULL) {
|
||||||
// If s_listen_on URL is https://, tell listening connection to use TLS
|
|
||||||
struct mg_tls_opts opts = {
|
struct mg_tls_opts opts = {
|
||||||
//.ca = "ca.pem", // Uncomment to enable two-way SSL
|
//.ca = "ca.pem", // Uncomment to enable two-way SSL
|
||||||
.cert = "server.pem", // Certificate PEM file
|
.cert = "server.pem", // Certificate PEM file
|
||||||
@@ -34,7 +36,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
mg_http_reply(c, 200, "", "{\"result\": \"%.*s\"}\n", (int) hm->uri.len,
|
mg_http_reply(c, 200, "", "{\"result\": \"%.*s\"}\n", (int) hm->uri.len,
|
||||||
hm->uri.ptr);
|
hm->uri.ptr);
|
||||||
} else {
|
} else {
|
||||||
struct mg_http_serve_opts opts = {.root_dir = s_web_directory};
|
struct mg_http_serve_opts opts = {.root_dir = s_root_dir};
|
||||||
mg_http_serve_dir(c, ev_data, &opts);
|
mg_http_serve_dir(c, ev_data, &opts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,8 +47,9 @@ int main(void) {
|
|||||||
struct mg_mgr mgr; // Event manager
|
struct mg_mgr mgr; // Event manager
|
||||||
mg_log_set("2"); // Set to 3 to enable debug
|
mg_log_set("2"); // Set to 3 to enable debug
|
||||||
mg_mgr_init(&mgr); // Initialise event manager
|
mg_mgr_init(&mgr); // Initialise event manager
|
||||||
mg_http_listen(&mgr, s_listen_on, fn, NULL); // Create HTTP listener
|
mg_http_listen(&mgr, s_http_addr, fn, NULL); // Create HTTP listener
|
||||||
for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
mg_http_listen(&mgr, s_https_addr, fn, (void *) 1); // HTTPS listener
|
||||||
|
for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
||||||
mg_mgr_free(&mgr);
|
mg_mgr_free(&mgr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
mg_tls_init(c, &opts);
|
mg_tls_init(c, &opts);
|
||||||
}
|
}
|
||||||
} else if (ev == MG_EV_CLOSE) {
|
} else if (ev == MG_EV_CLOSE) {
|
||||||
if (c2 != NULL) c2->is_closing = 1;
|
if (c->label[0] != 'B' && c2 != NULL) c2->is_closing = 1;
|
||||||
c->fn_data = NULL;
|
c->fn_data = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ ROOT ?= $(realpath $(CURDIR)/../..)
|
|||||||
DEFS ?= -DMG_ENABLE_LINES=1 -DMG_ENABLE_DIRECTORY_LISTING=1 -DMG_ENABLE_SSI=1
|
DEFS ?= -DMG_ENABLE_LINES=1 -DMG_ENABLE_DIRECTORY_LISTING=1 -DMG_ENABLE_SSI=1
|
||||||
CFLAGS ?= -I../.. -W -Wall -DMG_ENABLE_IPV6=1 $(DEFS) $(EXTRA)
|
CFLAGS ?= -I../.. -W -Wall -DMG_ENABLE_IPV6=1 $(DEFS) $(EXTRA)
|
||||||
VCFLAGS = /nologo /W3 /O2 /I../.. $(DEFS) $(EXTRA) /link /incremental:no /machine:IX86
|
VCFLAGS = /nologo /W3 /O2 /I../.. $(DEFS) $(EXTRA) /link /incremental:no /machine:IX86
|
||||||
VC98 = docker run --rm -e Tmp=. -v $(ROOT):$(ROOT) -w $(CURDIR) docker.io/mdashnet/vc98
|
VC98 = docker run -it --rm -e Tmp=. -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/vc98
|
||||||
|
LIN = docker run -it --rm -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/cc2
|
||||||
|
|
||||||
all: $(PROG)
|
all: $(PROG)
|
||||||
$(DEBUGGER) ./$(PROG) $(ARGS)
|
$(DEBUGGER) ./$(PROG) $(ARGS)
|
||||||
@@ -14,5 +15,10 @@ $(PROG): main.c Makefile
|
|||||||
mongoose.exe: main.c
|
mongoose.exe: main.c
|
||||||
$(VC98) wine cl ../../mongoose.c main.c $(VCFLAGS) ws2_32.lib /out:$@
|
$(VC98) wine cl ../../mongoose.c main.c $(VCFLAGS) ws2_32.lib /out:$@
|
||||||
|
|
||||||
|
linux: all
|
||||||
|
linux: CFLAGS += -O2 -fsanitize=address,undefined,shift,null,return,bounds,alignment,object-size,bool,enum -static-libasan
|
||||||
|
#linux: CC = $(LIN) cc
|
||||||
|
#linux: DEBUGGER = $(LIN)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb mongoose mongoose_* mongoose.*
|
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb mongoose mongoose_* mongoose.*
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2020 Cesanta Software Limited
|
// Copyright (c) 2020 Cesanta Software Limited
|
||||||
// All rights reserved
|
// All rights reserved
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
|
||||||
static const char *s_debug_level = "2";
|
static const char *s_debug_level = "2";
|
||||||
@@ -9,9 +10,18 @@ static const char *s_listening_address = "http://localhost:8000";
|
|||||||
static const char *s_enable_hexdump = "no";
|
static const char *s_enable_hexdump = "no";
|
||||||
static const char *s_ssi_pattern = "#.shtml";
|
static const char *s_ssi_pattern = "#.shtml";
|
||||||
|
|
||||||
|
// Handle interrupts, like Ctrl-C
|
||||||
|
static int s_signo;
|
||||||
|
static void signal_handler(int signo) {
|
||||||
|
s_signo = signo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event handler for the listening connection.
|
||||||
|
// Simply serve static files from `s_root_dir`
|
||||||
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||||
if (ev == MG_EV_HTTP_MSG) {
|
if (ev == MG_EV_HTTP_MSG) {
|
||||||
struct mg_http_serve_opts opts = {s_root_dir, s_ssi_pattern};
|
struct mg_http_serve_opts opts = {.root_dir = s_root_dir,
|
||||||
|
.ssi_pattern = s_ssi_pattern};
|
||||||
mg_http_serve_dir(c, ev_data, &opts);
|
mg_http_serve_dir(c, ev_data, &opts);
|
||||||
}
|
}
|
||||||
(void) fn_data;
|
(void) fn_data;
|
||||||
@@ -19,8 +29,8 @@ static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
|
|
||||||
static void usage(const char *prog) {
|
static void usage(const char *prog) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Mongoose v.%s, built " __DATE__ " " __TIME__
|
"Mongoose v.%s\n"
|
||||||
"\nUsage: %s OPTIONS\n"
|
"Usage: %s OPTIONS\n"
|
||||||
" -H yes|no - enable traffic hexdump, default: '%s'\n"
|
" -H yes|no - enable traffic hexdump, default: '%s'\n"
|
||||||
" -S GLOB - glob pattern for SSI files, default: '%s'\n"
|
" -S GLOB - glob pattern for SSI files, default: '%s'\n"
|
||||||
" -d DIR - directory to serve, default: '%s'\n"
|
" -d DIR - directory to serve, default: '%s'\n"
|
||||||
@@ -54,6 +64,8 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialise stuff
|
// Initialise stuff
|
||||||
|
signal(SIGINT, signal_handler);
|
||||||
|
signal(SIGTERM, signal_handler);
|
||||||
mg_log_set(s_debug_level);
|
mg_log_set(s_debug_level);
|
||||||
mg_mgr_init(&mgr);
|
mg_mgr_init(&mgr);
|
||||||
if ((c = mg_http_listen(&mgr, s_listening_address, cb, &mgr)) == NULL) {
|
if ((c = mg_http_listen(&mgr, s_listening_address, cb, &mgr)) == NULL) {
|
||||||
@@ -64,8 +76,9 @@ int main(int argc, char *argv[]) {
|
|||||||
if (mg_casecmp(s_enable_hexdump, "yes") == 0) c->is_hexdumping = 1;
|
if (mg_casecmp(s_enable_hexdump, "yes") == 0) c->is_hexdumping = 1;
|
||||||
|
|
||||||
// Start infinite event loop
|
// Start infinite event loop
|
||||||
LOG(LL_INFO, ("Starting Mongoose web server v%s", MG_VERSION));
|
LOG(LL_INFO, ("Starting Mongoose v%s, serving [%s]", MG_VERSION, s_root_dir));
|
||||||
for (;;) mg_mgr_poll(&mgr, 1000);
|
while (s_signo == 0) mg_mgr_poll(&mgr, 1000);
|
||||||
mg_mgr_free(&mgr);
|
mg_mgr_free(&mgr);
|
||||||
|
LOG(LL_INFO, ("Exiting on signal %d", s_signo));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
PROG ?= example
|
||||||
|
CFLAGS ?= -DMG_ENABLE_LINES $(EXTRA)
|
||||||
|
|
||||||
|
ifneq ($(MBEDTLS),)
|
||||||
|
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS)/include -I/usr/include
|
||||||
|
CFLAGS += -L$(MBEDTLS)/lib -lmbedtls -lmbedcrypto -lmbedx509
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(OPENSSL),)
|
||||||
|
CFLAGS += -DMG_ENABLE_OPENSSL=1 -I$(OPENSSL)/include
|
||||||
|
CFLAGS += -L$(OPENSSL)/lib -lssl -lcrypto
|
||||||
|
endif
|
||||||
|
|
||||||
|
all: $(PROG)
|
||||||
|
$(DEBUGGER) ./$(PROG) $(ARGS)
|
||||||
|
|
||||||
|
|
||||||
|
$(PROG): main.c
|
||||||
|
$(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) -o $(PROG) main.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
|
||||||
@@ -0,0 +1,507 @@
|
|||||||
|
Subject: O=Digital Signature Trust Co., CN=DST Root CA X3
|
||||||
|
Not Before: Sep 30 21:12:19 2000 GMT
|
||||||
|
Not After : Sep 30 14:01:15 2021 GMT
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
|
||||||
|
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
|
||||||
|
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
|
||||||
|
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
|
||||||
|
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||||
|
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
|
||||||
|
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
|
||||||
|
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
|
||||||
|
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
|
||||||
|
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
|
||||||
|
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
|
||||||
|
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
|
||||||
|
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
|
||||||
|
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
|
||||||
|
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
|
||||||
|
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
|
||||||
|
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
|
||||||
|
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
|
||||||
|
Not Before: May 12 18:46:00 2000 GMT
|
||||||
|
Not After : May 12 23:59:00 2025 GMT
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
|
||||||
|
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
|
||||||
|
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
|
||||||
|
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
|
||||||
|
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
|
||||||
|
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
|
||||||
|
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
|
||||||
|
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
|
||||||
|
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
|
||||||
|
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
|
||||||
|
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
|
||||||
|
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
|
||||||
|
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
|
||||||
|
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
|
||||||
|
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
|
||||||
|
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
|
||||||
|
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
|
||||||
|
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
|
||||||
|
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
|
||||||
|
Not Before: May 21 04:00:00 2002 GMT
|
||||||
|
Not After : May 21 04:00:00 2022 GMT
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
|
||||||
|
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
|
||||||
|
YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
|
||||||
|
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
|
||||||
|
R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
|
||||||
|
9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
|
||||||
|
fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
|
||||||
|
iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
|
||||||
|
1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
|
||||||
|
bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
|
||||||
|
MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
|
||||||
|
ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
|
||||||
|
uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
|
||||||
|
Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
|
||||||
|
tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
|
||||||
|
PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
|
||||||
|
hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
|
||||||
|
5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 ECC 256 bit SSL CA - G2
|
||||||
|
Not Before: May 12 00:00:00 2015 GMT
|
||||||
|
Not After : May 11 23:59:59 2025 GMT
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEajCCA1KgAwIBAgIQP5KHvp0dpKN6nfYoLndaxDANBgkqhkiG9w0BAQsFADCB
|
||||||
|
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
|
||||||
|
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
|
||||||
|
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
|
||||||
|
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
|
||||||
|
aG9yaXR5IC0gRzUwHhcNMTUwNTEyMDAwMDAwWhcNMjUwNTExMjM1OTU5WjCBgDEL
|
||||||
|
MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD
|
||||||
|
VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMTEwLwYDVQQDEyhTeW1hbnRlYyBD
|
||||||
|
bGFzcyAzIEVDQyAyNTYgYml0IFNTTCBDQSAtIEcyMFkwEwYHKoZIzj0CAQYIKoZI
|
||||||
|
zj0DAQcDQgAEDxukkdfnrOfRTk63ZFvhj39uBNOrONtEt0Bcbb2WljffeYmGZ/ex
|
||||||
|
Hwie/WM7RoyfvVPoFdyXPiuBRq2Gfw4BOaOCAV0wggFZMC4GCCsGAQUFBwEBBCIw
|
||||||
|
IDAeBggrBgEFBQcwAYYSaHR0cDovL3Muc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYB
|
||||||
|
Af8CAQAwZQYDVR0gBF4wXDBaBgpghkgBhvhFAQc2MEwwIwYIKwYBBQUHAgEWF2h0
|
||||||
|
dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkaF2h0dHBzOi8vZC5z
|
||||||
|
eW1jYi5jb20vcnBhMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9zLnN5bWNiLmNv
|
||||||
|
bS9wY2EzLWc1LmNybDAOBgNVHQ8BAf8EBAMCAQYwKwYDVR0RBCQwIqQgMB4xHDAa
|
||||||
|
BgNVBAMTE1NZTUMtRUNDLUNBLXAyNTYtMjIwHQYDVR0OBBYEFCXwiuFLetkBlQrt
|
||||||
|
xlPxjHgf2fP4MB8GA1UdIwQYMBaAFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
|
||||||
|
SIb3DQEBCwUAA4IBAQAMMGUXBaWTdaLxsTGtcB/naqjIQrLvoV9NG+7MoHpGd/69
|
||||||
|
dZ/h2zOy7sGFUHoG/0HGRA9rxT/5w5GkEVIVkxtWyIWWq6rs4CTZt8Bej/KHYRbo
|
||||||
|
jtEDUkCTZSTLiCvguPyvinXgxy+LHT+PmdtEfXsvcdbeBSWUYpOsDYvD2hNtz9dw
|
||||||
|
Od5nBosMApmdxt+z7LQyZu8wMnfI1U6IMO+RWowxZ8uy0oswdFYd32l9xe+aAE/k
|
||||||
|
y9alLu/M9pvxiUKufqHJRgDBKA6uDjHLMPX+/nxXaNCPX3SI4KVZ1stHQ/U5oNlM
|
||||||
|
dHN9umAvlU313g0IgJrjsQ2nIdf9dsdP+6lrmP7s
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
|
||||||
|
Not Before: Nov 8 00:00:00 2006 GMT
|
||||||
|
Not After : Jul 16 23:59:59 2036 GMT
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
|
||||||
|
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
|
||||||
|
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
|
||||||
|
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
|
||||||
|
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
|
||||||
|
aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
|
||||||
|
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
|
||||||
|
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
|
||||||
|
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
|
||||||
|
U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
|
||||||
|
aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
|
||||||
|
nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
|
||||||
|
t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
|
||||||
|
SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
|
||||||
|
BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
|
||||||
|
rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
|
||||||
|
NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
|
||||||
|
BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
|
||||||
|
BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
|
||||||
|
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
|
||||||
|
MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
|
||||||
|
p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
|
||||||
|
5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
|
||||||
|
WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
|
||||||
|
4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
|
||||||
|
hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Subject: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
|
||||||
|
Not Before: Jun 29 17:06:20 2004 GMT
|
||||||
|
Not After : Jun 29 17:06:20 2034 GMT
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
|
||||||
|
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
|
||||||
|
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
|
||||||
|
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
|
||||||
|
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
|
||||||
|
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
|
||||||
|
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
|
||||||
|
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
|
||||||
|
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
|
||||||
|
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
|
||||||
|
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
|
||||||
|
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
|
||||||
|
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
|
||||||
|
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
|
||||||
|
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
|
||||||
|
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
|
||||||
|
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
|
||||||
|
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
|
||||||
|
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
|
||||||
|
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
|
||||||
|
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
|
||||||
|
ReYNnyicsbkqWletNw+vHX/bvZ8=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
# Note: Amazon ATS endpoint uses this (2018/12/18)
|
||||||
|
Subject: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority
|
||||||
|
Not Before: Jun 29 17:39:16 2004 GMT
|
||||||
|
Not After : Jun 29 17:39:16 2034 GMT
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
|
||||||
|
MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
|
||||||
|
U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
|
||||||
|
NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
|
||||||
|
ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
|
||||||
|
ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
|
||||||
|
DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
|
||||||
|
8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
|
||||||
|
+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
|
||||||
|
X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
|
||||||
|
K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
|
||||||
|
1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
|
||||||
|
A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
|
||||||
|
zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
|
||||||
|
YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
|
||||||
|
bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
|
||||||
|
DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
|
||||||
|
L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
|
||||||
|
eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
|
||||||
|
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
|
||||||
|
VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
|
||||||
|
WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Not Before: Sep 1 00:00:00 2009 GMT
|
||||||
|
Not After : Dec 31 23:59:59 2037 GMT
|
||||||
|
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
|
||||||
|
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
|
||||||
|
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
|
||||||
|
ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
|
||||||
|
MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
|
||||||
|
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
|
||||||
|
aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
|
||||||
|
Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
||||||
|
ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
|
||||||
|
nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
|
||||||
|
HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
|
||||||
|
Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
|
||||||
|
dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
|
||||||
|
HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
|
||||||
|
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
|
||||||
|
CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
|
||||||
|
sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
|
||||||
|
4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
|
||||||
|
8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
|
||||||
|
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
|
||||||
|
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Services Root Certificate Authority - G2
|
||||||
|
Not Before: Sep 1 00:00:00 2009 GMT
|
||||||
|
Not After : Dec 31 23:59:59 2037 GMT
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
|
||||||
|
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
|
||||||
|
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
|
||||||
|
ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
|
||||||
|
MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
|
||||||
|
VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
|
||||||
|
ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
|
||||||
|
dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
|
||||||
|
hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
|
||||||
|
OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
|
||||||
|
8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
|
||||||
|
Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
|
||||||
|
hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
|
||||||
|
6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
|
||||||
|
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
|
||||||
|
AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
|
||||||
|
bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
|
||||||
|
ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
|
||||||
|
qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
|
||||||
|
iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
|
||||||
|
0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
|
||||||
|
sSi6
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Subject: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign
|
||||||
|
Not Before: Dec 15 08:00:00 2006 GMT
|
||||||
|
Not After : Dec 15 08:00:00 2021 GMT
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
|
||||||
|
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
|
||||||
|
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
|
||||||
|
MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
|
||||||
|
A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
|
||||||
|
hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
|
||||||
|
v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
|
||||||
|
eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
|
||||||
|
tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
|
||||||
|
C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
|
||||||
|
zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
|
||||||
|
mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
|
||||||
|
V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
|
||||||
|
bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
|
||||||
|
3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
|
||||||
|
J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
|
||||||
|
291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
|
||||||
|
ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
|
||||||
|
AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
|
||||||
|
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
|
||||||
|
Not Before: Nov 10 00:00:00 2006 GMT
|
||||||
|
Not After : Nov 10 00:00:00 2031 GMT
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
|
||||||
|
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
||||||
|
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
|
||||||
|
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
|
||||||
|
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
|
||||||
|
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
|
||||||
|
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
|
||||||
|
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
|
||||||
|
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
|
||||||
|
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
|
||||||
|
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
|
||||||
|
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
|
||||||
|
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
|
||||||
|
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
|
||||||
|
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
|
||||||
|
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
|
||||||
|
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
|
||||||
|
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
|
||||||
|
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
|
||||||
|
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
|
||||||
|
+OkuE6N36B9K
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
|
||||||
|
Not Before: Nov 10 00:00:00 2006 GMT
|
||||||
|
Not After : Nov 10 00:00:00 2031 GMT
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
|
||||||
|
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
||||||
|
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
|
||||||
|
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
|
||||||
|
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
|
||||||
|
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
|
||||||
|
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
|
||||||
|
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
|
||||||
|
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
|
||||||
|
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
|
||||||
|
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
|
||||||
|
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
|
||||||
|
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
|
||||||
|
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
|
||||||
|
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
|
||||||
|
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
|
||||||
|
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
|
||||||
|
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
|
||||||
|
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
|
||||||
|
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
# *.azure-devices.de use this root.
|
||||||
|
Subject: C = DE, O = D-Trust GmbH, CN = D-TRUST Root Class 3 CA 2 2009
|
||||||
|
Not Before: Nov 5 08:35:58 2009 GMT
|
||||||
|
Not After : Nov 5 08:35:58 2029 GMT
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
|
||||||
|
MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
|
||||||
|
bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
|
||||||
|
ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
|
||||||
|
HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
|
||||||
|
BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
|
||||||
|
UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
|
||||||
|
tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
|
||||||
|
ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
|
||||||
|
lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
|
||||||
|
/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
|
||||||
|
A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
|
||||||
|
A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
|
||||||
|
dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
|
||||||
|
MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
|
||||||
|
cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
|
||||||
|
L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
|
||||||
|
BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
|
||||||
|
acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
|
||||||
|
o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
|
||||||
|
zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
|
||||||
|
PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
|
||||||
|
Johw1+qRzT65ysCQblrGXnRl11z+o+I=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
# https://www.amazontrust.com/repository/
|
||||||
|
Subject: C = US, O = Amazon, CN = Amazon Root CA 1
|
||||||
|
Not Before: May 26 00:00:00 2015 GMT
|
||||||
|
Not After : Jan 17 00:00:00 2038 GMT
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
|
||||||
|
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
|
||||||
|
b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
|
||||||
|
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
|
||||||
|
b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
|
||||||
|
ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
|
||||||
|
9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
|
||||||
|
IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
|
||||||
|
VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
|
||||||
|
93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
|
||||||
|
jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
|
||||||
|
AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA
|
||||||
|
A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI
|
||||||
|
U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs
|
||||||
|
N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
|
||||||
|
o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
|
||||||
|
5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
|
||||||
|
rqXRfboQnoZsG4q5WTP468SQvvG5
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Subject: C = US, O = Amazon, CN = Amazon Root CA 2
|
||||||
|
Not Before: May 26 00:00:00 2015 GMT
|
||||||
|
Not After : May 26 00:00:00 2040 GMT
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
|
||||||
|
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
|
||||||
|
b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
|
||||||
|
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
|
||||||
|
b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK
|
||||||
|
gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ
|
||||||
|
W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg
|
||||||
|
1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K
|
||||||
|
8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r
|
||||||
|
2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me
|
||||||
|
z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR
|
||||||
|
8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj
|
||||||
|
mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz
|
||||||
|
7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6
|
||||||
|
+XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI
|
||||||
|
0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
|
||||||
|
Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm
|
||||||
|
UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2
|
||||||
|
LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
|
||||||
|
+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS
|
||||||
|
k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl
|
||||||
|
7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm
|
||||||
|
btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl
|
||||||
|
urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+
|
||||||
|
fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63
|
||||||
|
n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
|
||||||
|
76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
|
||||||
|
9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
|
||||||
|
4PsJYGw=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Not Before: May 26 00:00:00 2015 GMT
|
||||||
|
Not After : May 26 00:00:00 2040 GMT
|
||||||
|
Subject: C = US, O = Amazon, CN = Amazon Root CA 3
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5
|
||||||
|
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
|
||||||
|
Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
|
||||||
|
A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
|
||||||
|
Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl
|
||||||
|
ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j
|
||||||
|
QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr
|
||||||
|
ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr
|
||||||
|
BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM
|
||||||
|
YyRIHN8wfdVoOw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Not Before: May 26 00:00:00 2015 GMT
|
||||||
|
Not After : May 26 00:00:00 2040 GMT
|
||||||
|
Subject: C = US, O = Amazon, CN = Amazon Root CA 4
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5
|
||||||
|
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
|
||||||
|
Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
|
||||||
|
A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
|
||||||
|
Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi
|
||||||
|
9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk
|
||||||
|
M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB
|
||||||
|
/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB
|
||||||
|
MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw
|
||||||
|
CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
|
||||||
|
1KyLa2tJElMzrdfkviT8tQp21KW8EA==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Not Before: Nov 10 00:00:00 2006 GMT
|
||||||
|
Not After : Nov 10 00:00:00 2031 GMT
|
||||||
|
Subject: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
|
||||||
|
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
||||||
|
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
|
||||||
|
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
|
||||||
|
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
|
||||||
|
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
|
||||||
|
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
|
||||||
|
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
|
||||||
|
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
|
||||||
|
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
|
||||||
|
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
|
||||||
|
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
|
||||||
|
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
|
||||||
|
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
|
||||||
|
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
|
||||||
|
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
|
||||||
|
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
|
||||||
|
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
|
||||||
|
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
|
||||||
|
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Not Before: Nov 13 00:00:00 2012 GMT
|
||||||
|
Not After : Jan 19 03:14:07 2038 GMT
|
||||||
|
Subject: OU = GlobalSign ECC Root CA - R4, O = GlobalSign, CN = GlobalSign
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk
|
||||||
|
MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH
|
||||||
|
bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
|
||||||
|
DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
|
||||||
|
QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
|
||||||
|
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ
|
||||||
|
FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw
|
||||||
|
DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F
|
||||||
|
uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX
|
||||||
|
kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
|
||||||
|
ewv4n4Q=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Not Before: Nov 1 00:00:42 2018 GMT
|
||||||
|
Not After : Nov 1 00:00:42 2042 GMT
|
||||||
|
Subject: C = US, O = Google Trust Services LLC, CN = GTS LTSR
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIBxTCCAWugAwIBAgINAfD3nVndblD3QnNxUDAKBggqhkjOPQQDAjBEMQswCQYD
|
||||||
|
VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzERMA8G
|
||||||
|
A1UEAxMIR1RTIExUU1IwHhcNMTgxMTAxMDAwMDQyWhcNNDIxMTAxMDAwMDQyWjBE
|
||||||
|
MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
|
||||||
|
QzERMA8GA1UEAxMIR1RTIExUU1IwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATN
|
||||||
|
8YyO2u+yCQoZdwAkUNv5c3dokfULfrA6QJgFV2XMuENtQZIG5HUOS6jFn8f0ySlV
|
||||||
|
eORCxqFyjDJyRn86d+Iko0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUw
|
||||||
|
AwEB/zAdBgNVHQ4EFgQUPv7/zFLrvzQ+PfNA0OQlsV+4u1IwCgYIKoZIzj0EAwID
|
||||||
|
SAAwRQIhAPKuf/VtBHqGw3TUwUIq7TfaExp3bH7bjCBmVXJupT9FAiBr0SmCtsuk
|
||||||
|
miGgpajjf/gFigGM34F9021bCWs1MbL0SA==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
// Copyright (c) 2021 Cesanta Software Limited
|
||||||
|
// All rights reserved
|
||||||
|
//
|
||||||
|
// Example HTTP client.
|
||||||
|
// Instead of buffering the whole HTTP response in memory and wait for the
|
||||||
|
// MG_EV_HTTP_MSG event, this client catches MG_EV_HTTP_CHUNK events and
|
||||||
|
// prints them. This is useful to download large content without spooling
|
||||||
|
// everything to memory, or catch chunked content.
|
||||||
|
//
|
||||||
|
// You can change `s_url` from the command line by executing: ./example YOUR_URL
|
||||||
|
//
|
||||||
|
// To enable SSL/TLS for this client, build it like this:
|
||||||
|
// make MBEDTLS=/path/to/your/mbedtls/installation
|
||||||
|
// make OPENSSL=/path/to/your/openssl/installation
|
||||||
|
|
||||||
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
// The very first web page in history. You can replace it from command line
|
||||||
|
static const char *s_url = "http://info.cern.ch";
|
||||||
|
|
||||||
|
// Print HTTP response and signal that we're done
|
||||||
|
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||||
|
if (ev == MG_EV_CONNECT) {
|
||||||
|
// Connected to server. Extract host name from URL
|
||||||
|
struct mg_str host = mg_url_host(s_url);
|
||||||
|
|
||||||
|
// If s_url is https://, tell client connection to use TLS
|
||||||
|
if (mg_url_is_ssl(s_url)) {
|
||||||
|
struct mg_tls_opts opts = {.ca = "ca.pem", .srvname = host};
|
||||||
|
mg_tls_init(c, &opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send request
|
||||||
|
mg_printf(c,
|
||||||
|
"GET %s HTTP/1.0\r\n"
|
||||||
|
"Host: %.*s\r\n"
|
||||||
|
"\r\n",
|
||||||
|
mg_url_uri(s_url), (int) host.len, host.ptr);
|
||||||
|
} else if (ev == MG_EV_HTTP_CHUNK) {
|
||||||
|
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||||
|
LOG(LL_INFO, ("%.*s", (int) hm->chunk.len, hm->chunk.ptr));
|
||||||
|
mg_http_delete_chunk(c, hm);
|
||||||
|
if (hm->chunk.len == 0) *(bool *) fn_data = true; // Last chunk
|
||||||
|
} else if (ev == MG_EV_HTTP_MSG) {
|
||||||
|
// Response is received. Print it
|
||||||
|
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||||
|
LOG(LL_INFO, ("%.*s", (int) hm->body.len, hm->body.ptr));
|
||||||
|
c->is_closing = 1; // Tell mongoose to close this connection
|
||||||
|
*(bool *) fn_data = true; // Tell event loop to stop
|
||||||
|
} else if (ev == MG_EV_ERROR) {
|
||||||
|
*(bool *) fn_data = true; // Error, tell event loop to stop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
struct mg_mgr mgr; // Event manager
|
||||||
|
bool done = false; // Event handler flips it to true
|
||||||
|
if (argc > 1) s_url = argv[1]; // Use URL from command line
|
||||||
|
mg_log_set("3"); // Set to 0 to disable debug
|
||||||
|
mg_mgr_init(&mgr); // Initialise event manager
|
||||||
|
mg_http_connect(&mgr, s_url, fn, &done); // Create client connection
|
||||||
|
while (!done) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
||||||
|
mg_mgr_free(&mgr); // Free resources
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+12
-12
@@ -29,9 +29,9 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
// MQTT connect is successful
|
// MQTT connect is successful
|
||||||
struct mg_str topic = mg_str(s_topic), data = mg_str("hello");
|
struct mg_str topic = mg_str(s_topic), data = mg_str("hello");
|
||||||
LOG(LL_INFO, ("CONNECTED to %s", s_url));
|
LOG(LL_INFO, ("CONNECTED to %s", s_url));
|
||||||
mg_mqtt_sub(c, &topic);
|
mg_mqtt_sub(c, &topic, 1);
|
||||||
LOG(LL_INFO, ("SUBSCRIBED to %.*s", (int) topic.len, topic.ptr));
|
LOG(LL_INFO, ("SUBSCRIBED to %.*s", (int) topic.len, topic.ptr));
|
||||||
mg_mqtt_pub(c, &topic, &data);
|
mg_mqtt_pub(c, &topic, &data, 1, false);
|
||||||
LOG(LL_INFO, ("PUBSLISHED %.*s -> %.*s", (int) data.len, data.ptr,
|
LOG(LL_INFO, ("PUBSLISHED %.*s -> %.*s", (int) data.len, data.ptr,
|
||||||
(int) topic.len, topic.ptr));
|
(int) topic.len, topic.ptr));
|
||||||
} else if (ev == MG_EV_MQTT_MSG) {
|
} else if (ev == MG_EV_MQTT_MSG) {
|
||||||
@@ -47,16 +47,16 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
struct mg_mgr mgr; // Event manager
|
struct mg_mgr mgr; // Event manager
|
||||||
struct mg_mqtt_opts opts; // MQTT connection options
|
struct mg_mqtt_opts opts; // MQTT connection options
|
||||||
bool done = false; // Event handler flips it to true when done
|
bool done = false; // Event handler flips it to true when done
|
||||||
mg_mgr_init(&mgr); // Initialise event manager
|
mg_mgr_init(&mgr); // Initialise event manager
|
||||||
memset(&opts, 0, sizeof(opts)); // Set MQTT options
|
memset(&opts, 0, sizeof(opts)); // Set MQTT options
|
||||||
opts.qos = 1; // Set QoS to 1
|
opts.qos = 1; // Set QoS to 1
|
||||||
opts.will_topic = mg_str(s_topic); // Set last will topic
|
opts.will_topic = mg_str(s_topic); // Set last will topic
|
||||||
opts.will_message = mg_str("goodbye"); // And last will message
|
opts.will_message = mg_str("goodbye"); // And last will message
|
||||||
mg_mqtt_connect(&mgr, s_url, &opts, fn, &done); // Create client connection
|
mg_mqtt_connect(&mgr, s_url, &opts, fn, &done); // Create client connection
|
||||||
while (done == false) mg_mgr_poll(&mgr, 1000); // Event loop
|
while (done == false) mg_mgr_poll(&mgr, 1000); // Event loop
|
||||||
mg_mgr_free(&mgr); // Finished, cleanup
|
mg_mgr_free(&mgr); // Finished, cleanup
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
mm->data.ptr, (int) mm->topic.len, mm->topic.ptr));
|
mm->data.ptr, (int) mm->topic.len, mm->topic.ptr));
|
||||||
for (struct sub *sub = s_subs; sub != NULL; sub = sub->next) {
|
for (struct sub *sub = s_subs; sub != NULL; sub = sub->next) {
|
||||||
if (mg_strcmp(mm->topic, sub->topic) != 0) continue;
|
if (mg_strcmp(mm->topic, sub->topic) != 0) continue;
|
||||||
mg_mqtt_pub(sub->c, &mm->topic, &mm->data);
|
mg_mqtt_pub(sub->c, &mm->topic, &mm->data, 1, false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Whitespace-only changes.
@@ -0,0 +1,620 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f7xx_hal.c
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief HAL module driver.
|
||||||
|
* This is the common part of the HAL initialization
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
==============================================================================
|
||||||
|
##### How to use this driver #####
|
||||||
|
==============================================================================
|
||||||
|
[..]
|
||||||
|
The common HAL driver contains a set of generic and common APIs that can be
|
||||||
|
used by the PPP peripheral drivers and the user to start using the HAL.
|
||||||
|
[..]
|
||||||
|
The HAL contains two APIs' categories:
|
||||||
|
(+) Common HAL APIs
|
||||||
|
(+) Services HAL APIs
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f7xx_hal.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F7xx_HAL_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup HAL HAL
|
||||||
|
* @brief HAL module driver.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
/** @addtogroup HAL_Private_Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief STM32F7xx HAL Driver version number V1.2.9
|
||||||
|
*/
|
||||||
|
#define __STM32F7xx_HAL_VERSION_MAIN (0x01) /*!< [31:24] main version */
|
||||||
|
#define __STM32F7xx_HAL_VERSION_SUB1 (0x02) /*!< [23:16] sub1 version */
|
||||||
|
#define __STM32F7xx_HAL_VERSION_SUB2 (0x09) /*!< [15:8] sub2 version */
|
||||||
|
#define __STM32F7xx_HAL_VERSION_RC (0x00) /*!< [7:0] release candidate */
|
||||||
|
#define __STM32F7xx_HAL_VERSION ((__STM32F7xx_HAL_VERSION_MAIN << 24)\
|
||||||
|
|(__STM32F7xx_HAL_VERSION_SUB1 << 16)\
|
||||||
|
|(__STM32F7xx_HAL_VERSION_SUB2 << 8 )\
|
||||||
|
|(__STM32F7xx_HAL_VERSION_RC))
|
||||||
|
|
||||||
|
#define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
/* Exported variables ---------------------------------------------------------*/
|
||||||
|
/** @addtogroup HAL_Exported_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
__IO uint32_t uwTick;
|
||||||
|
uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */
|
||||||
|
HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
/** @defgroup HAL_Exported_Functions HAL Exported Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup HAL_Exported_Functions_Group1 Initialization and de-initialization Functions
|
||||||
|
* @brief Initialization and de-initialization functions
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
===============================================================================
|
||||||
|
##### Initialization and Configuration functions #####
|
||||||
|
===============================================================================
|
||||||
|
[..] This section provides functions allowing to:
|
||||||
|
(+) Initializes the Flash interface the NVIC allocation and initial clock
|
||||||
|
configuration. It initializes the systick also when timeout is needed
|
||||||
|
and the backup domain when enabled.
|
||||||
|
(+) De-Initializes common part of the HAL.
|
||||||
|
(+) Configure the time base source to have 1ms time base with a dedicated
|
||||||
|
Tick interrupt priority.
|
||||||
|
(++) SysTick timer is used by default as source of time base, but user
|
||||||
|
can eventually implement his proper time base source (a general purpose
|
||||||
|
timer for example or other time source), keeping in mind that Time base
|
||||||
|
duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
|
||||||
|
handled in milliseconds basis.
|
||||||
|
(++) Time base configuration function (HAL_InitTick ()) is called automatically
|
||||||
|
at the beginning of the program after reset by HAL_Init() or at any time
|
||||||
|
when clock is configured, by HAL_RCC_ClockConfig().
|
||||||
|
(++) Source of time base is configured to generate interrupts at regular
|
||||||
|
time intervals. Care must be taken if HAL_Delay() is called from a
|
||||||
|
peripheral ISR process, the Tick interrupt line must have higher priority
|
||||||
|
(numerically lower) than the peripheral interrupt. Otherwise the caller
|
||||||
|
ISR process will be blocked.
|
||||||
|
(++) functions affecting time base configurations are declared as __weak
|
||||||
|
to make override possible in case of other implementations in user file.
|
||||||
|
@endverbatim
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function is used to initialize the HAL Library; it must be the first
|
||||||
|
* instruction to be executed in the main program (before to call any other
|
||||||
|
* HAL function), it performs the following:
|
||||||
|
* Configure the Flash prefetch, and instruction cache through ART accelerator.
|
||||||
|
* Configures the SysTick to generate an interrupt each 1 millisecond,
|
||||||
|
* which is clocked by the HSI (at this stage, the clock is not yet
|
||||||
|
* configured and thus the system is running from the internal HSI at 16 MHz).
|
||||||
|
* Set NVIC Group Priority to 4.
|
||||||
|
* Calls the HAL_MspInit() callback function defined in user file
|
||||||
|
* "stm32f7xx_hal_msp.c" to do the global low level hardware initialization
|
||||||
|
*
|
||||||
|
* @note SysTick is used as time base for the HAL_Delay() function, the application
|
||||||
|
* need to ensure that the SysTick time base is always set to 1 millisecond
|
||||||
|
* to have correct HAL operation.
|
||||||
|
* @retval HAL status
|
||||||
|
*/
|
||||||
|
HAL_StatusTypeDef HAL_Init(void)
|
||||||
|
{
|
||||||
|
/* Configure Instruction cache through ART accelerator */
|
||||||
|
#if (ART_ACCLERATOR_ENABLE != 0)
|
||||||
|
__HAL_FLASH_ART_ENABLE();
|
||||||
|
#endif /* ART_ACCLERATOR_ENABLE */
|
||||||
|
|
||||||
|
/* Configure Flash prefetch */
|
||||||
|
#if (PREFETCH_ENABLE != 0U)
|
||||||
|
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
|
||||||
|
#endif /* PREFETCH_ENABLE */
|
||||||
|
|
||||||
|
/* Set Interrupt Group Priority */
|
||||||
|
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
|
||||||
|
|
||||||
|
/* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
|
||||||
|
HAL_InitTick(TICK_INT_PRIORITY);
|
||||||
|
|
||||||
|
/* Init the low level hardware */
|
||||||
|
HAL_MspInit();
|
||||||
|
|
||||||
|
/* Return function status */
|
||||||
|
return HAL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function de-Initializes common part of the HAL and stops the systick.
|
||||||
|
* This function is optional.
|
||||||
|
* @retval HAL status
|
||||||
|
*/
|
||||||
|
HAL_StatusTypeDef HAL_DeInit(void)
|
||||||
|
{
|
||||||
|
/* Reset of all peripherals */
|
||||||
|
__HAL_RCC_APB1_FORCE_RESET();
|
||||||
|
__HAL_RCC_APB1_RELEASE_RESET();
|
||||||
|
|
||||||
|
__HAL_RCC_APB2_FORCE_RESET();
|
||||||
|
__HAL_RCC_APB2_RELEASE_RESET();
|
||||||
|
|
||||||
|
__HAL_RCC_AHB1_FORCE_RESET();
|
||||||
|
__HAL_RCC_AHB1_RELEASE_RESET();
|
||||||
|
|
||||||
|
__HAL_RCC_AHB2_FORCE_RESET();
|
||||||
|
__HAL_RCC_AHB2_RELEASE_RESET();
|
||||||
|
|
||||||
|
__HAL_RCC_AHB3_FORCE_RESET();
|
||||||
|
__HAL_RCC_AHB3_RELEASE_RESET();
|
||||||
|
|
||||||
|
/* De-Init the low level hardware */
|
||||||
|
HAL_MspDeInit();
|
||||||
|
|
||||||
|
/* Return function status */
|
||||||
|
return HAL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the MSP.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
__weak void HAL_MspInit(void)
|
||||||
|
{
|
||||||
|
/* NOTE : This function should not be modified, when the callback is needed,
|
||||||
|
the HAL_MspInit could be implemented in the user file
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DeInitializes the MSP.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
__weak void HAL_MspDeInit(void)
|
||||||
|
{
|
||||||
|
/* NOTE : This function should not be modified, when the callback is needed,
|
||||||
|
the HAL_MspDeInit could be implemented in the user file
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function configures the source of the time base.
|
||||||
|
* The time source is configured to have 1ms time base with a dedicated
|
||||||
|
* Tick interrupt priority.
|
||||||
|
* @note This function is called automatically at the beginning of program after
|
||||||
|
* reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig().
|
||||||
|
* @note In the default implementation, SysTick timer is the source of time base.
|
||||||
|
* It is used to generate interrupts at regular time intervals.
|
||||||
|
* Care must be taken if HAL_Delay() is called from a peripheral ISR process,
|
||||||
|
* The SysTick interrupt must have higher priority (numerically lower)
|
||||||
|
* than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
|
||||||
|
* The function is declared as __weak to be overwritten in case of other
|
||||||
|
* implementation in user file.
|
||||||
|
* @param TickPriority Tick interrupt priority.
|
||||||
|
* @retval HAL status
|
||||||
|
*/
|
||||||
|
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
|
||||||
|
{
|
||||||
|
/* Configure the SysTick to have interrupt in 1ms time basis*/
|
||||||
|
if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U)
|
||||||
|
{
|
||||||
|
return HAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure the SysTick IRQ priority */
|
||||||
|
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
|
||||||
|
{
|
||||||
|
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
|
||||||
|
uwTickPrio = TickPriority;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return HAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return function status */
|
||||||
|
return HAL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup HAL_Exported_Functions_Group2 HAL Control functions
|
||||||
|
* @brief HAL Control functions
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
===============================================================================
|
||||||
|
##### HAL Control functions #####
|
||||||
|
===============================================================================
|
||||||
|
[..] This section provides functions allowing to:
|
||||||
|
(+) Provide a tick value in millisecond
|
||||||
|
(+) Provide a blocking delay in millisecond
|
||||||
|
(+) Suspend the time base source interrupt
|
||||||
|
(+) Resume the time base source interrupt
|
||||||
|
(+) Get the HAL API driver version
|
||||||
|
(+) Get the device identifier
|
||||||
|
(+) Get the device revision identifier
|
||||||
|
(+) Enable/Disable Debug module during SLEEP mode
|
||||||
|
(+) Enable/Disable Debug module during STOP mode
|
||||||
|
(+) Enable/Disable Debug module during STANDBY mode
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function is called to increment a global variable "uwTick"
|
||||||
|
* used as application time base.
|
||||||
|
* @note In the default implementation, this variable is incremented each 1ms
|
||||||
|
* in SysTick ISR.
|
||||||
|
* @note This function is declared as __weak to be overwritten in case of other
|
||||||
|
* implementations in user file.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
__weak void HAL_IncTick(void)
|
||||||
|
{
|
||||||
|
uwTick += uwTickFreq;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Provides a tick value in millisecond.
|
||||||
|
* @note This function is declared as __weak to be overwritten in case of other
|
||||||
|
* implementations in user file.
|
||||||
|
* @retval tick value
|
||||||
|
*/
|
||||||
|
__weak uint32_t HAL_GetTick(void)
|
||||||
|
{
|
||||||
|
return uwTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function returns a tick priority.
|
||||||
|
* @retval tick priority
|
||||||
|
*/
|
||||||
|
uint32_t HAL_GetTickPrio(void)
|
||||||
|
{
|
||||||
|
return uwTickPrio;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set new tick Freq.
|
||||||
|
* @retval Status
|
||||||
|
*/
|
||||||
|
HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)
|
||||||
|
{
|
||||||
|
HAL_StatusTypeDef status = HAL_OK;
|
||||||
|
HAL_TickFreqTypeDef prevTickFreq;
|
||||||
|
|
||||||
|
assert_param(IS_TICKFREQ(Freq));
|
||||||
|
|
||||||
|
if (uwTickFreq != Freq)
|
||||||
|
{
|
||||||
|
/* Back up uwTickFreq frequency */
|
||||||
|
prevTickFreq = uwTickFreq;
|
||||||
|
|
||||||
|
/* Update uwTickFreq global variable used by HAL_InitTick() */
|
||||||
|
uwTickFreq = Freq;
|
||||||
|
|
||||||
|
/* Apply the new tick Freq */
|
||||||
|
status = HAL_InitTick(uwTickPrio);
|
||||||
|
|
||||||
|
if (status != HAL_OK)
|
||||||
|
{
|
||||||
|
/* Restore previous tick frequency */
|
||||||
|
uwTickFreq = prevTickFreq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return tick frequency.
|
||||||
|
* @retval tick period in Hz
|
||||||
|
*/
|
||||||
|
HAL_TickFreqTypeDef HAL_GetTickFreq(void)
|
||||||
|
{
|
||||||
|
return uwTickFreq;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function provides minimum delay (in milliseconds) based
|
||||||
|
* on variable incremented.
|
||||||
|
* @note In the default implementation , SysTick timer is the source of time base.
|
||||||
|
* It is used to generate interrupts at regular time intervals where uwTick
|
||||||
|
* is incremented.
|
||||||
|
* @note This function is declared as __weak to be overwritten in case of other
|
||||||
|
* implementations in user file.
|
||||||
|
* @param Delay specifies the delay time length, in milliseconds.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
__weak void HAL_Delay(uint32_t Delay)
|
||||||
|
{
|
||||||
|
uint32_t tickstart = HAL_GetTick();
|
||||||
|
uint32_t wait = Delay;
|
||||||
|
|
||||||
|
/* Add a freq to guarantee minimum wait */
|
||||||
|
if (wait < HAL_MAX_DELAY)
|
||||||
|
{
|
||||||
|
wait += (uint32_t)(uwTickFreq);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((HAL_GetTick() - tickstart) < wait)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Suspend Tick increment.
|
||||||
|
* @note In the default implementation , SysTick timer is the source of time base. It is
|
||||||
|
* used to generate interrupts at regular time intervals. Once HAL_SuspendTick()
|
||||||
|
* is called, the SysTick interrupt will be disabled and so Tick increment
|
||||||
|
* is suspended.
|
||||||
|
* @note This function is declared as __weak to be overwritten in case of other
|
||||||
|
* implementations in user file.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
__weak void HAL_SuspendTick(void)
|
||||||
|
{
|
||||||
|
/* Disable SysTick Interrupt */
|
||||||
|
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resume Tick increment.
|
||||||
|
* @note In the default implementation , SysTick timer is the source of time base. It is
|
||||||
|
* used to generate interrupts at regular time intervals. Once HAL_ResumeTick()
|
||||||
|
* is called, the SysTick interrupt will be enabled and so Tick increment
|
||||||
|
* is resumed.
|
||||||
|
* @note This function is declared as __weak to be overwritten in case of other
|
||||||
|
* implementations in user file.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
__weak void HAL_ResumeTick(void)
|
||||||
|
{
|
||||||
|
/* Enable SysTick Interrupt */
|
||||||
|
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the HAL revision
|
||||||
|
* @retval version : 0xXYZR (8bits for each decimal, R for RC)
|
||||||
|
*/
|
||||||
|
uint32_t HAL_GetHalVersion(void)
|
||||||
|
{
|
||||||
|
return __STM32F7xx_HAL_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the device revision identifier.
|
||||||
|
* @retval Device revision identifier
|
||||||
|
*/
|
||||||
|
uint32_t HAL_GetREVID(void)
|
||||||
|
{
|
||||||
|
return((DBGMCU->IDCODE) >> 16U);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the device identifier.
|
||||||
|
* @retval Device identifier
|
||||||
|
*/
|
||||||
|
uint32_t HAL_GetDEVID(void)
|
||||||
|
{
|
||||||
|
return((DBGMCU->IDCODE) & IDCODE_DEVID_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns first word of the unique device identifier (UID based on 96 bits)
|
||||||
|
* @retval Device identifier
|
||||||
|
*/
|
||||||
|
uint32_t HAL_GetUIDw0(void)
|
||||||
|
{
|
||||||
|
return(READ_REG(*((uint32_t *)UID_BASE)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns second word of the unique device identifier (UID based on 96 bits)
|
||||||
|
* @retval Device identifier
|
||||||
|
*/
|
||||||
|
uint32_t HAL_GetUIDw1(void)
|
||||||
|
{
|
||||||
|
return(READ_REG(*((uint32_t *)(UID_BASE + 4U))));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns third word of the unique device identifier (UID based on 96 bits)
|
||||||
|
* @retval Device identifier
|
||||||
|
*/
|
||||||
|
uint32_t HAL_GetUIDw2(void)
|
||||||
|
{
|
||||||
|
return(READ_REG(*((uint32_t *)(UID_BASE + 8U))));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the Debug Module during SLEEP mode
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_DBGMCU_EnableDBGSleepMode(void)
|
||||||
|
{
|
||||||
|
SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the Debug Module during SLEEP mode
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_DBGMCU_DisableDBGSleepMode(void)
|
||||||
|
{
|
||||||
|
CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the Debug Module during STOP mode
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_DBGMCU_EnableDBGStopMode(void)
|
||||||
|
{
|
||||||
|
SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the Debug Module during STOP mode
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_DBGMCU_DisableDBGStopMode(void)
|
||||||
|
{
|
||||||
|
CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the Debug Module during STANDBY mode
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_DBGMCU_EnableDBGStandbyMode(void)
|
||||||
|
{
|
||||||
|
SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the Debug Module during STANDBY mode
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_DBGMCU_DisableDBGStandbyMode(void)
|
||||||
|
{
|
||||||
|
CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the I/O Compensation Cell.
|
||||||
|
* @note The I/O compensation cell can be used only when the device supply
|
||||||
|
* voltage ranges from 2.4 to 3.6 V.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_EnableCompensationCell(void)
|
||||||
|
{
|
||||||
|
SYSCFG->CMPCR |= SYSCFG_CMPCR_CMP_PD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power-down the I/O Compensation Cell.
|
||||||
|
* @note The I/O compensation cell can be used only when the device supply
|
||||||
|
* voltage ranges from 2.4 to 3.6 V.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_DisableCompensationCell(void)
|
||||||
|
{
|
||||||
|
SYSCFG->CMPCR &= (uint32_t)~((uint32_t)SYSCFG_CMPCR_CMP_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the FMC Memory Mapping Swapping.
|
||||||
|
*
|
||||||
|
* @note SDRAM is accessible at 0x60000000
|
||||||
|
* and NOR/RAM is accessible at 0xC0000000
|
||||||
|
*
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_EnableFMCMemorySwapping(void)
|
||||||
|
{
|
||||||
|
SYSCFG->MEMRMP |= SYSCFG_MEMRMP_SWP_FMC_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disables the FMC Memory Mapping Swapping
|
||||||
|
*
|
||||||
|
* @note SDRAM is accessible at 0xC0000000 (default mapping)
|
||||||
|
* and NOR/RAM is accessible at 0x60000000 (default mapping)
|
||||||
|
*
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_DisableFMCMemorySwapping(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
SYSCFG->MEMRMP &= (uint32_t)~((uint32_t)SYSCFG_MEMRMP_SWP_FMC);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
|
||||||
|
/**
|
||||||
|
* @brief Enable the Internal FLASH Bank Swapping.
|
||||||
|
*
|
||||||
|
* @note This function can be used only for STM32F77xx/STM32F76xx devices.
|
||||||
|
*
|
||||||
|
* @note Flash Bank2 mapped at 0x08000000 (AXI) (aliased at 0x00200000 (TCM))
|
||||||
|
* and Flash Bank1 mapped at 0x08100000 (AXI) (aliased at 0x00300000 (TCM))
|
||||||
|
*
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_EnableMemorySwappingBank(void)
|
||||||
|
{
|
||||||
|
SET_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_SWP_FB);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the Internal FLASH Bank Swapping.
|
||||||
|
*
|
||||||
|
* @note This function can be used only for STM32F77xx/STM32F76xx devices.
|
||||||
|
*
|
||||||
|
* @note The default state : Flash Bank1 mapped at 0x08000000 (AXI) (aliased at 0x00200000 (TCM))
|
||||||
|
* and Flash Bank2 mapped at 0x08100000 (AXI)( aliased at 0x00300000 (TCM))
|
||||||
|
*
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_DisableMemorySwappingBank(void)
|
||||||
|
{
|
||||||
|
CLEAR_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_SWP_FB);
|
||||||
|
}
|
||||||
|
#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -0,0 +1,276 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f7xx_hal.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief This file contains all the functions prototypes for the HAL
|
||||||
|
* module driver.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32F7xx_HAL_H
|
||||||
|
#define __STM32F7xx_HAL_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f7xx_hal_conf.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F7xx_HAL_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup HAL
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/** @defgroup HAL_Exported_Constants HAL Exported Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup HAL_TICK_FREQ Tick Frequency
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
HAL_TICK_FREQ_10HZ = 100U,
|
||||||
|
HAL_TICK_FREQ_100HZ = 10U,
|
||||||
|
HAL_TICK_FREQ_1KHZ = 1U,
|
||||||
|
HAL_TICK_FREQ_DEFAULT = HAL_TICK_FREQ_1KHZ
|
||||||
|
} HAL_TickFreqTypeDef;
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup SYSCFG_BootMode Boot Mode
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SYSCFG_MEM_BOOT_ADD0 ((uint32_t)0x00000000U)
|
||||||
|
#define SYSCFG_MEM_BOOT_ADD1 SYSCFG_MEMRMP_MEM_BOOT
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/** @defgroup HAL_Exported_Macros HAL Exported Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @brief Freeze/Unfreeze Peripherals in Debug mode
|
||||||
|
*/
|
||||||
|
#define __HAL_DBGMCU_FREEZE_TIM2() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM2_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_TIM3() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM3_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_TIM4() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM4_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_TIM5() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM5_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_TIM6() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM6_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_TIM7() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM7_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_TIM12() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM12_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_TIM13() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM13_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_TIM14() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM14_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_LPTIM1() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_LPTIM1_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_RTC() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_RTC_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_WWDG() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_WWDG_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_IWDG() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_IWDG_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_I2C1_TIMEOUT() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_I2C2_TIMEOUT() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_I2C2_SMBUS_TIMEOUT))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_I2C3_TIMEOUT() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_I2C3_SMBUS_TIMEOUT))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_I2C4_TIMEOUT() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_I2C4_SMBUS_TIMEOUT))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_CAN1() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_CAN1_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_CAN2() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_CAN2_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_TIM1() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM1_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_TIM8() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM8_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_TIM9() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM9_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_TIM10() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM10_STOP))
|
||||||
|
#define __HAL_DBGMCU_FREEZE_TIM11() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM11_STOP))
|
||||||
|
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_TIM2() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM2_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_TIM3() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM3_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_TIM4() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM4_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_TIM5() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM5_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_TIM6() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM6_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_TIM7() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM7_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_TIM12() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM12_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_TIM13() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM13_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_TIM14() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM14_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_LPTIM1() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_LPTIM1_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_RTC() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_RTC_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_WWDG() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_WWDG_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_IWDG() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_IWDG_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_I2C1_TIMEOUT() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_I2C2_TIMEOUT() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_I2C2_SMBUS_TIMEOUT))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_I2C3_TIMEOUT() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_I2C3_SMBUS_TIMEOUT))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_I2C4_TIMEOUT() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_I2C4_SMBUS_TIMEOUT))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_CAN1() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_CAN1_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_CAN2() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_CAN2_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_TIM1() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM1_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_TIM8() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM8_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_TIM9() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM9_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_TIM10() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM10_STOP))
|
||||||
|
#define __HAL_DBGMCU_UNFREEZE_TIM11() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM11_STOP))
|
||||||
|
|
||||||
|
|
||||||
|
/** @brief FMC (NOR/RAM) mapped at 0x60000000 and SDRAM mapped at 0xC0000000
|
||||||
|
*/
|
||||||
|
#define __HAL_SYSCFG_REMAPMEMORY_FMC() (SYSCFG->MEMRMP &= ~(SYSCFG_MEMRMP_SWP_FMC))
|
||||||
|
|
||||||
|
|
||||||
|
/** @brief FMC/SDRAM mapped at 0x60000000 (NOR/RAM) mapped at 0xC0000000
|
||||||
|
*/
|
||||||
|
#define __HAL_SYSCFG_REMAPMEMORY_FMC_SDRAM() do {SYSCFG->MEMRMP &= ~(SYSCFG_MEMRMP_SWP_FMC);\
|
||||||
|
SYSCFG->MEMRMP |= (SYSCFG_MEMRMP_SWP_FMC_0);\
|
||||||
|
}while(0);
|
||||||
|
/**
|
||||||
|
* @brief Return the memory boot mapping as configured by user.
|
||||||
|
* @retval The boot mode as configured by user. The returned value can be one
|
||||||
|
* of the following values:
|
||||||
|
* @arg @ref SYSCFG_MEM_BOOT_ADD0
|
||||||
|
* @arg @ref SYSCFG_MEM_BOOT_ADD1
|
||||||
|
*/
|
||||||
|
#define __HAL_SYSCFG_GET_BOOT_MODE() READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_MEM_BOOT)
|
||||||
|
|
||||||
|
#if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
|
||||||
|
/** @brief SYSCFG Break Cortex-M7 Lockup lock.
|
||||||
|
* Enable and lock the connection of Cortex-M7 LOCKUP (Hardfault) output to TIM1/8 Break input.
|
||||||
|
* @note The selected configuration is locked and can be unlocked only by system reset.
|
||||||
|
*/
|
||||||
|
#define __HAL_SYSCFG_BREAK_LOCKUP_LOCK() SET_BIT(SYSCFG->CBR, SYSCFG_CBR_CLL)
|
||||||
|
|
||||||
|
/** @brief SYSCFG Break PVD lock.
|
||||||
|
* Enable and lock the PVD connection to Timer1/8 Break input, as well as the PVDE and PLS[2:0] in the PWR_CR1 register.
|
||||||
|
* @note The selected configuration is locked and can be unlocked only by system reset.
|
||||||
|
*/
|
||||||
|
#define __HAL_SYSCFG_BREAK_PVD_LOCK() SET_BIT(SYSCFG->CBR, SYSCFG_CBR_PVDL)
|
||||||
|
#endif /* STM32F765xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup HAL_Private_Macros HAL Private Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define IS_TICKFREQ(FREQ) (((FREQ) == HAL_TICK_FREQ_10HZ) || \
|
||||||
|
((FREQ) == HAL_TICK_FREQ_100HZ) || \
|
||||||
|
((FREQ) == HAL_TICK_FREQ_1KHZ))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
/** @addtogroup HAL_Exported_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/** @addtogroup HAL_Exported_Functions_Group1
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* Initialization and Configuration functions ******************************/
|
||||||
|
HAL_StatusTypeDef HAL_Init(void);
|
||||||
|
HAL_StatusTypeDef HAL_DeInit(void);
|
||||||
|
void HAL_MspInit(void);
|
||||||
|
void HAL_MspDeInit(void);
|
||||||
|
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority);
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported variables ---------------------------------------------------------*/
|
||||||
|
/** @addtogroup HAL_Exported_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
extern __IO uint32_t uwTick;
|
||||||
|
extern uint32_t uwTickPrio;
|
||||||
|
extern HAL_TickFreqTypeDef uwTickFreq;
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup HAL_Exported_Functions_Group2
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* Peripheral Control functions ************************************************/
|
||||||
|
void HAL_IncTick(void);
|
||||||
|
void HAL_Delay(uint32_t Delay);
|
||||||
|
uint32_t HAL_GetTick(void);
|
||||||
|
uint32_t HAL_GetTickPrio(void);
|
||||||
|
HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq);
|
||||||
|
HAL_TickFreqTypeDef HAL_GetTickFreq(void);
|
||||||
|
void HAL_SuspendTick(void);
|
||||||
|
void HAL_ResumeTick(void);
|
||||||
|
uint32_t HAL_GetHalVersion(void);
|
||||||
|
uint32_t HAL_GetREVID(void);
|
||||||
|
uint32_t HAL_GetDEVID(void);
|
||||||
|
uint32_t HAL_GetUIDw0(void);
|
||||||
|
uint32_t HAL_GetUIDw1(void);
|
||||||
|
uint32_t HAL_GetUIDw2(void);
|
||||||
|
void HAL_DBGMCU_EnableDBGSleepMode(void);
|
||||||
|
void HAL_DBGMCU_DisableDBGSleepMode(void);
|
||||||
|
void HAL_DBGMCU_EnableDBGStopMode(void);
|
||||||
|
void HAL_DBGMCU_DisableDBGStopMode(void);
|
||||||
|
void HAL_DBGMCU_EnableDBGStandbyMode(void);
|
||||||
|
void HAL_DBGMCU_DisableDBGStandbyMode(void);
|
||||||
|
void HAL_EnableCompensationCell(void);
|
||||||
|
void HAL_DisableCompensationCell(void);
|
||||||
|
void HAL_EnableFMCMemorySwapping(void);
|
||||||
|
void HAL_DisableFMCMemorySwapping(void);
|
||||||
|
#if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
|
||||||
|
void HAL_EnableMemorySwappingBank(void);
|
||||||
|
void HAL_DisableMemorySwappingBank(void);
|
||||||
|
#endif /* STM32F765xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
/* Private types -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/** @defgroup HAL_Private_Variables HAL Private Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
/* Private constants ---------------------------------------------------------*/
|
||||||
|
/** @defgroup HAL_Private_Constants HAL Private Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
/* Private macros ------------------------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __STM32F7xx_HAL_H */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -0,0 +1,305 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define HAL_ETH_MODULE_ENABLED
|
||||||
|
#define HAL_RCC_MODULE_ENABLED
|
||||||
|
#define HAL_CORTEX_MODULE_ENABLED
|
||||||
|
#define HAL_GPIO_MODULE_ENABLED
|
||||||
|
|
||||||
|
#include "stm32f7xx.h"
|
||||||
|
#include "stm32f7xx_hal_cortex.h"
|
||||||
|
#include "stm32f7xx_hal_def.h"
|
||||||
|
#include "stm32f7xx_hal_rcc.h"
|
||||||
|
#include "stm32f7xx_hal_gpio.h"
|
||||||
|
|
||||||
|
#define UID_BASE 0x1FF0F420UL
|
||||||
|
#define __HAL_FLASH_ART_ENABLE() SET_BIT(FLASH->ACR, FLASH_ACR_ARTEN)
|
||||||
|
#define __HAL_FLASH_PREFETCH_BUFFER_ENABLE() (FLASH->ACR |= FLASH_ACR_PRFTEN)
|
||||||
|
|
||||||
|
#define assert_param(expr) ((void) 0U)
|
||||||
|
|
||||||
|
#define HAL_MODULE_ENABLED
|
||||||
|
#define HAL_ADC_MODULE_ENABLED
|
||||||
|
#define HAL_CAN_MODULE_ENABLED
|
||||||
|
#define HAL_CEC_MODULE_ENABLED
|
||||||
|
#define HAL_CRC_MODULE_ENABLED
|
||||||
|
#define HAL_CRYP_MODULE_ENABLED
|
||||||
|
#define HAL_DAC_MODULE_ENABLED
|
||||||
|
#define HAL_DCMI_MODULE_ENABLED
|
||||||
|
#define HAL_DMA_MODULE_ENABLED
|
||||||
|
#define HAL_DMA2D_MODULE_ENABLED
|
||||||
|
#define HAL_ETH_MODULE_ENABLED
|
||||||
|
#define HAL_FLASH_MODULE_ENABLED
|
||||||
|
//#define HAL_NAND_MODULE_ENABLED
|
||||||
|
#define HAL_NOR_MODULE_ENABLED
|
||||||
|
#define HAL_SRAM_MODULE_ENABLED
|
||||||
|
#define HAL_SDRAM_MODULE_ENABLED
|
||||||
|
#define HAL_HASH_MODULE_ENABLED
|
||||||
|
#define HAL_GPIO_MODULE_ENABLED
|
||||||
|
#define HAL_I2C_MODULE_ENABLED
|
||||||
|
//#define HAL_I2S_MODULE_ENABLED
|
||||||
|
//#define HAL_IWDG_MODULE_ENABLED
|
||||||
|
#define HAL_LPTIM_MODULE_ENABLED
|
||||||
|
#define HAL_LTDC_MODULE_ENABLED
|
||||||
|
#define HAL_PWR_MODULE_ENABLED
|
||||||
|
#define HAL_QSPI_MODULE_ENABLED
|
||||||
|
#define HAL_RCC_MODULE_ENABLED
|
||||||
|
#define HAL_RNG_MODULE_ENABLED
|
||||||
|
#define HAL_RTC_MODULE_ENABLED
|
||||||
|
//#define HAL_SAI_MODULE_ENABLED
|
||||||
|
#define HAL_SD_MODULE_ENABLED
|
||||||
|
#define HAL_SPI_MODULE_ENABLED
|
||||||
|
#define HAL_TIM_MODULE_ENABLED
|
||||||
|
#define HAL_UART_MODULE_ENABLED
|
||||||
|
#define HAL_USART_MODULE_ENABLED
|
||||||
|
#define HAL_IRDA_MODULE_ENABLED
|
||||||
|
#define HAL_SMARTCARD_MODULE_ENABLED
|
||||||
|
//#define HAL_WWDG_MODULE_ENABLED
|
||||||
|
#define HAL_CORTEX_MODULE_ENABLED
|
||||||
|
//#define HAL_PCD_MODULE_ENABLED
|
||||||
|
//#define HAL_HCD_MODULE_ENABLED
|
||||||
|
|
||||||
|
/* ########################## HSE/HSI Values adaptation ##################### */
|
||||||
|
/**
|
||||||
|
* @brief Adjust the value of External High Speed oscillator (HSE) used in your
|
||||||
|
* application. This value is used by the RCC HAL module to compute the system
|
||||||
|
* frequency (when HSE is used as system clock source, directly or through the
|
||||||
|
* PLL).
|
||||||
|
*/
|
||||||
|
#if !defined(HSE_VALUE)
|
||||||
|
#define HSE_VALUE \
|
||||||
|
((uint32_t) 25000000) /*!< Value of the External oscillator in Hz */
|
||||||
|
#endif /* HSE_VALUE */
|
||||||
|
|
||||||
|
#if !defined(HSE_STARTUP_TIMEOUT)
|
||||||
|
#define HSE_STARTUP_TIMEOUT \
|
||||||
|
((uint32_t) 5000) /*!< Time out for HSE start up, in ms */
|
||||||
|
#endif /* HSE_STARTUP_TIMEOUT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Internal High Speed oscillator (HSI) value.
|
||||||
|
* This value is used by the RCC HAL module to compute the system
|
||||||
|
* frequency (when HSI is used as system clock source, directly or through the
|
||||||
|
* PLL).
|
||||||
|
*/
|
||||||
|
#if !defined(HSI_VALUE)
|
||||||
|
#define HSI_VALUE \
|
||||||
|
((uint32_t) 16000000) /*!< Value of the Internal oscillator in Hz*/
|
||||||
|
#endif /* HSI_VALUE */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Internal Low Speed oscillator (LSI) value.
|
||||||
|
*/
|
||||||
|
#if !defined(LSI_VALUE)
|
||||||
|
#define LSI_VALUE ((uint32_t) 40000)
|
||||||
|
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz \
|
||||||
|
The real value may vary depending on the variations \
|
||||||
|
in voltage and temperature. */
|
||||||
|
/**
|
||||||
|
* @brief External Low Speed oscillator (LSE) value.
|
||||||
|
*/
|
||||||
|
#if !defined(LSE_VALUE)
|
||||||
|
#define LSE_VALUE \
|
||||||
|
((uint32_t) 32768) /*!< Value of the External Low Speed oscillator in Hz */
|
||||||
|
#endif /* LSE_VALUE */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief External clock source for I2S peripheral
|
||||||
|
* This value is used by the I2S HAL module to compute the I2S clock
|
||||||
|
* source frequency, this source is inserted directly through I2S_CKIN pad.
|
||||||
|
*/
|
||||||
|
#if !defined(EXTERNAL_CLOCK_VALUE)
|
||||||
|
#define EXTERNAL_CLOCK_VALUE \
|
||||||
|
((uint32_t) 12288000) /*!< Value of the Internal oscillator in Hz*/
|
||||||
|
#endif /* EXTERNAL_CLOCK_VALUE */
|
||||||
|
|
||||||
|
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||||
|
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||||
|
|
||||||
|
/* ########################### System Configuration ######################### */
|
||||||
|
/**
|
||||||
|
* @brief This is the HAL system configuration section
|
||||||
|
*/
|
||||||
|
#define VDD_VALUE ((uint32_t) 3300) /*!< Value of VDD in mv */
|
||||||
|
#define TICK_INT_PRIORITY ((uint32_t) 0x0F) /*!< tick interrupt priority */
|
||||||
|
#define USE_RTOS 0
|
||||||
|
#define ART_ACCLERATOR_ENABLE 1 /* To enable instruction cache and prefetch */
|
||||||
|
|
||||||
|
/* ########################## Assert Selection ############################## */
|
||||||
|
/**
|
||||||
|
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||||
|
* HAL drivers code
|
||||||
|
*/
|
||||||
|
/* #define USE_FULL_ASSERT 1 */
|
||||||
|
|
||||||
|
/* ################## Ethernet peripheral configuration ##################### */
|
||||||
|
|
||||||
|
/* Section 1 : Ethernet peripheral configuration */
|
||||||
|
|
||||||
|
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
|
||||||
|
#define MAC_ADDR0 2
|
||||||
|
#define MAC_ADDR1 0
|
||||||
|
#define MAC_ADDR2 0
|
||||||
|
#define MAC_ADDR3 0
|
||||||
|
#define MAC_ADDR4 0
|
||||||
|
#define MAC_ADDR5 0
|
||||||
|
|
||||||
|
/* Definition of the Ethernet driver buffers size and count */
|
||||||
|
#define ETH_RX_BUF_SIZE \
|
||||||
|
ETH_MAX_PACKET_SIZE /* buffer size for receive */
|
||||||
|
#define ETH_TX_BUF_SIZE \
|
||||||
|
ETH_MAX_PACKET_SIZE /* buffer size for transmit */
|
||||||
|
#define ETH_RXBUFNB ((uint32_t) 8) /* 8 Rx buffers of size ETH_RX_BUF_SIZE */
|
||||||
|
#define ETH_TXBUFNB ((uint32_t) 4) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
|
||||||
|
|
||||||
|
/* Section 2: PHY configuration section */
|
||||||
|
|
||||||
|
/* DP83848 PHY Address*/
|
||||||
|
#define DP83848_PHY_ADDRESS 0x01
|
||||||
|
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
|
||||||
|
#define PHY_RESET_DELAY ((uint32_t) 0x000000FF)
|
||||||
|
/* PHY Configuration delay */
|
||||||
|
#define PHY_CONFIG_DELAY ((uint32_t) 0x00000FFF)
|
||||||
|
|
||||||
|
#define PHY_READ_TO ((uint32_t) 0x0000FFFF)
|
||||||
|
#define PHY_WRITE_TO ((uint32_t) 0x0000FFFF)
|
||||||
|
|
||||||
|
/* Section 3: Common PHY Registers */
|
||||||
|
|
||||||
|
#define PHY_BCR ((uint16_t) 0x00) /*!< Transceiver Basic Control Register */
|
||||||
|
#define PHY_BSR ((uint16_t) 0x01) /*!< Transceiver Basic Status Register */
|
||||||
|
|
||||||
|
#define PHY_RESET ((uint16_t) 0x8000) /*!< PHY Reset */
|
||||||
|
#define PHY_LOOPBACK ((uint16_t) 0x4000) /*!< Select loop-back mode */
|
||||||
|
#define PHY_FULLDUPLEX_100M \
|
||||||
|
((uint16_t) 0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
|
||||||
|
#define PHY_HALFDUPLEX_100M \
|
||||||
|
((uint16_t) 0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
|
||||||
|
#define PHY_FULLDUPLEX_10M \
|
||||||
|
((uint16_t) 0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
|
||||||
|
#define PHY_HALFDUPLEX_10M \
|
||||||
|
((uint16_t) 0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
|
||||||
|
#define PHY_AUTONEGOTIATION \
|
||||||
|
((uint16_t) 0x1000) /*!< Enable auto-negotiation function */
|
||||||
|
#define PHY_RESTART_AUTONEGOTIATION \
|
||||||
|
((uint16_t) 0x0200) /*!< Restart auto-negotiation function */
|
||||||
|
#define PHY_POWERDOWN \
|
||||||
|
((uint16_t) 0x0800) /*!< Select the power down mode */
|
||||||
|
#define PHY_ISOLATE \
|
||||||
|
((uint16_t) 0x0400) /*!< Isolate PHY from MII */
|
||||||
|
|
||||||
|
#define PHY_AUTONEGO_COMPLETE \
|
||||||
|
((uint16_t) 0x0020) /*!< Auto-Negotiation process completed */
|
||||||
|
#define PHY_LINKED_STATUS \
|
||||||
|
((uint16_t) 0x0004) /*!< Valid link established */
|
||||||
|
#define PHY_JABBER_DETECTION \
|
||||||
|
((uint16_t) 0x0002) /*!< Jabber condition detected */
|
||||||
|
|
||||||
|
/* Section 4: Extended PHY Registers */
|
||||||
|
|
||||||
|
#define PHY_SR \
|
||||||
|
((uint16_t) 0x10) /*!< PHY status register Offset */
|
||||||
|
#define PHY_MICR \
|
||||||
|
((uint16_t) 0x11) /*!< MII Interrupt Control Register */
|
||||||
|
#define PHY_MISR \
|
||||||
|
((uint16_t) 0x12) /*!< MII Interrupt Status and Misc. Control Register */
|
||||||
|
|
||||||
|
#define PHY_LINK_STATUS \
|
||||||
|
((uint16_t) 0x0001) /*!< PHY Link mask */
|
||||||
|
#define PHY_SPEED_STATUS \
|
||||||
|
((uint16_t) 0x0002) /*!< PHY Speed mask */
|
||||||
|
#define PHY_DUPLEX_STATUS \
|
||||||
|
((uint16_t) 0x0004) /*!< PHY Duplex mask */
|
||||||
|
|
||||||
|
#define PHY_MICR_INT_EN \
|
||||||
|
((uint16_t) 0x0002) /*!< PHY Enable interrupts */
|
||||||
|
#define PHY_MICR_INT_OE \
|
||||||
|
((uint16_t) 0x0001) /*!< PHY Enable output interrupt events */
|
||||||
|
|
||||||
|
#define PHY_MISR_LINK_INT_EN \
|
||||||
|
((uint16_t) 0x0020) /*!< Enable Interrupt on change of link status */
|
||||||
|
#define PHY_LINK_INTERRUPT \
|
||||||
|
((uint16_t) 0x2000) /*!< PHY link status interrupt mask */
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define HAL_ETH_MODULE_ENABLED
|
||||||
|
#define HAL_RCC_MODULE_ENABLED
|
||||||
|
#define HAL_CORTEX_MODULE_ENABLED
|
||||||
|
#define HAL_GPIO_MODULE_ENABLED
|
||||||
|
|
||||||
|
#include "stm32f7xx.h"
|
||||||
|
#include "stm32f7xx_hal_cortex.h"
|
||||||
|
#include "stm32f7xx_hal_def.h"
|
||||||
|
#include "stm32f7xx_hal_rcc.h"
|
||||||
|
|
||||||
|
#define UID_BASE 0x1FF0F420UL
|
||||||
|
#define __HAL_FLASH_ART_ENABLE() SET_BIT(FLASH->ACR, FLASH_ACR_ARTEN)
|
||||||
|
#define __HAL_FLASH_PREFETCH_BUFFER_ENABLE() (FLASH->ACR |= FLASH_ACR_PRFTEN)
|
||||||
|
|
||||||
|
#define ETH_RXBUFNB 3
|
||||||
|
#define ETH_TXBUFNB 2
|
||||||
|
#define ETH_RX_BUF_SIZE (ipconfigNETWORK_MTU + 36)
|
||||||
|
#define ETH_TX_BUF_SIZE (ipconfigNETWORK_MTU + 36)
|
||||||
|
|
||||||
|
#define assert_param(expr) ((void) 0U)
|
||||||
|
|
||||||
|
#define LAN8742A_PHY_ADDRESS 0x00
|
||||||
|
#define PHY_RESET_DELAY ((uint32_t)0x00000FFF)
|
||||||
|
#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF)
|
||||||
|
#define PHY_READ_TO ((uint32_t)0x0000FFFF)
|
||||||
|
#define PHY_WRITE_TO ((uint32_t)0x0000FFFF)
|
||||||
|
#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */
|
||||||
|
#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */
|
||||||
|
#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */
|
||||||
|
#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */
|
||||||
|
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
|
||||||
|
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
|
||||||
|
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
|
||||||
|
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
|
||||||
|
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
|
||||||
|
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
|
||||||
|
#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */
|
||||||
|
#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */
|
||||||
|
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
|
||||||
|
#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */
|
||||||
|
#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */
|
||||||
|
#define PHY_SR ((uint16_t)0x1F) /*!< PHY special control/ status register Offset */
|
||||||
|
#define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< PHY Speed mask */
|
||||||
|
#define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< PHY Duplex mask */
|
||||||
|
#define PHY_ISFR ((uint16_t)0x1D) /*!< PHY Interrupt Source Flag register Offset */
|
||||||
|
#define PHY_ISFR_INT4 ((uint16_t)0x0010) /*!< PHY Link down inturrupt */
|
||||||
|
|
||||||
|
#if !defined(HSE_VALUE)
|
||||||
|
#define HSE_VALUE \
|
||||||
|
((uint32_t) 8000000U) /*!< Value of the External oscillator in Hz */
|
||||||
|
#endif /* HSE_VALUE */
|
||||||
|
#if !defined(HSE_STARTUP_TIMEOUT)
|
||||||
|
#define HSE_STARTUP_TIMEOUT \
|
||||||
|
((uint32_t) 100U) /*!< Time out for HSE start up, in ms */
|
||||||
|
#endif /* HSE_STARTUP_TIMEOUT */
|
||||||
|
#if !defined(HSI_VALUE)
|
||||||
|
#define HSI_VALUE \
|
||||||
|
((uint32_t) 16000000U) /*!< Value of the Internal oscillator in Hz*/
|
||||||
|
#endif /* HSI_VALUE */
|
||||||
|
#if !defined(LSI_VALUE)
|
||||||
|
#define LSI_VALUE ((uint32_t) 32000U) /*!< LSI Typical Value in Hz*/
|
||||||
|
#endif
|
||||||
|
#if !defined(LSE_VALUE)
|
||||||
|
#define LSE_VALUE \
|
||||||
|
((uint32_t) 32768U) /*!< Value of the External Low Speed oscillator in Hz */
|
||||||
|
#endif /* LSE_VALUE */
|
||||||
|
#if !defined(LSE_STARTUP_TIMEOUT)
|
||||||
|
#define LSE_STARTUP_TIMEOUT \
|
||||||
|
((uint32_t) 5000U) /*!< Time out for LSE start up, in ms */
|
||||||
|
#endif /* LSE_STARTUP_TIMEOUT */
|
||||||
|
#if !defined(EXTERNAL_CLOCK_VALUE)
|
||||||
|
#define EXTERNAL_CLOCK_VALUE \
|
||||||
|
((uint32_t) 12288000U) /*!< Value of the Internal oscillator in Hz*/
|
||||||
|
#endif /* EXTERNAL_CLOCK_VALUE */
|
||||||
|
#define VDD_VALUE ((uint32_t) 3300U) /*!< Value of VDD in mv */
|
||||||
|
#define TICK_INT_PRIORITY ((uint32_t) 0x0FU) /*!< tick interrupt priority */
|
||||||
|
#define USE_RTOS 0U
|
||||||
|
#define PREFETCH_ENABLE 1U
|
||||||
|
#define ART_ACCLERATOR_ENABLE 1U /* To enable instruction cache and prefetch \
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,505 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f7xx_hal_cortex.c
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief CORTEX HAL module driver.
|
||||||
|
* This file provides firmware functions to manage the following
|
||||||
|
* functionalities of the CORTEX:
|
||||||
|
* + Initialization and de-initialization functions
|
||||||
|
* + Peripheral Control functions
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
==============================================================================
|
||||||
|
##### How to use this driver #####
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
[..]
|
||||||
|
*** How to configure Interrupts using CORTEX HAL driver ***
|
||||||
|
===========================================================
|
||||||
|
[..]
|
||||||
|
This section provides functions allowing to configure the NVIC interrupts (IRQ).
|
||||||
|
The Cortex-M4 exceptions are managed by CMSIS functions.
|
||||||
|
|
||||||
|
(#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping()
|
||||||
|
function according to the following table.
|
||||||
|
(#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority().
|
||||||
|
(#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ().
|
||||||
|
(#) please refer to programming manual for details in how to configure priority.
|
||||||
|
|
||||||
|
-@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ preemption is no more possible.
|
||||||
|
The pending IRQ priority will be managed only by the sub priority.
|
||||||
|
|
||||||
|
-@- IRQ priority order (sorted by highest to lowest priority):
|
||||||
|
(+@) Lowest preemption priority
|
||||||
|
(+@) Lowest sub priority
|
||||||
|
(+@) Lowest hardware priority (IRQ number)
|
||||||
|
|
||||||
|
[..]
|
||||||
|
*** How to configure Systick using CORTEX HAL driver ***
|
||||||
|
========================================================
|
||||||
|
[..]
|
||||||
|
Setup SysTick Timer for time base.
|
||||||
|
|
||||||
|
(+) The HAL_SYSTICK_Config() function calls the SysTick_Config() function which
|
||||||
|
is a CMSIS function that:
|
||||||
|
(++) Configures the SysTick Reload register with value passed as function parameter.
|
||||||
|
(++) Configures the SysTick IRQ priority to the lowest value (0x0F).
|
||||||
|
(++) Resets the SysTick Counter register.
|
||||||
|
(++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK).
|
||||||
|
(++) Enables the SysTick Interrupt.
|
||||||
|
(++) Starts the SysTick Counter.
|
||||||
|
|
||||||
|
(+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro
|
||||||
|
__HAL_CORTEX_SYSTICKCLK_CONFIG(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
|
||||||
|
HAL_SYSTICK_Config() function call. The __HAL_CORTEX_SYSTICKCLK_CONFIG() macro is defined
|
||||||
|
inside the stm32f7xx_hal_cortex.h file.
|
||||||
|
|
||||||
|
(+) You can change the SysTick IRQ priority by calling the
|
||||||
|
HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function
|
||||||
|
call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function.
|
||||||
|
|
||||||
|
(+) To adjust the SysTick time base, use the following formula:
|
||||||
|
|
||||||
|
Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s)
|
||||||
|
(++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function
|
||||||
|
(++) Reload Value should not exceed 0xFFFFFF
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f7xx_hal.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F7xx_HAL_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CORTEX CORTEX
|
||||||
|
* @brief CORTEX HAL module driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||||
|
|
||||||
|
/* Private types -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* Private constants ---------------------------------------------------------*/
|
||||||
|
/* Private macros ------------------------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||||
|
* @brief Initialization and Configuration functions
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
==============================================================================
|
||||||
|
##### Initialization and de-initialization functions #####
|
||||||
|
==============================================================================
|
||||||
|
[..]
|
||||||
|
This section provides the CORTEX HAL driver functions allowing to configure Interrupts
|
||||||
|
Systick functionalities
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the priority grouping field (preemption priority and subpriority)
|
||||||
|
* using the required unlock sequence.
|
||||||
|
* @param PriorityGroup The priority grouping bits length.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
|
||||||
|
* 4 bits for subpriority
|
||||||
|
* @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
|
||||||
|
* 3 bits for subpriority
|
||||||
|
* @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
|
||||||
|
* 2 bits for subpriority
|
||||||
|
* @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
|
||||||
|
* 1 bits for subpriority
|
||||||
|
* @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
|
||||||
|
* 0 bits for subpriority
|
||||||
|
* @note When the NVIC_PriorityGroup_0 is selected, IRQ preemption is no more possible.
|
||||||
|
* The pending IRQ priority will be managed only by the subpriority.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
|
||||||
|
|
||||||
|
/* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
|
||||||
|
NVIC_SetPriorityGrouping(PriorityGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the priority of an interrupt.
|
||||||
|
* @param IRQn External interrupt number.
|
||||||
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h))
|
||||||
|
* @param PreemptPriority The preemption priority for the IRQn channel.
|
||||||
|
* This parameter can be a value between 0 and 15
|
||||||
|
* A lower priority value indicates a higher priority
|
||||||
|
* @param SubPriority the subpriority level for the IRQ channel.
|
||||||
|
* This parameter can be a value between 0 and 15
|
||||||
|
* A lower priority value indicates a higher priority.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
|
||||||
|
{
|
||||||
|
uint32_t prioritygroup = 0x00;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
|
||||||
|
assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
|
||||||
|
|
||||||
|
prioritygroup = NVIC_GetPriorityGrouping();
|
||||||
|
|
||||||
|
NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables a device specific interrupt in the NVIC interrupt controller.
|
||||||
|
* @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
|
||||||
|
* function should be called before.
|
||||||
|
* @param IRQn External interrupt number.
|
||||||
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h))
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||||
|
|
||||||
|
/* Enable interrupt */
|
||||||
|
NVIC_EnableIRQ(IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disables a device specific interrupt in the NVIC interrupt controller.
|
||||||
|
* @param IRQn External interrupt number.
|
||||||
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h))
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||||
|
|
||||||
|
/* Disable interrupt */
|
||||||
|
NVIC_DisableIRQ(IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initiates a system reset request to reset the MCU.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_NVIC_SystemReset(void)
|
||||||
|
{
|
||||||
|
/* System Reset */
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
||||||
|
* Counter is in free running mode to generate periodic interrupts.
|
||||||
|
* @param TicksNumb Specifies the ticks Number of ticks between two interrupts.
|
||||||
|
* @retval status: - 0 Function succeeded.
|
||||||
|
* - 1 Function failed.
|
||||||
|
*/
|
||||||
|
uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
|
||||||
|
{
|
||||||
|
return SysTick_Config(TicksNumb);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CORTEX_Exported_Functions_Group2 Peripheral Control functions
|
||||||
|
* @brief Cortex control functions
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
==============================================================================
|
||||||
|
##### Peripheral Control functions #####
|
||||||
|
==============================================================================
|
||||||
|
[..]
|
||||||
|
This subsection provides a set of functions allowing to control the CORTEX
|
||||||
|
(NVIC, SYSTICK, MPU) functionalities.
|
||||||
|
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (__MPU_PRESENT == 1)
|
||||||
|
/**
|
||||||
|
* @brief Disables the MPU
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_MPU_Disable(void)
|
||||||
|
{
|
||||||
|
/* Make sure outstanding transfers are done */
|
||||||
|
__DMB();
|
||||||
|
|
||||||
|
/* Disable fault exceptions */
|
||||||
|
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
|
||||||
|
|
||||||
|
/* Disable the MPU and clear the control register*/
|
||||||
|
MPU->CTRL = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables the MPU
|
||||||
|
* @param MPU_Control Specifies the control mode of the MPU during hard fault,
|
||||||
|
* NMI, FAULTMASK and privileged access to the default memory
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg MPU_HFNMI_PRIVDEF_NONE
|
||||||
|
* @arg MPU_HARDFAULT_NMI
|
||||||
|
* @arg MPU_PRIVILEGED_DEFAULT
|
||||||
|
* @arg MPU_HFNMI_PRIVDEF
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_MPU_Enable(uint32_t MPU_Control)
|
||||||
|
{
|
||||||
|
/* Enable the MPU */
|
||||||
|
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
|
||||||
|
|
||||||
|
/* Enable fault exceptions */
|
||||||
|
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
||||||
|
|
||||||
|
/* Ensure MPU setting take effects */
|
||||||
|
__DSB();
|
||||||
|
__ISB();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes and configures the Region and the memory to be protected.
|
||||||
|
* @param MPU_Init Pointer to a MPU_Region_InitTypeDef structure that contains
|
||||||
|
* the initialization and configuration information.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
|
||||||
|
assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));
|
||||||
|
|
||||||
|
/* Set the Region number */
|
||||||
|
MPU->RNR = MPU_Init->Number;
|
||||||
|
|
||||||
|
if ((MPU_Init->Enable) != RESET)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
|
||||||
|
assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
|
||||||
|
assert_param(IS_MPU_TEX_LEVEL(MPU_Init->TypeExtField));
|
||||||
|
assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_Init->IsShareable));
|
||||||
|
assert_param(IS_MPU_ACCESS_CACHEABLE(MPU_Init->IsCacheable));
|
||||||
|
assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
|
||||||
|
assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
|
||||||
|
assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
|
||||||
|
|
||||||
|
MPU->RBAR = MPU_Init->BaseAddress;
|
||||||
|
MPU->RASR = ((uint32_t)MPU_Init->DisableExec << MPU_RASR_XN_Pos) |
|
||||||
|
((uint32_t)MPU_Init->AccessPermission << MPU_RASR_AP_Pos) |
|
||||||
|
((uint32_t)MPU_Init->TypeExtField << MPU_RASR_TEX_Pos) |
|
||||||
|
((uint32_t)MPU_Init->IsShareable << MPU_RASR_S_Pos) |
|
||||||
|
((uint32_t)MPU_Init->IsCacheable << MPU_RASR_C_Pos) |
|
||||||
|
((uint32_t)MPU_Init->IsBufferable << MPU_RASR_B_Pos) |
|
||||||
|
((uint32_t)MPU_Init->SubRegionDisable << MPU_RASR_SRD_Pos) |
|
||||||
|
((uint32_t)MPU_Init->Size << MPU_RASR_SIZE_Pos) |
|
||||||
|
((uint32_t)MPU_Init->Enable << MPU_RASR_ENABLE_Pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MPU->RBAR = 0x00;
|
||||||
|
MPU->RASR = 0x00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* __MPU_PRESENT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the priority grouping field from the NVIC Interrupt Controller.
|
||||||
|
* @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field)
|
||||||
|
*/
|
||||||
|
uint32_t HAL_NVIC_GetPriorityGrouping(void)
|
||||||
|
{
|
||||||
|
/* Get the PRIGROUP[10:8] field value */
|
||||||
|
return NVIC_GetPriorityGrouping();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the priority of an interrupt.
|
||||||
|
* @param IRQn External interrupt number.
|
||||||
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h))
|
||||||
|
* @param PriorityGroup the priority grouping bits length.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
|
||||||
|
* 4 bits for subpriority
|
||||||
|
* @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
|
||||||
|
* 3 bits for subpriority
|
||||||
|
* @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
|
||||||
|
* 2 bits for subpriority
|
||||||
|
* @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
|
||||||
|
* 1 bits for subpriority
|
||||||
|
* @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
|
||||||
|
* 0 bits for subpriority
|
||||||
|
* @param pPreemptPriority Pointer on the Preemptive priority value (starting from 0).
|
||||||
|
* @param pSubPriority Pointer on the Subpriority value (starting from 0).
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *pPreemptPriority, uint32_t *pSubPriority)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
|
||||||
|
/* Get priority for Cortex-M system or device specific interrupts */
|
||||||
|
NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets Pending bit of an external interrupt.
|
||||||
|
* @param IRQn External interrupt number
|
||||||
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h))
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||||
|
|
||||||
|
/* Set interrupt pending */
|
||||||
|
NVIC_SetPendingIRQ(IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets Pending Interrupt (reads the pending register in the NVIC
|
||||||
|
* and returns the pending bit for the specified interrupt).
|
||||||
|
* @param IRQn External interrupt number.
|
||||||
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h))
|
||||||
|
* @retval status: - 0 Interrupt status is not pending.
|
||||||
|
* - 1 Interrupt status is pending.
|
||||||
|
*/
|
||||||
|
uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||||
|
|
||||||
|
/* Return 1 if pending else 0 */
|
||||||
|
return NVIC_GetPendingIRQ(IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears the pending bit of an external interrupt.
|
||||||
|
* @param IRQn External interrupt number.
|
||||||
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h))
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||||
|
|
||||||
|
/* Clear pending interrupt */
|
||||||
|
NVIC_ClearPendingIRQ(IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets active interrupt ( reads the active register in NVIC and returns the active bit).
|
||||||
|
* @param IRQn External interrupt number
|
||||||
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h))
|
||||||
|
* @retval status: - 0 Interrupt status is not pending.
|
||||||
|
* - 1 Interrupt status is pending.
|
||||||
|
*/
|
||||||
|
uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||||
|
|
||||||
|
/* Return 1 if active else 0 */
|
||||||
|
return NVIC_GetActive(IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configures the SysTick clock source.
|
||||||
|
* @param CLKSource specifies the SysTick clock source.
|
||||||
|
* This parameter can be one of the following values:
|
||||||
|
* @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
|
||||||
|
* @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
|
||||||
|
if (CLKSource == SYSTICK_CLKSOURCE_HCLK)
|
||||||
|
{
|
||||||
|
SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles SYSTICK interrupt request.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_SYSTICK_IRQHandler(void)
|
||||||
|
{
|
||||||
|
HAL_SYSTICK_Callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SYSTICK callback.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
__weak void HAL_SYSTICK_Callback(void)
|
||||||
|
{
|
||||||
|
/* NOTE : This function Should not be modified, when the callback is needed,
|
||||||
|
the HAL_SYSTICK_Callback could be implemented in the user file
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -0,0 +1,406 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f7xx_hal_cortex.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief Header file of CORTEX HAL module.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32F7xx_HAL_CORTEX_H
|
||||||
|
#define __STM32F7xx_HAL_CORTEX_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f7xx_hal_def.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F7xx_HAL_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup CORTEX
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
/** @defgroup CORTEX_Exported_Types Cortex Exported Types
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (__MPU_PRESENT == 1)
|
||||||
|
/** @defgroup CORTEX_MPU_Region_Initialization_Structure_definition MPU Region Initialization Structure Definition
|
||||||
|
* @brief MPU Region initialization structure
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t Enable; /*!< Specifies the status of the region.
|
||||||
|
This parameter can be a value of @ref CORTEX_MPU_Region_Enable */
|
||||||
|
uint8_t Number; /*!< Specifies the number of the region to protect.
|
||||||
|
This parameter can be a value of @ref CORTEX_MPU_Region_Number */
|
||||||
|
uint32_t BaseAddress; /*!< Specifies the base address of the region to protect. */
|
||||||
|
uint8_t Size; /*!< Specifies the size of the region to protect.
|
||||||
|
This parameter can be a value of @ref CORTEX_MPU_Region_Size */
|
||||||
|
uint8_t SubRegionDisable; /*!< Specifies the number of the subregion protection to disable.
|
||||||
|
This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF */
|
||||||
|
uint8_t TypeExtField; /*!< Specifies the TEX field level.
|
||||||
|
This parameter can be a value of @ref CORTEX_MPU_TEX_Levels */
|
||||||
|
uint8_t AccessPermission; /*!< Specifies the region access permission type.
|
||||||
|
This parameter can be a value of @ref CORTEX_MPU_Region_Permission_Attributes */
|
||||||
|
uint8_t DisableExec; /*!< Specifies the instruction access status.
|
||||||
|
This parameter can be a value of @ref CORTEX_MPU_Instruction_Access */
|
||||||
|
uint8_t IsShareable; /*!< Specifies the shareability status of the protected region.
|
||||||
|
This parameter can be a value of @ref CORTEX_MPU_Access_Shareable */
|
||||||
|
uint8_t IsCacheable; /*!< Specifies the cacheable status of the region protected.
|
||||||
|
This parameter can be a value of @ref CORTEX_MPU_Access_Cacheable */
|
||||||
|
uint8_t IsBufferable; /*!< Specifies the bufferable status of the protected region.
|
||||||
|
This parameter can be a value of @ref CORTEX_MPU_Access_Bufferable */
|
||||||
|
}MPU_Region_InitTypeDef;
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
#endif /* __MPU_PRESENT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/** @defgroup CORTEX_Exported_Constants CORTEX Exported Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CORTEX_Preemption_Priority_Group CORTEX Preemption Priority Group
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define NVIC_PRIORITYGROUP_0 ((uint32_t)0x00000007U) /*!< 0 bits for pre-emption priority
|
||||||
|
4 bits for subpriority */
|
||||||
|
#define NVIC_PRIORITYGROUP_1 ((uint32_t)0x00000006U) /*!< 1 bits for pre-emption priority
|
||||||
|
3 bits for subpriority */
|
||||||
|
#define NVIC_PRIORITYGROUP_2 ((uint32_t)0x00000005U) /*!< 2 bits for pre-emption priority
|
||||||
|
2 bits for subpriority */
|
||||||
|
#define NVIC_PRIORITYGROUP_3 ((uint32_t)0x00000004U) /*!< 3 bits for pre-emption priority
|
||||||
|
1 bits for subpriority */
|
||||||
|
#define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003U) /*!< 4 bits for pre-emption priority
|
||||||
|
0 bits for subpriority */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CORTEX_SysTick_clock_source CORTEX _SysTick clock source
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SYSTICK_CLKSOURCE_HCLK_DIV8 ((uint32_t)0x00000000U)
|
||||||
|
#define SYSTICK_CLKSOURCE_HCLK ((uint32_t)0x00000004U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (__MPU_PRESENT == 1)
|
||||||
|
/** @defgroup CORTEX_MPU_HFNMI_PRIVDEF_Control MPU HFNMI and PRIVILEGED Access control
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define MPU_HFNMI_PRIVDEF_NONE ((uint32_t)0x00000000U)
|
||||||
|
#define MPU_HARDFAULT_NMI ((uint32_t)0x00000002U)
|
||||||
|
#define MPU_PRIVILEGED_DEFAULT ((uint32_t)0x00000004U)
|
||||||
|
#define MPU_HFNMI_PRIVDEF ((uint32_t)0x00000006U)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CORTEX_MPU_Region_Enable CORTEX MPU Region Enable
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define MPU_REGION_ENABLE ((uint8_t)0x01U)
|
||||||
|
#define MPU_REGION_DISABLE ((uint8_t)0x00U)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CORTEX_MPU_Instruction_Access CORTEX MPU Instruction Access
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define MPU_INSTRUCTION_ACCESS_ENABLE ((uint8_t)0x00U)
|
||||||
|
#define MPU_INSTRUCTION_ACCESS_DISABLE ((uint8_t)0x01U)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CORTEX_MPU_Access_Shareable CORTEX MPU Instruction Access Shareable
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define MPU_ACCESS_SHAREABLE ((uint8_t)0x01U)
|
||||||
|
#define MPU_ACCESS_NOT_SHAREABLE ((uint8_t)0x00U)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CORTEX_MPU_Access_Cacheable CORTEX MPU Instruction Access Cacheable
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define MPU_ACCESS_CACHEABLE ((uint8_t)0x01U)
|
||||||
|
#define MPU_ACCESS_NOT_CACHEABLE ((uint8_t)0x00U)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CORTEX_MPU_Access_Bufferable CORTEX MPU Instruction Access Bufferable
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define MPU_ACCESS_BUFFERABLE ((uint8_t)0x01U)
|
||||||
|
#define MPU_ACCESS_NOT_BUFFERABLE ((uint8_t)0x00U)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CORTEX_MPU_TEX_Levels MPU TEX Levels
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define MPU_TEX_LEVEL0 ((uint8_t)0x00U)
|
||||||
|
#define MPU_TEX_LEVEL1 ((uint8_t)0x01U)
|
||||||
|
#define MPU_TEX_LEVEL2 ((uint8_t)0x02U)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CORTEX_MPU_Region_Size CORTEX MPU Region Size
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define MPU_REGION_SIZE_32B ((uint8_t)0x04U)
|
||||||
|
#define MPU_REGION_SIZE_64B ((uint8_t)0x05U)
|
||||||
|
#define MPU_REGION_SIZE_128B ((uint8_t)0x06U)
|
||||||
|
#define MPU_REGION_SIZE_256B ((uint8_t)0x07U)
|
||||||
|
#define MPU_REGION_SIZE_512B ((uint8_t)0x08U)
|
||||||
|
#define MPU_REGION_SIZE_1KB ((uint8_t)0x09U)
|
||||||
|
#define MPU_REGION_SIZE_2KB ((uint8_t)0x0AU)
|
||||||
|
#define MPU_REGION_SIZE_4KB ((uint8_t)0x0BU)
|
||||||
|
#define MPU_REGION_SIZE_8KB ((uint8_t)0x0CU)
|
||||||
|
#define MPU_REGION_SIZE_16KB ((uint8_t)0x0DU)
|
||||||
|
#define MPU_REGION_SIZE_32KB ((uint8_t)0x0EU)
|
||||||
|
#define MPU_REGION_SIZE_64KB ((uint8_t)0x0FU)
|
||||||
|
#define MPU_REGION_SIZE_128KB ((uint8_t)0x10U)
|
||||||
|
#define MPU_REGION_SIZE_256KB ((uint8_t)0x11U)
|
||||||
|
#define MPU_REGION_SIZE_512KB ((uint8_t)0x12U)
|
||||||
|
#define MPU_REGION_SIZE_1MB ((uint8_t)0x13U)
|
||||||
|
#define MPU_REGION_SIZE_2MB ((uint8_t)0x14U)
|
||||||
|
#define MPU_REGION_SIZE_4MB ((uint8_t)0x15U)
|
||||||
|
#define MPU_REGION_SIZE_8MB ((uint8_t)0x16U)
|
||||||
|
#define MPU_REGION_SIZE_16MB ((uint8_t)0x17U)
|
||||||
|
#define MPU_REGION_SIZE_32MB ((uint8_t)0x18U)
|
||||||
|
#define MPU_REGION_SIZE_64MB ((uint8_t)0x19U)
|
||||||
|
#define MPU_REGION_SIZE_128MB ((uint8_t)0x1AU)
|
||||||
|
#define MPU_REGION_SIZE_256MB ((uint8_t)0x1BU)
|
||||||
|
#define MPU_REGION_SIZE_512MB ((uint8_t)0x1CU)
|
||||||
|
#define MPU_REGION_SIZE_1GB ((uint8_t)0x1DU)
|
||||||
|
#define MPU_REGION_SIZE_2GB ((uint8_t)0x1EU)
|
||||||
|
#define MPU_REGION_SIZE_4GB ((uint8_t)0x1FU)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CORTEX_MPU_Region_Permission_Attributes CORTEX MPU Region Permission Attributes
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define MPU_REGION_NO_ACCESS ((uint8_t)0x00U)
|
||||||
|
#define MPU_REGION_PRIV_RW ((uint8_t)0x01U)
|
||||||
|
#define MPU_REGION_PRIV_RW_URO ((uint8_t)0x02U)
|
||||||
|
#define MPU_REGION_FULL_ACCESS ((uint8_t)0x03U)
|
||||||
|
#define MPU_REGION_PRIV_RO ((uint8_t)0x05U)
|
||||||
|
#define MPU_REGION_PRIV_RO_URO ((uint8_t)0x06U)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CORTEX_MPU_Region_Number CORTEX MPU Region Number
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define MPU_REGION_NUMBER0 ((uint8_t)0x00U)
|
||||||
|
#define MPU_REGION_NUMBER1 ((uint8_t)0x01U)
|
||||||
|
#define MPU_REGION_NUMBER2 ((uint8_t)0x02U)
|
||||||
|
#define MPU_REGION_NUMBER3 ((uint8_t)0x03U)
|
||||||
|
#define MPU_REGION_NUMBER4 ((uint8_t)0x04U)
|
||||||
|
#define MPU_REGION_NUMBER5 ((uint8_t)0x05U)
|
||||||
|
#define MPU_REGION_NUMBER6 ((uint8_t)0x06U)
|
||||||
|
#define MPU_REGION_NUMBER7 ((uint8_t)0x07U)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
#endif /* __MPU_PRESENT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Exported Macros -----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
/** @addtogroup CORTEX_Exported_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup CORTEX_Exported_Functions_Group1
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* Initialization and de-initialization functions *****************************/
|
||||||
|
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup);
|
||||||
|
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority);
|
||||||
|
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn);
|
||||||
|
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn);
|
||||||
|
void HAL_NVIC_SystemReset(void);
|
||||||
|
uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb);
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup CORTEX_Exported_Functions_Group2
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* Peripheral Control functions ***********************************************/
|
||||||
|
#if (__MPU_PRESENT == 1)
|
||||||
|
void HAL_MPU_Enable(uint32_t MPU_Control);
|
||||||
|
void HAL_MPU_Disable(void);
|
||||||
|
void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init);
|
||||||
|
#endif /* __MPU_PRESENT */
|
||||||
|
uint32_t HAL_NVIC_GetPriorityGrouping(void);
|
||||||
|
void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority);
|
||||||
|
uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn);
|
||||||
|
void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn);
|
||||||
|
void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn);
|
||||||
|
uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn);
|
||||||
|
void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource);
|
||||||
|
void HAL_SYSTICK_IRQHandler(void);
|
||||||
|
void HAL_SYSTICK_Callback(void);
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Private types -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* Private constants ---------------------------------------------------------*/
|
||||||
|
/* Private macros ------------------------------------------------------------*/
|
||||||
|
/** @defgroup CORTEX_Private_Macros CORTEX Private Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PRIORITYGROUP_0) || \
|
||||||
|
((GROUP) == NVIC_PRIORITYGROUP_1) || \
|
||||||
|
((GROUP) == NVIC_PRIORITYGROUP_2) || \
|
||||||
|
((GROUP) == NVIC_PRIORITYGROUP_3) || \
|
||||||
|
((GROUP) == NVIC_PRIORITYGROUP_4))
|
||||||
|
|
||||||
|
#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10U)
|
||||||
|
|
||||||
|
#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10U)
|
||||||
|
|
||||||
|
#define IS_NVIC_DEVICE_IRQ(IRQ) ((IRQ) >= 0x00)
|
||||||
|
|
||||||
|
#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SYSTICK_CLKSOURCE_HCLK) || \
|
||||||
|
((SOURCE) == SYSTICK_CLKSOURCE_HCLK_DIV8))
|
||||||
|
|
||||||
|
#if (__MPU_PRESENT == 1)
|
||||||
|
#define IS_MPU_REGION_ENABLE(STATE) (((STATE) == MPU_REGION_ENABLE) || \
|
||||||
|
((STATE) == MPU_REGION_DISABLE))
|
||||||
|
|
||||||
|
#define IS_MPU_INSTRUCTION_ACCESS(STATE) (((STATE) == MPU_INSTRUCTION_ACCESS_ENABLE) || \
|
||||||
|
((STATE) == MPU_INSTRUCTION_ACCESS_DISABLE))
|
||||||
|
|
||||||
|
#define IS_MPU_ACCESS_SHAREABLE(STATE) (((STATE) == MPU_ACCESS_SHAREABLE) || \
|
||||||
|
((STATE) == MPU_ACCESS_NOT_SHAREABLE))
|
||||||
|
|
||||||
|
#define IS_MPU_ACCESS_CACHEABLE(STATE) (((STATE) == MPU_ACCESS_CACHEABLE) || \
|
||||||
|
((STATE) == MPU_ACCESS_NOT_CACHEABLE))
|
||||||
|
|
||||||
|
#define IS_MPU_ACCESS_BUFFERABLE(STATE) (((STATE) == MPU_ACCESS_BUFFERABLE) || \
|
||||||
|
((STATE) == MPU_ACCESS_NOT_BUFFERABLE))
|
||||||
|
|
||||||
|
#define IS_MPU_TEX_LEVEL(TYPE) (((TYPE) == MPU_TEX_LEVEL0) || \
|
||||||
|
((TYPE) == MPU_TEX_LEVEL1) || \
|
||||||
|
((TYPE) == MPU_TEX_LEVEL2))
|
||||||
|
|
||||||
|
#define IS_MPU_REGION_PERMISSION_ATTRIBUTE(TYPE) (((TYPE) == MPU_REGION_NO_ACCESS) || \
|
||||||
|
((TYPE) == MPU_REGION_PRIV_RW) || \
|
||||||
|
((TYPE) == MPU_REGION_PRIV_RW_URO) || \
|
||||||
|
((TYPE) == MPU_REGION_FULL_ACCESS) || \
|
||||||
|
((TYPE) == MPU_REGION_PRIV_RO) || \
|
||||||
|
((TYPE) == MPU_REGION_PRIV_RO_URO))
|
||||||
|
|
||||||
|
#define IS_MPU_REGION_NUMBER(NUMBER) (((NUMBER) == MPU_REGION_NUMBER0) || \
|
||||||
|
((NUMBER) == MPU_REGION_NUMBER1) || \
|
||||||
|
((NUMBER) == MPU_REGION_NUMBER2) || \
|
||||||
|
((NUMBER) == MPU_REGION_NUMBER3) || \
|
||||||
|
((NUMBER) == MPU_REGION_NUMBER4) || \
|
||||||
|
((NUMBER) == MPU_REGION_NUMBER5) || \
|
||||||
|
((NUMBER) == MPU_REGION_NUMBER6) || \
|
||||||
|
((NUMBER) == MPU_REGION_NUMBER7))
|
||||||
|
|
||||||
|
#define IS_MPU_REGION_SIZE(SIZE) (((SIZE) == MPU_REGION_SIZE_32B) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_64B) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_128B) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_256B) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_512B) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_1KB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_2KB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_4KB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_8KB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_16KB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_32KB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_64KB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_128KB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_256KB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_512KB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_1MB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_2MB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_4MB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_8MB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_16MB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_32MB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_64MB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_128MB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_256MB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_512MB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_1GB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_2GB) || \
|
||||||
|
((SIZE) == MPU_REGION_SIZE_4GB))
|
||||||
|
|
||||||
|
#define IS_MPU_SUB_REGION_DISABLE(SUBREGION) ((SUBREGION) < (uint16_t)0x00FFU)
|
||||||
|
#endif /* __MPU_PRESENT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __STM32F7xx_HAL_CORTEX_H */
|
||||||
|
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f7xx_hal_def.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief This file contains HAL common defines, enumeration, macros and
|
||||||
|
* structures definitions.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32F7xx_HAL_DEF
|
||||||
|
#define __STM32F7xx_HAL_DEF
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f7xx.h"
|
||||||
|
#include "Legacy/stm32_hal_legacy.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief HAL Status structures definition
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
HAL_OK = 0x00U,
|
||||||
|
HAL_ERROR = 0x01U,
|
||||||
|
HAL_BUSY = 0x02U,
|
||||||
|
HAL_TIMEOUT = 0x03U
|
||||||
|
} HAL_StatusTypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief HAL Lock structures definition
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
HAL_UNLOCKED = 0x00U,
|
||||||
|
HAL_LOCKED = 0x01U
|
||||||
|
} HAL_LockTypeDef;
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */
|
||||||
|
|
||||||
|
#define HAL_MAX_DELAY 0xFFFFFFFFU
|
||||||
|
|
||||||
|
#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) == (BIT))
|
||||||
|
#define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == 0U)
|
||||||
|
|
||||||
|
#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \
|
||||||
|
do{ \
|
||||||
|
(__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \
|
||||||
|
(__DMA_HANDLE__).Parent = (__HANDLE__); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/** @brief Reset the Handle's State field.
|
||||||
|
* @param __HANDLE__ specifies the Peripheral Handle.
|
||||||
|
* @note This macro can be used for the following purpose:
|
||||||
|
* - When the Handle is declared as local variable; before passing it as parameter
|
||||||
|
* to HAL_PPP_Init() for the first time, it is mandatory to use this macro
|
||||||
|
* to set to 0 the Handle's "State" field.
|
||||||
|
* Otherwise, "State" field may have any random value and the first time the function
|
||||||
|
* HAL_PPP_Init() is called, the low level hardware initialization will be missed
|
||||||
|
* (i.e. HAL_PPP_MspInit() will not be executed).
|
||||||
|
* - When there is a need to reconfigure the low level hardware: instead of calling
|
||||||
|
* HAL_PPP_DeInit() then HAL_PPP_Init(), user can make a call to this macro then HAL_PPP_Init().
|
||||||
|
* In this later function, when the Handle's "State" field is set to 0, it will execute the function
|
||||||
|
* HAL_PPP_MspInit() which will reconfigure the low level hardware.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
#define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = 0U)
|
||||||
|
|
||||||
|
#if (USE_RTOS == 1U)
|
||||||
|
/* Reserved for future use */
|
||||||
|
#error "USE_RTOS should be 0 in the current HAL release"
|
||||||
|
#else
|
||||||
|
#define __HAL_LOCK(__HANDLE__) \
|
||||||
|
do{ \
|
||||||
|
if((__HANDLE__)->Lock == HAL_LOCKED) \
|
||||||
|
{ \
|
||||||
|
return HAL_BUSY; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
(__HANDLE__)->Lock = HAL_LOCKED; \
|
||||||
|
} \
|
||||||
|
}while (0U)
|
||||||
|
|
||||||
|
#define __HAL_UNLOCK(__HANDLE__) \
|
||||||
|
do{ \
|
||||||
|
(__HANDLE__)->Lock = HAL_UNLOCKED; \
|
||||||
|
}while (0U)
|
||||||
|
#endif /* USE_RTOS */
|
||||||
|
|
||||||
|
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
|
||||||
|
#ifndef __weak
|
||||||
|
#define __weak __attribute__((weak))
|
||||||
|
#endif
|
||||||
|
#ifndef __packed
|
||||||
|
#define __packed __attribute__((packed))
|
||||||
|
#endif
|
||||||
|
#elif defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
|
||||||
|
#ifndef __weak
|
||||||
|
#define __weak __attribute__((weak))
|
||||||
|
#endif /* __weak */
|
||||||
|
#ifndef __packed
|
||||||
|
#define __packed __attribute__((__packed__))
|
||||||
|
#endif /* __packed */
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */
|
||||||
|
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
|
||||||
|
#ifndef __ALIGN_BEGIN
|
||||||
|
#define __ALIGN_BEGIN
|
||||||
|
#endif
|
||||||
|
#ifndef __ALIGN_END
|
||||||
|
#define __ALIGN_END __attribute__ ((aligned (4)))
|
||||||
|
#endif
|
||||||
|
#elif defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
|
||||||
|
#ifndef __ALIGN_END
|
||||||
|
#define __ALIGN_END __attribute__ ((aligned (4)))
|
||||||
|
#endif /* __ALIGN_END */
|
||||||
|
#ifndef __ALIGN_BEGIN
|
||||||
|
#define __ALIGN_BEGIN
|
||||||
|
#endif /* __ALIGN_BEGIN */
|
||||||
|
#else
|
||||||
|
#ifndef __ALIGN_END
|
||||||
|
#define __ALIGN_END
|
||||||
|
#endif /* __ALIGN_END */
|
||||||
|
#ifndef __ALIGN_BEGIN
|
||||||
|
#if defined (__CC_ARM) /* ARM Compiler V5*/
|
||||||
|
#define __ALIGN_BEGIN __align(4)
|
||||||
|
#elif defined (__ICCARM__) /* IAR Compiler */
|
||||||
|
#define __ALIGN_BEGIN
|
||||||
|
#endif /* __CC_ARM */
|
||||||
|
#endif /* __ALIGN_BEGIN */
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
|
/* Macro to get variable aligned on 32-bytes,needed for cache maintenance purpose */
|
||||||
|
#if defined (__GNUC__) /* GNU Compiler */
|
||||||
|
#define ALIGN_32BYTES(buf) buf __attribute__ ((aligned (32)))
|
||||||
|
#elif defined (__ICCARM__) /* IAR Compiler */
|
||||||
|
#define ALIGN_32BYTES(buf) _Pragma("data_alignment=32") buf
|
||||||
|
#elif defined (__CC_ARM) /* ARM Compiler */
|
||||||
|
#define ALIGN_32BYTES(buf) __align(32) buf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief __RAM_FUNC definition
|
||||||
|
*/
|
||||||
|
#if defined ( __CC_ARM ) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
||||||
|
/* ARM Compiler V4/V5 and V6
|
||||||
|
--------------------------
|
||||||
|
RAM functions are defined using the toolchain options.
|
||||||
|
Functions that are executed in RAM should reside in a separate source module.
|
||||||
|
Using the 'Options for File' dialog you can simply change the 'Code / Const'
|
||||||
|
area of a module to a memory space in physical RAM.
|
||||||
|
Available memory areas are declared in the 'Target' tab of the 'Options for Target'
|
||||||
|
dialog.
|
||||||
|
*/
|
||||||
|
#define __RAM_FUNC
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ )
|
||||||
|
/* ICCARM Compiler
|
||||||
|
---------------
|
||||||
|
RAM functions are defined using a specific toolchain keyword "__ramfunc".
|
||||||
|
*/
|
||||||
|
#define __RAM_FUNC __ramfunc
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ )
|
||||||
|
/* GNU Compiler
|
||||||
|
------------
|
||||||
|
RAM functions are defined using a specific toolchain attribute
|
||||||
|
"__attribute__((section(".RamFunc")))".
|
||||||
|
*/
|
||||||
|
#define __RAM_FUNC __attribute__((section(".RamFunc")))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief __NOINLINE definition
|
||||||
|
*/
|
||||||
|
#if defined ( __CC_ARM ) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) || defined ( __GNUC__ )
|
||||||
|
/* ARM V4/V5 and V6 & GNU Compiler
|
||||||
|
-------------------------------
|
||||||
|
*/
|
||||||
|
#define __NOINLINE __attribute__ ( (noinline) )
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ )
|
||||||
|
/* ICCARM Compiler
|
||||||
|
---------------
|
||||||
|
*/
|
||||||
|
#define __NOINLINE _Pragma("optimize = no_inline")
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ___STM32F7xx_HAL_DEF */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -0,0 +1,531 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f7xx_hal_gpio.c
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief GPIO HAL module driver.
|
||||||
|
* This file provides firmware functions to manage the following
|
||||||
|
* functionalities of the General Purpose Input/Output (GPIO) peripheral:
|
||||||
|
* + Initialization and de-initialization functions
|
||||||
|
* + IO operation functions
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
==============================================================================
|
||||||
|
##### GPIO Peripheral features #####
|
||||||
|
==============================================================================
|
||||||
|
[..]
|
||||||
|
Subject to the specific hardware characteristics of each I/O port listed in the datasheet, each
|
||||||
|
port bit of the General Purpose IO (GPIO) Ports, can be individually configured by software
|
||||||
|
in several modes:
|
||||||
|
(+) Input mode
|
||||||
|
(+) Analog mode
|
||||||
|
(+) Output mode
|
||||||
|
(+) Alternate function mode
|
||||||
|
(+) External interrupt/event lines
|
||||||
|
|
||||||
|
[..]
|
||||||
|
During and just after reset, the alternate functions and external interrupt
|
||||||
|
lines are not active and the I/O ports are configured in input floating mode.
|
||||||
|
|
||||||
|
[..]
|
||||||
|
All GPIO pins have weak internal pull-up and pull-down resistors, which can be
|
||||||
|
activated or not.
|
||||||
|
|
||||||
|
[..]
|
||||||
|
In Output or Alternate mode, each IO can be configured on open-drain or push-pull
|
||||||
|
type and the IO speed can be selected depending on the VDD value.
|
||||||
|
|
||||||
|
[..]
|
||||||
|
All ports have external interrupt/event capability. To use external interrupt
|
||||||
|
lines, the port must be configured in input mode. All available GPIO pins are
|
||||||
|
connected to the 16 external interrupt/event lines from EXTI0 to EXTI15.
|
||||||
|
|
||||||
|
[..]
|
||||||
|
The external interrupt/event controller consists of up to 23 edge detectors
|
||||||
|
(16 lines are connected to GPIO) for generating event/interrupt requests (each
|
||||||
|
input line can be independently configured to select the type (interrupt or event)
|
||||||
|
and the corresponding trigger event (rising or falling or both). Each line can
|
||||||
|
also be masked independently.
|
||||||
|
|
||||||
|
##### How to use this driver #####
|
||||||
|
==============================================================================
|
||||||
|
[..]
|
||||||
|
(#) Enable the GPIO AHB clock using the following function: __HAL_RCC_GPIOx_CLK_ENABLE().
|
||||||
|
|
||||||
|
(#) Configure the GPIO pin(s) using HAL_GPIO_Init().
|
||||||
|
(++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure
|
||||||
|
(++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef
|
||||||
|
structure.
|
||||||
|
(++) In case of Output or alternate function mode selection: the speed is
|
||||||
|
configured through "Speed" member from GPIO_InitTypeDef structure.
|
||||||
|
(++) In alternate mode is selection, the alternate function connected to the IO
|
||||||
|
is configured through "Alternate" member from GPIO_InitTypeDef structure.
|
||||||
|
(++) Analog mode is required when a pin is to be used as ADC channel
|
||||||
|
or DAC output.
|
||||||
|
(++) In case of external interrupt/event selection the "Mode" member from
|
||||||
|
GPIO_InitTypeDef structure select the type (interrupt or event) and
|
||||||
|
the corresponding trigger event (rising or falling or both).
|
||||||
|
|
||||||
|
(#) In case of external interrupt/event mode selection, configure NVIC IRQ priority
|
||||||
|
mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using
|
||||||
|
HAL_NVIC_EnableIRQ().
|
||||||
|
|
||||||
|
(#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin().
|
||||||
|
|
||||||
|
(#) To set/reset the level of a pin configured in output mode use
|
||||||
|
HAL_GPIO_WritePin()/HAL_GPIO_TogglePin().
|
||||||
|
|
||||||
|
(#) To lock pin configuration until next reset use HAL_GPIO_LockPin().
|
||||||
|
|
||||||
|
|
||||||
|
(#) During and just after reset, the alternate functions are not
|
||||||
|
active and the GPIO pins are configured in input floating mode (except JTAG
|
||||||
|
pins).
|
||||||
|
|
||||||
|
(#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose
|
||||||
|
(PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has
|
||||||
|
priority over the GPIO function.
|
||||||
|
|
||||||
|
(#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as
|
||||||
|
general purpose PH0 and PH1, respectively, when the HSE oscillator is off.
|
||||||
|
The HSE has priority over the GPIO function.
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f7xx_hal.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F7xx_HAL_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO GPIO
|
||||||
|
* @brief GPIO HAL module driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
/** @addtogroup GPIO_Private_Constants GPIO Private Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define GPIO_MODE ((uint32_t)0x00000003U)
|
||||||
|
#define EXTI_MODE ((uint32_t)0x10000000U)
|
||||||
|
#define GPIO_MODE_IT ((uint32_t)0x00010000U)
|
||||||
|
#define GPIO_MODE_EVT ((uint32_t)0x00020000U)
|
||||||
|
#define RISING_EDGE ((uint32_t)0x00100000U)
|
||||||
|
#define FALLING_EDGE ((uint32_t)0x00200000U)
|
||||||
|
#define GPIO_OUTPUT_TYPE ((uint32_t)0x00000010U)
|
||||||
|
|
||||||
|
#define GPIO_NUMBER ((uint32_t)16U)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
/** @defgroup GPIO_Exported_Functions GPIO Exported Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||||
|
* @brief Initialization and Configuration functions
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
===============================================================================
|
||||||
|
##### Initialization and de-initialization functions #####
|
||||||
|
===============================================================================
|
||||||
|
[..]
|
||||||
|
This section provides functions allowing to initialize and de-initialize the GPIOs
|
||||||
|
to be ready for use.
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init.
|
||||||
|
* @param GPIOx where x can be (A..K) to select the GPIO peripheral.
|
||||||
|
* @param GPIO_Init pointer to a GPIO_InitTypeDef structure that contains
|
||||||
|
* the configuration information for the specified GPIO peripheral.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
|
||||||
|
{
|
||||||
|
uint32_t position = 0x00;
|
||||||
|
uint32_t ioposition = 0x00;
|
||||||
|
uint32_t iocurrent = 0x00;
|
||||||
|
uint32_t temp = 0x00;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
|
||||||
|
assert_param(IS_GPIO_PIN(GPIO_Init->Pin));
|
||||||
|
assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
|
||||||
|
assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
|
||||||
|
|
||||||
|
/* Configure the port pins */
|
||||||
|
for(position = 0; position < GPIO_NUMBER; position++)
|
||||||
|
{
|
||||||
|
/* Get the IO position */
|
||||||
|
ioposition = ((uint32_t)0x01) << position;
|
||||||
|
/* Get the current IO position */
|
||||||
|
iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;
|
||||||
|
|
||||||
|
if(iocurrent == ioposition)
|
||||||
|
{
|
||||||
|
/*--------------------- GPIO Mode Configuration ------------------------*/
|
||||||
|
/* In case of Output or Alternate function mode selection */
|
||||||
|
if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) ||
|
||||||
|
(GPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (GPIO_Init->Mode == GPIO_MODE_AF_OD))
|
||||||
|
{
|
||||||
|
/* Check the Speed parameter */
|
||||||
|
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
||||||
|
/* Configure the IO Speed */
|
||||||
|
temp = GPIOx->OSPEEDR;
|
||||||
|
temp &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2));
|
||||||
|
temp |= (GPIO_Init->Speed << (position * 2));
|
||||||
|
GPIOx->OSPEEDR = temp;
|
||||||
|
|
||||||
|
/* Configure the IO Output Type */
|
||||||
|
temp = GPIOx->OTYPER;
|
||||||
|
temp &= ~(GPIO_OTYPER_OT_0 << position) ;
|
||||||
|
temp |= (((GPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4) << position);
|
||||||
|
GPIOx->OTYPER = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Activate the Pull-up or Pull down resistor for the current IO */
|
||||||
|
temp = GPIOx->PUPDR;
|
||||||
|
temp &= ~(GPIO_PUPDR_PUPDR0 << (position * 2));
|
||||||
|
temp |= ((GPIO_Init->Pull) << (position * 2));
|
||||||
|
GPIOx->PUPDR = temp;
|
||||||
|
|
||||||
|
/* In case of Alternate function mode selection */
|
||||||
|
if((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD))
|
||||||
|
{
|
||||||
|
/* Check the Alternate function parameter */
|
||||||
|
assert_param(IS_GPIO_AF(GPIO_Init->Alternate));
|
||||||
|
|
||||||
|
/* Configure Alternate function mapped with the current IO */
|
||||||
|
temp = GPIOx->AFR[position >> 3];
|
||||||
|
temp &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ;
|
||||||
|
temp |= ((uint32_t)(GPIO_Init->Alternate) << (((uint32_t)position & (uint32_t)0x07) * 4));
|
||||||
|
GPIOx->AFR[position >> 3] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure IO Direction mode (Input, Output, Alternate or Analog) */
|
||||||
|
temp = GPIOx->MODER;
|
||||||
|
temp &= ~(GPIO_MODER_MODER0 << (position * 2));
|
||||||
|
temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2));
|
||||||
|
GPIOx->MODER = temp;
|
||||||
|
|
||||||
|
/*--------------------- EXTI Mode Configuration ------------------------*/
|
||||||
|
/* Configure the External Interrupt or event for the current IO */
|
||||||
|
if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
|
||||||
|
{
|
||||||
|
/* Enable SYSCFG Clock */
|
||||||
|
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||||
|
|
||||||
|
temp = SYSCFG->EXTICR[position >> 2];
|
||||||
|
temp &= ~(((uint32_t)0x0F) << (4 * (position & 0x03)));
|
||||||
|
temp |= ((uint32_t)(GPIO_GET_INDEX(GPIOx)) << (4 * (position & 0x03)));
|
||||||
|
SYSCFG->EXTICR[position >> 2] = temp;
|
||||||
|
|
||||||
|
/* Clear EXTI line configuration */
|
||||||
|
temp = EXTI->IMR;
|
||||||
|
temp &= ~((uint32_t)iocurrent);
|
||||||
|
if((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
|
||||||
|
{
|
||||||
|
temp |= iocurrent;
|
||||||
|
}
|
||||||
|
EXTI->IMR = temp;
|
||||||
|
|
||||||
|
temp = EXTI->EMR;
|
||||||
|
temp &= ~((uint32_t)iocurrent);
|
||||||
|
if((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
|
||||||
|
{
|
||||||
|
temp |= iocurrent;
|
||||||
|
}
|
||||||
|
EXTI->EMR = temp;
|
||||||
|
|
||||||
|
/* Clear Rising Falling edge configuration */
|
||||||
|
temp = EXTI->RTSR;
|
||||||
|
temp &= ~((uint32_t)iocurrent);
|
||||||
|
if((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE)
|
||||||
|
{
|
||||||
|
temp |= iocurrent;
|
||||||
|
}
|
||||||
|
EXTI->RTSR = temp;
|
||||||
|
|
||||||
|
temp = EXTI->FTSR;
|
||||||
|
temp &= ~((uint32_t)iocurrent);
|
||||||
|
if((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE)
|
||||||
|
{
|
||||||
|
temp |= iocurrent;
|
||||||
|
}
|
||||||
|
EXTI->FTSR = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief De-initializes the GPIOx peripheral registers to their default reset values.
|
||||||
|
* @param GPIOx where x can be (A..K) to select the GPIO peripheral.
|
||||||
|
* @param GPIO_Pin specifies the port bit to be written.
|
||||||
|
* This parameter can be one of GPIO_PIN_x where x can be (0..15).
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
uint32_t position;
|
||||||
|
uint32_t ioposition = 0x00;
|
||||||
|
uint32_t iocurrent = 0x00;
|
||||||
|
uint32_t tmp = 0x00;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
|
||||||
|
|
||||||
|
/* Configure the port pins */
|
||||||
|
for(position = 0; position < GPIO_NUMBER; position++)
|
||||||
|
{
|
||||||
|
/* Get the IO position */
|
||||||
|
ioposition = ((uint32_t)0x01) << position;
|
||||||
|
/* Get the current IO position */
|
||||||
|
iocurrent = (GPIO_Pin) & ioposition;
|
||||||
|
|
||||||
|
if(iocurrent == ioposition)
|
||||||
|
{
|
||||||
|
/*------------------------- EXTI Mode Configuration --------------------*/
|
||||||
|
tmp = SYSCFG->EXTICR[position >> 2];
|
||||||
|
tmp &= (((uint32_t)0x0F) << (4 * (position & 0x03)));
|
||||||
|
if(tmp == ((uint32_t)(GPIO_GET_INDEX(GPIOx)) << (4 * (position & 0x03))))
|
||||||
|
{
|
||||||
|
/* Clear EXTI line configuration */
|
||||||
|
EXTI->IMR &= ~((uint32_t)iocurrent);
|
||||||
|
EXTI->EMR &= ~((uint32_t)iocurrent);
|
||||||
|
|
||||||
|
/* Clear Rising Falling edge configuration */
|
||||||
|
EXTI->RTSR &= ~((uint32_t)iocurrent);
|
||||||
|
EXTI->FTSR &= ~((uint32_t)iocurrent);
|
||||||
|
|
||||||
|
/* Configure the External Interrupt or event for the current IO */
|
||||||
|
tmp = ((uint32_t)0x0F) << (4 * (position & 0x03));
|
||||||
|
SYSCFG->EXTICR[position >> 2] &= ~tmp;
|
||||||
|
}
|
||||||
|
/*------------------------- GPIO Mode Configuration --------------------*/
|
||||||
|
/* Configure IO Direction in Input Floating Mode */
|
||||||
|
GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (position * 2));
|
||||||
|
|
||||||
|
/* Configure the default Alternate Function in current IO */
|
||||||
|
GPIOx->AFR[position >> 3] &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ;
|
||||||
|
|
||||||
|
/* Deactivate the Pull-up and Pull-down resistor for the current IO */
|
||||||
|
GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << (position * 2));
|
||||||
|
|
||||||
|
/* Configure the default value IO Output Type */
|
||||||
|
GPIOx->OTYPER &= ~(GPIO_OTYPER_OT_0 << position) ;
|
||||||
|
|
||||||
|
/* Configure the default value for IO Speed */
|
||||||
|
GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions
|
||||||
|
* @brief GPIO Read and Write
|
||||||
|
*
|
||||||
|
@verbatim
|
||||||
|
===============================================================================
|
||||||
|
##### IO operation functions #####
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
@endverbatim
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads the specified input port pin.
|
||||||
|
* @param GPIOx where x can be (A..K) to select the GPIO peripheral.
|
||||||
|
* @param GPIO_Pin specifies the port bit to read.
|
||||||
|
* This parameter can be GPIO_PIN_x where x can be (0..15).
|
||||||
|
* @retval The input port pin value.
|
||||||
|
*/
|
||||||
|
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
GPIO_PinState bitstatus;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||||
|
|
||||||
|
if((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)
|
||||||
|
{
|
||||||
|
bitstatus = GPIO_PIN_SET;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bitstatus = GPIO_PIN_RESET;
|
||||||
|
}
|
||||||
|
return bitstatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets or clears the selected data port bit.
|
||||||
|
*
|
||||||
|
* @note This function uses GPIOx_BSRR register to allow atomic read/modify
|
||||||
|
* accesses. In this way, there is no risk of an IRQ occurring between
|
||||||
|
* the read and the modify access.
|
||||||
|
*
|
||||||
|
* @param GPIOx where x can be (A..K) to select the GPIO peripheral.
|
||||||
|
* @param GPIO_Pin specifies the port bit to be written.
|
||||||
|
* This parameter can be one of GPIO_PIN_x where x can be (0..15).
|
||||||
|
* @param PinState specifies the value to be written to the selected bit.
|
||||||
|
* This parameter can be one of the GPIO_PinState enum values:
|
||||||
|
* @arg GPIO_PIN_RESET: to clear the port pin
|
||||||
|
* @arg GPIO_PIN_SET: to set the port pin
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
|
||||||
|
{
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||||
|
assert_param(IS_GPIO_PIN_ACTION(PinState));
|
||||||
|
|
||||||
|
if(PinState != GPIO_PIN_RESET)
|
||||||
|
{
|
||||||
|
GPIOx->BSRR = GPIO_Pin;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GPIOx->BSRR = (uint32_t)GPIO_Pin << 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Toggles the specified GPIO pins.
|
||||||
|
* @param GPIOx Where x can be (A..I) to select the GPIO peripheral.
|
||||||
|
* @param GPIO_Pin Specifies the pins to be toggled.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
uint32_t odr;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||||
|
|
||||||
|
/* get current Output Data Register value */
|
||||||
|
odr = GPIOx->ODR;
|
||||||
|
|
||||||
|
/* Set selected pins that were at low level, and reset ones that were high */
|
||||||
|
GPIOx->BSRR = ((odr & GPIO_Pin) << GPIO_NUMBER) | (~odr & GPIO_Pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Locks GPIO Pins configuration registers.
|
||||||
|
* @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR,
|
||||||
|
* GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH.
|
||||||
|
* @note The configuration of the locked GPIO pins can no longer be modified
|
||||||
|
* until the next reset.
|
||||||
|
* @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32F7 family
|
||||||
|
* @param GPIO_Pin specifies the port bit to be locked.
|
||||||
|
* This parameter can be any combination of GPIO_PIN_x where x can be (0..15).
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
__IO uint32_t tmp = GPIO_LCKR_LCKK;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||||
|
|
||||||
|
/* Apply lock key write sequence */
|
||||||
|
tmp |= GPIO_Pin;
|
||||||
|
/* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
|
||||||
|
GPIOx->LCKR = tmp;
|
||||||
|
/* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */
|
||||||
|
GPIOx->LCKR = GPIO_Pin;
|
||||||
|
/* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
|
||||||
|
GPIOx->LCKR = tmp;
|
||||||
|
/* Read LCKR register. This read is mandatory to complete key lock sequence */
|
||||||
|
tmp = GPIOx->LCKR;
|
||||||
|
|
||||||
|
/* Read again in order to confirm lock is active */
|
||||||
|
if((GPIOx->LCKR & GPIO_LCKR_LCKK) != RESET)
|
||||||
|
{
|
||||||
|
return HAL_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return HAL_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles EXTI interrupt request.
|
||||||
|
* @param GPIO_Pin Specifies the pins connected EXTI line
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
/* EXTI line interrupt detected */
|
||||||
|
if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
|
||||||
|
{
|
||||||
|
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
|
||||||
|
HAL_GPIO_EXTI_Callback(GPIO_Pin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief EXTI line detection callbacks.
|
||||||
|
* @param GPIO_Pin Specifies the pins connected EXTI line
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
|
||||||
|
{
|
||||||
|
/* Prevent unused argument(s) compilation warning */
|
||||||
|
UNUSED(GPIO_Pin);
|
||||||
|
|
||||||
|
/* NOTE: This function Should not be modified, when the callback is needed,
|
||||||
|
the HAL_GPIO_EXTI_Callback could be implemented in the user file
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -0,0 +1,309 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f7xx_hal_gpio.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief Header file of GPIO HAL module.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32F7xx_HAL_GPIO_H
|
||||||
|
#define __STM32F7xx_HAL_GPIO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f7xx_hal_def.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F7xx_HAL_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup GPIO
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
/** @defgroup GPIO_Exported_Types GPIO Exported Types
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPIO Init structure definition
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t Pin; /*!< Specifies the GPIO pins to be configured.
|
||||||
|
This parameter can be any value of @ref GPIO_pins_define */
|
||||||
|
|
||||||
|
uint32_t Mode; /*!< Specifies the operating mode for the selected pins.
|
||||||
|
This parameter can be a value of @ref GPIO_mode_define */
|
||||||
|
|
||||||
|
uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
|
||||||
|
This parameter can be a value of @ref GPIO_pull_define */
|
||||||
|
|
||||||
|
uint32_t Speed; /*!< Specifies the speed for the selected pins.
|
||||||
|
This parameter can be a value of @ref GPIO_speed_define */
|
||||||
|
|
||||||
|
uint32_t Alternate; /*!< Peripheral to be connected to the selected pins.
|
||||||
|
This parameter can be a value of @ref GPIO_Alternate_function_selection */
|
||||||
|
}GPIO_InitTypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPIO Bit SET and Bit RESET enumeration
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GPIO_PIN_RESET = 0,
|
||||||
|
GPIO_PIN_SET
|
||||||
|
}GPIO_PinState;
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_Exported_Constants GPIO Exported Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_pins_define GPIO pins define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define GPIO_PIN_0 ((uint16_t)0x0001U) /* Pin 0 selected */
|
||||||
|
#define GPIO_PIN_1 ((uint16_t)0x0002U) /* Pin 1 selected */
|
||||||
|
#define GPIO_PIN_2 ((uint16_t)0x0004U) /* Pin 2 selected */
|
||||||
|
#define GPIO_PIN_3 ((uint16_t)0x0008U) /* Pin 3 selected */
|
||||||
|
#define GPIO_PIN_4 ((uint16_t)0x0010U) /* Pin 4 selected */
|
||||||
|
#define GPIO_PIN_5 ((uint16_t)0x0020U) /* Pin 5 selected */
|
||||||
|
#define GPIO_PIN_6 ((uint16_t)0x0040U) /* Pin 6 selected */
|
||||||
|
#define GPIO_PIN_7 ((uint16_t)0x0080U) /* Pin 7 selected */
|
||||||
|
#define GPIO_PIN_8 ((uint16_t)0x0100U) /* Pin 8 selected */
|
||||||
|
#define GPIO_PIN_9 ((uint16_t)0x0200U) /* Pin 9 selected */
|
||||||
|
#define GPIO_PIN_10 ((uint16_t)0x0400U) /* Pin 10 selected */
|
||||||
|
#define GPIO_PIN_11 ((uint16_t)0x0800U) /* Pin 11 selected */
|
||||||
|
#define GPIO_PIN_12 ((uint16_t)0x1000U) /* Pin 12 selected */
|
||||||
|
#define GPIO_PIN_13 ((uint16_t)0x2000U) /* Pin 13 selected */
|
||||||
|
#define GPIO_PIN_14 ((uint16_t)0x4000U) /* Pin 14 selected */
|
||||||
|
#define GPIO_PIN_15 ((uint16_t)0x8000U) /* Pin 15 selected */
|
||||||
|
#define GPIO_PIN_All ((uint16_t)0xFFFFU) /* All pins selected */
|
||||||
|
|
||||||
|
#define GPIO_PIN_MASK ((uint32_t)0x0000FFFFU) /* PIN mask for assert test */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_mode_define GPIO mode define
|
||||||
|
* @brief GPIO Configuration Mode
|
||||||
|
* Elements values convention: 0xX0yz00YZ
|
||||||
|
* - X : GPIO mode or EXTI Mode
|
||||||
|
* - y : External IT or Event trigger detection
|
||||||
|
* - z : IO configuration on External IT or Event
|
||||||
|
* - Y : Output type (Push Pull or Open Drain)
|
||||||
|
* - Z : IO Direction mode (Input, Output, Alternate or Analog)
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define GPIO_MODE_INPUT ((uint32_t)0x00000000U) /*!< Input Floating Mode */
|
||||||
|
#define GPIO_MODE_OUTPUT_PP ((uint32_t)0x00000001U) /*!< Output Push Pull Mode */
|
||||||
|
#define GPIO_MODE_OUTPUT_OD ((uint32_t)0x00000011U) /*!< Output Open Drain Mode */
|
||||||
|
#define GPIO_MODE_AF_PP ((uint32_t)0x00000002U) /*!< Alternate Function Push Pull Mode */
|
||||||
|
#define GPIO_MODE_AF_OD ((uint32_t)0x00000012U) /*!< Alternate Function Open Drain Mode */
|
||||||
|
|
||||||
|
#define GPIO_MODE_ANALOG ((uint32_t)0x00000003U) /*!< Analog Mode */
|
||||||
|
|
||||||
|
#define GPIO_MODE_IT_RISING ((uint32_t)0x10110000U) /*!< External Interrupt Mode with Rising edge trigger detection */
|
||||||
|
#define GPIO_MODE_IT_FALLING ((uint32_t)0x10210000U) /*!< External Interrupt Mode with Falling edge trigger detection */
|
||||||
|
#define GPIO_MODE_IT_RISING_FALLING ((uint32_t)0x10310000U) /*!< External Interrupt Mode with Rising/Falling edge trigger detection */
|
||||||
|
|
||||||
|
#define GPIO_MODE_EVT_RISING ((uint32_t)0x10120000U) /*!< External Event Mode with Rising edge trigger detection */
|
||||||
|
#define GPIO_MODE_EVT_FALLING ((uint32_t)0x10220000U) /*!< External Event Mode with Falling edge trigger detection */
|
||||||
|
#define GPIO_MODE_EVT_RISING_FALLING ((uint32_t)0x10320000U) /*!< External Event Mode with Rising/Falling edge trigger detection */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_speed_define GPIO speed define
|
||||||
|
* @brief GPIO Output Maximum frequency
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define GPIO_SPEED_FREQ_LOW ((uint32_t)0x00000000U) /*!< Low speed */
|
||||||
|
#define GPIO_SPEED_FREQ_MEDIUM ((uint32_t)0x00000001U) /*!< Medium speed */
|
||||||
|
#define GPIO_SPEED_FREQ_HIGH ((uint32_t)0x00000002U) /*!< Fast speed */
|
||||||
|
#define GPIO_SPEED_FREQ_VERY_HIGH ((uint32_t)0x00000003U) /*!< High speed */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_pull_define GPIO pull define
|
||||||
|
* @brief GPIO Pull-Up or Pull-Down Activation
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define GPIO_NOPULL ((uint32_t)0x00000000U) /*!< No Pull-up or Pull-down activation */
|
||||||
|
#define GPIO_PULLUP ((uint32_t)0x00000001U) /*!< Pull-up activation */
|
||||||
|
#define GPIO_PULLDOWN ((uint32_t)0x00000002U) /*!< Pull-down activation */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/** @defgroup GPIO_Exported_Macros GPIO Exported Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether the specified EXTI line flag is set or not.
|
||||||
|
* @param __EXTI_LINE__ specifies the EXTI line flag to check.
|
||||||
|
* This parameter can be GPIO_PIN_x where x can be(0..15)
|
||||||
|
* @retval The new state of __EXTI_LINE__ (SET or RESET).
|
||||||
|
*/
|
||||||
|
#define __HAL_GPIO_EXTI_GET_FLAG(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears the EXTI's line pending flags.
|
||||||
|
* @param __EXTI_LINE__ specifies the EXTI lines flags to clear.
|
||||||
|
* This parameter can be any combination of GPIO_PIN_x where x can be (0..15)
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
#define __HAL_GPIO_EXTI_CLEAR_FLAG(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether the specified EXTI line is asserted or not.
|
||||||
|
* @param __EXTI_LINE__ specifies the EXTI line to check.
|
||||||
|
* This parameter can be GPIO_PIN_x where x can be(0..15)
|
||||||
|
* @retval The new state of __EXTI_LINE__ (SET or RESET).
|
||||||
|
*/
|
||||||
|
#define __HAL_GPIO_EXTI_GET_IT(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears the EXTI's line pending bits.
|
||||||
|
* @param __EXTI_LINE__ specifies the EXTI lines to clear.
|
||||||
|
* This parameter can be any combination of GPIO_PIN_x where x can be (0..15)
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
#define __HAL_GPIO_EXTI_CLEAR_IT(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generates a Software interrupt on selected EXTI line.
|
||||||
|
* @param __EXTI_LINE__ specifies the EXTI line to check.
|
||||||
|
* This parameter can be GPIO_PIN_x where x can be(0..15)
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
#define __HAL_GPIO_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER |= (__EXTI_LINE__))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Include GPIO HAL Extension module */
|
||||||
|
#include "stm32f7xx_hal_gpio_ex.h"
|
||||||
|
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
/** @addtogroup GPIO_Exported_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup GPIO_Exported_Functions_Group1
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* Initialization and de-initialization functions *****************************/
|
||||||
|
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
|
||||||
|
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup GPIO_Exported_Functions_Group2
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* IO operation functions *****************************************************/
|
||||||
|
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||||
|
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
|
||||||
|
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||||
|
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||||
|
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
|
||||||
|
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
/* Private types -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* Private constants ---------------------------------------------------------*/
|
||||||
|
/** @defgroup GPIO_Private_Constants GPIO Private Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Private macros ------------------------------------------------------------*/
|
||||||
|
/** @defgroup GPIO_Private_Macros GPIO Private Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define IS_GPIO_PIN_ACTION(ACTION) (((ACTION) == GPIO_PIN_RESET) || ((ACTION) == GPIO_PIN_SET))
|
||||||
|
#define IS_GPIO_PIN(__PIN__) ((((uint32_t)(__PIN__) & GPIO_PIN_MASK) != 0x00U))
|
||||||
|
#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_MODE_INPUT) ||\
|
||||||
|
((MODE) == GPIO_MODE_OUTPUT_PP) ||\
|
||||||
|
((MODE) == GPIO_MODE_OUTPUT_OD) ||\
|
||||||
|
((MODE) == GPIO_MODE_AF_PP) ||\
|
||||||
|
((MODE) == GPIO_MODE_AF_OD) ||\
|
||||||
|
((MODE) == GPIO_MODE_IT_RISING) ||\
|
||||||
|
((MODE) == GPIO_MODE_IT_FALLING) ||\
|
||||||
|
((MODE) == GPIO_MODE_IT_RISING_FALLING) ||\
|
||||||
|
((MODE) == GPIO_MODE_EVT_RISING) ||\
|
||||||
|
((MODE) == GPIO_MODE_EVT_FALLING) ||\
|
||||||
|
((MODE) == GPIO_MODE_EVT_RISING_FALLING) ||\
|
||||||
|
((MODE) == GPIO_MODE_ANALOG))
|
||||||
|
#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_SPEED_LOW) || ((SPEED) == GPIO_SPEED_MEDIUM) || \
|
||||||
|
((SPEED) == GPIO_SPEED_FAST) || ((SPEED) == GPIO_SPEED_HIGH))
|
||||||
|
#define IS_GPIO_PULL(PULL) (((PULL) == GPIO_NOPULL) || ((PULL) == GPIO_PULLUP) || \
|
||||||
|
((PULL) == GPIO_PULLDOWN))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
/** @defgroup GPIO_Private_Functions GPIO Private Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __STM32F7xx_HAL_GPIO_H */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -0,0 +1,658 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f7xx_hal_gpio_ex.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief Header file of GPIO HAL Extension module.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32F7xx_HAL_GPIO_EX_H
|
||||||
|
#define __STM32F7xx_HAL_GPIO_EX_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f7xx_hal_def.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F7xx_HAL_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIOEx GPIOEx
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
/** @defgroup GPIOEx_Exported_Constants GPIO Exported Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup GPIO_Alternate_function_selection GPIO Alternate Function Selection
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/*--------------- STM32F74xxx/STM32F75xxx/STM32F76xxx/STM32F77xxx -------------*/
|
||||||
|
#if defined (STM32F745xx) || defined (STM32F746xx) || defined (STM32F756xx) || defined (STM32F765xx) || defined (STM32F767xx) ||\
|
||||||
|
defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx) || defined (STM32F750xx)
|
||||||
|
/**
|
||||||
|
* @brief AF 0 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF0_RTC_50Hz ((uint8_t)0x00U) /* RTC_50Hz Alternate Function mapping */
|
||||||
|
#define GPIO_AF0_MCO ((uint8_t)0x00U) /* MCO (MCO1 and MCO2) Alternate Function mapping */
|
||||||
|
#define GPIO_AF0_SWJ ((uint8_t)0x00U) /* SWJ (SWD and JTAG) Alternate Function mapping */
|
||||||
|
#define GPIO_AF0_TRACE ((uint8_t)0x00U) /* TRACE Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 1 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF1_TIM1 ((uint8_t)0x01U) /* TIM1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF1_TIM2 ((uint8_t)0x01U) /* TIM2 Alternate Function mapping */
|
||||||
|
#if defined (STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx)
|
||||||
|
#define GPIO_AF1_UART5 ((uint8_t)0x01U) /* UART5 Alternate Function mapping */
|
||||||
|
#define GPIO_AF1_I2C4 ((uint8_t)0x01U) /* I2C4 Alternate Function mapping */
|
||||||
|
#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 2 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF2_TIM3 ((uint8_t)0x02U) /* TIM3 Alternate Function mapping */
|
||||||
|
#define GPIO_AF2_TIM4 ((uint8_t)0x02U) /* TIM4 Alternate Function mapping */
|
||||||
|
#define GPIO_AF2_TIM5 ((uint8_t)0x02U) /* TIM5 Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 3 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF3_TIM8 ((uint8_t)0x03U) /* TIM8 Alternate Function mapping */
|
||||||
|
#define GPIO_AF3_TIM9 ((uint8_t)0x03U) /* TIM9 Alternate Function mapping */
|
||||||
|
#define GPIO_AF3_TIM10 ((uint8_t)0x03U) /* TIM10 Alternate Function mapping */
|
||||||
|
#define GPIO_AF3_TIM11 ((uint8_t)0x03U) /* TIM11 Alternate Function mapping */
|
||||||
|
#define GPIO_AF3_LPTIM1 ((uint8_t)0x03U) /* LPTIM1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF3_CEC ((uint8_t)0x03U) /* CEC Alternate Function mapping */
|
||||||
|
#if defined (STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx)
|
||||||
|
#define GPIO_AF3_DFSDM1 ((uint8_t)0x03U) /* DFSDM1 Alternate Function mapping */
|
||||||
|
#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
|
||||||
|
/**
|
||||||
|
* @brief AF 4 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /* I2C1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF4_I2C2 ((uint8_t)0x04U) /* I2C2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF4_I2C3 ((uint8_t)0x04U) /* I2C3 Alternate Function mapping */
|
||||||
|
#define GPIO_AF4_I2C4 ((uint8_t)0x04U) /* I2C4 Alternate Function mapping */
|
||||||
|
#define GPIO_AF4_CEC ((uint8_t)0x04U) /* CEC Alternate Function mapping */
|
||||||
|
#if defined (STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx)
|
||||||
|
#define GPIO_AF4_USART1 ((uint8_t)0x04) /* USART1 Alternate Function mapping */
|
||||||
|
#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 5 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF5_SPI1 ((uint8_t)0x05U) /* SPI1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /* SPI2/I2S2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF5_SPI3 ((uint8_t)0x05U) /* SPI3/I2S3 Alternate Function mapping */
|
||||||
|
#define GPIO_AF5_SPI4 ((uint8_t)0x05U) /* SPI4 Alternate Function mapping */
|
||||||
|
#define GPIO_AF5_SPI5 ((uint8_t)0x05U) /* SPI5 Alternate Function mapping */
|
||||||
|
#define GPIO_AF5_SPI6 ((uint8_t)0x05U) /* SPI6 Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 6 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF6_SPI3 ((uint8_t)0x06U) /* SPI3/I2S3 Alternate Function mapping */
|
||||||
|
#define GPIO_AF6_SAI1 ((uint8_t)0x06U) /* SAI1 Alternate Function mapping */
|
||||||
|
#if defined (STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx)
|
||||||
|
#define GPIO_AF6_UART4 ((uint8_t)0x06U) /* UART4 Alternate Function mapping */
|
||||||
|
#define GPIO_AF6_DFSDM1 ((uint8_t)0x06U) /* DFSDM1 Alternate Function mapping */
|
||||||
|
#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 7 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF7_USART1 ((uint8_t)0x07U) /* USART1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF7_USART2 ((uint8_t)0x07U) /* USART2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF7_USART3 ((uint8_t)0x07U) /* USART3 Alternate Function mapping */
|
||||||
|
#define GPIO_AF7_UART5 ((uint8_t)0x07U) /* UART5 Alternate Function mapping */
|
||||||
|
#define GPIO_AF7_SPDIFRX ((uint8_t)0x07U) /* SPDIF-RX Alternate Function mapping */
|
||||||
|
#define GPIO_AF7_SPI2 ((uint8_t)0x07U) /* SPI2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF7_SPI3 ((uint8_t)0x07U) /* SPI3 Alternate Function mapping */
|
||||||
|
#if defined (STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx)
|
||||||
|
#define GPIO_AF7_SPI6 ((uint8_t)0x07U) /* SPI6 Alternate Function mapping */
|
||||||
|
#define GPIO_AF7_DFSDM1 ((uint8_t)0x07U) /* DFSDM1 Alternate Function mapping */
|
||||||
|
#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 8 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF8_UART4 ((uint8_t)0x08U) /* UART4 Alternate Function mapping */
|
||||||
|
#define GPIO_AF8_UART5 ((uint8_t)0x08U) /* UART5 Alternate Function mapping */
|
||||||
|
#define GPIO_AF8_USART6 ((uint8_t)0x08U) /* USART6 Alternate Function mapping */
|
||||||
|
#define GPIO_AF8_UART7 ((uint8_t)0x08U) /* UART7 Alternate Function mapping */
|
||||||
|
#define GPIO_AF8_UART8 ((uint8_t)0x08U) /* UART8 Alternate Function mapping */
|
||||||
|
#define GPIO_AF8_SPDIFRX ((uint8_t)0x08U) /* SPIDIF-RX Alternate Function mapping */
|
||||||
|
#define GPIO_AF8_SAI2 ((uint8_t)0x08U) /* SAI2 Alternate Function mapping */
|
||||||
|
#if defined (STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx)
|
||||||
|
#define GPIO_AF8_SPI6 ((uint8_t)0x08U) /* SPI6 Alternate Function mapping */
|
||||||
|
#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 9 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF9_CAN1 ((uint8_t)0x09U) /* CAN1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF9_CAN2 ((uint8_t)0x09U) /* CAN2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF9_TIM12 ((uint8_t)0x09U) /* TIM12 Alternate Function mapping */
|
||||||
|
#define GPIO_AF9_TIM13 ((uint8_t)0x09U) /* TIM13 Alternate Function mapping */
|
||||||
|
#define GPIO_AF9_TIM14 ((uint8_t)0x09U) /* TIM14 Alternate Function mapping */
|
||||||
|
#define GPIO_AF9_QUADSPI ((uint8_t)0x09U) /* QUADSPI Alternate Function mapping */
|
||||||
|
#if defined(STM32F746xx) || defined(STM32F756xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx) || defined(STM32F750xx)
|
||||||
|
#define GPIO_AF9_LTDC ((uint8_t)0x09U) /* LCD-TFT Alternate Function mapping */
|
||||||
|
#endif /* STM32F746xx || STM32F756xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx || STM32F750xx */
|
||||||
|
#if defined(STM32F746xx) || defined(STM32F756xx) || defined(STM32F765xx) || defined(STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx) || defined(STM32F750xx)
|
||||||
|
#define GPIO_AF9_FMC ((uint8_t)0x09U) /* FMC Alternate Function mapping */
|
||||||
|
#endif /* STM32F746xx || STM32F756xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx || STM32F750xx */
|
||||||
|
/**
|
||||||
|
* @brief AF 10 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF10_OTG_FS ((uint8_t)0xAU) /* OTG_FS Alternate Function mapping */
|
||||||
|
#define GPIO_AF10_OTG_HS ((uint8_t)0xAU) /* OTG_HS Alternate Function mapping */
|
||||||
|
#define GPIO_AF10_QUADSPI ((uint8_t)0xAU) /* QUADSPI Alternate Function mapping */
|
||||||
|
#define GPIO_AF10_SAI2 ((uint8_t)0xAU) /* SAI2 Alternate Function mapping */
|
||||||
|
#if defined (STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx)
|
||||||
|
#define GPIO_AF10_DFSDM1 ((uint8_t)0x0AU) /* DFSDM1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF10_SDMMC2 ((uint8_t)0x0AU) /* SDMMC2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF10_LTDC ((uint8_t)0x0AU) /* LCD-TFT Alternate Function mapping */
|
||||||
|
#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 11 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF11_ETH ((uint8_t)0x0BU) /* ETHERNET Alternate Function mapping */
|
||||||
|
#if defined(STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
|
||||||
|
#define GPIO_AF11_CAN3 ((uint8_t)0x0BU) /* CAN3 Alternate Function mapping */
|
||||||
|
#define GPIO_AF11_SDMMC2 ((uint8_t)0x0BU) /* SDMMC2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF11_I2C4 ((uint8_t)0x0BU) /* I2C4 Alternate Function mapping */
|
||||||
|
#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 12 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF12_FMC ((uint8_t)0xCU) /* FMC Alternate Function mapping */
|
||||||
|
#define GPIO_AF12_OTG_HS_FS ((uint8_t)0xCU) /* OTG HS configured in FS, Alternate Function mapping */
|
||||||
|
#define GPIO_AF12_SDMMC1 ((uint8_t)0xCU) /* SDMMC1 Alternate Function mapping */
|
||||||
|
#if defined(STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
|
||||||
|
#define GPIO_AF12_MDIOS ((uint8_t)0xCU) /* SDMMC1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF12_UART7 ((uint8_t)0xCU) /* UART7 Alternate Function mapping */
|
||||||
|
#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 13 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF13_DCMI ((uint8_t)0x0DU) /* DCMI Alternate Function mapping */
|
||||||
|
#if defined (STM32F769xx) || defined (STM32F779xx)
|
||||||
|
#define GPIO_AF13_DSI ((uint8_t)0x0DU) /* DSI Alternate Function mapping */
|
||||||
|
#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
|
||||||
|
#if defined(STM32F746xx) || defined(STM32F756xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx) || defined(STM32F750xx)
|
||||||
|
#define GPIO_AF13_LTDC ((uint8_t)0x0DU) /* LTDC Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 14 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF14_LTDC ((uint8_t)0x0EU) /* LCD-TFT Alternate Function mapping */
|
||||||
|
#endif /* STM32F746xx || STM32F756xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx || STM32F750xx */
|
||||||
|
/**
|
||||||
|
* @brief AF 15 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF15_EVENTOUT ((uint8_t)0x0FU) /* EVENTOUT Alternate Function mapping */
|
||||||
|
#endif /* STM32F745xx || STM32F746xx || STM32F756xx || STM32F765xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*---------------------------- STM32F72xxx/STM32F73xxx -----------------------*/
|
||||||
|
#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F732xx) || defined(STM32F733xx) || defined(STM32F730xx)
|
||||||
|
/**
|
||||||
|
* @brief AF 0 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF0_RTC_50Hz ((uint8_t)0x00U) /* RTC_50Hz Alternate Function mapping */
|
||||||
|
#define GPIO_AF0_MCO ((uint8_t)0x00U) /* MCO (MCO1 and MCO2) Alternate Function mapping */
|
||||||
|
#define GPIO_AF0_SWJ ((uint8_t)0x00U) /* SWJ (SWD and JTAG) Alternate Function mapping */
|
||||||
|
#define GPIO_AF0_TRACE ((uint8_t)0x00U) /* TRACE Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 1 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF1_TIM1 ((uint8_t)0x01U) /* TIM1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF1_TIM2 ((uint8_t)0x01U) /* TIM2 Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 2 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF2_TIM3 ((uint8_t)0x02U) /* TIM3 Alternate Function mapping */
|
||||||
|
#define GPIO_AF2_TIM4 ((uint8_t)0x02U) /* TIM4 Alternate Function mapping */
|
||||||
|
#define GPIO_AF2_TIM5 ((uint8_t)0x02U) /* TIM5 Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 3 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF3_TIM8 ((uint8_t)0x03U) /* TIM8 Alternate Function mapping */
|
||||||
|
#define GPIO_AF3_TIM9 ((uint8_t)0x03U) /* TIM9 Alternate Function mapping */
|
||||||
|
#define GPIO_AF3_TIM10 ((uint8_t)0x03U) /* TIM10 Alternate Function mapping */
|
||||||
|
#define GPIO_AF3_TIM11 ((uint8_t)0x03U) /* TIM11 Alternate Function mapping */
|
||||||
|
#define GPIO_AF3_LPTIM1 ((uint8_t)0x03U) /* LPTIM1 Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 4 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /* I2C1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF4_I2C2 ((uint8_t)0x04U) /* I2C2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF4_I2C3 ((uint8_t)0x04U) /* I2C3 Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 5 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF5_SPI1 ((uint8_t)0x05U) /* SPI1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /* SPI2/I2S2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF5_SPI3 ((uint8_t)0x05U) /* SPI3/I2S3 Alternate Function mapping */
|
||||||
|
#define GPIO_AF5_SPI4 ((uint8_t)0x05U) /* SPI4 Alternate Function mapping */
|
||||||
|
#define GPIO_AF5_SPI5 ((uint8_t)0x05U) /* SPI5 Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 6 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF6_SPI3 ((uint8_t)0x06U) /* SPI3/I2S3 Alternate Function mapping */
|
||||||
|
#define GPIO_AF6_SAI1 ((uint8_t)0x06U) /* SAI1 Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 7 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF7_USART1 ((uint8_t)0x07U) /* USART1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF7_USART2 ((uint8_t)0x07U) /* USART2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF7_USART3 ((uint8_t)0x07U) /* USART3 Alternate Function mapping */
|
||||||
|
#define GPIO_AF7_UART5 ((uint8_t)0x07U) /* UART5 Alternate Function mapping */
|
||||||
|
#define GPIO_AF7_SPI2 ((uint8_t)0x07U) /* SPI2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF7_SPI3 ((uint8_t)0x07U) /* SPI3 Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 8 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF8_UART4 ((uint8_t)0x08U) /* UART4 Alternate Function mapping */
|
||||||
|
#define GPIO_AF8_UART5 ((uint8_t)0x08U) /* UART5 Alternate Function mapping */
|
||||||
|
#define GPIO_AF8_USART6 ((uint8_t)0x08U) /* USART6 Alternate Function mapping */
|
||||||
|
#define GPIO_AF8_UART7 ((uint8_t)0x08U) /* UART7 Alternate Function mapping */
|
||||||
|
#define GPIO_AF8_UART8 ((uint8_t)0x08U) /* UART8 Alternate Function mapping */
|
||||||
|
#define GPIO_AF8_SAI2 ((uint8_t)0x08U) /* SAI2 Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 9 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF9_CAN1 ((uint8_t)0x09U) /* CAN1 Alternate Function mapping */
|
||||||
|
#define GPIO_AF9_TIM12 ((uint8_t)0x09U) /* TIM12 Alternate Function mapping */
|
||||||
|
#define GPIO_AF9_TIM13 ((uint8_t)0x09U) /* TIM13 Alternate Function mapping */
|
||||||
|
#define GPIO_AF9_TIM14 ((uint8_t)0x09U) /* TIM14 Alternate Function mapping */
|
||||||
|
#define GPIO_AF9_QUADSPI ((uint8_t)0x09U) /* QUADSPI Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 10 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF10_OTG_FS ((uint8_t)0xAU) /* OTG_FS Alternate Function mapping */
|
||||||
|
#define GPIO_AF10_OTG_HS ((uint8_t)0xAU) /* OTG_HS Alternate Function mapping */
|
||||||
|
#define GPIO_AF10_QUADSPI ((uint8_t)0xAU) /* QUADSPI Alternate Function mapping */
|
||||||
|
#define GPIO_AF10_SAI2 ((uint8_t)0xAU) /* SAI2 Alternate Function mapping */
|
||||||
|
#define GPIO_AF10_SDMMC2 ((uint8_t)0x0AU) /* SDMMC2 Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 11 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF11_SDMMC2 ((uint8_t)0x0BU) /* SDMMC2 Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 12 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF12_FMC ((uint8_t)0xCU) /* FMC Alternate Function mapping */
|
||||||
|
#define GPIO_AF12_OTG_HS_FS ((uint8_t)0xCU) /* OTG HS configured in FS, Alternate Function mapping */
|
||||||
|
#define GPIO_AF12_SDMMC1 ((uint8_t)0xCU) /* SDMMC1 Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 13 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF13_RNG ((uint8_t)0x0DU) /* RNG Alternate Function mapping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AF 15 selection
|
||||||
|
*/
|
||||||
|
#define GPIO_AF15_EVENTOUT ((uint8_t)0x0FU) /* EVENTOUT Alternate Function mapping */
|
||||||
|
#endif /* STM32F722xx || STM32F723xx || STM32F732xx || STM32F733xx || STM32F730xx */
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/** @defgroup GPIOEx_Exported_Macros GPIO Exported Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
/** @defgroup GPIOEx_Exported_Functions GPIO Exported Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
/* Private types -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* Private constants ---------------------------------------------------------*/
|
||||||
|
/** @defgroup GPIOEx_Private_Constants GPIO Private Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPIO pin available on the platform
|
||||||
|
*/
|
||||||
|
/* Defines the available pins per GPIOs */
|
||||||
|
#define GPIOA_PIN_AVAILABLE GPIO_PIN_All
|
||||||
|
#define GPIOB_PIN_AVAILABLE GPIO_PIN_All
|
||||||
|
#define GPIOC_PIN_AVAILABLE GPIO_PIN_All
|
||||||
|
#define GPIOD_PIN_AVAILABLE GPIO_PIN_All
|
||||||
|
#define GPIOE_PIN_AVAILABLE GPIO_PIN_All
|
||||||
|
#define GPIOF_PIN_AVAILABLE GPIO_PIN_All
|
||||||
|
#define GPIOG_PIN_AVAILABLE GPIO_PIN_All
|
||||||
|
#define GPIOI_PIN_AVAILABLE GPIO_PIN_All
|
||||||
|
#define GPIOJ_PIN_AVAILABLE GPIO_PIN_All
|
||||||
|
#define GPIOH_PIN_AVAILABLE GPIO_PIN_All
|
||||||
|
#define GPIOK_PIN_AVAILABLE (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | \
|
||||||
|
GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Private macros ------------------------------------------------------------*/
|
||||||
|
/** @defgroup GPIOEx_Private_Macros GPIO Private Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/** @defgroup GPIOEx_Get_Port_Index GPIO Get Port Index
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#if defined (STM32F745xx) || defined (STM32F746xx) || defined (STM32F756xx) || defined (STM32F765xx) ||\
|
||||||
|
defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx) ||\
|
||||||
|
defined (STM32F750xx)
|
||||||
|
#define GPIO_GET_INDEX(__GPIOx__) (uint8_t)(((__GPIOx__) == (GPIOA))? 0U :\
|
||||||
|
((__GPIOx__) == (GPIOB))? 1U :\
|
||||||
|
((__GPIOx__) == (GPIOC))? 2U :\
|
||||||
|
((__GPIOx__) == (GPIOD))? 3U :\
|
||||||
|
((__GPIOx__) == (GPIOE))? 4U :\
|
||||||
|
((__GPIOx__) == (GPIOF))? 5U :\
|
||||||
|
((__GPIOx__) == (GPIOG))? 6U :\
|
||||||
|
((__GPIOx__) == (GPIOH))? 7U :\
|
||||||
|
((__GPIOx__) == (GPIOI))? 8U :\
|
||||||
|
((__GPIOx__) == (GPIOJ))? 9U : 10U)
|
||||||
|
#endif /* STM32F745xx || STM32F746xx || STM32F756xx || STM32F765xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx || STM32F750xx */
|
||||||
|
|
||||||
|
#if defined (STM32F722xx) || defined (STM32F723xx) || defined (STM32F732xx) || defined (STM32F733xx) || defined (STM32F730xx)
|
||||||
|
#define GPIO_GET_INDEX(__GPIOx__) (uint8_t)(((__GPIOx__) == (GPIOA))? 0U :\
|
||||||
|
((__GPIOx__) == (GPIOB))? 1U :\
|
||||||
|
((__GPIOx__) == (GPIOC))? 2U :\
|
||||||
|
((__GPIOx__) == (GPIOD))? 3U :\
|
||||||
|
((__GPIOx__) == (GPIOE))? 4U :\
|
||||||
|
((__GPIOx__) == (GPIOF))? 5U :\
|
||||||
|
((__GPIOx__) == (GPIOG))? 6U :\
|
||||||
|
((__GPIOx__) == (GPIOH))? 7U : 8U)
|
||||||
|
#endif /* STM32F722xx || STM32F723xx || STM32F732xx || STM32F733xx || STM32F730xx */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define IS_GPIO_PIN_AVAILABLE(__INSTANCE__,__PIN__) \
|
||||||
|
((((__INSTANCE__) == GPIOA) && (((__PIN__) & (GPIOA_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOA_PIN_AVAILABLE)) == (GPIOA_PIN_AVAILABLE))) || \
|
||||||
|
(((__INSTANCE__) == GPIOB) && (((__PIN__) & (GPIOB_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOB_PIN_AVAILABLE)) == (GPIOB_PIN_AVAILABLE))) || \
|
||||||
|
(((__INSTANCE__) == GPIOC) && (((__PIN__) & (GPIOC_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOC_PIN_AVAILABLE)) == (GPIOC_PIN_AVAILABLE))) || \
|
||||||
|
(((__INSTANCE__) == GPIOD) && (((__PIN__) & (GPIOD_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOD_PIN_AVAILABLE)) == (GPIOD_PIN_AVAILABLE))) || \
|
||||||
|
(((__INSTANCE__) == GPIOE) && (((__PIN__) & (GPIOE_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOE_PIN_AVAILABLE)) == (GPIOE_PIN_AVAILABLE))) || \
|
||||||
|
(((__INSTANCE__) == GPIOF) && (((__PIN__) & (GPIOF_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOF_PIN_AVAILABLE)) == (GPIOF_PIN_AVAILABLE))) || \
|
||||||
|
(((__INSTANCE__) == GPIOG) && (((__PIN__) & (GPIOG_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOG_PIN_AVAILABLE)) == (GPIOG_PIN_AVAILABLE))) || \
|
||||||
|
(((__INSTANCE__) == GPIOI) && (((__PIN__) & (GPIOI_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOI_PIN_AVAILABLE)) == (GPIOI_PIN_AVAILABLE))) || \
|
||||||
|
(((__INSTANCE__) == GPIOJ) && (((__PIN__) & (GPIOJ_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOJ_PIN_AVAILABLE)) == (GPIOJ_PIN_AVAILABLE))) || \
|
||||||
|
(((__INSTANCE__) == GPIOK) && (((__PIN__) & (GPIOK_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOK_PIN_AVAILABLE)) == (GPIOK_PIN_AVAILABLE))) || \
|
||||||
|
(((__INSTANCE__) == GPIOH) && (((__PIN__) & (GPIOH_PIN_AVAILABLE)) != 0) && (((__PIN__) | (GPIOH_PIN_AVAILABLE)) == (GPIOH_PIN_AVAILABLE))))
|
||||||
|
/** @defgroup GPIOEx_IS_Alternat_function_selection GPIO Check Alternate Function
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#if defined(STM32F756xx) || defined(STM32F746xx) || defined(STM32F750xx)
|
||||||
|
#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF1_TIM1) || \
|
||||||
|
((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \
|
||||||
|
((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF1_TIM2) || \
|
||||||
|
((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \
|
||||||
|
((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \
|
||||||
|
((AF) == GPIO_AF3_TIM9) || ((AF) == GPIO_AF3_TIM10) || \
|
||||||
|
((AF) == GPIO_AF3_TIM11) || ((AF) == GPIO_AF3_LPTIM1) || \
|
||||||
|
((AF) == GPIO_AF3_CEC) || ((AF) == GPIO_AF4_CEC) || \
|
||||||
|
((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \
|
||||||
|
((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF4_I2C4) || \
|
||||||
|
((AF) == GPIO_AF5_SPI1) || ((AF) == GPIO_AF5_SPI2) || \
|
||||||
|
((AF) == GPIO_AF5_SPI3) || ((AF) == GPIO_AF5_SPI4) || \
|
||||||
|
((AF) == GPIO_AF5_SPI5) || ((AF) == GPIO_AF5_SPI6) || \
|
||||||
|
((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF6_SAI1) || \
|
||||||
|
((AF) == GPIO_AF7_SPI3) || ((AF) == GPIO_AF7_SPI2) || \
|
||||||
|
((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \
|
||||||
|
((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF7_UART5) || \
|
||||||
|
((AF) == GPIO_AF7_SPDIFRX) || ((AF) == GPIO_AF8_SPDIFRX) || \
|
||||||
|
((AF) == GPIO_AF8_SAI2) || ((AF) == GPIO_AF8_USART6) || \
|
||||||
|
((AF) == GPIO_AF8_UART4) || ((AF) == GPIO_AF8_UART5) || \
|
||||||
|
((AF) == GPIO_AF8_UART7) || ((AF) == GPIO_AF8_UART8) || \
|
||||||
|
((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_CAN2) || \
|
||||||
|
((AF) == GPIO_AF9_TIM12) || ((AF) == GPIO_AF9_TIM12) || \
|
||||||
|
((AF) == GPIO_AF9_TIM14) || ((AF) == GPIO_AF9_QUADSPI) || \
|
||||||
|
((AF) == GPIO_AF9_LTDC) || ((AF) == GPIO_AF10_OTG_FS) || \
|
||||||
|
((AF) == GPIO_AF10_OTG_HS) || ((AF) == GPIO_AF10_SAI2) || \
|
||||||
|
((AF) == GPIO_AF10_QUADSPI) || ((AF) == GPIO_AF11_ETH) || \
|
||||||
|
((AF) == GPIO_AF12_OTG_HS_FS) || ((AF) == GPIO_AF12_SDMMC1) || \
|
||||||
|
((AF) == GPIO_AF12_FMC) || ((AF) == GPIO_AF15_EVENTOUT) || \
|
||||||
|
((AF) == GPIO_AF13_DCMI) || ((AF) == GPIO_AF14_LTDC))
|
||||||
|
#elif defined(STM32F745xx)
|
||||||
|
#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF1_TIM1) || \
|
||||||
|
((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \
|
||||||
|
((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF1_TIM2) || \
|
||||||
|
((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \
|
||||||
|
((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \
|
||||||
|
((AF) == GPIO_AF3_TIM9) || ((AF) == GPIO_AF3_TIM10) || \
|
||||||
|
((AF) == GPIO_AF3_TIM11) || ((AF) == GPIO_AF3_LPTIM1) || \
|
||||||
|
((AF) == GPIO_AF3_CEC) || ((AF) == GPIO_AF4_CEC) || \
|
||||||
|
((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \
|
||||||
|
((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF4_I2C4) || \
|
||||||
|
((AF) == GPIO_AF5_SPI1) || ((AF) == GPIO_AF5_SPI2) || \
|
||||||
|
((AF) == GPIO_AF5_SPI3) || ((AF) == GPIO_AF5_SPI4) || \
|
||||||
|
((AF) == GPIO_AF5_SPI5) || ((AF) == GPIO_AF5_SPI6) || \
|
||||||
|
((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF6_SAI1) || \
|
||||||
|
((AF) == GPIO_AF7_SPI3) || ((AF) == GPIO_AF7_SPI2) || \
|
||||||
|
((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \
|
||||||
|
((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF7_UART5) || \
|
||||||
|
((AF) == GPIO_AF7_SPDIFRX) || ((AF) == GPIO_AF8_SPDIFRX) || \
|
||||||
|
((AF) == GPIO_AF8_SAI2) || ((AF) == GPIO_AF8_USART6) || \
|
||||||
|
((AF) == GPIO_AF8_UART4) || ((AF) == GPIO_AF8_UART5) || \
|
||||||
|
((AF) == GPIO_AF8_UART7) || ((AF) == GPIO_AF8_UART8) || \
|
||||||
|
((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_CAN2) || \
|
||||||
|
((AF) == GPIO_AF9_TIM12) || ((AF) == GPIO_AF9_TIM12) || \
|
||||||
|
((AF) == GPIO_AF9_TIM14) || ((AF) == GPIO_AF9_QUADSPI) || \
|
||||||
|
((AF) == GPIO_AF13_DCMI) || ((AF) == GPIO_AF10_OTG_FS) || \
|
||||||
|
((AF) == GPIO_AF10_OTG_HS) || ((AF) == GPIO_AF10_SAI2) || \
|
||||||
|
((AF) == GPIO_AF10_QUADSPI) || ((AF) == GPIO_AF11_ETH) || \
|
||||||
|
((AF) == GPIO_AF12_OTG_HS_FS) || ((AF) == GPIO_AF12_SDMMC1) || \
|
||||||
|
((AF) == GPIO_AF12_FMC) || ((AF) == GPIO_AF15_EVENTOUT))
|
||||||
|
#elif defined(STM32F767xx) || defined(STM32F777xx)
|
||||||
|
#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF1_TIM1) || \
|
||||||
|
((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \
|
||||||
|
((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF1_TIM2) || \
|
||||||
|
((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \
|
||||||
|
((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \
|
||||||
|
((AF) == GPIO_AF3_TIM9) || ((AF) == GPIO_AF3_TIM10) || \
|
||||||
|
((AF) == GPIO_AF3_TIM11) || ((AF) == GPIO_AF3_LPTIM1) || \
|
||||||
|
((AF) == GPIO_AF3_CEC) || ((AF) == GPIO_AF4_CEC) || \
|
||||||
|
((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \
|
||||||
|
((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF4_I2C4) || \
|
||||||
|
((AF) == GPIO_AF5_SPI1) || ((AF) == GPIO_AF5_SPI2) || \
|
||||||
|
((AF) == GPIO_AF5_SPI3) || ((AF) == GPIO_AF5_SPI4) || \
|
||||||
|
((AF) == GPIO_AF5_SPI5) || ((AF) == GPIO_AF5_SPI6) || \
|
||||||
|
((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF6_SAI1) || \
|
||||||
|
((AF) == GPIO_AF7_SPI3) || ((AF) == GPIO_AF7_SPI2) || \
|
||||||
|
((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \
|
||||||
|
((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF7_UART5) || \
|
||||||
|
((AF) == GPIO_AF7_SPDIFRX) || ((AF) == GPIO_AF8_SPDIFRX) || \
|
||||||
|
((AF) == GPIO_AF8_SAI2) || ((AF) == GPIO_AF8_USART6) || \
|
||||||
|
((AF) == GPIO_AF8_UART4) || ((AF) == GPIO_AF8_UART5) || \
|
||||||
|
((AF) == GPIO_AF8_UART7) || ((AF) == GPIO_AF8_UART8) || \
|
||||||
|
((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_CAN2) || \
|
||||||
|
((AF) == GPIO_AF9_TIM12) || ((AF) == GPIO_AF9_TIM12) || \
|
||||||
|
((AF) == GPIO_AF9_TIM14) || ((AF) == GPIO_AF9_QUADSPI) || \
|
||||||
|
((AF) == GPIO_AF10_OTG_FS) || ((AF) == GPIO_AF9_LTDC) || \
|
||||||
|
((AF) == GPIO_AF10_OTG_HS) || ((AF) == GPIO_AF10_SAI2) || \
|
||||||
|
((AF) == GPIO_AF10_QUADSPI) || ((AF) == GPIO_AF11_ETH) || \
|
||||||
|
((AF) == GPIO_AF10_SDMMC2) || ((AF) == GPIO_AF11_SDMMC2) || \
|
||||||
|
((AF) == GPIO_AF11_CAN3) || ((AF) == GPIO_AF12_OTG_HS_FS) || \
|
||||||
|
((AF) == GPIO_AF12_SDMMC1) || ((AF) == GPIO_AF12_FMC) || \
|
||||||
|
((AF) == GPIO_AF15_EVENTOUT) || ((AF) == GPIO_AF13_DCMI) || \
|
||||||
|
((AF) == GPIO_AF14_LTDC))
|
||||||
|
#elif defined(STM32F769xx) || defined(STM32F779xx)
|
||||||
|
#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF1_TIM1) || \
|
||||||
|
((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \
|
||||||
|
((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF1_TIM2) || \
|
||||||
|
((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \
|
||||||
|
((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \
|
||||||
|
((AF) == GPIO_AF3_TIM9) || ((AF) == GPIO_AF3_TIM10) || \
|
||||||
|
((AF) == GPIO_AF3_TIM11) || ((AF) == GPIO_AF3_LPTIM1) || \
|
||||||
|
((AF) == GPIO_AF3_CEC) || ((AF) == GPIO_AF4_CEC) || \
|
||||||
|
((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \
|
||||||
|
((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF4_I2C4) || \
|
||||||
|
((AF) == GPIO_AF5_SPI1) || ((AF) == GPIO_AF5_SPI2) || \
|
||||||
|
((AF) == GPIO_AF5_SPI3) || ((AF) == GPIO_AF5_SPI4) || \
|
||||||
|
((AF) == GPIO_AF5_SPI5) || ((AF) == GPIO_AF5_SPI6) || \
|
||||||
|
((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF6_SAI1) || \
|
||||||
|
((AF) == GPIO_AF7_SPI3) || ((AF) == GPIO_AF7_SPI2) || \
|
||||||
|
((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \
|
||||||
|
((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF7_UART5) || \
|
||||||
|
((AF) == GPIO_AF7_SPDIFRX) || ((AF) == GPIO_AF8_SPDIFRX) || \
|
||||||
|
((AF) == GPIO_AF8_SAI2) || ((AF) == GPIO_AF8_USART6) || \
|
||||||
|
((AF) == GPIO_AF8_UART4) || ((AF) == GPIO_AF8_UART5) || \
|
||||||
|
((AF) == GPIO_AF8_UART7) || ((AF) == GPIO_AF8_UART8) || \
|
||||||
|
((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_CAN2) || \
|
||||||
|
((AF) == GPIO_AF9_TIM12) || ((AF) == GPIO_AF9_TIM12) || \
|
||||||
|
((AF) == GPIO_AF9_TIM14) || ((AF) == GPIO_AF9_QUADSPI) || \
|
||||||
|
((AF) == GPIO_AF9_LTDC) || ((AF) == GPIO_AF10_OTG_FS) || \
|
||||||
|
((AF) == GPIO_AF10_OTG_HS) || ((AF) == GPIO_AF10_SAI2) || \
|
||||||
|
((AF) == GPIO_AF10_QUADSPI) || ((AF) == GPIO_AF11_ETH) || \
|
||||||
|
((AF) == GPIO_AF10_SDMMC2) || ((AF) == GPIO_AF11_SDMMC2) || \
|
||||||
|
((AF) == GPIO_AF11_CAN3) || ((AF) == GPIO_AF12_OTG_HS_FS) || \
|
||||||
|
((AF) == GPIO_AF12_SDMMC1) || ((AF) == GPIO_AF12_FMC) || \
|
||||||
|
((AF) == GPIO_AF15_EVENTOUT) || ((AF) == GPIO_AF13_DCMI) || \
|
||||||
|
((AF) == GPIO_AF14_LTDC) || ((AF) == GPIO_AF13_DSI))
|
||||||
|
#elif defined(STM32F765xx)
|
||||||
|
#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF1_TIM1) || \
|
||||||
|
((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \
|
||||||
|
((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF1_TIM2) || \
|
||||||
|
((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \
|
||||||
|
((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \
|
||||||
|
((AF) == GPIO_AF3_TIM9) || ((AF) == GPIO_AF3_TIM10) || \
|
||||||
|
((AF) == GPIO_AF3_TIM11) || ((AF) == GPIO_AF3_LPTIM1) || \
|
||||||
|
((AF) == GPIO_AF3_CEC) || ((AF) == GPIO_AF4_CEC) || \
|
||||||
|
((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \
|
||||||
|
((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF4_I2C4) || \
|
||||||
|
((AF) == GPIO_AF5_SPI1) || ((AF) == GPIO_AF5_SPI2) || \
|
||||||
|
((AF) == GPIO_AF5_SPI3) || ((AF) == GPIO_AF5_SPI4) || \
|
||||||
|
((AF) == GPIO_AF5_SPI5) || ((AF) == GPIO_AF5_SPI6) || \
|
||||||
|
((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF6_SAI1) || \
|
||||||
|
((AF) == GPIO_AF7_SPI3) || ((AF) == GPIO_AF7_SPI2) || \
|
||||||
|
((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \
|
||||||
|
((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF7_UART5) || \
|
||||||
|
((AF) == GPIO_AF7_SPDIFRX) || ((AF) == GPIO_AF8_SPDIFRX) || \
|
||||||
|
((AF) == GPIO_AF8_SAI2) || ((AF) == GPIO_AF8_USART6) || \
|
||||||
|
((AF) == GPIO_AF8_UART4) || ((AF) == GPIO_AF8_UART5) || \
|
||||||
|
((AF) == GPIO_AF8_UART7) || ((AF) == GPIO_AF8_UART8) || \
|
||||||
|
((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_CAN2) || \
|
||||||
|
((AF) == GPIO_AF9_TIM12) || ((AF) == GPIO_AF9_TIM12) || \
|
||||||
|
((AF) == GPIO_AF9_TIM14) || ((AF) == GPIO_AF9_QUADSPI) || \
|
||||||
|
((AF) == GPIO_AF10_OTG_HS) || ((AF) == GPIO_AF10_SAI2) || \
|
||||||
|
((AF) == GPIO_AF10_QUADSPI) || ((AF) == GPIO_AF11_ETH) || \
|
||||||
|
((AF) == GPIO_AF10_SDMMC2) || ((AF) == GPIO_AF11_SDMMC2) || \
|
||||||
|
((AF) == GPIO_AF11_CAN3) || ((AF) == GPIO_AF12_OTG_HS_FS) || \
|
||||||
|
((AF) == GPIO_AF12_SDMMC1) || ((AF) == GPIO_AF12_FMC) || \
|
||||||
|
((AF) == GPIO_AF15_EVENTOUT) || ((AF) == GPIO_AF13_DCMI) || \
|
||||||
|
((AF) == GPIO_AF10_OTG_FS))
|
||||||
|
#elif defined (STM32F722xx) || defined (STM32F723xx) || defined (STM32F732xx) || defined (STM32F733xx) || defined (STM32F730xx)
|
||||||
|
#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF1_TIM1) || \
|
||||||
|
((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \
|
||||||
|
((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF1_TIM2) || \
|
||||||
|
((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \
|
||||||
|
((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \
|
||||||
|
((AF) == GPIO_AF3_TIM9) || ((AF) == GPIO_AF3_TIM10) || \
|
||||||
|
((AF) == GPIO_AF3_TIM11) || ((AF) == GPIO_AF3_LPTIM1) || \
|
||||||
|
((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \
|
||||||
|
((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF5_SPI1) || \
|
||||||
|
((AF) == GPIO_AF5_SPI2) || ((AF) == GPIO_AF5_SPI3) || \
|
||||||
|
((AF) == GPIO_AF5_SPI4) || ((AF) == GPIO_AF5_SPI5) || \
|
||||||
|
((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF6_SAI1) || \
|
||||||
|
((AF) == GPIO_AF7_SPI3) || ((AF) == GPIO_AF7_SPI2) || \
|
||||||
|
((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \
|
||||||
|
((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF7_UART5) || \
|
||||||
|
((AF) == GPIO_AF8_SAI2) || ((AF) == GPIO_AF8_USART6) || \
|
||||||
|
((AF) == GPIO_AF8_UART4) || ((AF) == GPIO_AF8_UART5) || \
|
||||||
|
((AF) == GPIO_AF8_UART7) || ((AF) == GPIO_AF8_UART8) || \
|
||||||
|
((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_TIM12) || \
|
||||||
|
((AF) == GPIO_AF9_TIM12) || ((AF) == GPIO_AF9_TIM14) || \
|
||||||
|
((AF) == GPIO_AF9_QUADSPI) || ((AF) == GPIO_AF10_OTG_HS) || \
|
||||||
|
((AF) == GPIO_AF10_SAI2) || ((AF) == GPIO_AF10_QUADSPI) || \
|
||||||
|
((AF) == GPIO_AF10_SDMMC2) || ((AF) == GPIO_AF11_SDMMC2) || \
|
||||||
|
((AF) == GPIO_AF12_OTG_HS_FS) || ((AF) == GPIO_AF12_SDMMC1) || \
|
||||||
|
((AF) == GPIO_AF12_FMC) || ((AF) == GPIO_AF15_EVENTOUT) || \
|
||||||
|
((AF) == GPIO_AF10_OTG_FS))
|
||||||
|
#endif /* STM32F756xx || STM32F746xx || STM32F750xx */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
/** @defgroup GPIOEx_Private_Functions GPIO Private Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __STM32F7xx_HAL_GPIO_EX_H */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,95 @@
|
|||||||
|
# FreeRTOS/{FreeRTOS-Kernel V10.4.3,FreeRTOS-Plus-TCP V2.3.2}
|
||||||
|
PROG = firmware
|
||||||
|
ARCH = stm32f7
|
||||||
|
PROJECT_ROOT_PATH = $(realpath $(CURDIR)/../..)
|
||||||
|
DOCKER ?= docker run -it --rm -v $(PROJECT_ROOT_PATH):$(PROJECT_ROOT_PATH) -w $(CURDIR) mdashnet/armgcc
|
||||||
|
FREERTOS_KERNEL_PATH ?= $(PROJECT_ROOT_PATH)/test/freertos-kernel
|
||||||
|
FREERTOS_PLUS_TCP_PATH ?= $(PROJECT_ROOT_PATH)/test/freertos-tcp
|
||||||
|
|
||||||
|
MONGOOSE_FLAGS = -DMG_ARCH=MG_ARCH_FREERTOS_TCP -DMG_ENABLE_FS=1
|
||||||
|
MCU_FLAGS = -mcpu=cortex-m7 -mthumb -mfloat-abi=softfp -mfpu=vfpv4
|
||||||
|
#-mcpu=cortex-m7 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard
|
||||||
|
|
||||||
|
INCLUDES = -I$(PROJECT_ROOT_PATH) -I$(ARCH) -I$(FREERTOS_KERNEL_PATH)/include -I$(FREERTOS_PLUS_TCP_PATH)/include
|
||||||
|
INCLUDES += -I$(FREERTOS_PLUS_TCP_PATH)/tools/tcp_utilities/include
|
||||||
|
INCLUDES += -I$(FREERTOS_PLUS_TCP_PATH)/../Utilities/include
|
||||||
|
#INCLUDES += -IH2
|
||||||
|
#INCLUDES += -I/Users/lsm/src/htibosch/plus/stm32F7/ST_Library/include
|
||||||
|
INCLUDES += -IHAL
|
||||||
|
INCLUDES += -I$(FREERTOS_PLUS_TCP_PATH)/portable/Compiler/GCC
|
||||||
|
INCLUDES += -I$(FREERTOS_PLUS_TCP_PATH)/portable/NetworkInterface/STM32Fxx
|
||||||
|
INCLUDES += -I$(FREERTOS_PLUS_TCP_PATH)/portable/NetworkInterface/include
|
||||||
|
NETFLAGS = -DSTM32F7xx -DSTM32F746xx -Wno-sign-compare -Wno-unused-function #-Wno-cpp
|
||||||
|
|
||||||
|
CFLAGS = -g3 -O0 -W -Wall $(MCU_FLAGS)
|
||||||
|
CFLAGS += $(INCLUDES) $(MONGOOSE_FLAGS) $(NETFLAGS) $(EXTRA)
|
||||||
|
|
||||||
|
LINKFLAGS = -T$(ARCH)/link.ld -mcpu=cortex-m7 -mthumb -nostartfiles --specs rdimon.specs -Wl,--gc-sections
|
||||||
|
|
||||||
|
SOURCES = main.c $(PROJECT_ROOT_PATH)/mongoose.c
|
||||||
|
SOURCES += $(wildcard HAL/*.c)
|
||||||
|
#SOURCES += -I$(realpath $(FREERTOS_KERNEL_PATH)/../../stm32F7/ST_Library/sources)/
|
||||||
|
|
||||||
|
# FreeRTOS kernel sources
|
||||||
|
SOURCES += $(wildcard $(FREERTOS_KERNEL_PATH)/*.c)
|
||||||
|
SOURCES += $(FREERTOS_KERNEL_PATH)/portable/MemMang/heap_5.c
|
||||||
|
SOURCES += $(FREERTOS_KERNEL_PATH)/portable/GCC/ARM_CM7/r0p1/port.c
|
||||||
|
|
||||||
|
# FreeRTOS TCP stack sources
|
||||||
|
SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_ARP.c
|
||||||
|
SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_DHCP.c
|
||||||
|
SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_DNS.c
|
||||||
|
SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_IP.c
|
||||||
|
SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_Sockets.c
|
||||||
|
SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_Stream_Buffer.c
|
||||||
|
SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_TCP_IP.c
|
||||||
|
SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_TCP_WIN.c
|
||||||
|
SOURCES += $(FREERTOS_PLUS_TCP_PATH)/FreeRTOS_UDP_IP.c
|
||||||
|
SOURCES += $(FREERTOS_PLUS_TCP_PATH)/portable/NetworkInterface/Common/phyHandling.c
|
||||||
|
SOURCES += $(FREERTOS_PLUS_TCP_PATH)/portable/BufferManagement/BufferAllocation_1.c
|
||||||
|
SOURCES += $(FREERTOS_PLUS_TCP_PATH)/portable/NetworkInterface/STM32Fxx/NetworkInterface.c
|
||||||
|
SOURCES += $(FREERTOS_PLUS_TCP_PATH)/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.c
|
||||||
|
|
||||||
|
OBJECTS = obj/boot.o $(SOURCES:%.c=obj/%.o)
|
||||||
|
|
||||||
|
all: $(PROG).hex
|
||||||
|
|
||||||
|
$(PROG).bin: $(PROG).elf
|
||||||
|
$(DOCKER) arm-none-eabi-objcopy -O binary $< $@
|
||||||
|
|
||||||
|
$(PROG).hex: $(PROG).bin
|
||||||
|
$(DOCKER) arm-none-eabi-objcopy -I binary -O ihex --change-address 0x8000000 $< $@
|
||||||
|
|
||||||
|
$(PROG).elf: $(OBJECTS) Makefile
|
||||||
|
$(DOCKER) arm-none-eabi-gcc $(OBJECTS) $(LINKFLAGS) -o $@
|
||||||
|
$(DOCKER) arm-none-eabi-size -A $@
|
||||||
|
|
||||||
|
obj/%.o: %.c
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
$(DOCKER) arm-none-eabi-gcc $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
obj/boot.o: $(ARCH)/boot.s
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
$(DOCKER) arm-none-eabi-as -g3 --warn --fatal-warnings $(MCU_FLAGS) $< -o $@
|
||||||
|
|
||||||
|
flash: $(PROG).bin
|
||||||
|
st-flash --reset write $< 0x8000000
|
||||||
|
|
||||||
|
openocd:
|
||||||
|
openocd -f openocd.cfg
|
||||||
|
|
||||||
|
ELF ?= $(PROG).elf
|
||||||
|
gdb: #$(PROG).elf
|
||||||
|
arm-none-eabi-gdb \
|
||||||
|
-ex 'set confirm off' \
|
||||||
|
-ex 'target extended-remote :3333' \
|
||||||
|
-ex 'monitor arm semihosting enable' \
|
||||||
|
-ex 'monitor reset halt' \
|
||||||
|
-ex 'load' \
|
||||||
|
-ex 'monitor reset init' \
|
||||||
|
-ex '$(GDBCMD)' \
|
||||||
|
-ex 'r' \
|
||||||
|
$(ELF)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -rf *.{bin,elf,map,lst,tgz,zip,hex} obj
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# Mongoose with STM32, FreeRTOS kernel and FreeRTOS-TCP network stack
|
||||||
|
|
||||||
|
The `-DMG_ARCH=MG_ARCH_FREERTOS_TCP` compilation flag enables FreeRTOS+TCP support.
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
// Copyright (c) 2021 Cesanta Software Limited
|
||||||
|
// All rights reserved
|
||||||
|
|
||||||
|
#include "device.h"
|
||||||
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
static const char *s_debug_level = "4";
|
||||||
|
static const char *s_listening_address = "http://0.0.0.0:80";
|
||||||
|
|
||||||
|
// Event handler for the listening connection.
|
||||||
|
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||||
|
if (ev == MG_EV_HTTP_MSG) {
|
||||||
|
#if MG_ENABLE_FS
|
||||||
|
struct mg_http_serve_opts opts = {.root_dir = "/"};
|
||||||
|
mg_http_serve_dir(c, ev_data, &opts);
|
||||||
|
#else
|
||||||
|
mg_http_reply(c, 200, "", "hello, %s!\n", "world");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
(void) fn_data;
|
||||||
|
(void) ev_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void server(void *args) {
|
||||||
|
struct mg_mgr mgr;
|
||||||
|
mg_log_set(s_debug_level);
|
||||||
|
mg_mgr_init(&mgr);
|
||||||
|
LOG(LL_INFO, ("Starting Mongoose v%s", MG_VERSION)); // Tell the world
|
||||||
|
mg_http_listen(&mgr, s_listening_address, cb, &mgr); // Web listener
|
||||||
|
while (args == NULL) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
||||||
|
mg_mgr_free(&mgr); // Unreachable
|
||||||
|
}
|
||||||
|
|
||||||
|
static void blinker(void *args) {
|
||||||
|
uint16_t pin = ((char *) args)[0] == '1' ? LED2 : LED3;
|
||||||
|
int ms = pin == LED2 ? 3750 : 5130;
|
||||||
|
for (;;) {
|
||||||
|
gpio_toggle(pin);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(ms));
|
||||||
|
LOG(LL_INFO, ("blink %s, RAM: %u", (char *) args, xPortGetFreeHeapSize()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start Mongoose server when network is ready
|
||||||
|
void vApplicationIPNetworkEventHook(eIPCallbackEvent_t ev) {
|
||||||
|
static bool mongoose_started = false;
|
||||||
|
LOG(LL_INFO, ("FreeRTOS net event %d, up: %d", ev, eNetworkUp));
|
||||||
|
if (ev == eNetworkUp && mongoose_started == false) {
|
||||||
|
xTaskCreate(server, "server", 8192, NULL, configMAX_PRIORITIES - 1, NULL);
|
||||||
|
mongoose_started = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_heap(void) {
|
||||||
|
extern uint32_t _end, _estack;
|
||||||
|
uint8_t *ptr = (uint8_t *) ((((uint32_t) &_end) + 7) & ~7U);
|
||||||
|
uint32_t len = (uint32_t)((char *) &_estack - (char *) &_end);
|
||||||
|
HeapRegion_t regions[] = {{ptr, len}, {NULL, 0}};
|
||||||
|
vPortDefineHeapRegions(regions);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
init_hardware();
|
||||||
|
init_heap();
|
||||||
|
|
||||||
|
// Initialise networking task. Can be done before scheduler is started
|
||||||
|
static const uint8_t macaddr[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
|
||||||
|
static const uint8_t ipaddr[4] = {192, 168, 0, 77};
|
||||||
|
static const uint8_t netmask[4] = {255, 255, 255, 0};
|
||||||
|
static const uint8_t dnsaddr[4] = {8, 8, 8, 8};
|
||||||
|
static const uint8_t gwaddr[4] = {192, 168, 0, 1};
|
||||||
|
FreeRTOS_IPInit(ipaddr, netmask, gwaddr, dnsaddr, macaddr);
|
||||||
|
|
||||||
|
xTaskCreate(blinker, "blinker", 512, "1", configMAX_PRIORITIES - 1, NULL);
|
||||||
|
xTaskCreate(blinker, "blinker", 512, "2", configMAX_PRIORITIES - 1, NULL);
|
||||||
|
vTaskStartScheduler(); // This blocks
|
||||||
|
return 0; // Unreachable
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stubs for FreeRTOS-TCP network interface
|
||||||
|
uint32_t ulApplicationGetNextSequenceNumber(uint32_t a, uint16_t b, uint32_t c,
|
||||||
|
uint16_t d) {
|
||||||
|
return a ^ b ^ c ^ d;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseType_t xApplicationGetRandomNumber(uint32_t *p) {
|
||||||
|
*p = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SystemCoreClock = 216000000;
|
||||||
|
uint32_t HAL_RCC_GetHCLKFreq(void) {
|
||||||
|
return SystemCoreClock;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t HAL_GetTick(void) {
|
||||||
|
return configTICK_RATE_HZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "stm32f7xx_hal_conf.h"
|
||||||
|
#include "stm32fxx_hal_eth.h"
|
||||||
|
void HAL_ETH_MspInit( ETH_HandleTypeDef* heth ) {
|
||||||
|
GPIO_InitTypeDef GPIO_InitStructure;
|
||||||
|
if (heth->Instance == ETH) {
|
||||||
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||||
|
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||||
|
__HAL_RCC_GPIOG_CLK_ENABLE();
|
||||||
|
|
||||||
|
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
|
||||||
|
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||||
|
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||||
|
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
|
||||||
|
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
|
||||||
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||||
|
|
||||||
|
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
|
||||||
|
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||||
|
|
||||||
|
GPIO_InitStructure.Pin = GPIO_PIN_2 | GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14;
|
||||||
|
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
|
||||||
|
|
||||||
|
HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(ETH_IRQn);
|
||||||
|
|
||||||
|
__HAL_RCC_ETH_CLK_ENABLE();
|
||||||
|
HAL_NVIC_SetPriorityGrouping( NVIC_PRIORITYGROUP_4 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int vLoggingPrintf(const char *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
char buf[100];
|
||||||
|
int n = vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
write(1, buf, n);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *_sbrk(ptrdiff_t incr) {
|
||||||
|
(void) incr;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
source [find interface/stlink-v2-1.cfg]
|
||||||
|
transport select hla_swd
|
||||||
|
source [find target/stm32f7x.cfg]
|
||||||
|
reset_config srst_only srst_nogate
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define configUSE_PREEMPTION 1
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
#define configCPU_CLOCK_HZ ((unsigned long) 216000000)
|
||||||
|
#define configSYSTICK_CLOCK_HZ (configCPU_CLOCK_HZ / 8)
|
||||||
|
#define configTICK_RATE_HZ 250
|
||||||
|
#define configMAX_PRIORITIES 5
|
||||||
|
#define configMINIMAL_STACK_SIZE 512
|
||||||
|
#define configMAX_TASK_NAME_LEN 16
|
||||||
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
|
#define configUSE_TASK_NOTIFICATIONS 1
|
||||||
|
#define configUSE_MUTEXES 1
|
||||||
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
|
#define configQUEUE_REGISTRY_SIZE 8
|
||||||
|
|
||||||
|
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||||
|
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||||
|
|
||||||
|
#define configUSE_IDLE_HOOK 0
|
||||||
|
#define configUSE_TICK_HOOK 0
|
||||||
|
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||||
|
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||||
|
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
|
||||||
|
|
||||||
|
#define configGENERATE_RUN_TIME_STATS 0
|
||||||
|
#define configUSE_TRACE_FACILITY 0
|
||||||
|
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||||
|
|
||||||
|
#define configUSE_CO_ROUTINES 0
|
||||||
|
#define configMAX_CO_ROUTINE_PRIORITIES 1
|
||||||
|
|
||||||
|
#define configUSE_TIMERS 0
|
||||||
|
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1)
|
||||||
|
#define configTIMER_QUEUE_LENGTH 10
|
||||||
|
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||||
|
|
||||||
|
#ifdef __NVIC_PRIO_BITS
|
||||||
|
#define configPRIO_BITS __NVIC_PRIO_BITS
|
||||||
|
#else
|
||||||
|
#define configPRIO_BITS 4
|
||||||
|
#endif
|
||||||
|
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
|
||||||
|
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 4
|
||||||
|
#define configKERNEL_INTERRUPT_PRIORITY \
|
||||||
|
(configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
|
||||||
|
#define configMAX_SYSCALL_INTERRUPT_PRIORITY \
|
||||||
|
(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
|
||||||
|
|
||||||
|
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
|
||||||
|
|
||||||
|
#define INCLUDE_vTaskPrioritySet 1
|
||||||
|
#define INCLUDE_uxTaskPriorityGet 1
|
||||||
|
#define INCLUDE_vTaskDelete 1
|
||||||
|
#define INCLUDE_vTaskCleanUpResources 0
|
||||||
|
#define INCLUDE_vTaskSuspend 1
|
||||||
|
#define INCLUDE_vTaskDelayUntil 0
|
||||||
|
#define INCLUDE_vTaskDelay 1
|
||||||
|
#define INCLUDE_xTimerPendFunctionCall 0
|
||||||
|
#define INCLUDE_eTaskGetState 1
|
||||||
|
#define INCLUDE_pcTaskGetTaskName 1
|
||||||
|
#define INCLUDE_xTaskGetSchedulerState 1
|
||||||
|
|
||||||
|
#define vPortSVCHandler SVC_Handler
|
||||||
|
#define xPortPendSVHandler PendSV_Handler
|
||||||
|
#define xPortSysTickHandler SysTick_Handler
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
#define FREERTOS_IP_CONFIG_H
|
||||||
|
|
||||||
|
#ifndef ipconfigHAS_DEBUG_PRINTF
|
||||||
|
#define ipconfigHAS_DEBUG_PRINTF 1
|
||||||
|
#endif
|
||||||
|
#if (ipconfigHAS_DEBUG_PRINTF == 1)
|
||||||
|
#define FreeRTOS_debug_printf(X) vLoggingPrintf X
|
||||||
|
#endif
|
||||||
|
#ifndef ipconfigHAS_PRINTF
|
||||||
|
#define ipconfigHAS_PRINTF 1
|
||||||
|
#endif
|
||||||
|
#if (ipconfigHAS_PRINTF == 1)
|
||||||
|
#define FreeRTOS_printf(X) vLoggingPrintf X
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN
|
||||||
|
#define ipconfigREPLY_TO_INCOMING_PINGS 1
|
||||||
|
#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM (1)
|
||||||
|
#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM (1)
|
||||||
|
#define ipconfigZERO_COPY_RX_DRIVER (1)
|
||||||
|
#define ipconfigZERO_COPY_TX_DRIVER (1)
|
||||||
|
#define ipconfigIP_TASK_PRIORITY 4
|
||||||
|
#define niEMAC_HANDLER_TASK_PRIORITY 5
|
||||||
|
#define ipconfigIPERF_PRIORITY_IPERF_TASK 6
|
||||||
|
#define ipconfigIP_TASK_STACK_SIZE_WORDS (configMINIMAL_STACK_SIZE * 5)
|
||||||
|
extern UBaseType_t uxRand();
|
||||||
|
#define ipconfigRAND32() uxRand()
|
||||||
|
#define ipconfigUSE_NETWORK_EVENT_HOOK 1
|
||||||
|
#define ipconfigUSE_DHCP 0
|
||||||
|
#define ipconfigDHCP_REGISTER_HOSTNAME 0
|
||||||
|
#define ipconfigDHCP_USES_UNICAST 1
|
||||||
|
#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD (pdMS_TO_TICKS(30000))
|
||||||
|
#define ipconfigARP_CACHE_ENTRIES 6
|
||||||
|
#define ipconfigMAX_ARP_RETRANSMISSIONS (5)
|
||||||
|
#define ipconfigMAX_ARP_AGE 150
|
||||||
|
#define ipconfigINCLUDE_FULL_INET_ADDR 0
|
||||||
|
#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 20
|
||||||
|
#define ipconfigEVENT_QUEUE_LENGTH (ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5)
|
||||||
|
#define ipconfigUDP_TIME_TO_LIVE 128
|
||||||
|
#define ipconfigTCP_TIME_TO_LIVE 128
|
||||||
|
#define ipconfigUSE_TCP 1
|
||||||
|
#define ipconfigSUPPORT_SELECT_FUNCTION 1
|
||||||
|
#define ipconfigUSE_TCP_WIN 0
|
||||||
|
#define ipconfigNETWORK_MTU 1500
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
.cpu cortex-m7
|
||||||
|
.fpu softvfp
|
||||||
|
.syntax unified
|
||||||
|
.thumb
|
||||||
|
|
||||||
|
.section .vectortab,"a",%progbits
|
||||||
|
// Cortex-M7 interrupt handlers
|
||||||
|
.word _estack // 0 Stack top address
|
||||||
|
.word _reset // 1 Reset
|
||||||
|
.word pass // 2 NMI
|
||||||
|
.word halt // 3 Hard Fault
|
||||||
|
.word halt // 4 MM Fault
|
||||||
|
.word halt // 5 Bus Fault
|
||||||
|
.word halt // 6 Usage Fault
|
||||||
|
.word 0 // 7 RESERVED
|
||||||
|
.word 0 // 8 RESERVED
|
||||||
|
.word 0 // 9 RESERVED
|
||||||
|
.word 0 // 10 RESERVED
|
||||||
|
.word SVC_Handler // 11 SV call
|
||||||
|
.word halt // 12 Debug reserved
|
||||||
|
.word 0 // 13 RESERVED
|
||||||
|
.word PendSV_Handler // 14 PendSV
|
||||||
|
.word SysTick_Handler // 15 SysTick
|
||||||
|
// 98 STM32 handlers
|
||||||
|
.word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt
|
||||||
|
.word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt
|
||||||
|
.word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt
|
||||||
|
.word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt
|
||||||
|
.word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt
|
||||||
|
.word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt
|
||||||
|
.word halt,ETH_IRQHandler,halt,halt,halt,halt,halt,halt,halt,halt
|
||||||
|
.word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt
|
||||||
|
.word halt,halt,halt,halt,halt,halt,halt,halt,halt,halt
|
||||||
|
.word halt,halt,halt,halt,halt,halt,halt,halt
|
||||||
|
|
||||||
|
.section .text
|
||||||
|
.global _reset
|
||||||
|
_reset:
|
||||||
|
ldr sp, =_estack
|
||||||
|
bl main
|
||||||
|
b .
|
||||||
|
|
||||||
|
halt: b .
|
||||||
|
pass: bx lr
|
||||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,87 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file core_cmFunc.h
|
||||||
|
* @brief CMSIS Cortex-M Core Function Access Header File
|
||||||
|
* @version V4.30
|
||||||
|
* @date 20. October 2015
|
||||||
|
******************************************************************************/
|
||||||
|
/* Copyright (c) 2009 - 2015 ARM LIMITED
|
||||||
|
|
||||||
|
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 ARM 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 COPYRIGHT HOLDERS AND 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.
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#if defined ( __ICCARM__ )
|
||||||
|
#pragma system_include /* treat file as system include file for MISRA check */
|
||||||
|
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#pragma clang system_header /* treat file as system include file */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CORE_CMFUNC_H
|
||||||
|
#define __CORE_CMFUNC_H
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################### Core Function Access ########################### */
|
||||||
|
/** \ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------ RealView Compiler -----------------*/
|
||||||
|
#if defined ( __CC_ARM )
|
||||||
|
#include "cmsis_armcc.h"
|
||||||
|
|
||||||
|
/*------------------ ARM Compiler V6 -------------------*/
|
||||||
|
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#include "cmsis_armcc_V6.h"
|
||||||
|
|
||||||
|
/*------------------ GNU Compiler ----------------------*/
|
||||||
|
#elif defined ( __GNUC__ )
|
||||||
|
#include "cmsis_gcc.h"
|
||||||
|
|
||||||
|
/*------------------ ICC Compiler ----------------------*/
|
||||||
|
#elif defined ( __ICCARM__ )
|
||||||
|
#include <cmsis_iar.h>
|
||||||
|
|
||||||
|
/*------------------ TI CCS Compiler -------------------*/
|
||||||
|
#elif defined ( __TMS470__ )
|
||||||
|
#include <cmsis_ccs.h>
|
||||||
|
|
||||||
|
/*------------------ TASKING Compiler ------------------*/
|
||||||
|
#elif defined ( __TASKING__ )
|
||||||
|
/*
|
||||||
|
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||||
|
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||||
|
* Including the CMSIS ones.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------ COSMIC Compiler -------------------*/
|
||||||
|
#elif defined ( __CSMC__ )
|
||||||
|
#include <cmsis_csm.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||||
|
|
||||||
|
#endif /* __CORE_CMFUNC_H */
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file core_cmInstr.h
|
||||||
|
* @brief CMSIS Cortex-M Core Instruction Access Header File
|
||||||
|
* @version V4.30
|
||||||
|
* @date 20. October 2015
|
||||||
|
******************************************************************************/
|
||||||
|
/* Copyright (c) 2009 - 2015 ARM LIMITED
|
||||||
|
|
||||||
|
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 ARM 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 COPYRIGHT HOLDERS AND 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.
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#if defined ( __ICCARM__ )
|
||||||
|
#pragma system_include /* treat file as system include file for MISRA check */
|
||||||
|
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#pragma clang system_header /* treat file as system include file */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CORE_CMINSTR_H
|
||||||
|
#define __CORE_CMINSTR_H
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################## Core Instruction Access ######################### */
|
||||||
|
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||||
|
Access to dedicated instructions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------ RealView Compiler -----------------*/
|
||||||
|
#if defined ( __CC_ARM )
|
||||||
|
#include "cmsis_armcc.h"
|
||||||
|
|
||||||
|
/*------------------ ARM Compiler V6 -------------------*/
|
||||||
|
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#include "cmsis_armcc_V6.h"
|
||||||
|
|
||||||
|
/*------------------ GNU Compiler ----------------------*/
|
||||||
|
#elif defined ( __GNUC__ )
|
||||||
|
#include "cmsis_gcc.h"
|
||||||
|
|
||||||
|
/*------------------ ICC Compiler ----------------------*/
|
||||||
|
#elif defined ( __ICCARM__ )
|
||||||
|
#include <cmsis_iar.h>
|
||||||
|
|
||||||
|
/*------------------ TI CCS Compiler -------------------*/
|
||||||
|
#elif defined ( __TMS470__ )
|
||||||
|
#include <cmsis_ccs.h>
|
||||||
|
|
||||||
|
/*------------------ TASKING Compiler ------------------*/
|
||||||
|
#elif defined ( __TASKING__ )
|
||||||
|
/*
|
||||||
|
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||||
|
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||||
|
* Including the CMSIS ones.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------ COSMIC Compiler -------------------*/
|
||||||
|
#elif defined ( __CSMC__ )
|
||||||
|
#include <cmsis_csm.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||||
|
|
||||||
|
#endif /* __CORE_CMINSTR_H */
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file core_cmSimd.h
|
||||||
|
* @brief CMSIS Cortex-M SIMD Header File
|
||||||
|
* @version V4.30
|
||||||
|
* @date 20. October 2015
|
||||||
|
******************************************************************************/
|
||||||
|
/* Copyright (c) 2009 - 2015 ARM LIMITED
|
||||||
|
|
||||||
|
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 ARM 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 COPYRIGHT HOLDERS AND 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.
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#if defined ( __ICCARM__ )
|
||||||
|
#pragma system_include /* treat file as system include file for MISRA check */
|
||||||
|
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#pragma clang system_header /* treat file as system include file */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CORE_CMSIMD_H
|
||||||
|
#define __CORE_CMSIMD_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ################### Compiler specific Intrinsics ########################### */
|
||||||
|
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
|
||||||
|
Access to dedicated SIMD instructions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------ RealView Compiler -----------------*/
|
||||||
|
#if defined ( __CC_ARM )
|
||||||
|
#include "cmsis_armcc.h"
|
||||||
|
|
||||||
|
/*------------------ ARM Compiler V6 -------------------*/
|
||||||
|
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#include "cmsis_armcc_V6.h"
|
||||||
|
|
||||||
|
/*------------------ GNU Compiler ----------------------*/
|
||||||
|
#elif defined ( __GNUC__ )
|
||||||
|
#include "cmsis_gcc.h"
|
||||||
|
|
||||||
|
/*------------------ ICC Compiler ----------------------*/
|
||||||
|
#elif defined ( __ICCARM__ )
|
||||||
|
#include <cmsis_iar.h>
|
||||||
|
|
||||||
|
/*------------------ TI CCS Compiler -------------------*/
|
||||||
|
#elif defined ( __TMS470__ )
|
||||||
|
#include <cmsis_ccs.h>
|
||||||
|
|
||||||
|
/*------------------ TASKING Compiler ------------------*/
|
||||||
|
#elif defined ( __TASKING__ )
|
||||||
|
/*
|
||||||
|
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||||
|
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||||
|
* Including the CMSIS ones.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------ COSMIC Compiler -------------------*/
|
||||||
|
#elif defined ( __CSMC__ )
|
||||||
|
#include <cmsis_csm.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_SIMD_intrinsics */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CORE_CMSIMD_H */
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
// Copyright (c) 2018-2021 Cesanta Software Limited
|
||||||
|
// All rights reserved
|
||||||
|
// https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf
|
||||||
|
// Memory map: 2.2.2
|
||||||
|
|
||||||
|
#include "stm32f746xx.h"
|
||||||
|
//#include "stm32f7xx_hal.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
#define BIT(x) ((uint32_t) 1 << (x))
|
||||||
|
#define PIN(bank, num) ((((bank) - 'A') << 8) | (num))
|
||||||
|
|
||||||
|
static inline void spin(uint32_t count) {
|
||||||
|
while (count--) asm("nop");
|
||||||
|
}
|
||||||
|
static inline GPIO_TypeDef *gpio_bank(uint16_t pin) {
|
||||||
|
return (GPIO_TypeDef *) (0x40020000 + 0x400 * (pin >> 8));
|
||||||
|
}
|
||||||
|
static inline void gpio_on(uint16_t pin) {
|
||||||
|
gpio_bank(pin)->ODR |= BIT(pin & 255);
|
||||||
|
}
|
||||||
|
static inline void gpio_off(uint16_t pin) {
|
||||||
|
gpio_bank(pin)->ODR &= ~BIT(pin & 255);
|
||||||
|
}
|
||||||
|
static inline void gpio_toggle(uint16_t pin) {
|
||||||
|
gpio_bank(pin)->ODR ^= BIT(pin & 255);
|
||||||
|
}
|
||||||
|
enum { GPIO_IN, GPIO_OUT, GPIO_AF, GPIO_ANALOG };
|
||||||
|
enum { GPIO_PP, GPIO_OD };
|
||||||
|
enum { GPIO_SPEED_LOW, GPIO_SPEED_MEDIUM, GPIO_SPEED_HIGH, GPIO_SPEED_INSANE };
|
||||||
|
enum { GPIO_PULL_NONE, GPIO_PULL_UP, GPIO_PULL_DOWN };
|
||||||
|
static inline void gpio_init(uint16_t pin, uint8_t mode, uint8_t type,
|
||||||
|
uint8_t speed, uint8_t pull, uint8_t af) {
|
||||||
|
GPIO_TypeDef *gpio = gpio_bank(pin);
|
||||||
|
uint8_t n = pin & 255;
|
||||||
|
gpio->MODER &= ~(3 << (n * 2));
|
||||||
|
gpio->MODER |= (mode << (n * 2));
|
||||||
|
gpio->OTYPER &= ~(1 << n);
|
||||||
|
gpio->OTYPER |= (type << n);
|
||||||
|
gpio->OSPEEDR &= ~(3 << (n * 2));
|
||||||
|
gpio->OSPEEDR |= (speed << (n * 2));
|
||||||
|
gpio->PUPDR &= ~(3 << (n * 2));
|
||||||
|
gpio->PUPDR |= (pull << (n * 2));
|
||||||
|
if (n < 8) {
|
||||||
|
gpio->AFR[0] &= 15 << (n * 4);
|
||||||
|
gpio->AFR[0] |= af << (n * 4);
|
||||||
|
} else {
|
||||||
|
gpio->AFR[1] &= 15 << (n * 4);
|
||||||
|
gpio->AFR[1] |= af << (n * 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void init_clock(void) {
|
||||||
|
RCC->CR |= RCC_CR_HSEBYP | RCC_CR_HSEON; // Start HSE
|
||||||
|
while ((RCC->CR & RCC_CR_HSERDY) == 0) (void) 0;
|
||||||
|
|
||||||
|
#define PLL_M 8 // 8MHz HSE down-to 1MHz PLL input
|
||||||
|
#define PLL_N 432 // 432 MHz VCO output
|
||||||
|
#define PLL_P 2 // 216 MHz PLL output
|
||||||
|
#define PLL_Q 9 // 48 MHz (USB)
|
||||||
|
RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) - 1) << 16) |
|
||||||
|
(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
|
||||||
|
RCC->CR |= RCC_CR_PLLON; // Enable the main PLL
|
||||||
|
FLASH->ACR = FLASH_ACR_ARTEN | FLASH_ACR_PRFTEN | FLASH_ACR_LATENCY_4WS;
|
||||||
|
|
||||||
|
// Configure AHB/APB prescalers
|
||||||
|
// AHB Prescaler = /1 -> 216 MHz
|
||||||
|
// APB1 Prescaler = /4 -> 54 MHz
|
||||||
|
// APB2 Prescaler = /2 -> 108 MHz
|
||||||
|
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
|
||||||
|
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
|
||||||
|
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
|
||||||
|
while ((RCC->CR & RCC_CR_PLLRDY) == 0) (void) 0;
|
||||||
|
|
||||||
|
RCC->CFGR &= ~RCC_CFGR_SW; // Select the main PLL
|
||||||
|
RCC->CFGR |= RCC_CFGR_SW_PLL; // as system clock source
|
||||||
|
while ((RCC->CFGR & RCC_CFGR_SWS) == 0) (void) 0;
|
||||||
|
|
||||||
|
// Ethernet clock
|
||||||
|
RCC->AHB1ENR |= RCC_AHB1ENR_ETHMACEN;
|
||||||
|
RCC->AHB1ENR |= RCC_AHB1ENR_ETHMACTXEN;
|
||||||
|
RCC->AHB1ENR |= RCC_AHB1ENR_ETHMACRXEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define delay(ms) vTaskDelay(pdMS_TO_TICKS(ms))
|
||||||
|
|
||||||
|
#define LED1 PIN('B', 0) // On-board LED pin
|
||||||
|
#define LED2 PIN('B', 7) // On-board LED pin
|
||||||
|
#define LED3 PIN('B', 14) // On-board LED pin
|
||||||
|
|
||||||
|
static inline void led_toggle(void) {
|
||||||
|
gpio_toggle(LED2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void init_ram(void) {
|
||||||
|
extern uint32_t _sbss, _ebss;
|
||||||
|
extern uint32_t _sdata, _edata, _sidata;
|
||||||
|
memset(&_sbss, 0, ((char *) &_ebss - (char *) &_sbss));
|
||||||
|
memcpy(&_sdata, &_sidata, ((char *) &_edata - (char *) &_sdata));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void init_hardware(void) {
|
||||||
|
init_ram();
|
||||||
|
init_clock();
|
||||||
|
RCC->AHB1ENR |= BIT(0) | BIT(1) | BIT(2) | BIT(6); // Init GPIO banks A,B,C,G
|
||||||
|
gpio_init(LED1, GPIO_OUT, GPIO_PP, GPIO_SPEED_LOW, GPIO_PULL_NONE, 0);
|
||||||
|
gpio_init(LED2, GPIO_OUT, GPIO_PP, GPIO_SPEED_LOW, GPIO_PULL_NONE, 0);
|
||||||
|
gpio_init(LED3, GPIO_OUT, GPIO_PP, GPIO_SPEED_LOW, GPIO_PULL_NONE, 0);
|
||||||
|
gpio_on(LED2);
|
||||||
|
#if 0
|
||||||
|
uint16_t a1 = PIN('A', 1), a2 = PIN('A', 2), a7 = PIN('A', 7);
|
||||||
|
gpio_init(a1, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11);
|
||||||
|
gpio_init(a2, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11);
|
||||||
|
gpio_init(a7, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11);
|
||||||
|
|
||||||
|
uint16_t b13 = PIN('B', 13);
|
||||||
|
gpio_init(b13, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11);
|
||||||
|
|
||||||
|
uint16_t c1 = PIN('C', 1), c4 = PIN('C', 4), c5 = PIN('C', 5);
|
||||||
|
gpio_init(c1, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11);
|
||||||
|
gpio_init(c4, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11);
|
||||||
|
gpio_init(c5, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11);
|
||||||
|
|
||||||
|
uint16_t g2 = PIN('G', 2), g11 = PIN('G', 11), g13 = PIN('G', 13),
|
||||||
|
g14 = PIN('G', 14);
|
||||||
|
gpio_init(g2, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11);
|
||||||
|
gpio_init(g11, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11);
|
||||||
|
gpio_init(g13, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11);
|
||||||
|
gpio_init(g14, GPIO_AF, GPIO_PP, GPIO_SPEED_INSANE, GPIO_PULL_NONE, 11);
|
||||||
|
|
||||||
|
HAL_Init();
|
||||||
|
HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(ETH_IRQn);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
ENTRY(_reset);
|
||||||
|
MEMORY {
|
||||||
|
ram(rwx) : ORIGIN = 0x20000000, LENGTH = 307k
|
||||||
|
rom(rx) : ORIGIN = 0x08000000, LENGTH = 1024k
|
||||||
|
}
|
||||||
|
_estack = ORIGIN(ram) + LENGTH(ram); /* boot.s and init_heap() */
|
||||||
|
SECTIONS {
|
||||||
|
.vectortab : { KEEP(*(.vectortab)) } > rom
|
||||||
|
.text : { *(.text*) } > rom
|
||||||
|
.rodata : { *(.rodata*) } > rom
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
_sdata = .; /* for init_ram() */
|
||||||
|
*(.first_data)
|
||||||
|
*(.data SORT(.data.*))
|
||||||
|
_edata = .; /* for init_ram() */
|
||||||
|
} > ram AT > rom
|
||||||
|
_sidata = LOADADDR(.data);
|
||||||
|
|
||||||
|
.bss : {
|
||||||
|
_sbss = .; /* for init_ram() */
|
||||||
|
__bss_start__ = _sbss; /* for libc */
|
||||||
|
*(.bss SORT(.bss.*) COMMON)
|
||||||
|
_ebss = .; /* for init_ram() */
|
||||||
|
__bss_end__ = _ebss; /* for libc */
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
. = ALIGN(8);
|
||||||
|
end = .; /* for syscalls.c */
|
||||||
|
_end = .; /* for cmsis_gcc.h and init_ram() */
|
||||||
|
__end__ = .; /* for libc */
|
||||||
|
}
|
||||||
@@ -0,0 +1,248 @@
|
|||||||
|
/*
|
||||||
|
* FreeRTOS Kernel V10.4.3
|
||||||
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the
|
||||||
|
* given hardware and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*-----------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE uint32_t
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
typedef portSTACK_TYPE StackType_t;
|
||||||
|
typedef long BaseType_t;
|
||||||
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
|
typedef uint16_t TickType_t;
|
||||||
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
|
#else
|
||||||
|
typedef uint32_t TickType_t;
|
||||||
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
|
* not need to be guarded with a critical section. */
|
||||||
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Architecture specifics. */
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Scheduler utilities. */
|
||||||
|
#define portYIELD() \
|
||||||
|
{ \
|
||||||
|
/* Set a PendSV to request a context switch. */ \
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
|
\
|
||||||
|
/* Barriers are normally not required but do ensure the code is completely \
|
||||||
|
* within the specified behaviour for the architecture. */ \
|
||||||
|
__asm volatile ( "dsb" ::: "memory" ); \
|
||||||
|
__asm volatile ( "isb" ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD()
|
||||||
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Critical section management. */
|
||||||
|
extern void vPortEnterCritical( void );
|
||||||
|
extern void vPortExitCritical( void );
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x )
|
||||||
|
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
||||||
|
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
|
* not necessary for to use this port. They are defined so the common demo files
|
||||||
|
* (which build with all the ports) will build. */
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Tickless idle/low power functionality. */
|
||||||
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Architecture specific optimisations. */
|
||||||
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
|
/* Generic helper function. */
|
||||||
|
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
|
{
|
||||||
|
uint8_t ucReturn;
|
||||||
|
|
||||||
|
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||||
|
|
||||||
|
return ucReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the configuration. */
|
||||||
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifdef configASSERT
|
||||||
|
void vPortValidateInterruptPriority( void );
|
||||||
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* portNOP() is not required by this port. */
|
||||||
|
#define portNOP()
|
||||||
|
|
||||||
|
#define portINLINE __inline
|
||||||
|
|
||||||
|
#ifndef portFORCE_INLINE
|
||||||
|
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
||||||
|
{
|
||||||
|
uint32_t ulCurrentInterrupt;
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
/* Obtain the number of the currently executing interrupt. */
|
||||||
|
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
|
||||||
|
|
||||||
|
if( ulCurrentInterrupt == 0 )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
||||||
|
{
|
||||||
|
uint32_t ulNewBASEPRI;
|
||||||
|
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" mov %0, %1 \n"\
|
||||||
|
" cpsid i \n"\
|
||||||
|
" msr basepri, %0 \n"\
|
||||||
|
" isb \n"\
|
||||||
|
" dsb \n"\
|
||||||
|
" cpsie i \n"\
|
||||||
|
: "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||||
|
{
|
||||||
|
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||||
|
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" mrs %0, basepri \n"\
|
||||||
|
" mov %1, %2 \n"\
|
||||||
|
" cpsid i \n"\
|
||||||
|
" msr basepri, %1 \n"\
|
||||||
|
" isb \n"\
|
||||||
|
" dsb \n"\
|
||||||
|
" cpsie i \n"\
|
||||||
|
: "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
|
);
|
||||||
|
|
||||||
|
/* This return will not be reached but is necessary to prevent compiler
|
||||||
|
* warnings. */
|
||||||
|
return ulOriginalBASEPRI;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,220 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f7xx.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief CMSIS STM32F7xx Device Peripheral Access Layer Header File.
|
||||||
|
*
|
||||||
|
* The file is the unique include file that the application programmer
|
||||||
|
* is using in the C source code, usually in main.c. This file contains:
|
||||||
|
* - Configuration section that allows to select:
|
||||||
|
* - The STM32F7xx device used in the target application
|
||||||
|
* - To use or not the peripheral’s drivers in application code(i.e.
|
||||||
|
* code will be based on direct access to peripheral’s registers
|
||||||
|
* rather than drivers API), this option is controlled by
|
||||||
|
* "#define USE_HAL_DRIVER"
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup CMSIS
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup stm32f7xx
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __STM32F7xx_H
|
||||||
|
#define __STM32F7xx_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/** @addtogroup Library_configuration_section
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief STM32 Family
|
||||||
|
*/
|
||||||
|
#if !defined (STM32F7)
|
||||||
|
#define STM32F7
|
||||||
|
#endif /* STM32F7 */
|
||||||
|
|
||||||
|
/* Uncomment the line below according to the target STM32 device used in your
|
||||||
|
application
|
||||||
|
*/
|
||||||
|
#if !defined (STM32F756xx) && !defined (STM32F746xx) && !defined (STM32F745xx) && !defined (STM32F765xx) && \
|
||||||
|
!defined (STM32F767xx) && !defined (STM32F769xx) && !defined (STM32F777xx) && !defined (STM32F779xx) && \
|
||||||
|
!defined (STM32F722xx) && !defined (STM32F723xx) && !defined (STM32F732xx) && !defined (STM32F733xx) && \
|
||||||
|
!defined (STM32F730xx) && !defined (STM32F750xx)
|
||||||
|
|
||||||
|
/* #define STM32F756xx */ /*!< STM32F756VG, STM32F756ZG, STM32F756ZG, STM32F756IG, STM32F756BG,
|
||||||
|
STM32F756NG Devices */
|
||||||
|
/* #define STM32F746xx */ /*!< STM32F746VE, STM32F746VG, STM32F746ZE, STM32F746ZG, STM32F746IE, STM32F746IG,
|
||||||
|
STM32F746BE, STM32F746BG, STM32F746NE, STM32F746NG Devices */
|
||||||
|
/* #define STM32F745xx */ /*!< STM32F745VE, STM32F745VG, STM32F745ZG, STM32F745ZE, STM32F745IE, STM32F745IG Devices */
|
||||||
|
/* #define STM32F765xx */ /*!< STM32F765BI, STM32F765BG, STM32F765NI, STM32F765NG, STM32F765II, STM32F765IG,
|
||||||
|
STM32F765ZI, STM32F765ZG, STM32F765VI, STM32F765VG Devices */
|
||||||
|
/* #define STM32F767xx */ /*!< STM32F767BG, STM32F767BI, STM32F767IG, STM32F767II, STM32F767NG, STM32F767NI,
|
||||||
|
STM32F767VG, STM32F767VI, STM32F767ZG, STM32F767ZI Devices */
|
||||||
|
/* #define STM32F769xx */ /*!< STM32F769AG, STM32F769AI, STM32F769BG, STM32F769BI, STM32F769IG, STM32F769II,
|
||||||
|
STM32F769NG, STM32F769NI, STM32F768AI Devices */
|
||||||
|
/* #define STM32F777xx */ /*!< STM32F777VI, STM32F777ZI, STM32F777II, STM32F777BI, STM32F777NI Devices */
|
||||||
|
/* #define STM32F779xx */ /*!< STM32F779II, STM32F779BI, STM32F779NI, STM32F779AI, STM32F778AI Devices */
|
||||||
|
/* #define STM32F722xx */ /*!< STM32F722IE, STM32F722ZE, STM32F722VE, STM32F722RE, STM32F722IC, STM32F722ZC,
|
||||||
|
STM32F722VC, STM32F722RC Devices */
|
||||||
|
/* #define STM32F723xx */ /*!< STM32F723IE, STM32F723ZE, STM32F723VE, STM32F723IC, STM32F723ZC, STM32F723VC Devices */
|
||||||
|
/* #define STM32F732xx */ /*!< STM32F732IE, STM32F732ZE, STM32F732VE, STM32F732RE Devices */
|
||||||
|
/* #define STM32F733xx */ /*!< STM32F733IE, STM32F733ZE, STM32F733VE Devices */
|
||||||
|
/* #define STM32F730xx */ /*!< STM32F730R, STM32F730V, STM32F730Z, STM32F730I Devices */
|
||||||
|
/* #define STM32F750xx */ /*!< STM32F750V, STM32F750Z, STM32F750N Devices */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Tip: To avoid modifying this file each time you need to switch between these
|
||||||
|
devices, you can define the device in your toolchain compiler preprocessor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined (USE_HAL_DRIVER)
|
||||||
|
/**
|
||||||
|
* @brief Comment the line below if you will not use the peripherals drivers.
|
||||||
|
In this case, these drivers will not be included and the application code will
|
||||||
|
be based on direct access to peripherals registers
|
||||||
|
*/
|
||||||
|
/*#define USE_HAL_DRIVER */
|
||||||
|
#endif /* USE_HAL_DRIVER */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CMSIS Device version number V1.2.6
|
||||||
|
*/
|
||||||
|
#define __STM32F7_CMSIS_VERSION_MAIN (0x01) /*!< [31:24] main version */
|
||||||
|
#define __STM32F7_CMSIS_VERSION_SUB1 (0x02) /*!< [23:16] sub1 version */
|
||||||
|
#define __STM32F7_CMSIS_VERSION_SUB2 (0x06) /*!< [15:8] sub2 version */
|
||||||
|
#define __STM32F7_CMSIS_VERSION_RC (0x00) /*!< [7:0] release candidate */
|
||||||
|
#define __STM32F7_CMSIS_VERSION ((__STM32F7_CMSIS_VERSION_MAIN << 24)\
|
||||||
|
|(__STM32F7_CMSIS_VERSION_SUB1 << 16)\
|
||||||
|
|(__STM32F7_CMSIS_VERSION_SUB2 << 8 )\
|
||||||
|
|(__STM32F7_CMSIS_VERSION_RC))
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup Device_Included
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#if defined(STM32F722xx)
|
||||||
|
#include "stm32f722xx.h"
|
||||||
|
#elif defined(STM32F723xx)
|
||||||
|
#include "stm32f723xx.h"
|
||||||
|
#elif defined(STM32F732xx)
|
||||||
|
#include "stm32f732xx.h"
|
||||||
|
#elif defined(STM32F733xx)
|
||||||
|
#include "stm32f733xx.h"
|
||||||
|
#elif defined(STM32F756xx)
|
||||||
|
#include "stm32f756xx.h"
|
||||||
|
#elif defined(STM32F746xx)
|
||||||
|
#include "stm32f746xx.h"
|
||||||
|
#elif defined(STM32F745xx)
|
||||||
|
#include "stm32f745xx.h"
|
||||||
|
#elif defined(STM32F765xx)
|
||||||
|
#include "stm32f765xx.h"
|
||||||
|
#elif defined(STM32F767xx)
|
||||||
|
#include "stm32f767xx.h"
|
||||||
|
#elif defined(STM32F769xx)
|
||||||
|
#include "stm32f769xx.h"
|
||||||
|
#elif defined(STM32F777xx)
|
||||||
|
#include "stm32f777xx.h"
|
||||||
|
#elif defined(STM32F779xx)
|
||||||
|
#include "stm32f779xx.h"
|
||||||
|
#elif defined(STM32F730xx)
|
||||||
|
#include "stm32f730xx.h"
|
||||||
|
#elif defined(STM32F750xx)
|
||||||
|
#include "stm32f750xx.h"
|
||||||
|
#else
|
||||||
|
#error "Please select first the target STM32F7xx device used in your application (in stm32f7xx.h file)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup Exported_types
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
RESET = 0U,
|
||||||
|
SET = !RESET
|
||||||
|
} FlagStatus, ITStatus;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DISABLE = 0U,
|
||||||
|
ENABLE = !DISABLE
|
||||||
|
} FunctionalState;
|
||||||
|
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
SUCCESS = 0U,
|
||||||
|
ERROR = !SUCCESS
|
||||||
|
} ErrorStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup Exported_macro
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SET_BIT(REG, BIT) ((REG) |= (BIT))
|
||||||
|
|
||||||
|
#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
|
||||||
|
|
||||||
|
#define READ_BIT(REG, BIT) ((REG) & (BIT))
|
||||||
|
|
||||||
|
#define CLEAR_REG(REG) ((REG) = (0x0))
|
||||||
|
|
||||||
|
#define WRITE_REG(REG, VAL) ((REG) = (VAL))
|
||||||
|
|
||||||
|
#define READ_REG(REG) ((REG))
|
||||||
|
|
||||||
|
#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
|
||||||
|
|
||||||
|
#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef USE_HAL_DRIVER
|
||||||
|
#include "stm32f7xx_hal.h"
|
||||||
|
#endif /* USE_HAL_DRIVER */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* __STM32F7xx_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file system_stm32f7xx.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief CMSIS Cortex-M7 Device System Source File for STM32F7xx devices.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
*modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of STMicroelectronics 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 HOLDER 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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup CMSIS
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup stm32f7xx_system
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Define to prevent recursive inclusion
|
||||||
|
*/
|
||||||
|
#ifndef __SYSTEM_STM32F7XX_H
|
||||||
|
#define __SYSTEM_STM32F7XX_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @addtogroup STM32F7xx_System_Includes
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F7xx_System_Exported_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* The SystemCoreClock variable is updated in three ways:
|
||||||
|
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||||
|
2) by calling HAL API function HAL_RCC_GetSysClockFreq()
|
||||||
|
3) each time HAL_RCC_ClockConfig() is called to configure the system clock
|
||||||
|
frequency Note: If you use this function to configure the system clock; then
|
||||||
|
there is no need to call the 2 first functions listed above, since
|
||||||
|
SystemCoreClock variable is updated automatically.
|
||||||
|
*/
|
||||||
|
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
|
||||||
|
|
||||||
|
extern const uint8_t AHBPrescTable[16]; /*!< AHB prescalers table values */
|
||||||
|
extern const uint8_t APBPrescTable[8]; /*!< APB prescalers table values */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F7xx_System_Exported_Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F7xx_System_Exported_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F7xx_System_Exported_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void SystemInit(void);
|
||||||
|
extern void SystemCoreClockUpdate(void);
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*__SYSTEM_STM32F7XX_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -32,8 +32,8 @@ static void broadcast_mjpeg_frame(struct mg_mgr *mgr) {
|
|||||||
size_t nfiles = sizeof(files) / sizeof(files[0]);
|
size_t nfiles = sizeof(files) / sizeof(files[0]);
|
||||||
static size_t i;
|
static size_t i;
|
||||||
const char *path = files[i++ % nfiles];
|
const char *path = files[i++ % nfiles];
|
||||||
size_t size = mg_file_size(path);
|
size_t size = 0;
|
||||||
char *data = mg_file_read(path); // Read next file
|
char *data = mg_file_read(path, &size); // Read next file
|
||||||
struct mg_connection *c;
|
struct mg_connection *c;
|
||||||
for (c = mgr->conns; c != NULL; c = c->next) {
|
for (c = mgr->conns; c != NULL; c = c->next) {
|
||||||
if (c->label[0] != 'S') continue; // Skip non-stream connections
|
if (c->label[0] != 'S') continue; // Skip non-stream connections
|
||||||
|
|||||||
+1094
-831
File diff suppressed because it is too large.
Load diff
+346
-206
@@ -1,5 +1,5 @@
|
|||||||
// Copyright (c) 2004-2013 Sergey Lyubka
|
// Copyright (c) 2004-2013 Sergey Lyubka
|
||||||
// Copyright (c) 2013-2020 Cesanta Software Limited
|
// Copyright (c) 2013-2021 Cesanta Software Limited
|
||||||
// All rights reserved
|
// All rights reserved
|
||||||
//
|
//
|
||||||
// This software is dual-licensed: you can redistribute it and/or modify
|
// This software is dual-licensed: you can redistribute it and/or modify
|
||||||
@@ -15,8 +15,14 @@
|
|||||||
// Alternatively, you can license this software under a commercial
|
// Alternatively, you can license this software under a commercial
|
||||||
// license, as set out in <https://www.cesanta.com/license>.
|
// license, as set out in <https://www.cesanta.com/license>.
|
||||||
|
|
||||||
#pragma once
|
#ifndef MONGOOSE_H
|
||||||
#define MG_VERSION "7.1"
|
#define MONGOOSE_H
|
||||||
|
|
||||||
|
#define MG_VERSION "7.3"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define MG_ARCH_CUSTOM 0
|
#define MG_ARCH_CUSTOM 0
|
||||||
@@ -24,54 +30,20 @@
|
|||||||
#define MG_ARCH_WIN32 2
|
#define MG_ARCH_WIN32 2
|
||||||
#define MG_ARCH_ESP32 3
|
#define MG_ARCH_ESP32 3
|
||||||
#define MG_ARCH_ESP8266 4
|
#define MG_ARCH_ESP8266 4
|
||||||
#define MG_ARCH_CC3100 5
|
#define MG_ARCH_FREERTOS_TCP 5
|
||||||
#define MG_ARCH_CC3200 6
|
#define MG_ARCH_FREERTOS_LWIP 6
|
||||||
#define MG_ARCH_CC3220 7
|
|
||||||
#define MG_ARCH_MSP432 8
|
|
||||||
#define MG_ARCH_TM4C129 9
|
|
||||||
#define MG_ARCH_MBED 10
|
|
||||||
#define MG_ARCH_WINCE 11
|
|
||||||
#define MG_ARCH_NXP_LPC 12
|
|
||||||
#define MG_ARCH_NXP_KINETIS 13
|
|
||||||
#define MG_ARCH_NRF51 14
|
|
||||||
#define MG_ARCH_NRF52 15
|
|
||||||
#define MG_ARCH_PIC32 16
|
|
||||||
#define MG_ARCH_RS14100 17
|
|
||||||
#define MG_ARCH_STM32 18
|
|
||||||
#define MG_ARCH_FREERTOS 19
|
|
||||||
|
|
||||||
#if !defined(MG_ARCH)
|
#if !defined(MG_ARCH)
|
||||||
#if defined(TARGET_IS_MSP432P4XX) || defined(__MSP432P401R__)
|
#if defined(__unix__) || defined(__APPLE__)
|
||||||
#define MG_ARCH MG_ARCH_MSP432
|
|
||||||
#elif defined(cc3200) || defined(TARGET_IS_CC3200)
|
|
||||||
#define MG_ARCH MG_ARCH_CC3200
|
|
||||||
#elif defined(cc3220) || defined(TARGET_IS_CC3220)
|
|
||||||
#define MG_ARCH MG_ARCH_CC3220
|
|
||||||
#elif defined(__unix__) || defined(__APPLE__)
|
|
||||||
#define MG_ARCH MG_ARCH_UNIX
|
#define MG_ARCH MG_ARCH_UNIX
|
||||||
#elif defined(WINCE)
|
|
||||||
#define MG_ARCH MG_ARCH_WINCE
|
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
#define MG_ARCH MG_ARCH_WIN32
|
#define MG_ARCH MG_ARCH_WIN32
|
||||||
#elif defined(__MBED__)
|
|
||||||
#define MG_ARCH MG_ARCH_MBED
|
|
||||||
#elif defined(__USE_LPCOPEN)
|
|
||||||
#define MG_ARCH MG_ARCH_NXP_LPC
|
|
||||||
#elif defined(FRDM_K64F) || defined(FREEDOM)
|
|
||||||
#define MG_ARCH MG_ARCH_NXP_KINETIS
|
|
||||||
#elif defined(PIC32)
|
|
||||||
#define MG_ARCH MG_ARCH_PIC32
|
|
||||||
#elif defined(ICACHE_FLASH) || defined(ICACHE_RAM_ATTR)
|
#elif defined(ICACHE_FLASH) || defined(ICACHE_RAM_ATTR)
|
||||||
#define MG_ARCH MG_ARCH_ESP8266
|
#define MG_ARCH MG_ARCH_ESP8266
|
||||||
#elif defined(ESP_PLATFORM)
|
#elif defined(ESP_PLATFORM)
|
||||||
#define MG_ARCH MG_ARCH_ESP32
|
#define MG_ARCH MG_ARCH_ESP32
|
||||||
#elif defined(TARGET_IS_TM4C129_RA0) || defined(TARGET_IS_TM4C129_RA1) || \
|
#elif defined(FREERTOS_IP_H)
|
||||||
defined(TARGET_IS_TM4C129_RA2)
|
#define MG_ARCH MG_ARCH_FREERTOS_TCP
|
||||||
#define MG_ARCH MG_ARCH_TM4C129
|
|
||||||
#elif defined(RS14100)
|
|
||||||
#define MG_ARCH MG_ARCH_RS14100
|
|
||||||
#elif defined(STM32)
|
|
||||||
#define MG_ARCH MG_ARCH_STM32
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(MG_ARCH)
|
#if !defined(MG_ARCH)
|
||||||
@@ -79,23 +51,13 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif // !defined(MG_ARCH)
|
#endif // !defined(MG_ARCH)
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#if !defined(PRINTF_LIKE)
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#if defined(__GNUC__) || defined(__clang__) || defined(__TI_COMPILER_VERSION__)
|
||||||
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
#define PRINTF_LIKE(f, a) __attribute__((format(printf, f, a)))
|
||||||
|
#else
|
||||||
// Standard C headers
|
#define PRINTF_LIKE(f, a)
|
||||||
#include <ctype.h>
|
#endif
|
||||||
#include <errno.h>
|
#endif
|
||||||
#include <fcntl.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#if MG_ARCH == MG_ARCH_CUSTOM
|
#if MG_ARCH == MG_ARCH_CUSTOM
|
||||||
#include <mongoose_custom.h>
|
#include <mongoose_custom.h>
|
||||||
@@ -107,46 +69,132 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined(PRINTF_LIKE)
|
|
||||||
#if defined(__GNUC__) || defined(__clang__) || defined(__TI_COMPILER_VERSION__)
|
|
||||||
#define PRINTF_LIKE(f, a) __attribute__((format(printf, f, a)))
|
|
||||||
#else
|
|
||||||
#define PRINTF_LIKE(f, a)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if MG_ARCH == MG_ARCH_ESP32
|
#if MG_ARCH == MG_ARCH_ESP32
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#define MG_DIRSEP '/'
|
#define MG_DIRSEP '/'
|
||||||
|
#define MG_INT64_FMT "%lld"
|
||||||
|
#ifndef MG_PATH_MAX
|
||||||
|
#define MG_PATH_MAX 128
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if MG_ARCH == MG_ARCH_ESP8266
|
#if MG_ARCH == MG_ARCH_ESP8266
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <esp_system.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <esp_system.h>
|
||||||
|
|
||||||
#define MG_DIRSEP '/'
|
#define MG_DIRSEP '/'
|
||||||
|
#define MG_INT64_FMT "%lld"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if MG_ARCH == MG_ARCH_FREERTOS
|
#if MG_ARCH == MG_ARCH_FREERTOS_LWIP
|
||||||
#include <FreeRTOS.h>
|
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#include <sys/time.h>
|
||||||
|
#else
|
||||||
|
typedef long suseconds_t;
|
||||||
|
struct timeval {
|
||||||
|
time_t tv_sec;
|
||||||
|
suseconds_t tv_usec;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MG_ENABLE_FS
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <FreeRTOS.h>
|
||||||
#include <task.h>
|
#include <task.h>
|
||||||
|
|
||||||
|
#include <lwip/sockets.h>
|
||||||
|
|
||||||
|
#define MG_INT64_FMT "%lld"
|
||||||
|
#define MG_DIRSEP '/'
|
||||||
|
|
||||||
|
// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib
|
||||||
|
static inline void *mg_calloc(int cnt, size_t size) {
|
||||||
|
void *p = pvPortMalloc(cnt * size);
|
||||||
|
if (p != NULL) memset(p, 0, size);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
#define calloc(a, b) mg_calloc((a), (b))
|
||||||
|
#define free(a) vPortFree(a)
|
||||||
|
#define malloc(a) pvPortMalloc(a)
|
||||||
|
|
||||||
|
#define gmtime_r(a, b) gmtime(a)
|
||||||
|
|
||||||
|
#endif // MG_ARCH == MG_ARCH_FREERTOS_LWIP
|
||||||
|
|
||||||
|
|
||||||
|
#if MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#if MG_ENABLE_FS
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <FreeRTOS.h>
|
||||||
#include <FreeRTOS_IP.h>
|
#include <FreeRTOS_IP.h>
|
||||||
#include <FreeRTOS_Sockets.h>
|
#include <FreeRTOS_Sockets.h>
|
||||||
#include <stdbool.h>
|
#include <task.h>
|
||||||
|
|
||||||
|
#define MG_INT64_FMT "%lld"
|
||||||
#define MG_DIRSEP '/'
|
#define MG_DIRSEP '/'
|
||||||
|
|
||||||
|
// Why FreeRTOS-TCP did not implement a clean BSD API, but its own thing
|
||||||
|
// with FreeRTOS_ prefix, is beyond me
|
||||||
#define IPPROTO_TCP FREERTOS_IPPROTO_TCP
|
#define IPPROTO_TCP FREERTOS_IPPROTO_TCP
|
||||||
#define IPPROTO_UDP FREERTOS_IPPROTO_UDP
|
#define IPPROTO_UDP FREERTOS_IPPROTO_UDP
|
||||||
#define AF_INET FREERTOS_AF_INET
|
#define AF_INET FREERTOS_AF_INET
|
||||||
@@ -157,9 +205,7 @@
|
|||||||
#define SOL_SOCKET 0
|
#define SOL_SOCKET 0
|
||||||
#define SO_REUSEADDR 0
|
#define SO_REUSEADDR 0
|
||||||
#define sockaddr_in freertos_sockaddr
|
#define sockaddr_in freertos_sockaddr
|
||||||
struct sockaddr {
|
#define sockaddr freertos_sockaddr
|
||||||
uint8_t sa_len, sa_family;
|
|
||||||
};
|
|
||||||
#define accept(a, b, c) FreeRTOS_accept((a), (b), (c))
|
#define accept(a, b, c) FreeRTOS_accept((a), (b), (c))
|
||||||
#define connect(a, b, c) FreeRTOS_connect((a), (b), (c))
|
#define connect(a, b, c) FreeRTOS_connect((a), (b), (c))
|
||||||
#define bind(a, b, c) FreeRTOS_bind((a), (b), (c))
|
#define bind(a, b, c) FreeRTOS_bind((a), (b), (c))
|
||||||
@@ -174,55 +220,106 @@ struct sockaddr {
|
|||||||
#define closesocket(x) FreeRTOS_closesocket(x)
|
#define closesocket(x) FreeRTOS_closesocket(x)
|
||||||
#define gethostbyname(x) FreeRTOS_gethostbyname(x)
|
#define gethostbyname(x) FreeRTOS_gethostbyname(x)
|
||||||
|
|
||||||
#include <ff_stdio.h>
|
// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib
|
||||||
|
static inline void *mg_calloc(int cnt, size_t size) {
|
||||||
#undef FILE
|
void *p = pvPortMalloc(cnt * size);
|
||||||
#define FILE FF_FILE
|
if (p != NULL) memset(p, 0, size);
|
||||||
//#define SEEK_SET FF_SEEK_SET
|
return p;
|
||||||
//#define SEEK_END FF_SEEK_END
|
|
||||||
#define stat(a, b) ff_stat((a), (b))
|
|
||||||
#define fopen(a, b) ff_fopen((a), (b))
|
|
||||||
#define fclose(a) ff_fclose(a)
|
|
||||||
#define fread(a, b, c, d) ff_fread((a), (b), (c), (d))
|
|
||||||
#define fwrite(a, b, c, d) ff_fwrite((a), (b), (c), (d))
|
|
||||||
#define vfprintf ff_vfprintf
|
|
||||||
#define fprintf ff_fprintf
|
|
||||||
#define remove(a) ff_remove(a)
|
|
||||||
#define rename(a, b) ff_rename((a), (b), 1)
|
|
||||||
|
|
||||||
static inline int ff_vfprintf(FF_FILE *fp, const char *fmt, va_list ap) {
|
|
||||||
char *buf = NULL;
|
|
||||||
int n = mg_vasprintf(&buf, 0, fmt, ap);
|
|
||||||
if (buf != NULL) ff_fwrite(buf, 1, n, fp), free(buf);
|
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
#define calloc(a, b) mg_calloc((a), (b))
|
||||||
|
#define free(a) vPortFree(a)
|
||||||
|
#define malloc(a) pvPortMalloc(a)
|
||||||
|
|
||||||
|
#define gmtime_r(a, b) gmtime(a)
|
||||||
|
|
||||||
|
#if !defined(__GNUC__)
|
||||||
|
// copied from GCC on ARM; for some reason useconds are signed
|
||||||
|
typedef long suseconds_t;
|
||||||
|
struct timeval {
|
||||||
|
time_t tv_sec;
|
||||||
|
suseconds_t tv_usec;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef EINPROGRESS
|
||||||
|
#define EINPROGRESS pdFREERTOS_ERRNO_EINPROGRESS
|
||||||
|
#endif
|
||||||
|
#ifndef EWOULDBLOCK
|
||||||
|
#define EWOULDBLOCK pdFREERTOS_ERRNO_EWOULDBLOCK
|
||||||
|
#endif
|
||||||
|
#ifndef EAGAIN
|
||||||
|
#define EAGAIN pdFREERTOS_ERRNO_EAGAIN
|
||||||
|
#endif
|
||||||
|
#ifndef EINTR
|
||||||
|
#define EINTR pdFREERTOS_ERRNO_EINTR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||||
|
|
||||||
|
|
||||||
#if MG_ARCH == MG_ARCH_UNIX
|
#if MG_ARCH == MG_ARCH_UNIX
|
||||||
|
|
||||||
#define _DARWIN_UNLIMITED_SELECT 1
|
#define _DARWIN_UNLIMITED_SELECT 1
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define MG_DIRSEP '/'
|
#define MG_DIRSEP '/'
|
||||||
#define MG_ENABLE_POSIX 1
|
#define MG_ENABLE_POSIX 1
|
||||||
|
#define MG_INT64_FMT "%" PRId64
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if MG_ARCH == MG_ARCH_WIN32
|
#if MG_ARCH == MG_ARCH_WIN32
|
||||||
|
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||||
|
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1700
|
#if defined(_MSC_VER) && _MSC_VER < 1700
|
||||||
#define __func__ ""
|
#define __func__ ""
|
||||||
typedef __int64 int64_t;
|
typedef __int64 int64_t;
|
||||||
@@ -250,6 +347,7 @@ typedef enum { false = 0, true = 1 } bool;
|
|||||||
#define strdup(x) _strdup(x)
|
#define strdup(x) _strdup(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef unsigned suseconds_t;
|
||||||
typedef int socklen_t;
|
typedef int socklen_t;
|
||||||
#define MG_DIRSEP '\\'
|
#define MG_DIRSEP '\\'
|
||||||
#ifndef PATH_MAX
|
#ifndef PATH_MAX
|
||||||
@@ -261,7 +359,8 @@ typedef int socklen_t;
|
|||||||
#ifndef EWOULDBLOCK
|
#ifndef EWOULDBLOCK
|
||||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||||
#endif
|
#endif
|
||||||
#define realpath(a, b) _fullpath((b), (a), 512)
|
#define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
|
||||||
|
#define fopen(a, b) mg_fopen((a), (b))
|
||||||
#ifndef va_copy
|
#ifndef va_copy
|
||||||
#ifdef __va_copy
|
#ifdef __va_copy
|
||||||
#define va_copy __va_copy
|
#define va_copy __va_copy
|
||||||
@@ -273,16 +372,30 @@ typedef int socklen_t;
|
|||||||
#define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
|
#define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MG_INT64_FMT "%I64d"
|
||||||
|
|
||||||
|
static __inline FILE *mg_fopen(const char *path, const char *mode) {
|
||||||
|
wchar_t b1[PATH_MAX], b2[10];
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, path, -1, b1, sizeof(b1) / sizeof(b1[0]));
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, mode, -1, b2, sizeof(b2) / sizeof(b2[0]));
|
||||||
|
return _wfopen(b1, b2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://lgtm.com/rules/2154840805/ -gmtime, localtime, ctime and asctime
|
||||||
|
static __inline struct tm *gmtime_r(time_t *t, struct tm *tm) {
|
||||||
|
(void) tm;
|
||||||
|
return gmtime(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline struct tm *localtime_r(time_t *t, struct tm *tm) {
|
||||||
|
(void) tm;
|
||||||
|
return localtime(t);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef MG_ENABLE_LWIP
|
#ifndef MG_ENABLE_SOCKET
|
||||||
#define MG_ENABLE_LWIP 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MG_ENABLE_LWIP
|
|
||||||
#define MG_ENABLE_SOCKET 0
|
|
||||||
#elif !defined(MG_ENABLE_SOCKET)
|
|
||||||
#define MG_ENABLE_SOCKET 1
|
#define MG_ENABLE_SOCKET 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -310,20 +423,17 @@ typedef int socklen_t;
|
|||||||
#define MG_ENABLE_LOG 1
|
#define MG_ENABLE_LOG 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MG_ENABLE_MGOS
|
|
||||||
#define MG_ENABLE_MGOS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MG_ENABLE_MD5
|
#ifndef MG_ENABLE_MD5
|
||||||
#define MG_ENABLE_MD5 0
|
#define MG_ENABLE_MD5 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MG_ENABLE_DIRECTORY_LISTING
|
// Set MG_ENABLE_WINSOCK=0 for Win32 builds with external IP stack (like LWIP)
|
||||||
#define MG_ENABLE_DIRECTORY_LISTING 0
|
#ifndef MG_ENABLE_WINSOCK
|
||||||
|
#define MG_ENABLE_WINSOCK 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MG_ENABLE_HTTP_DEBUG_ENDPOINT
|
#ifndef MG_ENABLE_DIRECTORY_LISTING
|
||||||
#define MG_ENABLE_HTTP_DEBUG_ENDPOINT 0
|
#define MG_ENABLE_DIRECTORY_LISTING 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MG_ENABLE_SOCKETPAIR
|
#ifndef MG_ENABLE_SOCKETPAIR
|
||||||
@@ -344,6 +454,10 @@ typedef int socklen_t;
|
|||||||
#define MG_MAX_HTTP_HEADERS 40
|
#define MG_MAX_HTTP_HEADERS 40
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MG_PATH_MAX
|
||||||
|
#define MG_PATH_MAX PATH_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -356,6 +470,9 @@ struct mg_str {
|
|||||||
#define MG_NULL_STR \
|
#define MG_NULL_STR \
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
|
|
||||||
|
// Using macro to avoid shadowing C++ struct constructor, see #1298
|
||||||
|
#define mg_str(s) mg_str_s(s)
|
||||||
|
|
||||||
struct mg_str mg_str(const char *s);
|
struct mg_str mg_str(const char *s);
|
||||||
struct mg_str mg_str_n(const char *s, size_t n);
|
struct mg_str mg_str_n(const char *s, size_t n);
|
||||||
int mg_lower(const char *s);
|
int mg_lower(const char *s);
|
||||||
@@ -372,9 +489,6 @@ const char *mg_strstr(const struct mg_str haystack, const struct mg_str needle);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if MG_ENABLE_MGOS
|
|
||||||
#include <common/cs_dbg.h>
|
|
||||||
#else
|
|
||||||
#if MG_ENABLE_LOG
|
#if MG_ENABLE_LOG
|
||||||
#define LOG(level, args) \
|
#define LOG(level, args) \
|
||||||
do { \
|
do { \
|
||||||
@@ -384,27 +498,28 @@ enum { LL_NONE, LL_ERROR, LL_INFO, LL_DEBUG, LL_VERBOSE_DEBUG };
|
|||||||
bool mg_log_prefix(int ll, const char *file, int line, const char *fname);
|
bool mg_log_prefix(int ll, const char *file, int line, const char *fname);
|
||||||
void mg_log(const char *fmt, ...) PRINTF_LIKE(1, 2);
|
void mg_log(const char *fmt, ...) PRINTF_LIKE(1, 2);
|
||||||
void mg_log_set(const char *spec);
|
void mg_log_set(const char *spec);
|
||||||
void mg_log_set_callback(void (*fn)(const void *, int, void *), void *param);
|
void mg_log_set_callback(void (*fn)(const void *, size_t, void *), void *param);
|
||||||
#else
|
#else
|
||||||
#define LOG(level, args)
|
#define LOG(level, args) (void) 0
|
||||||
#endif
|
#define mg_log_set(x) (void) (x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct mg_timer {
|
struct mg_timer {
|
||||||
int period_ms; // Timer period in milliseconds
|
unsigned long period_ms; // Timer period in milliseconds
|
||||||
int flags; // Possible flags values below
|
unsigned flags; // Possible flags values below
|
||||||
#define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once
|
#define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once
|
||||||
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
|
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
|
||||||
void (*fn)(void *); // Function to call
|
void (*fn)(void *); // Function to call
|
||||||
void *arg; // Function agrument
|
void *arg; // Function argument
|
||||||
unsigned long expire; // Expiration timestamp in milliseconds
|
unsigned long expire; // Expiration timestamp in milliseconds
|
||||||
struct mg_timer *next; // Linkage in g_timers list
|
struct mg_timer *next; // Linkage in g_timers list
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct mg_timer *g_timers; // Global list of timers
|
extern struct mg_timer *g_timers; // Global list of timers
|
||||||
|
|
||||||
void mg_timer_init(struct mg_timer *, int ms, int, void (*fn)(void *), void *);
|
void mg_timer_init(struct mg_timer *, unsigned long ms, unsigned,
|
||||||
|
void (*fn)(void *), void *);
|
||||||
void mg_timer_free(struct mg_timer *);
|
void mg_timer_free(struct mg_timer *);
|
||||||
void mg_timer_poll(unsigned long uptime_ms);
|
void mg_timer_poll(unsigned long uptime_ms);
|
||||||
|
|
||||||
@@ -412,18 +527,33 @@ void mg_timer_poll(unsigned long uptime_ms);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
char *mg_file_read(const char *path);
|
// WEAK symbol makes it possible to define a "default" function implementation,
|
||||||
size_t mg_file_size(const char *path);
|
// which could be overridden by the user who can define a function with the
|
||||||
int mg_file_write(const char *path, const char *fmt, ...);
|
// same name without linking conflict
|
||||||
void mg_random(void *buf, size_t len);
|
#if !defined(WEAK)
|
||||||
bool mg_globmatch(const char *pattern, int plen, const char *s, int n);
|
#if (defined(__GNUC__) || defined(__clang__) || \
|
||||||
|
defined(__TI_COMPILER_VERSION__)) && \
|
||||||
|
!defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
#define WEAK __attribute__((weak))
|
||||||
|
#else
|
||||||
|
#define WEAK
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char *mg_file_read(const char *path, size_t *size);
|
||||||
|
int64_t mg_file_size(const char *path);
|
||||||
|
bool mg_file_write(const char *path, const void *buf, size_t len);
|
||||||
|
bool mg_file_printf(const char *path, const char *fmt, ...);
|
||||||
|
void mg_random(void *buf, size_t len) WEAK;
|
||||||
|
bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n);
|
||||||
bool mg_next_comma_entry(struct mg_str *s, struct mg_str *k, struct mg_str *v);
|
bool mg_next_comma_entry(struct mg_str *s, struct mg_str *k, struct mg_str *v);
|
||||||
uint16_t mg_ntohs(uint16_t net);
|
uint16_t mg_ntohs(uint16_t net);
|
||||||
uint32_t mg_ntohl(uint32_t net);
|
uint32_t mg_ntohl(uint32_t net);
|
||||||
|
uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
|
||||||
char *mg_hexdump(const void *buf, size_t len);
|
char *mg_hexdump(const void *buf, size_t len);
|
||||||
char *mg_hex(const void *buf, int len, char *dst);
|
char *mg_hex(const void *buf, size_t len, char *dst);
|
||||||
void mg_unhex(const char *buf, int len, unsigned char *to);
|
void mg_unhex(const char *buf, size_t len, unsigned char *to);
|
||||||
unsigned long mg_unhexn(const char *s, int len);
|
unsigned long mg_unhexn(const char *s, size_t len);
|
||||||
int mg_asprintf(char **buf, size_t size, const char *fmt, ...);
|
int mg_asprintf(char **buf, size_t size, const char *fmt, ...);
|
||||||
int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap);
|
int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap);
|
||||||
int64_t mg_to64(struct mg_str str);
|
int64_t mg_to64(struct mg_str str);
|
||||||
@@ -431,23 +561,18 @@ double mg_time(void);
|
|||||||
unsigned long mg_millis(void);
|
unsigned long mg_millis(void);
|
||||||
void mg_usleep(unsigned long usecs);
|
void mg_usleep(unsigned long usecs);
|
||||||
|
|
||||||
|
#if MG_ENABLE_FS
|
||||||
|
#ifdef _WIN32
|
||||||
|
typedef struct _stati64 mg_stat_t;
|
||||||
|
#else
|
||||||
|
typedef struct stat mg_stat_t;
|
||||||
|
#endif
|
||||||
|
int mg_stat(const char *path, mg_stat_t *);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define mg_htons(x) mg_ntohs(x)
|
#define mg_htons(x) mg_ntohs(x)
|
||||||
#define mg_htonl(x) mg_ntohl(x)
|
#define mg_htonl(x) mg_ntohl(x)
|
||||||
|
|
||||||
#define MG_SWAP16(x) ((((x) >> 8) & 255) | ((x & 255) << 8))
|
|
||||||
#define MG_SWAP32(x) \
|
|
||||||
(((x) >> 24) | (((x) &0xff0000) >> 8) | (((x) &0xff00) << 8) | ((x) << 24))
|
|
||||||
|
|
||||||
#if !defined(WEAK)
|
|
||||||
#if (defined(__GNUC__) || defined(__clang__) || \
|
|
||||||
defined(__TI_COMPILER_VERSION__)) && \
|
|
||||||
!defined(_WIN32)
|
|
||||||
#define WEAK __attribute__((weak))
|
|
||||||
#else
|
|
||||||
#define WEAK
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Expands to a string representation of its argument: e.g.
|
// Expands to a string representation of its argument: e.g.
|
||||||
// MG_STRINGIFY_LITERAL(5) expands to "5"
|
// MG_STRINGIFY_LITERAL(5) expands to "5"
|
||||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||||
@@ -455,7 +580,12 @@ void mg_usleep(unsigned long usecs);
|
|||||||
#else
|
#else
|
||||||
#define MG_STRINGIFY_LITERAL(x) #x
|
#define MG_STRINGIFY_LITERAL(x) #x
|
||||||
#endif
|
#endif
|
||||||
|
// Expands to a string representation of its argument, which can be a macro:
|
||||||
|
// #define FOO 123
|
||||||
|
// MG_STRINGIFY_MACRO(FOO) // Expands to 123
|
||||||
|
#define MG_STRINGIFY_MACRO(x) MG_STRINGIFY_LITERAL(x)
|
||||||
|
|
||||||
|
// Linked list management macros
|
||||||
#define LIST_ADD_HEAD(type_, head_, elem_) \
|
#define LIST_ADD_HEAD(type_, head_, elem_) \
|
||||||
do { \
|
do { \
|
||||||
(elem_)->next = (*head_); \
|
(elem_)->next = (*head_); \
|
||||||
@@ -476,11 +606,6 @@ void mg_usleep(unsigned long usecs);
|
|||||||
*h = (elem_)->next; \
|
*h = (elem_)->next; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
// Expands to a string representation of its argument, which can be a macro:
|
|
||||||
// #define FOO 123
|
|
||||||
// MG_STRINGIFY_MACRO(FOO) // Expands to 123
|
|
||||||
#define MG_STRINGIFY_MACRO(x) MG_STRINGIFY_LITERAL(x)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned short mg_url_port(const char *url);
|
unsigned short mg_url_port(const char *url);
|
||||||
@@ -498,8 +623,8 @@ struct mg_iobuf {
|
|||||||
size_t size, len;
|
size_t size, len;
|
||||||
};
|
};
|
||||||
|
|
||||||
void mg_iobuf_init(struct mg_iobuf *, size_t);
|
int mg_iobuf_init(struct mg_iobuf *, size_t);
|
||||||
void mg_iobuf_resize(struct mg_iobuf *, size_t);
|
int mg_iobuf_resize(struct mg_iobuf *, size_t);
|
||||||
void mg_iobuf_free(struct mg_iobuf *);
|
void mg_iobuf_free(struct mg_iobuf *);
|
||||||
size_t mg_iobuf_append(struct mg_iobuf *, const void *, size_t, size_t);
|
size_t mg_iobuf_append(struct mg_iobuf *, const void *, size_t, size_t);
|
||||||
size_t mg_iobuf_delete(struct mg_iobuf *, size_t);
|
size_t mg_iobuf_delete(struct mg_iobuf *, size_t);
|
||||||
@@ -542,38 +667,28 @@ void mg_hmac_sha1(const unsigned char *key, size_t key_len,
|
|||||||
struct mg_connection;
|
struct mg_connection;
|
||||||
typedef void (*mg_event_handler_t)(struct mg_connection *, int ev,
|
typedef void (*mg_event_handler_t)(struct mg_connection *, int ev,
|
||||||
void *ev_data, void *fn_data);
|
void *ev_data, void *fn_data);
|
||||||
#if 0
|
|
||||||
struct mg_fn {
|
|
||||||
struct mg_fn *next;
|
|
||||||
mg_event_handler_t fn;
|
|
||||||
void *fn_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
void mg_fn_add(struct mg_connection *c, mg_event_handler_t fn, void *fn_data);
|
|
||||||
void mg_fn_del(struct mg_connection *c, mg_event_handler_t fn);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void mg_call(struct mg_connection *c, int ev, void *ev_data);
|
void mg_call(struct mg_connection *c, int ev, void *ev_data);
|
||||||
void mg_error(struct mg_connection *c, const char *fmt, ...);
|
void mg_error(struct mg_connection *c, const char *fmt, ...);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MG_EV_ERROR, // Error char *error_message
|
MG_EV_ERROR, // Error char *error_message
|
||||||
MG_EV_POLL, // mg_mgr_poll iteration unsigned long *millis
|
MG_EV_POLL, // mg_mgr_poll iteration unsigned long *millis
|
||||||
MG_EV_RESOLVE, // Host name is resolved NULL
|
MG_EV_RESOLVE, // Host name is resolved NULL
|
||||||
MG_EV_CONNECT, // Connection established NULL
|
MG_EV_CONNECT, // Connection established NULL
|
||||||
MG_EV_ACCEPT, // Connection accepted NULL
|
MG_EV_ACCEPT, // Connection accepted NULL
|
||||||
MG_EV_READ, // Data received from socket struct mg_str *
|
MG_EV_READ, // Data received from socket struct mg_str *
|
||||||
MG_EV_WRITE, // Data written to socket int *num_bytes_written
|
MG_EV_WRITE, // Data written to socket long *bytes_written
|
||||||
MG_EV_CLOSE, // Connection closed NULL
|
MG_EV_CLOSE, // Connection closed NULL
|
||||||
MG_EV_HTTP_MSG, // HTTP request/response struct mg_http_message *
|
MG_EV_HTTP_MSG, // HTTP request/response struct mg_http_message *
|
||||||
MG_EV_WS_OPEN, // Websocket handshake done struct mg_http_message *
|
MG_EV_HTTP_CHUNK, // HTTP chunk (partial msg) struct mg_http_message *
|
||||||
MG_EV_WS_MSG, // Websocket msg, text or bin struct mg_ws_message *
|
MG_EV_WS_OPEN, // Websocket handshake done struct mg_http_message *
|
||||||
MG_EV_WS_CTL, // Websocket control msg struct mg_ws_message *
|
MG_EV_WS_MSG, // Websocket msg, text or bin struct mg_ws_message *
|
||||||
MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message *
|
MG_EV_WS_CTL, // Websocket control msg struct mg_ws_message *
|
||||||
MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message *
|
MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message *
|
||||||
MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code
|
MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message *
|
||||||
MG_EV_SNTP_TIME, // SNTP time received struct timeval *
|
MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code
|
||||||
MG_EV_USER, // Starting ID for user events
|
MG_EV_SNTP_TIME, // SNTP time received struct timeval *
|
||||||
|
MG_EV_USER, // Starting ID for user events
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -600,7 +715,8 @@ struct mg_mgr {
|
|||||||
struct mg_dns dns6; // DNS for IPv6
|
struct mg_dns dns6; // DNS for IPv6
|
||||||
int dnstimeout; // DNS resolve timeout in milliseconds
|
int dnstimeout; // DNS resolve timeout in milliseconds
|
||||||
unsigned long nextid; // Next connection ID
|
unsigned long nextid; // Next connection ID
|
||||||
#if MG_ARCH == MG_ARCH_FREERTOS
|
void *userdata; // Arbitrary user data pointer
|
||||||
|
#if MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||||
SocketSet_t ss; // NOTE(lsm): referenced from socket struct
|
SocketSet_t ss; // NOTE(lsm): referenced from socket struct
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -608,21 +724,21 @@ struct mg_mgr {
|
|||||||
struct mg_connection {
|
struct mg_connection {
|
||||||
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
||||||
struct mg_mgr *mgr; // Our container
|
struct mg_mgr *mgr; // Our container
|
||||||
struct mg_addr peer; // Remote peer address
|
struct mg_addr peer; // Remote address. For listeners, local address
|
||||||
void *fd; // Connected socket, or LWIP data
|
void *fd; // Connected socket, or LWIP data
|
||||||
unsigned long id; // Auto-incrementing unique connection ID
|
unsigned long id; // Auto-incrementing unique connection ID
|
||||||
struct mg_iobuf recv; // Incoming data
|
struct mg_iobuf recv; // Incoming data
|
||||||
struct mg_iobuf send; // Outgoing data
|
struct mg_iobuf send; // Outgoing data
|
||||||
mg_event_handler_t fn; // User-specified event handler function
|
mg_event_handler_t fn; // User-specified event handler function
|
||||||
void *fn_data; // User-speficied function parameter
|
void *fn_data; // User-specified function parameter
|
||||||
mg_event_handler_t pfn; // Protocol-specific handler function
|
mg_event_handler_t pfn; // Protocol-specific handler function
|
||||||
void *pfn_data; // Protocol-specific function parameter
|
void *pfn_data; // Protocol-specific function parameter
|
||||||
char label[32]; // Arbitrary label
|
char label[50]; // Arbitrary label
|
||||||
void *tls; // TLS specific data
|
void *tls; // TLS specific data
|
||||||
unsigned is_listening : 1; // Listening connection
|
unsigned is_listening : 1; // Listening connection
|
||||||
unsigned is_client : 1; // Outbound (client) connection
|
unsigned is_client : 1; // Outbound (client) connection
|
||||||
unsigned is_accepted : 1; // Accepted (server) connection
|
unsigned is_accepted : 1; // Accepted (server) connection
|
||||||
unsigned is_resolving : 1; // Non-blocking DNS resolv is in progress
|
unsigned is_resolving : 1; // Non-blocking DNS resolution is in progress
|
||||||
unsigned is_connecting : 1; // Non-blocking connect is in progress
|
unsigned is_connecting : 1; // Non-blocking connect is in progress
|
||||||
unsigned is_tls : 1; // TLS-enabled connection
|
unsigned is_tls : 1; // TLS-enabled connection
|
||||||
unsigned is_tls_hs : 1; // TLS handshake is in progress
|
unsigned is_tls_hs : 1; // TLS handshake is in progress
|
||||||
@@ -643,7 +759,7 @@ struct mg_connection *mg_listen(struct mg_mgr *, const char *url,
|
|||||||
mg_event_handler_t fn, void *fn_data);
|
mg_event_handler_t fn, void *fn_data);
|
||||||
struct mg_connection *mg_connect(struct mg_mgr *, const char *url,
|
struct mg_connection *mg_connect(struct mg_mgr *, const char *url,
|
||||||
mg_event_handler_t fn, void *fn_data);
|
mg_event_handler_t fn, void *fn_data);
|
||||||
int mg_send(struct mg_connection *, const void *, size_t);
|
bool mg_send(struct mg_connection *, const void *, size_t);
|
||||||
int mg_printf(struct mg_connection *, const char *fmt, ...);
|
int mg_printf(struct mg_connection *, const char *fmt, ...);
|
||||||
int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
|
int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
|
||||||
char *mg_straddr(struct mg_connection *, char *, size_t);
|
char *mg_straddr(struct mg_connection *, char *, size_t);
|
||||||
@@ -668,19 +784,30 @@ struct mg_http_message {
|
|||||||
struct mg_str method, uri, query, proto; // Request/response line
|
struct mg_str method, uri, query, proto; // Request/response line
|
||||||
struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers
|
struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers
|
||||||
struct mg_str body; // Body
|
struct mg_str body; // Body
|
||||||
struct mg_str message; // Request line + headers + body
|
struct mg_str head; // Request + headers
|
||||||
|
struct mg_str chunk; // Chunk for chunked encoding, or partial body
|
||||||
|
struct mg_str message; // Request + headers + body
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parameter for mg_http_serve_dir()
|
// Parameter for mg_http_serve_dir()
|
||||||
struct mg_http_serve_opts {
|
struct mg_http_serve_opts {
|
||||||
const char *root_dir; // Web root directory, must be non-NULL
|
const char *root_dir; // Web root directory, must be non-NULL
|
||||||
const char *ssi_pattern; // SSI filename pattern, e.g. #.shtml
|
const char *ssi_pattern; // SSI file name pattern, e.g. #.shtml
|
||||||
|
const char *extra_headers; // Extra HTTP headers to add in responses
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parameter for mg_http_next_multipart
|
||||||
|
struct mg_http_part {
|
||||||
|
struct mg_str name; // Form field name
|
||||||
|
struct mg_str filename; // Filename for file uploads
|
||||||
|
struct mg_str body; // Part contents
|
||||||
};
|
};
|
||||||
|
|
||||||
int mg_http_parse(const char *s, size_t len, struct mg_http_message *);
|
int mg_http_parse(const char *s, size_t len, struct mg_http_message *);
|
||||||
int mg_http_get_request_len(const unsigned char *buf, size_t buf_len);
|
int mg_http_get_request_len(const unsigned char *buf, size_t buf_len);
|
||||||
void mg_http_printf_chunk(struct mg_connection *cnn, const char *fmt, ...);
|
void mg_http_printf_chunk(struct mg_connection *cnn, const char *fmt, ...);
|
||||||
void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len);
|
void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len);
|
||||||
|
void mg_http_delete_chunk(struct mg_connection *c, struct mg_http_message *hm);
|
||||||
struct mg_connection *mg_http_listen(struct mg_mgr *, const char *url,
|
struct mg_connection *mg_http_listen(struct mg_mgr *, const char *url,
|
||||||
mg_event_handler_t fn, void *fn_data);
|
mg_event_handler_t fn, void *fn_data);
|
||||||
struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url,
|
struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url,
|
||||||
@@ -693,13 +820,16 @@ void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
|
|||||||
const char *body_fmt, ...);
|
const char *body_fmt, ...);
|
||||||
struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
|
struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
|
||||||
void mg_http_event_handler(struct mg_connection *c, int ev);
|
void mg_http_event_handler(struct mg_connection *c, int ev);
|
||||||
int mg_http_get_var(const struct mg_str *, const char *name, char *, int);
|
int mg_http_get_var(const struct mg_str *, const char *name, char *, size_t);
|
||||||
int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
|
int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
|
||||||
void mg_http_creds(struct mg_http_message *, char *user, int, char *pass, int);
|
size_t mg_url_encode(const char *s, size_t n, char *buf, size_t len);
|
||||||
|
void mg_http_creds(struct mg_http_message *, char *, size_t, char *, size_t);
|
||||||
bool mg_http_match_uri(const struct mg_http_message *, const char *glob);
|
bool mg_http_match_uri(const struct mg_http_message *, const char *glob);
|
||||||
int mg_http_upload(struct mg_connection *, struct mg_http_message *hm,
|
int mg_http_upload(struct mg_connection *, struct mg_http_message *hm,
|
||||||
const char *dir);
|
const char *dir);
|
||||||
void mg_http_bauth(struct mg_connection *, const char *user, const char *pass);
|
void mg_http_bauth(struct mg_connection *, const char *user, const char *pass);
|
||||||
|
struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v);
|
||||||
|
size_t mg_http_next_multipart(struct mg_str, size_t, struct mg_http_part *);
|
||||||
|
|
||||||
|
|
||||||
void mg_http_serve_ssi(struct mg_connection *c, const char *root,
|
void mg_http_serve_ssi(struct mg_connection *c, const char *root,
|
||||||
@@ -708,18 +838,18 @@ void mg_http_serve_ssi(struct mg_connection *c, const char *root,
|
|||||||
|
|
||||||
|
|
||||||
struct mg_tls_opts {
|
struct mg_tls_opts {
|
||||||
const char *ca; // CA certificate file. For both listeners and clients
|
const char *ca; // CA certificate file. For both listeners and clients
|
||||||
const char *cert; // Certificate
|
const char *cert; // Certificate
|
||||||
const char *certkey; // Certificate key
|
const char *certkey; // Certificate key
|
||||||
const char *ciphers; // Cipher list
|
const char *ciphers; // Cipher list
|
||||||
const char *srvname; // If not NULL, enables server name verification
|
struct mg_str srvname; // If not empty, enables server name verification
|
||||||
};
|
};
|
||||||
|
|
||||||
int mg_tls_init(struct mg_connection *, struct mg_tls_opts *);
|
void mg_tls_init(struct mg_connection *, struct mg_tls_opts *);
|
||||||
int mg_tls_free(struct mg_connection *);
|
void mg_tls_free(struct mg_connection *);
|
||||||
int mg_tls_send(struct mg_connection *, const void *buf, size_t len, int *fail);
|
long mg_tls_send(struct mg_connection *, const void *buf, size_t len);
|
||||||
int mg_tls_recv(struct mg_connection *, void *buf, size_t len, int *fail);
|
long mg_tls_recv(struct mg_connection *, void *buf, size_t len);
|
||||||
int mg_tls_handshake(struct mg_connection *);
|
void mg_tls_handshake(struct mg_connection *);
|
||||||
|
|
||||||
|
|
||||||
#define WEBSOCKET_OP_CONTINUE 0
|
#define WEBSOCKET_OP_CONTINUE 0
|
||||||
@@ -788,9 +918,9 @@ struct mg_mqtt_opts {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct mg_mqtt_message {
|
struct mg_mqtt_message {
|
||||||
struct mg_str topic; // Parsed topic
|
struct mg_str topic; // Parsed topic
|
||||||
struct mg_str data; // Parsed message
|
struct mg_str data; // Parsed message
|
||||||
struct mg_str dgram; // Whole MQTT datagram, including headers
|
struct mg_str dgram; // Whole MQTT datagram, including headers
|
||||||
uint16_t id; // Set for PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, PUBLISH
|
uint16_t id; // Set for PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, PUBLISH
|
||||||
uint8_t cmd; // MQTT command, one of MQTT_CMD_*
|
uint8_t cmd; // MQTT command, one of MQTT_CMD_*
|
||||||
uint8_t qos; // Quality of service
|
uint8_t qos; // Quality of service
|
||||||
@@ -802,14 +932,19 @@ struct mg_connection *mg_mqtt_connect(struct mg_mgr *, const char *url,
|
|||||||
mg_event_handler_t fn, void *fn_data);
|
mg_event_handler_t fn, void *fn_data);
|
||||||
struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
|
struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
|
||||||
mg_event_handler_t fn, void *fn_data);
|
mg_event_handler_t fn, void *fn_data);
|
||||||
void mg_mqtt_pub(struct mg_connection *, struct mg_str *topic,
|
void mg_mqtt_pub(struct mg_connection *c, struct mg_str *topic,
|
||||||
struct mg_str *data);
|
struct mg_str *data, int qos, bool retain);
|
||||||
void mg_mqtt_sub(struct mg_connection *, struct mg_str *topic);
|
void mg_mqtt_sub(struct mg_connection *, struct mg_str *topic, int qos);
|
||||||
int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m);
|
int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m);
|
||||||
void mg_mqtt_send_header(struct mg_connection *, uint8_t cmd, uint8_t flags,
|
void mg_mqtt_send_header(struct mg_connection *, uint8_t cmd, uint8_t flags,
|
||||||
uint32_t len);
|
uint32_t len);
|
||||||
int mg_mqtt_next_sub(struct mg_mqtt_message *msg, struct mg_str *topic,
|
size_t mg_mqtt_next_sub(struct mg_mqtt_message *msg, struct mg_str *topic,
|
||||||
uint8_t *qos, int pos);
|
uint8_t *qos, size_t pos);
|
||||||
|
size_t mg_mqtt_next_unsub(struct mg_mqtt_message *msg, struct mg_str *topic,
|
||||||
|
size_t pos);
|
||||||
|
void mg_mqtt_ping(struct mg_connection *);
|
||||||
|
void mg_mqtt_pong(struct mg_connection *);
|
||||||
|
void mg_mqtt_disconnect(struct mg_connection *);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -849,3 +984,8 @@ bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *);
|
|||||||
size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
|
size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
|
||||||
bool is_question, struct mg_dns_rr *);
|
bool is_question, struct mg_dns_rr *);
|
||||||
size_t mg_dns_decode_name(const uint8_t *, size_t, size_t, char *, size_t);
|
size_t mg_dns_decode_name(const uint8_t *, size_t, size_t, char *, size_t);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif // MONGOOSE_H
|
||||||
+16
-67
@@ -5,54 +5,20 @@
|
|||||||
#define MG_ARCH_WIN32 2
|
#define MG_ARCH_WIN32 2
|
||||||
#define MG_ARCH_ESP32 3
|
#define MG_ARCH_ESP32 3
|
||||||
#define MG_ARCH_ESP8266 4
|
#define MG_ARCH_ESP8266 4
|
||||||
#define MG_ARCH_CC3100 5
|
#define MG_ARCH_FREERTOS_TCP 5
|
||||||
#define MG_ARCH_CC3200 6
|
#define MG_ARCH_FREERTOS_LWIP 6
|
||||||
#define MG_ARCH_CC3220 7
|
|
||||||
#define MG_ARCH_MSP432 8
|
|
||||||
#define MG_ARCH_TM4C129 9
|
|
||||||
#define MG_ARCH_MBED 10
|
|
||||||
#define MG_ARCH_WINCE 11
|
|
||||||
#define MG_ARCH_NXP_LPC 12
|
|
||||||
#define MG_ARCH_NXP_KINETIS 13
|
|
||||||
#define MG_ARCH_NRF51 14
|
|
||||||
#define MG_ARCH_NRF52 15
|
|
||||||
#define MG_ARCH_PIC32 16
|
|
||||||
#define MG_ARCH_RS14100 17
|
|
||||||
#define MG_ARCH_STM32 18
|
|
||||||
#define MG_ARCH_FREERTOS 19
|
|
||||||
|
|
||||||
#if !defined(MG_ARCH)
|
#if !defined(MG_ARCH)
|
||||||
#if defined(TARGET_IS_MSP432P4XX) || defined(__MSP432P401R__)
|
#if defined(__unix__) || defined(__APPLE__)
|
||||||
#define MG_ARCH MG_ARCH_MSP432
|
|
||||||
#elif defined(cc3200) || defined(TARGET_IS_CC3200)
|
|
||||||
#define MG_ARCH MG_ARCH_CC3200
|
|
||||||
#elif defined(cc3220) || defined(TARGET_IS_CC3220)
|
|
||||||
#define MG_ARCH MG_ARCH_CC3220
|
|
||||||
#elif defined(__unix__) || defined(__APPLE__)
|
|
||||||
#define MG_ARCH MG_ARCH_UNIX
|
#define MG_ARCH MG_ARCH_UNIX
|
||||||
#elif defined(WINCE)
|
|
||||||
#define MG_ARCH MG_ARCH_WINCE
|
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
#define MG_ARCH MG_ARCH_WIN32
|
#define MG_ARCH MG_ARCH_WIN32
|
||||||
#elif defined(__MBED__)
|
|
||||||
#define MG_ARCH MG_ARCH_MBED
|
|
||||||
#elif defined(__USE_LPCOPEN)
|
|
||||||
#define MG_ARCH MG_ARCH_NXP_LPC
|
|
||||||
#elif defined(FRDM_K64F) || defined(FREEDOM)
|
|
||||||
#define MG_ARCH MG_ARCH_NXP_KINETIS
|
|
||||||
#elif defined(PIC32)
|
|
||||||
#define MG_ARCH MG_ARCH_PIC32
|
|
||||||
#elif defined(ICACHE_FLASH) || defined(ICACHE_RAM_ATTR)
|
#elif defined(ICACHE_FLASH) || defined(ICACHE_RAM_ATTR)
|
||||||
#define MG_ARCH MG_ARCH_ESP8266
|
#define MG_ARCH MG_ARCH_ESP8266
|
||||||
#elif defined(ESP_PLATFORM)
|
#elif defined(ESP_PLATFORM)
|
||||||
#define MG_ARCH MG_ARCH_ESP32
|
#define MG_ARCH MG_ARCH_ESP32
|
||||||
#elif defined(TARGET_IS_TM4C129_RA0) || defined(TARGET_IS_TM4C129_RA1) || \
|
#elif defined(FREERTOS_IP_H)
|
||||||
defined(TARGET_IS_TM4C129_RA2)
|
#define MG_ARCH MG_ARCH_FREERTOS_TCP
|
||||||
#define MG_ARCH MG_ARCH_TM4C129
|
|
||||||
#elif defined(RS14100)
|
|
||||||
#define MG_ARCH MG_ARCH_RS14100
|
|
||||||
#elif defined(STM32)
|
|
||||||
#define MG_ARCH MG_ARCH_STM32
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(MG_ARCH)
|
#if !defined(MG_ARCH)
|
||||||
@@ -60,34 +26,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif // !defined(MG_ARCH)
|
#endif // !defined(MG_ARCH)
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
|
||||||
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
|
||||||
|
|
||||||
// Standard C headers
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#if MG_ARCH == MG_ARCH_CUSTOM
|
|
||||||
#include <mongoose_custom.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "arch_esp32.h"
|
|
||||||
#include "arch_esp8266.h"
|
|
||||||
#include "arch_freertos.h"
|
|
||||||
#include "arch_unix.h"
|
|
||||||
#include "arch_win32.h"
|
|
||||||
|
|
||||||
#if !defined(PRINTF_LIKE)
|
#if !defined(PRINTF_LIKE)
|
||||||
#if defined(__GNUC__) || defined(__clang__) || defined(__TI_COMPILER_VERSION__)
|
#if defined(__GNUC__) || defined(__clang__) || defined(__TI_COMPILER_VERSION__)
|
||||||
#define PRINTF_LIKE(f, a) __attribute__((format(printf, f, a)))
|
#define PRINTF_LIKE(f, a) __attribute__((format(printf, f, a)))
|
||||||
@@ -95,3 +33,14 @@
|
|||||||
#define PRINTF_LIKE(f, a)
|
#define PRINTF_LIKE(f, a)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MG_ARCH == MG_ARCH_CUSTOM
|
||||||
|
#include <mongoose_custom.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "arch_esp32.h"
|
||||||
|
#include "arch_esp8266.h"
|
||||||
|
#include "arch_freertos_lwip.h"
|
||||||
|
#include "arch_freertos_tcp.h"
|
||||||
|
#include "arch_unix.h"
|
||||||
|
#include "arch_win32.h"
|
||||||
@@ -2,8 +2,25 @@
|
|||||||
|
|
||||||
#if MG_ARCH == MG_ARCH_ESP32
|
#if MG_ARCH == MG_ARCH_ESP32
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#define MG_DIRSEP '/'
|
#define MG_DIRSEP '/'
|
||||||
|
#define MG_INT64_FMT "%lld"
|
||||||
|
#ifndef MG_PATH_MAX
|
||||||
|
#define MG_PATH_MAX 128
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+16
-1
@@ -2,11 +2,26 @@
|
|||||||
|
|
||||||
#if MG_ARCH == MG_ARCH_ESP8266
|
#if MG_ARCH == MG_ARCH_ESP8266
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <esp_system.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <esp_system.h>
|
||||||
|
|
||||||
#define MG_DIRSEP '/'
|
#define MG_DIRSEP '/'
|
||||||
|
#define MG_INT64_FMT "%lld"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#if MG_ARCH == MG_ARCH_FREERTOS
|
|
||||||
#include <FreeRTOS.h>
|
|
||||||
|
|
||||||
#include <task.h>
|
|
||||||
|
|
||||||
#include <FreeRTOS_IP.h>
|
|
||||||
#include <FreeRTOS_Sockets.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define MG_DIRSEP '/'
|
|
||||||
#define IPPROTO_TCP FREERTOS_IPPROTO_TCP
|
|
||||||
#define IPPROTO_UDP FREERTOS_IPPROTO_UDP
|
|
||||||
#define AF_INET FREERTOS_AF_INET
|
|
||||||
#define SOCK_STREAM FREERTOS_SOCK_STREAM
|
|
||||||
#define SOCK_DGRAM FREERTOS_SOCK_DGRAM
|
|
||||||
#define SO_BROADCAST 0
|
|
||||||
#define SO_ERROR 0
|
|
||||||
#define SOL_SOCKET 0
|
|
||||||
#define SO_REUSEADDR 0
|
|
||||||
#define sockaddr_in freertos_sockaddr
|
|
||||||
struct sockaddr {
|
|
||||||
uint8_t sa_len, sa_family;
|
|
||||||
};
|
|
||||||
#define accept(a, b, c) FreeRTOS_accept((a), (b), (c))
|
|
||||||
#define connect(a, b, c) FreeRTOS_connect((a), (b), (c))
|
|
||||||
#define bind(a, b, c) FreeRTOS_bind((a), (b), (c))
|
|
||||||
#define listen(a, b) FreeRTOS_listen((a), (b))
|
|
||||||
#define socket(a, b, c) FreeRTOS_socket((a), (b), (c))
|
|
||||||
#define send(a, b, c, d) FreeRTOS_send((a), (b), (c), (d))
|
|
||||||
#define recv(a, b, c, d) FreeRTOS_recv((a), (b), (c), (d))
|
|
||||||
#define setsockopt(a, b, c, d, e) FreeRTOS_setsockopt((a), (b), (c), (d), (e))
|
|
||||||
#define sendto(a, b, c, d, e, f) FreeRTOS_sendto((a), (b), (c), (d), (e), (f))
|
|
||||||
#define recvfrom(a, b, c, d, e, f) \
|
|
||||||
FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f))
|
|
||||||
#define closesocket(x) FreeRTOS_closesocket(x)
|
|
||||||
#define gethostbyname(x) FreeRTOS_gethostbyname(x)
|
|
||||||
|
|
||||||
#include <ff_stdio.h>
|
|
||||||
|
|
||||||
#undef FILE
|
|
||||||
#define FILE FF_FILE
|
|
||||||
//#define SEEK_SET FF_SEEK_SET
|
|
||||||
//#define SEEK_END FF_SEEK_END
|
|
||||||
#define stat(a, b) ff_stat((a), (b))
|
|
||||||
#define fopen(a, b) ff_fopen((a), (b))
|
|
||||||
#define fclose(a) ff_fclose(a)
|
|
||||||
#define fread(a, b, c, d) ff_fread((a), (b), (c), (d))
|
|
||||||
#define fwrite(a, b, c, d) ff_fwrite((a), (b), (c), (d))
|
|
||||||
#define vfprintf ff_vfprintf
|
|
||||||
#define fprintf ff_fprintf
|
|
||||||
#define remove(a) ff_remove(a)
|
|
||||||
#define rename(a, b) ff_rename((a), (b), 1)
|
|
||||||
|
|
||||||
static inline int ff_vfprintf(FF_FILE *fp, const char *fmt, va_list ap) {
|
|
||||||
char *buf = NULL;
|
|
||||||
int n = mg_vasprintf(&buf, 0, fmt, ap);
|
|
||||||
if (buf != NULL) ff_fwrite(buf, 1, n, fp), free(buf);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if MG_ARCH == MG_ARCH_FREERTOS_LWIP
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#include <sys/time.h>
|
||||||
|
#else
|
||||||
|
typedef long suseconds_t;
|
||||||
|
struct timeval {
|
||||||
|
time_t tv_sec;
|
||||||
|
suseconds_t tv_usec;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MG_ENABLE_FS
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <FreeRTOS.h>
|
||||||
|
#include <task.h>
|
||||||
|
|
||||||
|
#include <lwip/sockets.h>
|
||||||
|
|
||||||
|
#define MG_INT64_FMT "%lld"
|
||||||
|
#define MG_DIRSEP '/'
|
||||||
|
|
||||||
|
// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib
|
||||||
|
static inline void *mg_calloc(int cnt, size_t size) {
|
||||||
|
void *p = pvPortMalloc(cnt * size);
|
||||||
|
if (p != NULL) memset(p, 0, size);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
#define calloc(a, b) mg_calloc((a), (b))
|
||||||
|
#define free(a) vPortFree(a)
|
||||||
|
#define malloc(a) pvPortMalloc(a)
|
||||||
|
|
||||||
|
#define gmtime_r(a, b) gmtime(a)
|
||||||
|
|
||||||
|
#endif // MG_ARCH == MG_ARCH_FREERTOS_LWIP
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#if MG_ENABLE_FS
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <FreeRTOS.h>
|
||||||
|
#include <FreeRTOS_IP.h>
|
||||||
|
#include <FreeRTOS_Sockets.h>
|
||||||
|
#include <task.h>
|
||||||
|
|
||||||
|
#define MG_INT64_FMT "%lld"
|
||||||
|
#define MG_DIRSEP '/'
|
||||||
|
|
||||||
|
// Why FreeRTOS-TCP did not implement a clean BSD API, but its own thing
|
||||||
|
// with FreeRTOS_ prefix, is beyond me
|
||||||
|
#define IPPROTO_TCP FREERTOS_IPPROTO_TCP
|
||||||
|
#define IPPROTO_UDP FREERTOS_IPPROTO_UDP
|
||||||
|
#define AF_INET FREERTOS_AF_INET
|
||||||
|
#define SOCK_STREAM FREERTOS_SOCK_STREAM
|
||||||
|
#define SOCK_DGRAM FREERTOS_SOCK_DGRAM
|
||||||
|
#define SO_BROADCAST 0
|
||||||
|
#define SO_ERROR 0
|
||||||
|
#define SOL_SOCKET 0
|
||||||
|
#define SO_REUSEADDR 0
|
||||||
|
#define sockaddr_in freertos_sockaddr
|
||||||
|
#define sockaddr freertos_sockaddr
|
||||||
|
#define accept(a, b, c) FreeRTOS_accept((a), (b), (c))
|
||||||
|
#define connect(a, b, c) FreeRTOS_connect((a), (b), (c))
|
||||||
|
#define bind(a, b, c) FreeRTOS_bind((a), (b), (c))
|
||||||
|
#define listen(a, b) FreeRTOS_listen((a), (b))
|
||||||
|
#define socket(a, b, c) FreeRTOS_socket((a), (b), (c))
|
||||||
|
#define send(a, b, c, d) FreeRTOS_send((a), (b), (c), (d))
|
||||||
|
#define recv(a, b, c, d) FreeRTOS_recv((a), (b), (c), (d))
|
||||||
|
#define setsockopt(a, b, c, d, e) FreeRTOS_setsockopt((a), (b), (c), (d), (e))
|
||||||
|
#define sendto(a, b, c, d, e, f) FreeRTOS_sendto((a), (b), (c), (d), (e), (f))
|
||||||
|
#define recvfrom(a, b, c, d, e, f) \
|
||||||
|
FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f))
|
||||||
|
#define closesocket(x) FreeRTOS_closesocket(x)
|
||||||
|
#define gethostbyname(x) FreeRTOS_gethostbyname(x)
|
||||||
|
|
||||||
|
// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib
|
||||||
|
static inline void *mg_calloc(int cnt, size_t size) {
|
||||||
|
void *p = pvPortMalloc(cnt * size);
|
||||||
|
if (p != NULL) memset(p, 0, size);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
#define calloc(a, b) mg_calloc((a), (b))
|
||||||
|
#define free(a) vPortFree(a)
|
||||||
|
#define malloc(a) pvPortMalloc(a)
|
||||||
|
|
||||||
|
#define gmtime_r(a, b) gmtime(a)
|
||||||
|
|
||||||
|
#if !defined(__GNUC__)
|
||||||
|
// copied from GCC on ARM; for some reason useconds are signed
|
||||||
|
typedef long suseconds_t;
|
||||||
|
struct timeval {
|
||||||
|
time_t tv_sec;
|
||||||
|
suseconds_t tv_usec;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EINPROGRESS
|
||||||
|
#define EINPROGRESS pdFREERTOS_ERRNO_EINPROGRESS
|
||||||
|
#endif
|
||||||
|
#ifndef EWOULDBLOCK
|
||||||
|
#define EWOULDBLOCK pdFREERTOS_ERRNO_EWOULDBLOCK
|
||||||
|
#endif
|
||||||
|
#ifndef EAGAIN
|
||||||
|
#define EAGAIN pdFREERTOS_ERRNO_EAGAIN
|
||||||
|
#endif
|
||||||
|
#ifndef EINTR
|
||||||
|
#define EINTR pdFREERTOS_ERRNO_EINTR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||||
@@ -5,17 +5,32 @@
|
|||||||
#define _DARWIN_UNLIMITED_SELECT 1
|
#define _DARWIN_UNLIMITED_SELECT 1
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define MG_DIRSEP '/'
|
#define MG_DIRSEP '/'
|
||||||
#define MG_ENABLE_POSIX 1
|
#define MG_ENABLE_POSIX 1
|
||||||
|
#define MG_INT64_FMT "%" PRId64
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+48
-1
@@ -2,6 +2,31 @@
|
|||||||
|
|
||||||
#if MG_ARCH == MG_ARCH_WIN32
|
#if MG_ARCH == MG_ARCH_WIN32
|
||||||
|
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||||
|
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1700
|
#if defined(_MSC_VER) && _MSC_VER < 1700
|
||||||
#define __func__ ""
|
#define __func__ ""
|
||||||
typedef __int64 int64_t;
|
typedef __int64 int64_t;
|
||||||
@@ -29,6 +54,7 @@ typedef enum { false = 0, true = 1 } bool;
|
|||||||
#define strdup(x) _strdup(x)
|
#define strdup(x) _strdup(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef unsigned suseconds_t;
|
||||||
typedef int socklen_t;
|
typedef int socklen_t;
|
||||||
#define MG_DIRSEP '\\'
|
#define MG_DIRSEP '\\'
|
||||||
#ifndef PATH_MAX
|
#ifndef PATH_MAX
|
||||||
@@ -40,7 +66,8 @@ typedef int socklen_t;
|
|||||||
#ifndef EWOULDBLOCK
|
#ifndef EWOULDBLOCK
|
||||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||||
#endif
|
#endif
|
||||||
#define realpath(a, b) _fullpath((b), (a), 512)
|
#define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
|
||||||
|
#define fopen(a, b) mg_fopen((a), (b))
|
||||||
#ifndef va_copy
|
#ifndef va_copy
|
||||||
#ifdef __va_copy
|
#ifdef __va_copy
|
||||||
#define va_copy __va_copy
|
#define va_copy __va_copy
|
||||||
@@ -52,4 +79,24 @@ typedef int socklen_t;
|
|||||||
#define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
|
#define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MG_INT64_FMT "%I64d"
|
||||||
|
|
||||||
|
static __inline FILE *mg_fopen(const char *path, const char *mode) {
|
||||||
|
wchar_t b1[PATH_MAX], b2[10];
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, path, -1, b1, sizeof(b1) / sizeof(b1[0]));
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, mode, -1, b2, sizeof(b2) / sizeof(b2[0]));
|
||||||
|
return _wfopen(b1, b2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://lgtm.com/rules/2154840805/ -gmtime, localtime, ctime and asctime
|
||||||
|
static __inline struct tm *gmtime_r(time_t *t, struct tm *tm) {
|
||||||
|
(void) tm;
|
||||||
|
return gmtime(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline struct tm *localtime_r(time_t *t, struct tm *tm) {
|
||||||
|
(void) tm;
|
||||||
|
return localtime(t);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+10
-10
@@ -31,16 +31,16 @@ static int mg_b64rev(int c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int mg_base64_update(unsigned char ch, char *to, int n) {
|
int mg_base64_update(unsigned char ch, char *to, int n) {
|
||||||
unsigned char rem = (n & 3) % 3;
|
int rem = (n & 3) % 3;
|
||||||
if (rem == 0) {
|
if (rem == 0) {
|
||||||
to[n] = mg_b64idx(ch >> 2);
|
to[n] = (char) mg_b64idx(ch >> 2);
|
||||||
to[++n] = (ch & 3) << 4;
|
to[++n] = (char) ((ch & 3) << 4);
|
||||||
} else if (rem == 1) {
|
} else if (rem == 1) {
|
||||||
to[n] = mg_b64idx(to[n] | (ch >> 4));
|
to[n] = (char) mg_b64idx(to[n] | (ch >> 4));
|
||||||
to[++n] = (ch & 15) << 2;
|
to[++n] = (char) ((ch & 15) << 2);
|
||||||
} else {
|
} else {
|
||||||
to[n] = mg_b64idx(to[n] | (ch >> 6));
|
to[n] = (char) mg_b64idx(to[n] | (ch >> 6));
|
||||||
to[++n] = mg_b64idx(ch & 63);
|
to[++n] = (char) mg_b64idx(ch & 63);
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
@@ -71,10 +71,10 @@ int mg_base64_decode(const char *src, int n, char *dst) {
|
|||||||
int a = mg_b64rev(src[0]), b = mg_b64rev(src[1]), c = mg_b64rev(src[2]),
|
int a = mg_b64rev(src[0]), b = mg_b64rev(src[1]), c = mg_b64rev(src[2]),
|
||||||
d = mg_b64rev(src[3]);
|
d = mg_b64rev(src[3]);
|
||||||
if (a == 64 || a < 0 || b == 64 || b < 0 || c < 0 || d < 0) return 0;
|
if (a == 64 || a < 0 || b == 64 || b < 0 || c < 0 || d < 0) return 0;
|
||||||
dst[len++] = (a << 2) | (b >> 4);
|
dst[len++] = (char) ((a << 2) | (b >> 4));
|
||||||
if (src[2] != '=') {
|
if (src[2] != '=') {
|
||||||
dst[len++] = (b << 4) | (c >> 2);
|
dst[len++] = (char) ((b << 4) | (c >> 2));
|
||||||
if (src[3] != '=') dst[len++] = (c << 6) | d;
|
if (src[3] != '=') dst[len++] = (char) ((c << 6) | d);
|
||||||
}
|
}
|
||||||
src += 4;
|
src += 4;
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-15
@@ -1,12 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef MG_ENABLE_LWIP
|
#ifndef MG_ENABLE_SOCKET
|
||||||
#define MG_ENABLE_LWIP 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MG_ENABLE_LWIP
|
|
||||||
#define MG_ENABLE_SOCKET 0
|
|
||||||
#elif !defined(MG_ENABLE_SOCKET)
|
|
||||||
#define MG_ENABLE_SOCKET 1
|
#define MG_ENABLE_SOCKET 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -34,20 +28,17 @@
|
|||||||
#define MG_ENABLE_LOG 1
|
#define MG_ENABLE_LOG 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MG_ENABLE_MGOS
|
|
||||||
#define MG_ENABLE_MGOS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MG_ENABLE_MD5
|
#ifndef MG_ENABLE_MD5
|
||||||
#define MG_ENABLE_MD5 0
|
#define MG_ENABLE_MD5 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MG_ENABLE_DIRECTORY_LISTING
|
// Set MG_ENABLE_WINSOCK=0 for Win32 builds with external IP stack (like LWIP)
|
||||||
#define MG_ENABLE_DIRECTORY_LISTING 0
|
#ifndef MG_ENABLE_WINSOCK
|
||||||
|
#define MG_ENABLE_WINSOCK 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MG_ENABLE_HTTP_DEBUG_ENDPOINT
|
#ifndef MG_ENABLE_DIRECTORY_LISTING
|
||||||
#define MG_ENABLE_HTTP_DEBUG_ENDPOINT 0
|
#define MG_ENABLE_DIRECTORY_LISTING 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MG_ENABLE_SOCKETPAIR
|
#ifndef MG_ENABLE_SOCKETPAIR
|
||||||
@@ -67,3 +58,7 @@
|
|||||||
#ifndef MG_MAX_HTTP_HEADERS
|
#ifndef MG_MAX_HTTP_HEADERS
|
||||||
#define MG_MAX_HTTP_HEADERS 40
|
#define MG_MAX_HTTP_HEADERS 40
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MG_PATH_MAX
|
||||||
|
#define MG_PATH_MAX PATH_MAX
|
||||||
|
#endif
|
||||||
@@ -70,11 +70,10 @@ size_t mg_dns_parse_name(const uint8_t *s, size_t n, size_t ofs, char *dst,
|
|||||||
|
|
||||||
size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
|
size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
|
||||||
bool is_question, struct mg_dns_rr *rr) {
|
bool is_question, struct mg_dns_rr *rr) {
|
||||||
const struct mg_dns_header *h = (struct mg_dns_header *) buf;
|
|
||||||
const uint8_t *s = buf + ofs, *e = &buf[len];
|
const uint8_t *s = buf + ofs, *e = &buf[len];
|
||||||
|
|
||||||
memset(rr, 0, sizeof(*rr));
|
memset(rr, 0, sizeof(*rr));
|
||||||
if (len < sizeof(*h)) return 0; // Too small, headers dont fit
|
if (len < sizeof(struct mg_dns_header)) return 0; // Too small
|
||||||
if (len > 512) return 0; // Too large, we don't expect that
|
if (len > 512) return 0; // Too large, we don't expect that
|
||||||
if (s >= e) return 0; // Overflow
|
if (s >= e) return 0; // Overflow
|
||||||
|
|
||||||
@@ -82,15 +81,15 @@ size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
|
|||||||
return 0;
|
return 0;
|
||||||
s += rr->nlen + 4;
|
s += rr->nlen + 4;
|
||||||
if (s > e) return 0;
|
if (s > e) return 0;
|
||||||
rr->atype = ((uint16_t) s[-4] << 8) | s[-3];
|
rr->atype = (uint16_t)(((uint16_t) s[-4] << 8) | s[-3]);
|
||||||
rr->aclass = ((uint16_t) s[-2] << 8) | s[-1];
|
rr->aclass = (uint16_t)(((uint16_t) s[-2] << 8) | s[-1]);
|
||||||
if (is_question) return rr->nlen + 4;
|
if (is_question) return (size_t)(rr->nlen + 4);
|
||||||
|
|
||||||
s += 6;
|
s += 6;
|
||||||
if (s > e) return 0;
|
if (s > e) return 0;
|
||||||
rr->alen = ((uint16_t) s[-2] << 8) | s[-1];
|
rr->alen = (uint16_t)(((uint16_t) s[-2] << 8) | s[-1]);
|
||||||
if (s + rr->alen > e) return 0;
|
if (s + rr->alen > e) return 0;
|
||||||
return rr->nlen + rr->alen + 10;
|
return (size_t)(rr->nlen + rr->alen + 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) {
|
bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) {
|
||||||
@@ -156,7 +155,9 @@ static void dns_cb(struct mg_connection *c, int ev, void *ev_data,
|
|||||||
if (d->c->is_resolving) {
|
if (d->c->is_resolving) {
|
||||||
d->c->is_resolving = 0;
|
d->c->is_resolving = 0;
|
||||||
if (dm.resolved) {
|
if (dm.resolved) {
|
||||||
|
#if MG_ENABLE_LOG
|
||||||
char buf[100];
|
char buf[100];
|
||||||
|
#endif
|
||||||
dm.addr.port = d->c->peer.port; // Save port
|
dm.addr.port = d->c->peer.port; // Save port
|
||||||
d->c->peer = dm.addr; // Copy resolved address
|
d->c->peer = dm.addr; // Copy resolved address
|
||||||
LOG(LL_DEBUG, ("%lu %s resolved to %s", d->c->id, dm.name,
|
LOG(LL_DEBUG, ("%lu %s resolved to %s", d->c->id, dm.name,
|
||||||
@@ -240,14 +241,18 @@ static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms,
|
|||||||
} else if ((d = (struct dns_data *) calloc(1, sizeof(*d))) == NULL) {
|
} else if ((d = (struct dns_data *) calloc(1, sizeof(*d))) == NULL) {
|
||||||
mg_error(c, "resolve OOM");
|
mg_error(c, "resolve OOM");
|
||||||
} else {
|
} else {
|
||||||
d->txnid = s_reqs ? s_reqs->txnid + 1 : 1;
|
#if MG_ENABLE_LOG
|
||||||
|
char buf[100];
|
||||||
|
#endif
|
||||||
|
d->txnid = s_reqs ? (uint16_t)(s_reqs->txnid + 1) : 1;
|
||||||
d->next = s_reqs;
|
d->next = s_reqs;
|
||||||
s_reqs = d;
|
s_reqs = d;
|
||||||
d->expire = mg_millis() + ms;
|
d->expire = mg_millis() + (unsigned long) ms;
|
||||||
d->c = c;
|
d->c = c;
|
||||||
c->is_resolving = 1;
|
c->is_resolving = 1;
|
||||||
LOG(LL_VERBOSE_DEBUG, ("%lu resolving %.*s, txnid %hu", c->id,
|
LOG(LL_VERBOSE_DEBUG,
|
||||||
(int) name->len, name->ptr, d->txnid));
|
("%lu resolving %.*s @ %s, txnid %hu", c->id, (int) name->len,
|
||||||
|
name->ptr, mg_ntoa(&dnsc->c->peer, buf, sizeof(buf)), d->txnid));
|
||||||
mg_dns_send(dnsc->c, name, d->txnid, ipv6);
|
mg_dns_send(dnsc->c, name, d->txnid, ipv6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-28
@@ -3,36 +3,26 @@
|
|||||||
struct mg_connection;
|
struct mg_connection;
|
||||||
typedef void (*mg_event_handler_t)(struct mg_connection *, int ev,
|
typedef void (*mg_event_handler_t)(struct mg_connection *, int ev,
|
||||||
void *ev_data, void *fn_data);
|
void *ev_data, void *fn_data);
|
||||||
#if 0
|
|
||||||
struct mg_fn {
|
|
||||||
struct mg_fn *next;
|
|
||||||
mg_event_handler_t fn;
|
|
||||||
void *fn_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
void mg_fn_add(struct mg_connection *c, mg_event_handler_t fn, void *fn_data);
|
|
||||||
void mg_fn_del(struct mg_connection *c, mg_event_handler_t fn);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void mg_call(struct mg_connection *c, int ev, void *ev_data);
|
void mg_call(struct mg_connection *c, int ev, void *ev_data);
|
||||||
void mg_error(struct mg_connection *c, const char *fmt, ...);
|
void mg_error(struct mg_connection *c, const char *fmt, ...);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MG_EV_ERROR, // Error char *error_message
|
MG_EV_ERROR, // Error char *error_message
|
||||||
MG_EV_POLL, // mg_mgr_poll iteration unsigned long *millis
|
MG_EV_POLL, // mg_mgr_poll iteration unsigned long *millis
|
||||||
MG_EV_RESOLVE, // Host name is resolved NULL
|
MG_EV_RESOLVE, // Host name is resolved NULL
|
||||||
MG_EV_CONNECT, // Connection established NULL
|
MG_EV_CONNECT, // Connection established NULL
|
||||||
MG_EV_ACCEPT, // Connection accepted NULL
|
MG_EV_ACCEPT, // Connection accepted NULL
|
||||||
MG_EV_READ, // Data received from socket struct mg_str *
|
MG_EV_READ, // Data received from socket struct mg_str *
|
||||||
MG_EV_WRITE, // Data written to socket int *num_bytes_written
|
MG_EV_WRITE, // Data written to socket long *bytes_written
|
||||||
MG_EV_CLOSE, // Connection closed NULL
|
MG_EV_CLOSE, // Connection closed NULL
|
||||||
MG_EV_HTTP_MSG, // HTTP request/response struct mg_http_message *
|
MG_EV_HTTP_MSG, // HTTP request/response struct mg_http_message *
|
||||||
MG_EV_WS_OPEN, // Websocket handshake done struct mg_http_message *
|
MG_EV_HTTP_CHUNK, // HTTP chunk (partial msg) struct mg_http_message *
|
||||||
MG_EV_WS_MSG, // Websocket msg, text or bin struct mg_ws_message *
|
MG_EV_WS_OPEN, // Websocket handshake done struct mg_http_message *
|
||||||
MG_EV_WS_CTL, // Websocket control msg struct mg_ws_message *
|
MG_EV_WS_MSG, // Websocket msg, text or bin struct mg_ws_message *
|
||||||
MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message *
|
MG_EV_WS_CTL, // Websocket control msg struct mg_ws_message *
|
||||||
MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message *
|
MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message *
|
||||||
MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code
|
MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message *
|
||||||
MG_EV_SNTP_TIME, // SNTP time received struct timeval *
|
MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code
|
||||||
MG_EV_USER, // Starting ID for user events
|
MG_EV_SNTP_TIME, // SNTP time received struct timeval *
|
||||||
|
MG_EV_USER, // Starting ID for user events
|
||||||
};
|
};
|
||||||
+534
-221
File diff suppressed because it is too large.
Load diff
+19
-5
@@ -16,19 +16,30 @@ struct mg_http_message {
|
|||||||
struct mg_str method, uri, query, proto; // Request/response line
|
struct mg_str method, uri, query, proto; // Request/response line
|
||||||
struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers
|
struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers
|
||||||
struct mg_str body; // Body
|
struct mg_str body; // Body
|
||||||
struct mg_str message; // Request line + headers + body
|
struct mg_str head; // Request + headers
|
||||||
|
struct mg_str chunk; // Chunk for chunked encoding, or partial body
|
||||||
|
struct mg_str message; // Request + headers + body
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parameter for mg_http_serve_dir()
|
// Parameter for mg_http_serve_dir()
|
||||||
struct mg_http_serve_opts {
|
struct mg_http_serve_opts {
|
||||||
const char *root_dir; // Web root directory, must be non-NULL
|
const char *root_dir; // Web root directory, must be non-NULL
|
||||||
const char *ssi_pattern; // SSI filename pattern, e.g. #.shtml
|
const char *ssi_pattern; // SSI file name pattern, e.g. #.shtml
|
||||||
|
const char *extra_headers; // Extra HTTP headers to add in responses
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parameter for mg_http_next_multipart
|
||||||
|
struct mg_http_part {
|
||||||
|
struct mg_str name; // Form field name
|
||||||
|
struct mg_str filename; // Filename for file uploads
|
||||||
|
struct mg_str body; // Part contents
|
||||||
};
|
};
|
||||||
|
|
||||||
int mg_http_parse(const char *s, size_t len, struct mg_http_message *);
|
int mg_http_parse(const char *s, size_t len, struct mg_http_message *);
|
||||||
int mg_http_get_request_len(const unsigned char *buf, size_t buf_len);
|
int mg_http_get_request_len(const unsigned char *buf, size_t buf_len);
|
||||||
void mg_http_printf_chunk(struct mg_connection *cnn, const char *fmt, ...);
|
void mg_http_printf_chunk(struct mg_connection *cnn, const char *fmt, ...);
|
||||||
void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len);
|
void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len);
|
||||||
|
void mg_http_delete_chunk(struct mg_connection *c, struct mg_http_message *hm);
|
||||||
struct mg_connection *mg_http_listen(struct mg_mgr *, const char *url,
|
struct mg_connection *mg_http_listen(struct mg_mgr *, const char *url,
|
||||||
mg_event_handler_t fn, void *fn_data);
|
mg_event_handler_t fn, void *fn_data);
|
||||||
struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url,
|
struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url,
|
||||||
@@ -41,10 +52,13 @@ void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
|
|||||||
const char *body_fmt, ...);
|
const char *body_fmt, ...);
|
||||||
struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
|
struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
|
||||||
void mg_http_event_handler(struct mg_connection *c, int ev);
|
void mg_http_event_handler(struct mg_connection *c, int ev);
|
||||||
int mg_http_get_var(const struct mg_str *, const char *name, char *, int);
|
int mg_http_get_var(const struct mg_str *, const char *name, char *, size_t);
|
||||||
int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
|
int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
|
||||||
void mg_http_creds(struct mg_http_message *, char *user, int, char *pass, int);
|
size_t mg_url_encode(const char *s, size_t n, char *buf, size_t len);
|
||||||
|
void mg_http_creds(struct mg_http_message *, char *, size_t, char *, size_t);
|
||||||
bool mg_http_match_uri(const struct mg_http_message *, const char *glob);
|
bool mg_http_match_uri(const struct mg_http_message *, const char *glob);
|
||||||
int mg_http_upload(struct mg_connection *, struct mg_http_message *hm,
|
int mg_http_upload(struct mg_connection *, struct mg_http_message *hm,
|
||||||
const char *dir);
|
const char *dir);
|
||||||
void mg_http_bauth(struct mg_connection *, const char *user, const char *pass);
|
void mg_http_bauth(struct mg_connection *, const char *user, const char *pass);
|
||||||
|
struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v);
|
||||||
|
size_t mg_http_next_multipart(struct mg_str, size_t, struct mg_http_part *);
|
||||||
+29
-14
@@ -3,39 +3,54 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) {
|
// Not using memset for zeroing memory, cause it can be dropped by compiler
|
||||||
|
// See https://github.com/cesanta/mongoose/pull/1265
|
||||||
|
static void zeromem(volatile unsigned char *buf, size_t len) {
|
||||||
|
if (buf != NULL) {
|
||||||
|
while (len--) *buf++ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) {
|
||||||
|
int ok = 1;
|
||||||
if (new_size == 0) {
|
if (new_size == 0) {
|
||||||
|
zeromem(io->buf, io->size);
|
||||||
free(io->buf);
|
free(io->buf);
|
||||||
io->buf = NULL;
|
io->buf = NULL;
|
||||||
io->len = io->size = 0;
|
io->len = io->size = 0;
|
||||||
} else if (new_size != io->size) {
|
} else if (new_size != io->size) {
|
||||||
// NOTE(lsm): do not use realloc here. Use malloc/free only, to ease the
|
// NOTE(lsm): do not use realloc here. Use calloc/free only, to ease the
|
||||||
// porting to some obscure platforms like FreeRTOS
|
// porting to some obscure platforms like FreeRTOS
|
||||||
void *p = malloc(new_size);
|
void *p = calloc(1, new_size);
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
memcpy(p, io->buf, io->size < new_size ? io->size : new_size);
|
size_t len = new_size < io->len ? new_size : io->len;
|
||||||
|
if (len > 0) memcpy(p, io->buf, len);
|
||||||
|
zeromem(io->buf, io->size);
|
||||||
free(io->buf);
|
free(io->buf);
|
||||||
io->buf = (unsigned char *) p;
|
io->buf = (unsigned char *) p;
|
||||||
io->size = new_size;
|
io->size = new_size;
|
||||||
} else {
|
} else {
|
||||||
|
ok = 0;
|
||||||
LOG(LL_ERROR,
|
LOG(LL_ERROR,
|
||||||
("%lu->%lu", (unsigned long) io->size, (unsigned long) new_size));
|
("%lu->%lu", (unsigned long) io->size, (unsigned long) new_size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_iobuf_init(struct mg_iobuf *io, size_t size) {
|
int mg_iobuf_init(struct mg_iobuf *io, size_t size) {
|
||||||
io->buf = NULL;
|
return mg_iobuf_resize(io, size);
|
||||||
io->len = io->size = 0;
|
|
||||||
if (size > 0) mg_iobuf_resize(io, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t mg_iobuf_append(struct mg_iobuf *io, const void *buf, size_t len,
|
size_t mg_iobuf_append(struct mg_iobuf *io, const void *buf, size_t len,
|
||||||
size_t chunk_size) {
|
size_t chunk_size) {
|
||||||
size_t new_size = io->len + len + chunk_size;
|
size_t new_size = io->len + len;
|
||||||
new_size -= new_size % chunk_size;
|
if (new_size > io->size) {
|
||||||
if (new_size != io->size) mg_iobuf_resize(io, new_size);
|
new_size += chunk_size; // Make sure that io->size
|
||||||
if (new_size != io->size) len = 0; // Realloc failure, append nothing
|
new_size -= new_size % chunk_size; // is aligned by chunk_size boundary
|
||||||
|
mg_iobuf_resize(io, new_size); // Attempt to realloc
|
||||||
|
if (new_size != io->size) len = 0; // Realloc failure, append nothing
|
||||||
|
}
|
||||||
if (buf != NULL) memmove(io->buf + io->len, buf, len);
|
if (buf != NULL) memmove(io->buf + io->len, buf, len);
|
||||||
io->len += len;
|
io->len += len;
|
||||||
return len;
|
return len;
|
||||||
@@ -44,11 +59,11 @@ size_t mg_iobuf_append(struct mg_iobuf *io, const void *buf, size_t len,
|
|||||||
size_t mg_iobuf_delete(struct mg_iobuf *io, size_t len) {
|
size_t mg_iobuf_delete(struct mg_iobuf *io, size_t len) {
|
||||||
if (len > io->len) len = 0;
|
if (len > io->len) len = 0;
|
||||||
memmove(io->buf, io->buf + len, io->len - len);
|
memmove(io->buf, io->buf + len, io->len - len);
|
||||||
|
zeromem(io->buf + io->len - len, len);
|
||||||
io->len -= len;
|
io->len -= len;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_iobuf_free(struct mg_iobuf *io) {
|
void mg_iobuf_free(struct mg_iobuf *io) {
|
||||||
free(io->buf);
|
mg_iobuf_resize(io, 0);
|
||||||
mg_iobuf_init(io, 0);
|
|
||||||
}
|
}
|
||||||
+2
-2
@@ -7,8 +7,8 @@ struct mg_iobuf {
|
|||||||
size_t size, len;
|
size_t size, len;
|
||||||
};
|
};
|
||||||
|
|
||||||
void mg_iobuf_init(struct mg_iobuf *, size_t);
|
int mg_iobuf_init(struct mg_iobuf *, size_t);
|
||||||
void mg_iobuf_resize(struct mg_iobuf *, size_t);
|
int mg_iobuf_resize(struct mg_iobuf *, size_t);
|
||||||
void mg_iobuf_free(struct mg_iobuf *);
|
void mg_iobuf_free(struct mg_iobuf *);
|
||||||
size_t mg_iobuf_append(struct mg_iobuf *, const void *, size_t, size_t);
|
size_t mg_iobuf_append(struct mg_iobuf *, const void *, size_t, size_t);
|
||||||
size_t mg_iobuf_delete(struct mg_iobuf *, size_t);
|
size_t mg_iobuf_delete(struct mg_iobuf *, size_t);
|
||||||
+1
-2
@@ -1,5 +1,5 @@
|
|||||||
// Copyright (c) 2004-2013 Sergey Lyubka
|
// Copyright (c) 2004-2013 Sergey Lyubka
|
||||||
// Copyright (c) 2013-2020 Cesanta Software Limited
|
// Copyright (c) 2013-2021 Cesanta Software Limited
|
||||||
// All rights reserved
|
// All rights reserved
|
||||||
//
|
//
|
||||||
// This software is dual-licensed: you can redistribute it and/or modify
|
// This software is dual-licensed: you can redistribute it and/or modify
|
||||||
@@ -14,4 +14,3 @@
|
|||||||
//
|
//
|
||||||
// Alternatively, you can license this software under a commercial
|
// Alternatively, you can license this software under a commercial
|
||||||
// license, as set out in <https://www.cesanta.com/license>.
|
// license, as set out in <https://www.cesanta.com/license>.
|
||||||
|
|
||||||
@@ -4,14 +4,13 @@
|
|||||||
#if MG_ENABLE_MGOS
|
#if MG_ENABLE_MGOS
|
||||||
#else
|
#else
|
||||||
#if MG_ENABLE_LOG
|
#if MG_ENABLE_LOG
|
||||||
static void mg_log_stdout(const void *buf, int len, void *userdata) {
|
static void mg_log_stdout(const void *buf, size_t len, void *userdata) {
|
||||||
(void) userdata;
|
(void) userdata;
|
||||||
fwrite(buf, 1, len, stdout);
|
fwrite(buf, 1, len, stdout);
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *s_spec = "2";
|
static const char *s_spec = "2";
|
||||||
static void (*s_fn)(const void *, int, void *) = mg_log_stdout;
|
static void (*s_fn)(const void *, size_t, void *) = mg_log_stdout;
|
||||||
static void *s_fn_param = NULL;
|
static void *s_fn_param = NULL;
|
||||||
|
|
||||||
void mg_log_set(const char *spec) {
|
void mg_log_set(const char *spec) {
|
||||||
@@ -24,9 +23,12 @@ bool mg_log_prefix(int level, const char *file, int line, const char *fname) {
|
|||||||
int max = LL_INFO;
|
int max = LL_INFO;
|
||||||
struct mg_str k, v, s = mg_str(s_spec);
|
struct mg_str k, v, s = mg_str(s_spec);
|
||||||
const char *p = strrchr(file, '/');
|
const char *p = strrchr(file, '/');
|
||||||
p = p == NULL ? file : p + 1;
|
|
||||||
|
|
||||||
if (s_fn == NULL) return false;
|
if (s_fn == NULL) return false;
|
||||||
|
|
||||||
|
if (p == NULL) p = strrchr(file, '\\');
|
||||||
|
p = p == NULL ? file : p + 1;
|
||||||
|
|
||||||
while (mg_next_comma_entry(&s, &k, &v)) {
|
while (mg_next_comma_entry(&s, &k, &v)) {
|
||||||
if (v.len == 0) max = atoi(k.ptr);
|
if (v.len == 0) max = atoi(k.ptr);
|
||||||
if (v.len > 0 && strncmp(p, k.ptr, k.len) == 0) max = atoi(v.ptr);
|
if (v.len > 0 && strncmp(p, k.ptr, k.len) == 0) max = atoi(v.ptr);
|
||||||
@@ -35,7 +37,7 @@ bool mg_log_prefix(int level, const char *file, int line, const char *fname) {
|
|||||||
if (level <= max) {
|
if (level <= max) {
|
||||||
char timebuf[21], buf[50] = "";
|
char timebuf[21], buf[50] = "";
|
||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
struct tm *tm = gmtime(&t);
|
struct tm tmp, *tm = gmtime_r(&t, &tmp);
|
||||||
int n, tag;
|
int n, tag;
|
||||||
strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm);
|
strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm);
|
||||||
tag = level == LL_ERROR ? 'E' : level == LL_INFO ? 'I' : ' ';
|
tag = level == LL_ERROR ? 'E' : level == LL_INFO ? 'I' : ' ';
|
||||||
@@ -57,14 +59,14 @@ void mg_log(const char *fmt, ...) {
|
|||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
len = mg_vasprintf(&buf, sizeof(mem), fmt, ap);
|
len = mg_vasprintf(&buf, sizeof(mem), fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
s_fn(buf, len, s_fn_param);
|
s_fn(buf, len > 0 ? (size_t) len : 0, s_fn_param);
|
||||||
s_fn("\n", 1, s_fn_param);
|
s_fn("\n", 1, s_fn_param);
|
||||||
if (buf != mem) free(buf);
|
if (buf != mem) free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_log_set_callback(void (*fn)(const void *, int, void *), void *param) {
|
void mg_log_set_callback(void (*fn)(const void *, size_t, void *), void *fnd) {
|
||||||
s_fn = fn;
|
s_fn = fn;
|
||||||
s_fn_param = param;
|
s_fn_param = fnd;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -3,9 +3,6 @@
|
|||||||
#include "arch.h"
|
#include "arch.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#if MG_ENABLE_MGOS
|
|
||||||
#include <common/cs_dbg.h>
|
|
||||||
#else
|
|
||||||
#if MG_ENABLE_LOG
|
#if MG_ENABLE_LOG
|
||||||
#define LOG(level, args) \
|
#define LOG(level, args) \
|
||||||
do { \
|
do { \
|
||||||
@@ -15,8 +12,8 @@ enum { LL_NONE, LL_ERROR, LL_INFO, LL_DEBUG, LL_VERBOSE_DEBUG };
|
|||||||
bool mg_log_prefix(int ll, const char *file, int line, const char *fname);
|
bool mg_log_prefix(int ll, const char *file, int line, const char *fname);
|
||||||
void mg_log(const char *fmt, ...) PRINTF_LIKE(1, 2);
|
void mg_log(const char *fmt, ...) PRINTF_LIKE(1, 2);
|
||||||
void mg_log_set(const char *spec);
|
void mg_log_set(const char *spec);
|
||||||
void mg_log_set_callback(void (*fn)(const void *, int, void *), void *param);
|
void mg_log_set_callback(void (*fn)(const void *, size_t, void *), void *param);
|
||||||
#else
|
#else
|
||||||
#define LOG(level, args)
|
#define LOG(level, args) (void) 0
|
||||||
#endif
|
#define mg_log_set(x) (void) (x)
|
||||||
#endif
|
#endif
|
||||||
-197
@@ -1,197 +0,0 @@
|
|||||||
#include "dns.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "net.h"
|
|
||||||
#include "private.h"
|
|
||||||
#include "tls.h"
|
|
||||||
#include "url.h"
|
|
||||||
|
|
||||||
#if MG_ENABLE_LWIP
|
|
||||||
#include <lwip/tcp.h>
|
|
||||||
#include <lwip/udp.h>
|
|
||||||
|
|
||||||
static void tcp_error_cb(void *arg, err_t err) {
|
|
||||||
struct mg_connection *c = (struct mg_connection *) arg;
|
|
||||||
mg_error(c, "%p err %ld", c->fd, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
static err_t connect_cb(void *arg, struct tcp_pcb *pcb, err_t err) {
|
|
||||||
struct mg_connection *c = (struct mg_connection *) arg;
|
|
||||||
LOG(LL_DEBUG, ("err %ld, arg %p, pcb %p", err, arg, pcb));
|
|
||||||
c->is_connecting = 0;
|
|
||||||
if (err != ERR_OK) mg_error(c, "%p err %d", c->fd, err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static err_t tcp_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p,
|
|
||||||
err_t err) {
|
|
||||||
struct mg_connection *c = (struct mg_connection *) arg;
|
|
||||||
LOG(LL_DEBUG,
|
|
||||||
("err %ld, pbuf %p/%d, io.len %d, io.size %d", err, p,
|
|
||||||
p == NULL ? 0 : (int) p->len, (int) c->recv.len, (int) c->recv.size));
|
|
||||||
if (err == ERR_OK && p != NULL) {
|
|
||||||
#if 0
|
|
||||||
if (s->io.size < s->io.len + p->len) {
|
|
||||||
char *buf = realloc(s->io.buf, s->io.len + p->len);
|
|
||||||
if (buf != NULL) {
|
|
||||||
s->io.buf = buf;
|
|
||||||
s->io.size = s->io.len + p->len;
|
|
||||||
} else {
|
|
||||||
return ERR_MEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// MLOG(LL_DEBUG, " --> cpy, %p %p", s->io.buf, p->payload);
|
|
||||||
memcpy(s->io.buf + s->io.len, p->payload, p->len);
|
|
||||||
s->io.len += p->len;
|
|
||||||
#endif
|
|
||||||
tcp_recved(pcb, p->len);
|
|
||||||
pbuf_free(p);
|
|
||||||
return err;
|
|
||||||
} else {
|
|
||||||
// rmsock(s);
|
|
||||||
return ERR_ABRT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void udp_recv_cb(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
|
||||||
const ip_addr_t *addr, uint16_t port) {
|
|
||||||
LOG(LL_DEBUG,
|
|
||||||
("%p %p pbuf %p/%d port %hu", arg, pcb, p, p == NULL ? 0 : p->len, port));
|
|
||||||
}
|
|
||||||
|
|
||||||
static err_t tcp_sent_cb(void *arg, struct tcp_pcb *pcb, uint16_t len) {
|
|
||||||
LOG(LL_DEBUG, ("%p %d", pcb, (int) len));
|
|
||||||
return ERR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int ll_write(struct mg_connection *c, const void *buf, int len,
|
|
||||||
int *fail) {
|
|
||||||
int n = c->is_tls ? mg_tls_send(c, buf, len, fail)
|
|
||||||
: mg_sock_send(c, buf, len, fail);
|
|
||||||
LOG(*fail ? LL_ERROR : LL_VERBOSE_DEBUG,
|
|
||||||
("%p %c%c%c %d/%d %d", c->fd, c->is_tls ? 'T' : 't',
|
|
||||||
c->is_udp ? 'U' : 'u', c->is_connecting ? 'C' : 'c', n, len,
|
|
||||||
MG_SOCK_ERRNO));
|
|
||||||
if (n > 0 && c->is_hexdumping) mg_hexdump(c, "->", buf, n);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int mg_send(struct mg_connection *c, const void *buf, size_t len) {
|
|
||||||
if (c->is_udp) {
|
|
||||||
struct udp_pcb *pcb = (struct udp_pcb *) c->fd;
|
|
||||||
struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
|
|
||||||
if (p != NULL) {
|
|
||||||
// p->payload = (void *) buf;
|
|
||||||
memcpy(p->payload, buf, len);
|
|
||||||
err_t err = udp_send(pcb, p);
|
|
||||||
pbuf_free(p);
|
|
||||||
LOG(LL_DEBUG,
|
|
||||||
("%lu UDP %d bytes -> %x:%hu, err %ld", c->id, (int) len,
|
|
||||||
(unsigned) *(uint32_t *) &pcb->remote_ip, pcb->remote_port, err));
|
|
||||||
if (err != ERR_OK) mg_error(c, "%p err %d", c->fd, err);
|
|
||||||
} else {
|
|
||||||
mg_error(c, "%p pbuf OOM", c->fd);
|
|
||||||
}
|
|
||||||
} else if (c->is_connecting) {
|
|
||||||
mg_iobuf_append(&c->send, buf, len, MG_IO_SIZE);
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
int fail, n = c->is_udp
|
|
||||||
? ll_write(c, buf, (SOCKET) len, &fail)
|
|
||||||
: mg_iobuf_append(&c->send, buf, len, MG_IO_SIZE);
|
|
||||||
return n;
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mg_connection *mg_mkconn(const char *url) {
|
|
||||||
struct mg_connection *c = (struct mg_connection *) calloc(1, sizeof(*c));
|
|
||||||
typedef void *(*new_t)(void);
|
|
||||||
int is_udp = strncmp(url, "udp:", 4) == 0;
|
|
||||||
if (c == NULL) {
|
|
||||||
LOG(LL_ERROR, ("%s %s", url, "OOM"));
|
|
||||||
} else if ((c->fd = (is_udp ? (new_t) udp_new : (new_t) tcp_new)()) == NULL) {
|
|
||||||
LOG(LL_ERROR, ("%s new", url));
|
|
||||||
free(c);
|
|
||||||
c = NULL;
|
|
||||||
} else {
|
|
||||||
c->is_udp = is_udp;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url,
|
|
||||||
mg_event_handler_t fn, void *fn_data) {
|
|
||||||
struct mg_connection *c = mg_mkconn(url);
|
|
||||||
struct mg_str host = mg_url_host(url);
|
|
||||||
if (c == NULL) return c;
|
|
||||||
c->next = mgr->conns;
|
|
||||||
mgr->conns = c;
|
|
||||||
// mg_set_non_blocking_mode((SOCKET) c->fd);
|
|
||||||
c->is_client = 1;
|
|
||||||
c->peer.port = mg_htons(mg_url_port(url));
|
|
||||||
c->fn = fn;
|
|
||||||
c->fn_data = fn_data;
|
|
||||||
c->is_hexdumping = 1;
|
|
||||||
if (c->is_udp) {
|
|
||||||
udp_bind(c->fd, IP_ADDR_ANY, 0);
|
|
||||||
udp_recv(c->fd, udp_recv_cb, c);
|
|
||||||
} else {
|
|
||||||
tcp_arg(c->fd, c);
|
|
||||||
tcp_err(c->fd, tcp_error_cb);
|
|
||||||
tcp_sent(c->fd, tcp_sent_cb);
|
|
||||||
tcp_recv(c->fd, tcp_recv_cb);
|
|
||||||
tcp_bind(c->fd, IP_ADDR_ANY, 0);
|
|
||||||
tcp_nagle_disable((struct tcp_pcb *) c->fd);
|
|
||||||
}
|
|
||||||
LOG(LL_DEBUG, ("%lu -> %s %s", c->id, url, c->is_udp ? "UDP" : "TCP"));
|
|
||||||
mg_resolve(mgr, c, &host, mgr->dnstimeout);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mg_connect_resolved(struct mg_connection *c) {
|
|
||||||
char buf[40];
|
|
||||||
ip_addr_t ipaddr;
|
|
||||||
memcpy(&ipaddr, &c->peer.ip, sizeof(ipaddr));
|
|
||||||
mg_call(c, MG_EV_RESOLVE, NULL);
|
|
||||||
LOG(LL_DEBUG, ("%lu resolved to %s", c->id, mg_straddr(c, buf, sizeof(buf))));
|
|
||||||
err_t err = c->is_udp ? udp_connect((struct udp_pcb *) c->fd, &ipaddr,
|
|
||||||
mg_ntohs(c->peer.port))
|
|
||||||
: tcp_connect((struct tcp_pcb *) c->fd, &ipaddr,
|
|
||||||
mg_ntohs(c->peer.port), connect_cb);
|
|
||||||
if (c->is_udp) c->is_connecting = 0;
|
|
||||||
if (err != ERR_OK) mg_error(c, "%p failed, err %d", c->fd, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
static err_t accept_cb(void *arg, struct tcp_pcb *pcb, err_t e) {
|
|
||||||
LOG(LL_DEBUG, ("%p err %ld, pcb %p", arg, e, pcb));
|
|
||||||
return ERR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
|
|
||||||
mg_event_handler_t fn, void *fn_data) {
|
|
||||||
struct mg_connection *c = mg_mkconn(url);
|
|
||||||
struct mg_str host = mg_url_host(url);
|
|
||||||
uint16_t port = mg_url_port(url);
|
|
||||||
uint32_t ipaddr;
|
|
||||||
err_t err;
|
|
||||||
if (c == NULL) return c;
|
|
||||||
mg_aton(host.ptr, &ipaddr);
|
|
||||||
if (!mg_vcasecmp(&host, "localhost")) ipaddr = mg_htonl(0x7f000001);
|
|
||||||
if ((err = tcp_bind(c->fd, (ip_addr_t *) &ipaddr, port)) != ERR_OK) {
|
|
||||||
mg_error(c, "%p tcp_bind(%x:%hu) -> %ld", c->fd, ipaddr, port, err);
|
|
||||||
} else {
|
|
||||||
tcp_listen(c->fd);
|
|
||||||
tcp_accept(c->fd, accept_cb);
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
|
|
||||||
LOG(LL_DEBUG, ("%p %d", mgr, ms));
|
|
||||||
mg_usleep(200 * 1000);
|
|
||||||
mg_timer_poll(mg_millis());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
+50
-26
@@ -1,8 +1,8 @@
|
|||||||
|
#include "mqtt.h"
|
||||||
#include "arch.h"
|
#include "arch.h"
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "mqtt.h"
|
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@@ -20,14 +20,14 @@ enum { MQTT_OK, MQTT_INCOMPLETE, MQTT_MALFORMED };
|
|||||||
void mg_mqtt_send_header(struct mg_connection *c, uint8_t cmd, uint8_t flags,
|
void mg_mqtt_send_header(struct mg_connection *c, uint8_t cmd, uint8_t flags,
|
||||||
uint32_t len) {
|
uint32_t len) {
|
||||||
uint8_t buf[1 + sizeof(len)], *vlen = &buf[1];
|
uint8_t buf[1 + sizeof(len)], *vlen = &buf[1];
|
||||||
buf[0] = (cmd << 4) | flags;
|
buf[0] = (uint8_t)((cmd << 4) | flags);
|
||||||
do {
|
do {
|
||||||
*vlen = len % 0x80;
|
*vlen = len % 0x80;
|
||||||
len /= 0x80;
|
len /= 0x80;
|
||||||
if (len > 0) *vlen |= 0x80;
|
if (len > 0) *vlen |= 0x80;
|
||||||
vlen++;
|
vlen++;
|
||||||
} while (len > 0 && vlen < &buf[sizeof(buf)]);
|
} while (len > 0 && vlen < &buf[sizeof(buf)]);
|
||||||
mg_send(c, buf, vlen - buf);
|
mg_send(c, buf, (size_t)(vlen - buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mg_send_u16(struct mg_connection *c, uint16_t value) {
|
static void mg_send_u16(struct mg_connection *c, uint16_t value) {
|
||||||
@@ -37,7 +37,7 @@ static void mg_send_u16(struct mg_connection *c, uint16_t value) {
|
|||||||
static void mqtt_login(struct mg_connection *c, const char *url,
|
static void mqtt_login(struct mg_connection *c, const char *url,
|
||||||
struct mg_mqtt_opts *opts) {
|
struct mg_mqtt_opts *opts) {
|
||||||
uint32_t total_len = 7 + 1 + 2 + 2;
|
uint32_t total_len = 7 + 1 + 2 + 2;
|
||||||
uint16_t flags = (opts->qos & 3) << 3;
|
uint16_t flags = (uint16_t)(((uint16_t) opts->qos & 3) << 3);
|
||||||
struct mg_str user = mg_url_user(url);
|
struct mg_str user = mg_url_user(url);
|
||||||
struct mg_str pass = mg_url_pass(url);
|
struct mg_str pass = mg_url_pass(url);
|
||||||
|
|
||||||
@@ -82,8 +82,8 @@ static void mqtt_login(struct mg_connection *c, const char *url,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void mg_mqtt_pub(struct mg_connection *c, struct mg_str *topic,
|
void mg_mqtt_pub(struct mg_connection *c, struct mg_str *topic,
|
||||||
struct mg_str *data) {
|
struct mg_str *data, int qos, bool retain) {
|
||||||
uint8_t flags = MQTT_QOS(1);
|
uint8_t flags = (uint8_t)(((qos & 3) << 1) | (retain ? 1 : 0));
|
||||||
uint32_t total_len = 2 + (uint32_t) topic->len + (uint32_t) data->len;
|
uint32_t total_len = 2 + (uint32_t) topic->len + (uint32_t) data->len;
|
||||||
LOG(LL_DEBUG, ("%lu [%.*s] -> [%.*s]", c->id, (int) topic->len,
|
LOG(LL_DEBUG, ("%lu [%.*s] -> [%.*s]", c->id, (int) topic->len,
|
||||||
(char *) topic->ptr, (int) data->len, (char *) data->ptr));
|
(char *) topic->ptr, (int) data->len, (char *) data->ptr));
|
||||||
@@ -99,17 +99,17 @@ void mg_mqtt_pub(struct mg_connection *c, struct mg_str *topic,
|
|||||||
mg_send(c, data->ptr, data->len);
|
mg_send(c, data->ptr, data->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_mqtt_sub(struct mg_connection *c, struct mg_str *topic) {
|
void mg_mqtt_sub(struct mg_connection *c, struct mg_str *topic, int qos) {
|
||||||
static uint16_t s_id;
|
static uint16_t s_id;
|
||||||
uint8_t qos = 1;
|
uint8_t qos_ = qos & 3;
|
||||||
uint32_t total_len = 2 + (uint32_t) topic->len + 2 + 1;
|
uint32_t total_len = 2 + (uint32_t) topic->len + 2 + 1;
|
||||||
mg_mqtt_send_header(c, MQTT_CMD_SUBSCRIBE, (uint8_t) MQTT_QOS(qos),
|
mg_mqtt_send_header(c, MQTT_CMD_SUBSCRIBE, (uint8_t) MQTT_QOS(qos_),
|
||||||
total_len);
|
total_len);
|
||||||
if (++s_id == 0) ++s_id;
|
if (++s_id == 0) ++s_id;
|
||||||
mg_send_u16(c, mg_htons(s_id));
|
mg_send_u16(c, mg_htons(s_id));
|
||||||
mg_send_u16(c, mg_htons((uint16_t) topic->len));
|
mg_send_u16(c, mg_htons((uint16_t) topic->len));
|
||||||
mg_send(c, topic->ptr, topic->len);
|
mg_send(c, topic->ptr, topic->len);
|
||||||
mg_send(c, &qos, sizeof(qos));
|
mg_send(c, &qos_, sizeof(qos_));
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m) {
|
int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m) {
|
||||||
@@ -119,21 +119,21 @@ int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m) {
|
|||||||
memset(m, 0, sizeof(*m));
|
memset(m, 0, sizeof(*m));
|
||||||
m->dgram.ptr = (char *) buf;
|
m->dgram.ptr = (char *) buf;
|
||||||
if (len < 2) return MQTT_INCOMPLETE;
|
if (len < 2) return MQTT_INCOMPLETE;
|
||||||
m->cmd = buf[0] >> 4;
|
m->cmd = (uint8_t)(buf[0] >> 4);
|
||||||
m->qos = (buf[0] >> 1) & 3;
|
m->qos = (buf[0] >> 1) & 3;
|
||||||
|
|
||||||
n = len_len = 0;
|
n = len_len = 0;
|
||||||
p = (uint8_t *) buf + 1;
|
p = (uint8_t *) buf + 1;
|
||||||
while ((size_t)(p - buf) < len) {
|
while ((size_t)(p - buf) < len) {
|
||||||
lc = *((uint8_t *) p++);
|
lc = *((uint8_t *) p++);
|
||||||
n += (lc & 0x7f) << 7 * len_len;
|
n += (uint32_t)((lc & 0x7f) << 7 * len_len);
|
||||||
len_len++;
|
len_len++;
|
||||||
if (!(lc & 0x80)) break;
|
if (!(lc & 0x80)) break;
|
||||||
if (len_len >= 4) return MQTT_MALFORMED;
|
if (len_len >= 4) return MQTT_MALFORMED;
|
||||||
}
|
}
|
||||||
end = p + n;
|
end = p + n;
|
||||||
if (lc & 0x80 || end > buf + len) return MQTT_INCOMPLETE;
|
if (lc & 0x80 || end > buf + len) return MQTT_INCOMPLETE;
|
||||||
m->dgram.len = end - buf;
|
m->dgram.len = (size_t)(end - buf);
|
||||||
|
|
||||||
switch (m->cmd) {
|
switch (m->cmd) {
|
||||||
case MQTT_CMD_CONNACK:
|
case MQTT_CMD_CONNACK:
|
||||||
@@ -146,28 +146,28 @@ int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m) {
|
|||||||
case MQTT_CMD_PUBCOMP:
|
case MQTT_CMD_PUBCOMP:
|
||||||
case MQTT_CMD_SUBACK:
|
case MQTT_CMD_SUBACK:
|
||||||
if (p + 2 > end) return MQTT_MALFORMED;
|
if (p + 2 > end) return MQTT_MALFORMED;
|
||||||
m->id = (p[0] << 8) | p[1];
|
m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]);
|
||||||
break;
|
break;
|
||||||
case MQTT_CMD_SUBSCRIBE: {
|
case MQTT_CMD_SUBSCRIBE: {
|
||||||
if (p + 2 > end) return MQTT_MALFORMED;
|
if (p + 2 > end) return MQTT_MALFORMED;
|
||||||
m->id = (p[0] << 8) | p[1];
|
m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]);
|
||||||
p += 2;
|
p += 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MQTT_CMD_PUBLISH: {
|
case MQTT_CMD_PUBLISH: {
|
||||||
if (p + 2 > end) return MQTT_MALFORMED;
|
if (p + 2 > end) return MQTT_MALFORMED;
|
||||||
m->topic.len = (p[0] << 8) | p[1];
|
m->topic.len = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]);
|
||||||
m->topic.ptr = (char *) p + 2;
|
m->topic.ptr = (char *) p + 2;
|
||||||
p += 2 + m->topic.len;
|
p += 2 + m->topic.len;
|
||||||
if (p > end) return MQTT_MALFORMED;
|
if (p > end) return MQTT_MALFORMED;
|
||||||
if (m->qos > 0) {
|
if (m->qos > 0) {
|
||||||
if (p + 2 > end) return MQTT_MALFORMED;
|
if (p + 2 > end) return MQTT_MALFORMED;
|
||||||
m->id = (p[0] << 8) | p[1];
|
m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]);
|
||||||
p += 2;
|
p += 2;
|
||||||
}
|
}
|
||||||
if (p > end) return MQTT_MALFORMED;
|
if (p > end) return MQTT_MALFORMED;
|
||||||
m->data.ptr = (char *) p;
|
m->data.ptr = (char *) p;
|
||||||
m->data.len = end - p;
|
m->data.len = (size_t)(end - p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -176,20 +176,32 @@ int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m) {
|
|||||||
return MQTT_OK;
|
return MQTT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_mqtt_next_sub(struct mg_mqtt_message *msg, struct mg_str *topic,
|
static size_t mg_mqtt_next_topic(struct mg_mqtt_message *msg,
|
||||||
uint8_t *qos, int pos) {
|
struct mg_str *topic, uint8_t *qos,
|
||||||
|
size_t pos) {
|
||||||
unsigned char *buf = (unsigned char *) msg->dgram.ptr + pos;
|
unsigned char *buf = (unsigned char *) msg->dgram.ptr + pos;
|
||||||
int new_pos;
|
size_t new_pos;
|
||||||
if ((size_t) pos >= msg->dgram.len) return -1;
|
if (pos >= msg->dgram.len) return 0;
|
||||||
|
|
||||||
topic->len = buf[0] << 8 | buf[1];
|
topic->len = (size_t)(((unsigned) buf[0]) << 8 | buf[1]);
|
||||||
topic->ptr = (char *) buf + 2;
|
topic->ptr = (char *) buf + 2;
|
||||||
new_pos = pos + 2 + topic->len + 1;
|
new_pos = pos + 2 + topic->len + (qos == NULL ? 0 : 1);
|
||||||
if ((size_t) new_pos > msg->dgram.len) return -1;
|
if ((size_t) new_pos > msg->dgram.len) return 0;
|
||||||
*qos = buf[2 + topic->len];
|
if (qos != NULL) *qos = buf[2 + topic->len];
|
||||||
return new_pos;
|
return new_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t mg_mqtt_next_sub(struct mg_mqtt_message *msg, struct mg_str *topic,
|
||||||
|
uint8_t *qos, size_t pos) {
|
||||||
|
uint8_t tmp;
|
||||||
|
return mg_mqtt_next_topic(msg, topic, qos == NULL ? &tmp : qos, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t mg_mqtt_next_unsub(struct mg_mqtt_message *msg, struct mg_str *topic,
|
||||||
|
size_t pos) {
|
||||||
|
return mg_mqtt_next_topic(msg, topic, NULL, pos);
|
||||||
|
}
|
||||||
|
|
||||||
static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data,
|
static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data,
|
||||||
void *fn_data) {
|
void *fn_data) {
|
||||||
if (ev == MG_EV_READ) {
|
if (ev == MG_EV_READ) {
|
||||||
@@ -232,6 +244,18 @@ static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data,
|
|||||||
(void) fn_data;
|
(void) fn_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mg_mqtt_ping(struct mg_connection *nc) {
|
||||||
|
mg_mqtt_send_header(nc, MQTT_CMD_PINGREQ, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mg_mqtt_pong(struct mg_connection *nc) {
|
||||||
|
mg_mqtt_send_header(nc, MQTT_CMD_PINGRESP, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mg_mqtt_disconnect(struct mg_connection *nc) {
|
||||||
|
mg_mqtt_send_header(nc, MQTT_CMD_DISCONNECT, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
struct mg_connection *mg_mqtt_connect(struct mg_mgr *mgr, const char *url,
|
struct mg_connection *mg_mqtt_connect(struct mg_mgr *mgr, const char *url,
|
||||||
struct mg_mqtt_opts *opts,
|
struct mg_mqtt_opts *opts,
|
||||||
mg_event_handler_t fn, void *fn_data) {
|
mg_event_handler_t fn, void *fn_data) {
|
||||||
|
|||||||
+13
-8
@@ -33,9 +33,9 @@ struct mg_mqtt_opts {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct mg_mqtt_message {
|
struct mg_mqtt_message {
|
||||||
struct mg_str topic; // Parsed topic
|
struct mg_str topic; // Parsed topic
|
||||||
struct mg_str data; // Parsed message
|
struct mg_str data; // Parsed message
|
||||||
struct mg_str dgram; // Whole MQTT datagram, including headers
|
struct mg_str dgram; // Whole MQTT datagram, including headers
|
||||||
uint16_t id; // Set for PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, PUBLISH
|
uint16_t id; // Set for PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, PUBLISH
|
||||||
uint8_t cmd; // MQTT command, one of MQTT_CMD_*
|
uint8_t cmd; // MQTT command, one of MQTT_CMD_*
|
||||||
uint8_t qos; // Quality of service
|
uint8_t qos; // Quality of service
|
||||||
@@ -47,11 +47,16 @@ struct mg_connection *mg_mqtt_connect(struct mg_mgr *, const char *url,
|
|||||||
mg_event_handler_t fn, void *fn_data);
|
mg_event_handler_t fn, void *fn_data);
|
||||||
struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
|
struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
|
||||||
mg_event_handler_t fn, void *fn_data);
|
mg_event_handler_t fn, void *fn_data);
|
||||||
void mg_mqtt_pub(struct mg_connection *, struct mg_str *topic,
|
void mg_mqtt_pub(struct mg_connection *c, struct mg_str *topic,
|
||||||
struct mg_str *data);
|
struct mg_str *data, int qos, bool retain);
|
||||||
void mg_mqtt_sub(struct mg_connection *, struct mg_str *topic);
|
void mg_mqtt_sub(struct mg_connection *, struct mg_str *topic, int qos);
|
||||||
int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m);
|
int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m);
|
||||||
void mg_mqtt_send_header(struct mg_connection *, uint8_t cmd, uint8_t flags,
|
void mg_mqtt_send_header(struct mg_connection *, uint8_t cmd, uint8_t flags,
|
||||||
uint32_t len);
|
uint32_t len);
|
||||||
int mg_mqtt_next_sub(struct mg_mqtt_message *msg, struct mg_str *topic,
|
size_t mg_mqtt_next_sub(struct mg_mqtt_message *msg, struct mg_str *topic,
|
||||||
uint8_t *qos, int pos);
|
uint8_t *qos, size_t pos);
|
||||||
|
size_t mg_mqtt_next_unsub(struct mg_mqtt_message *msg, struct mg_str *topic,
|
||||||
|
size_t pos);
|
||||||
|
void mg_mqtt_ping(struct mg_connection *);
|
||||||
|
void mg_mqtt_pong(struct mg_connection *);
|
||||||
|
void mg_mqtt_disconnect(struct mg_connection *);
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
#include "log.h"
|
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
#include "log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
int mg_vprintf(struct mg_connection *c, const char *fmt, va_list ap) {
|
int mg_vprintf(struct mg_connection *c, const char *fmt, va_list ap) {
|
||||||
char mem[256], *buf = mem;
|
char mem[256], *buf = mem;
|
||||||
int len = mg_vasprintf(&buf, sizeof(mem), fmt, ap);
|
int len = mg_vasprintf(&buf, sizeof(mem), fmt, ap);
|
||||||
len = mg_send(c, buf, len);
|
len = mg_send(c, buf, len > 0 ? (size_t) len : 0);
|
||||||
if (buf != mem) free(buf);
|
if (buf != mem) free(buf);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ static bool mg_aton4(struct mg_str str, struct mg_addr *addr) {
|
|||||||
if (str.ptr[i] >= '0' && str.ptr[i] <= '9') {
|
if (str.ptr[i] >= '0' && str.ptr[i] <= '9') {
|
||||||
int octet = data[num_dots] * 10 + (str.ptr[i] - '0');
|
int octet = data[num_dots] * 10 + (str.ptr[i] - '0');
|
||||||
if (octet > 255) return false;
|
if (octet > 255) return false;
|
||||||
data[num_dots] = octet;
|
data[num_dots] = (uint8_t) octet;
|
||||||
} else if (str.ptr[i] == '.') {
|
} else if (str.ptr[i] == '.') {
|
||||||
if (num_dots >= 3 || i == 0 || str.ptr[i - 1] == '.') return false;
|
if (num_dots >= 3 || i == 0 || str.ptr[i - 1] == '.') return false;
|
||||||
num_dots++;
|
num_dots++;
|
||||||
@@ -115,24 +115,25 @@ void mg_mgr_free(struct mg_mgr *mgr) {
|
|||||||
struct mg_connection *c;
|
struct mg_connection *c;
|
||||||
for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1;
|
for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1;
|
||||||
mg_mgr_poll(mgr, 0);
|
mg_mgr_poll(mgr, 0);
|
||||||
#if MG_ARCH == MG_ARCH_FREERTOS
|
#if MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||||
FreeRTOS_DeleteSocketSet(mgr->ss);
|
FreeRTOS_DeleteSocketSet(mgr->ss);
|
||||||
#endif
|
#endif
|
||||||
LOG(LL_INFO, ("All connections closed"));
|
LOG(LL_INFO, ("All connections closed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_mgr_init(struct mg_mgr *mgr) {
|
void mg_mgr_init(struct mg_mgr *mgr) {
|
||||||
#ifdef _WIN32
|
memset(mgr, 0, sizeof(*mgr));
|
||||||
WSADATA data;
|
#if defined(_WIN32) && MG_ENABLE_WINSOCK
|
||||||
WSAStartup(MAKEWORD(2, 2), &data);
|
// clang-format off
|
||||||
#elif MG_ARCH == MG_ARCH_FREERTOS
|
{ WSADATA data; WSAStartup(MAKEWORD(2, 2), &data); }
|
||||||
|
// clang-format on
|
||||||
|
#elif MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||||
mgr->ss = FreeRTOS_CreateSocketSet();
|
mgr->ss = FreeRTOS_CreateSocketSet();
|
||||||
#elif defined(__unix) || defined(__unix__) || defined(__APPLE__)
|
#elif defined(__unix) || defined(__unix__) || defined(__APPLE__)
|
||||||
// Ignore SIGPIPE signal, so if client cancels the request, it
|
// Ignore SIGPIPE signal, so if client cancels the request, it
|
||||||
// won't kill the whole process.
|
// won't kill the whole process.
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
#endif
|
#endif
|
||||||
memset(mgr, 0, sizeof(*mgr));
|
|
||||||
mgr->dnstimeout = 3000;
|
mgr->dnstimeout = 3000;
|
||||||
mgr->dns4.url = "udp://8.8.8.8:53";
|
mgr->dns4.url = "udp://8.8.8.8:53";
|
||||||
mgr->dns6.url = "udp://[2001:4860:4860::8888]:53";
|
mgr->dns6.url = "udp://[2001:4860:4860::8888]:53";
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ struct mg_mgr {
|
|||||||
struct mg_dns dns6; // DNS for IPv6
|
struct mg_dns dns6; // DNS for IPv6
|
||||||
int dnstimeout; // DNS resolve timeout in milliseconds
|
int dnstimeout; // DNS resolve timeout in milliseconds
|
||||||
unsigned long nextid; // Next connection ID
|
unsigned long nextid; // Next connection ID
|
||||||
#if MG_ARCH == MG_ARCH_FREERTOS
|
void *userdata; // Arbitrary user data pointer
|
||||||
|
#if MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||||
SocketSet_t ss; // NOTE(lsm): referenced from socket struct
|
SocketSet_t ss; // NOTE(lsm): referenced from socket struct
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -31,21 +32,21 @@ struct mg_mgr {
|
|||||||
struct mg_connection {
|
struct mg_connection {
|
||||||
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
||||||
struct mg_mgr *mgr; // Our container
|
struct mg_mgr *mgr; // Our container
|
||||||
struct mg_addr peer; // Remote peer address
|
struct mg_addr peer; // Remote address. For listeners, local address
|
||||||
void *fd; // Connected socket, or LWIP data
|
void *fd; // Connected socket, or LWIP data
|
||||||
unsigned long id; // Auto-incrementing unique connection ID
|
unsigned long id; // Auto-incrementing unique connection ID
|
||||||
struct mg_iobuf recv; // Incoming data
|
struct mg_iobuf recv; // Incoming data
|
||||||
struct mg_iobuf send; // Outgoing data
|
struct mg_iobuf send; // Outgoing data
|
||||||
mg_event_handler_t fn; // User-specified event handler function
|
mg_event_handler_t fn; // User-specified event handler function
|
||||||
void *fn_data; // User-speficied function parameter
|
void *fn_data; // User-specified function parameter
|
||||||
mg_event_handler_t pfn; // Protocol-specific handler function
|
mg_event_handler_t pfn; // Protocol-specific handler function
|
||||||
void *pfn_data; // Protocol-specific function parameter
|
void *pfn_data; // Protocol-specific function parameter
|
||||||
char label[32]; // Arbitrary label
|
char label[50]; // Arbitrary label
|
||||||
void *tls; // TLS specific data
|
void *tls; // TLS specific data
|
||||||
unsigned is_listening : 1; // Listening connection
|
unsigned is_listening : 1; // Listening connection
|
||||||
unsigned is_client : 1; // Outbound (client) connection
|
unsigned is_client : 1; // Outbound (client) connection
|
||||||
unsigned is_accepted : 1; // Accepted (server) connection
|
unsigned is_accepted : 1; // Accepted (server) connection
|
||||||
unsigned is_resolving : 1; // Non-blocking DNS resolv is in progress
|
unsigned is_resolving : 1; // Non-blocking DNS resolution is in progress
|
||||||
unsigned is_connecting : 1; // Non-blocking connect is in progress
|
unsigned is_connecting : 1; // Non-blocking connect is in progress
|
||||||
unsigned is_tls : 1; // TLS-enabled connection
|
unsigned is_tls : 1; // TLS-enabled connection
|
||||||
unsigned is_tls_hs : 1; // TLS handshake is in progress
|
unsigned is_tls_hs : 1; // TLS handshake is in progress
|
||||||
@@ -66,7 +67,7 @@ struct mg_connection *mg_listen(struct mg_mgr *, const char *url,
|
|||||||
mg_event_handler_t fn, void *fn_data);
|
mg_event_handler_t fn, void *fn_data);
|
||||||
struct mg_connection *mg_connect(struct mg_mgr *, const char *url,
|
struct mg_connection *mg_connect(struct mg_mgr *, const char *url,
|
||||||
mg_event_handler_t fn, void *fn_data);
|
mg_event_handler_t fn, void *fn_data);
|
||||||
int mg_send(struct mg_connection *, const void *, size_t);
|
bool mg_send(struct mg_connection *, const void *, size_t);
|
||||||
int mg_printf(struct mg_connection *, const char *fmt, ...);
|
int mg_printf(struct mg_connection *, const char *fmt, ...);
|
||||||
int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
|
int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
|
||||||
char *mg_straddr(struct mg_connection *, char *, size_t);
|
char *mg_straddr(struct mg_connection *, char *, size_t);
|
||||||
|
|||||||
@@ -1,12 +1 @@
|
|||||||
void mg_connect_resolved(struct mg_connection *);
|
void mg_connect_resolved(struct mg_connection *);
|
||||||
|
|
||||||
#if MG_ARCH == MG_ARCH_FREERTOS
|
|
||||||
static inline void *mg_calloc(int cnt, size_t size) {
|
|
||||||
void *p = pvPortMalloc(size);
|
|
||||||
if (p != NULL) memset(p, 0, size);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
#define calloc(a, b) mg_calloc((a), (b))
|
|
||||||
#define malloc(a) pvPortMalloc(a)
|
|
||||||
#define free(a) vPortFree(a)
|
|
||||||
#endif
|
|
||||||
+3
-3
@@ -22,8 +22,8 @@ int mg_sntp_parse(const unsigned char *buf, size_t len, struct timeval *tv) {
|
|||||||
} else {
|
} else {
|
||||||
uint32_t *data = (uint32_t *) &buf[40];
|
uint32_t *data = (uint32_t *) &buf[40];
|
||||||
tv->tv_sec = mg_ntohl(data[0]) - SNTP_TIME_OFFSET;
|
tv->tv_sec = mg_ntohl(data[0]) - SNTP_TIME_OFFSET;
|
||||||
tv->tv_usec = mg_ntohl(data[1]);
|
tv->tv_usec = (suseconds_t) mg_ntohl(data[1]);
|
||||||
s_sntmp_next = tv->tv_sec + SNTP_INTERVAL_SEC;
|
s_sntmp_next = (unsigned long) (tv->tv_sec + SNTP_INTERVAL_SEC);
|
||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
@@ -39,7 +39,7 @@ static void sntp_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
|
|||||||
}
|
}
|
||||||
c->recv.len = 0; // Clear receive buffer
|
c->recv.len = 0; // Clear receive buffer
|
||||||
} else if (ev == MG_EV_RESOLVE) {
|
} else if (ev == MG_EV_RESOLVE) {
|
||||||
mg_sntp_send(c, time(NULL));
|
mg_sntp_send(c, (unsigned long) time(NULL));
|
||||||
} else if (ev == MG_EV_CLOSE) {
|
} else if (ev == MG_EV_CLOSE) {
|
||||||
// mg_fn_del(c, sntp_cb);
|
// mg_fn_del(c, sntp_cb);
|
||||||
}
|
}
|
||||||
|
|||||||
+166
-146
@@ -10,25 +10,41 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#if MG_ENABLE_SOCKET
|
#if MG_ENABLE_SOCKET
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32) && MG_ENABLE_WINSOCK
|
||||||
#define MG_SOCK_ERRNO WSAGetLastError()
|
#define MG_SOCK_ERRNO WSAGetLastError()
|
||||||
#define FD(C_) ((SOCKET)(C_)->fd)
|
|
||||||
#ifndef SO_EXCLUSIVEADDRUSE
|
#ifndef SO_EXCLUSIVEADDRUSE
|
||||||
#define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
|
#define SO_EXCLUSIVEADDRUSE ((int) (~SO_REUSEADDR))
|
||||||
#endif
|
#endif
|
||||||
#elif MG_ARCH == MG_ARCH_FREERTOS
|
#elif MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||||
#define MG_SOCK_ERRNO errno
|
#define MG_SOCK_ERRNO errno
|
||||||
typedef Socket_t SOCKET;
|
typedef Socket_t SOCKET;
|
||||||
#define FD(C_) ((long) (C_)->fd)
|
|
||||||
#define INVALID_SOCKET FREERTOS_INVALID_SOCKET
|
#define INVALID_SOCKET FREERTOS_INVALID_SOCKET
|
||||||
#else
|
#else
|
||||||
#define MG_SOCK_ERRNO errno
|
#define MG_SOCK_ERRNO errno
|
||||||
|
#ifndef closesocket
|
||||||
#define closesocket(x) close(x)
|
#define closesocket(x) close(x)
|
||||||
|
#endif
|
||||||
#define INVALID_SOCKET (-1)
|
#define INVALID_SOCKET (-1)
|
||||||
typedef int SOCKET;
|
typedef int SOCKET;
|
||||||
#define FD(C_) ((SOCKET)(long) (C_)->fd)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
union _su {
|
||||||
|
SOCKET s;
|
||||||
|
void *ptr;
|
||||||
|
};
|
||||||
|
#define FD(c_) ptr2sock((c_)->fd)
|
||||||
|
|
||||||
|
static SOCKET ptr2sock(void *ptr) {
|
||||||
|
union _su u = {0};
|
||||||
|
u.ptr = ptr;
|
||||||
|
return u.s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *sock2ptr(SOCKET s) {
|
||||||
|
union _su u = {s};
|
||||||
|
return u.ptr;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef MSG_NONBLOCKING
|
#ifndef MSG_NONBLOCKING
|
||||||
#define MSG_NONBLOCKING 0
|
#define MSG_NONBLOCKING 0
|
||||||
#endif
|
#endif
|
||||||
@@ -57,61 +73,32 @@ static union usa tousa(struct mg_addr *a) {
|
|||||||
return usa;
|
return usa;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mg_sock_failed(void) {
|
static bool mg_sock_would_block(void) {
|
||||||
int err = MG_SOCK_ERRNO;
|
int err = MG_SOCK_ERRNO;
|
||||||
return err != EINPROGRESS && err != EWOULDBLOCK
|
return err == EINPROGRESS || err == EWOULDBLOCK
|
||||||
#ifndef WINCE
|
#ifndef WINCE
|
||||||
&& err != EAGAIN && err != EINTR
|
|| err == EAGAIN || err == EINTR
|
||||||
#endif
|
#endif
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) && MG_ENABLE_WINSOCK
|
||||||
&& err != WSAEINTR && err != WSAEWOULDBLOCK
|
|| err == WSAEINTR || err == WSAEWOULDBLOCK
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mg_connection *alloc_conn(struct mg_mgr *mgr, int is_client,
|
static struct mg_connection *alloc_conn(struct mg_mgr *mgr, bool is_client,
|
||||||
SOCKET fd) {
|
SOCKET fd) {
|
||||||
struct mg_connection *c = (struct mg_connection *) calloc(1, sizeof(*c));
|
struct mg_connection *c = (struct mg_connection *) calloc(1, sizeof(*c));
|
||||||
if (c != NULL) {
|
if (c != NULL) {
|
||||||
c->is_client = is_client;
|
c->is_client = is_client;
|
||||||
c->fd = (void *) (long) fd;
|
c->fd = sock2ptr(fd);
|
||||||
c->mgr = mgr;
|
c->mgr = mgr;
|
||||||
c->id = ++mgr->nextid;
|
c->id = ++mgr->nextid;
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mg_sock_recv(struct mg_connection *c, void *buf, int len,
|
static long mg_sock_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||||
int *fail) {
|
long n = 0;
|
||||||
int n = 0;
|
|
||||||
if (c->is_udp) {
|
|
||||||
union usa usa;
|
|
||||||
socklen_t slen = sizeof(usa.sin);
|
|
||||||
#if MG_ENABLE_IPV6
|
|
||||||
if (c->peer.is_ip6) slen = sizeof(usa.sin6);
|
|
||||||
#endif
|
|
||||||
n = recvfrom(FD(c), (char *) buf, len, 0, &usa.sa, &slen);
|
|
||||||
if (n > 0) {
|
|
||||||
if (c->peer.is_ip6) {
|
|
||||||
#if MG_ENABLE_IPV6
|
|
||||||
memcpy(c->peer.ip6, &usa.sin6.sin6_addr, sizeof(c->peer.ip6));
|
|
||||||
c->peer.port = usa.sin6.sin6_port;
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
c->peer.ip = *(uint32_t *) &usa.sin.sin_addr;
|
|
||||||
c->peer.port = usa.sin.sin_port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);
|
|
||||||
}
|
|
||||||
*fail = (n == 0) || (n < 0 && mg_sock_failed());
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mg_sock_send(struct mg_connection *c, const void *buf, int len,
|
|
||||||
int *fail) {
|
|
||||||
int n = 0;
|
|
||||||
if (c->is_udp) {
|
if (c->is_udp) {
|
||||||
union usa usa = tousa(&c->peer);
|
union usa usa = tousa(&c->peer);
|
||||||
socklen_t slen = sizeof(usa.sin);
|
socklen_t slen = sizeof(usa.sin);
|
||||||
@@ -122,77 +109,41 @@ static int mg_sock_send(struct mg_connection *c, const void *buf, int len,
|
|||||||
} else {
|
} else {
|
||||||
n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
|
n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
|
||||||
}
|
}
|
||||||
*fail = (n == 0) || (n < 0 && mg_sock_failed());
|
return n == 0 ? -1 : n < 0 && mg_sock_would_block() ? 0 : n;
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ll_read(struct mg_connection *c, void *buf, int len, int *fail) {
|
bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||||
int n = c->is_tls ? mg_tls_recv(c, buf, len, fail)
|
return c->is_udp ? mg_sock_send(c, buf, len) > 0
|
||||||
: mg_sock_recv(c, buf, len, fail);
|
: mg_iobuf_append(&c->send, buf, len, MG_IO_SIZE);
|
||||||
LOG(*fail ? LL_DEBUG : LL_VERBOSE_DEBUG,
|
|
||||||
("%lu %c%c%c %d/%d %d %d", c->id, c->is_tls ? 'T' : 't',
|
|
||||||
c->is_udp ? 'U' : 'u', c->is_connecting ? 'C' : 'c', n, len,
|
|
||||||
MG_SOCK_ERRNO, *fail));
|
|
||||||
if (n > 0 && c->is_hexdumping) {
|
|
||||||
char *s = mg_hexdump(buf, n);
|
|
||||||
// LOG(LL_INFO, ("\n-- %lu %s %s %d\n%s--", c->id, c->label, "<-", n, s));
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ll_write(struct mg_connection *c, const void *buf, int len,
|
|
||||||
int *fail) {
|
|
||||||
int n = c->is_tls ? mg_tls_send(c, buf, len, fail)
|
|
||||||
: mg_sock_send(c, buf, len, fail);
|
|
||||||
LOG(*fail ? LL_ERROR : LL_VERBOSE_DEBUG,
|
|
||||||
("%lu %c%c%c %d/%d %d", c->id, c->is_tls ? 'T' : 't',
|
|
||||||
c->is_udp ? 'U' : 'u', c->is_connecting ? 'C' : 'c', n, len,
|
|
||||||
MG_SOCK_ERRNO));
|
|
||||||
if (n > 0 && c->is_hexdumping) {
|
|
||||||
char *s = mg_hexdump(buf, len);
|
|
||||||
// LOG(LL_INFO, ("\n-- %lu %s %s %d\n%s--", c->id, c->label, "->", len, s));
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mg_send(struct mg_connection *c, const void *buf, size_t len) {
|
|
||||||
int fail, n = c->is_udp
|
|
||||||
? ll_write(c, buf, (SOCKET) len, &fail)
|
|
||||||
: (int) mg_iobuf_append(&c->send, buf, len, MG_IO_SIZE);
|
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mg_set_non_blocking_mode(SOCKET fd) {
|
static void mg_set_non_blocking_mode(SOCKET fd) {
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) && MG_ENABLE_WINSOCK
|
||||||
unsigned long on = 1;
|
unsigned long on = 1;
|
||||||
ioctlsocket(fd, FIONBIO, &on);
|
ioctlsocket(fd, FIONBIO, &on);
|
||||||
#elif MG_ARCH == MG_ARCH_FREERTOS
|
#elif MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||||
const BaseType_t off = 0;
|
const BaseType_t off = 0;
|
||||||
setsockopt(fd, 0, FREERTOS_SO_RCVTIMEO, &off, sizeof(off));
|
setsockopt(fd, 0, FREERTOS_SO_RCVTIMEO, &off, sizeof(off));
|
||||||
setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off));
|
setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off));
|
||||||
#else
|
#else
|
||||||
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
|
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK, FD_CLOEXEC);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SOCKET mg_open_listener(const char *url) {
|
SOCKET mg_open_listener(const char *url, struct mg_addr *addr) {
|
||||||
struct mg_addr addr;
|
|
||||||
SOCKET fd = INVALID_SOCKET;
|
SOCKET fd = INVALID_SOCKET;
|
||||||
|
memset(addr, 0, sizeof(*addr));
|
||||||
memset(&addr, 0, sizeof(addr));
|
addr->port = mg_htons(mg_url_port(url));
|
||||||
addr.port = mg_htons(mg_url_port(url));
|
if (!mg_aton(mg_url_host(url), addr)) {
|
||||||
if (!mg_aton(mg_url_host(url), &addr)) {
|
|
||||||
LOG(LL_ERROR, ("invalid listening URL: %s", url));
|
LOG(LL_ERROR, ("invalid listening URL: %s", url));
|
||||||
} else {
|
} else {
|
||||||
union usa usa = tousa(&addr);
|
union usa usa = tousa(addr);
|
||||||
int on = 1, af = AF_INET;
|
int on = 1, af = AF_INET;
|
||||||
int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM;
|
int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM;
|
||||||
int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
|
int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
|
||||||
socklen_t slen = sizeof(usa.sin);
|
socklen_t slen = sizeof(usa.sin);
|
||||||
#if MG_ENABLE_IPV6
|
#if MG_ENABLE_IPV6
|
||||||
if (addr.is_ip6) af = AF_INET6, slen = sizeof(usa.sin6);
|
if (addr->is_ip6) af = AF_INET6, slen = sizeof(usa.sin6);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((fd = socket(af, type, proto)) != INVALID_SOCKET &&
|
if ((fd = socket(af, type, proto)) != INVALID_SOCKET &&
|
||||||
@@ -216,56 +167,121 @@ SOCKET mg_open_listener(const char *url) {
|
|||||||
bind(fd, &usa.sa, slen) == 0 &&
|
bind(fd, &usa.sa, slen) == 0 &&
|
||||||
// NOTE(lsm): FreeRTOS uses backlog value as a connection limit
|
// NOTE(lsm): FreeRTOS uses backlog value as a connection limit
|
||||||
(type == SOCK_DGRAM || listen(fd, 128) == 0)) {
|
(type == SOCK_DGRAM || listen(fd, 128) == 0)) {
|
||||||
|
// In case port was set to 0, get the real port number
|
||||||
|
if (getsockname(fd, &usa.sa, &slen) == 0) {
|
||||||
|
addr->port = usa.sin.sin_port;
|
||||||
|
#if MG_ENABLE_IPV6
|
||||||
|
if (addr->is_ip6) addr->port = usa.sin6.sin6_port;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
mg_set_non_blocking_mode(fd);
|
mg_set_non_blocking_mode(fd);
|
||||||
} else if (fd != INVALID_SOCKET) {
|
} else if (fd != INVALID_SOCKET) {
|
||||||
LOG(LL_ERROR, ("Failed to listen on %s, errno %d", url, MG_SOCK_ERRNO));
|
|
||||||
closesocket(fd);
|
closesocket(fd);
|
||||||
fd = INVALID_SOCKET;
|
fd = INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (fd == INVALID_SOCKET) {
|
||||||
|
LOG(LL_ERROR, ("Failed to listen on %s, errno %d", url, MG_SOCK_ERRNO));
|
||||||
|
}
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_conn(struct mg_connection *c,
|
static long mg_sock_recv(struct mg_connection *c, void *buf, size_t len) {
|
||||||
int (*fn)(struct mg_connection *, void *, int, int *)) {
|
long n = 0;
|
||||||
unsigned char *buf;
|
if (c->is_udp) {
|
||||||
int rc, len, fail;
|
union usa usa;
|
||||||
|
socklen_t slen = sizeof(usa.sin);
|
||||||
// NOTE(lsm): do only one iteration of reads, cause some systems
|
#if MG_ENABLE_IPV6
|
||||||
// (e.g. FreeRTOS stack) return 0 instead of -1/EWOULDBLOCK when no data
|
if (c->peer.is_ip6) slen = sizeof(usa.sin6);
|
||||||
if (c->recv.size - c->recv.len < MG_IO_SIZE &&
|
#endif
|
||||||
c->recv.size < MG_MAX_RECV_BUF_SIZE) {
|
n = recvfrom(FD(c), (char *) buf, len, 0, &usa.sa, &slen);
|
||||||
mg_iobuf_resize(&c->recv, c->recv.size + MG_IO_SIZE);
|
if (n > 0) {
|
||||||
}
|
if (c->peer.is_ip6) {
|
||||||
buf = c->recv.buf + c->recv.len;
|
#if MG_ENABLE_IPV6
|
||||||
len = (int) (c->recv.size - c->recv.len);
|
memcpy(c->peer.ip6, &usa.sin6.sin6_addr, sizeof(c->peer.ip6));
|
||||||
rc = fn(c, buf, len, &fail);
|
c->peer.port = usa.sin6.sin6_port;
|
||||||
if (rc > 0) {
|
#endif
|
||||||
struct mg_str evd = mg_str_n((char *) buf, rc);
|
} else {
|
||||||
c->recv.len += rc;
|
c->peer.ip = *(uint32_t *) &usa.sin.sin_addr;
|
||||||
mg_call(c, MG_EV_READ, &evd);
|
c->peer.port = usa.sin.sin_port;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (fail) c->is_closing = 1;
|
n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);
|
||||||
|
}
|
||||||
|
return n == 0 ? -1 : n < 0 && mg_sock_would_block() ? 0 : n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(lsm): do only one iteration of reads, cause some systems
|
||||||
|
// (e.g. FreeRTOS stack) return 0 instead of -1/EWOULDBLOCK when no data
|
||||||
|
static void read_conn(struct mg_connection *c) {
|
||||||
|
if (c->recv.len >= MG_MAX_RECV_BUF_SIZE) {
|
||||||
|
mg_error(c, "max_recv_buf_size reached");
|
||||||
|
} else if (c->recv.size - c->recv.len < MG_IO_SIZE &&
|
||||||
|
!mg_iobuf_resize(&c->recv, c->recv.size + MG_IO_SIZE)) {
|
||||||
|
mg_error(c, "oom");
|
||||||
|
} else {
|
||||||
|
char *buf = (char *) &c->recv.buf[c->recv.len];
|
||||||
|
size_t len = c->recv.size - c->recv.len;
|
||||||
|
long n = c->is_tls ? mg_tls_recv(c, buf, len) : mg_sock_recv(c, buf, len);
|
||||||
|
LOG(n > 0 ? LL_VERBOSE_DEBUG : LL_DEBUG,
|
||||||
|
("%-3lu %d%d%d%d%d%d%d%d%d%d%d%d%d%d %7ld %ld/%ld err %d", c->id,
|
||||||
|
c->is_listening, c->is_client, c->is_accepted, c->is_resolving,
|
||||||
|
c->is_connecting, c->is_tls, c->is_tls_hs, c->is_udp, c->is_websocket,
|
||||||
|
c->is_hexdumping, c->is_draining, c->is_closing, c->is_readable,
|
||||||
|
c->is_writable, (long) c->recv.len, n, (long) len, MG_SOCK_ERRNO));
|
||||||
|
if (n == 0) {
|
||||||
|
// Do nothing
|
||||||
|
} else if (n < 0) {
|
||||||
|
c->is_closing = 1; // Error, or normal termination
|
||||||
|
} else if (n > 0) {
|
||||||
|
struct mg_str evd = mg_str_n(buf, (size_t) n);
|
||||||
|
if (c->is_hexdumping) {
|
||||||
|
char *s = mg_hexdump(buf, (size_t) n);
|
||||||
|
LOG(LL_INFO, ("\n-- %lu %s %s %ld\n%s", c->id, c->label, "<-", n, s));
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
c->recv.len += (size_t) n;
|
||||||
|
mg_call(c, MG_EV_READ, &evd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_conn(struct mg_connection *c) {
|
static void write_conn(struct mg_connection *c) {
|
||||||
int fail, rc = ll_write(c, c->send.buf, (SOCKET) c->send.len, &fail);
|
char *buf = (char *) c->send.buf;
|
||||||
if (rc > 0) {
|
size_t len = c->send.len;
|
||||||
mg_iobuf_delete(&c->send, rc);
|
long n = c->is_tls ? mg_tls_send(c, buf, len) : mg_sock_send(c, buf, len);
|
||||||
|
|
||||||
|
LOG(n > 0 ? LL_VERBOSE_DEBUG : LL_DEBUG,
|
||||||
|
("%-3lu %d%d%d%d%d%d%d%d%d%d%d%d%d%d %7ld %ld err %d", c->id,
|
||||||
|
c->is_listening, c->is_client, c->is_accepted, c->is_resolving,
|
||||||
|
c->is_connecting, c->is_tls, c->is_tls_hs, c->is_udp, c->is_websocket,
|
||||||
|
c->is_hexdumping, c->is_draining, c->is_closing, c->is_readable,
|
||||||
|
c->is_writable, (long) c->send.len, n, MG_SOCK_ERRNO));
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
// Do nothing
|
||||||
|
} else if (n < 0) {
|
||||||
|
c->is_closing = 1; // Error, or normal termination
|
||||||
|
} else if (n > 0) {
|
||||||
|
// Hexdump before deleting
|
||||||
|
if (c->is_hexdumping) {
|
||||||
|
char *s = mg_hexdump(buf, (size_t) n);
|
||||||
|
LOG(LL_INFO, ("\n-- %lu %s %s %ld\n%s", c->id, c->label, "<-", n, s));
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
mg_iobuf_delete(&c->send, (size_t) n);
|
||||||
if (c->send.len == 0) mg_iobuf_resize(&c->send, 0);
|
if (c->send.len == 0) mg_iobuf_resize(&c->send, 0);
|
||||||
mg_call(c, MG_EV_WRITE, &rc);
|
mg_call(c, MG_EV_WRITE, &n);
|
||||||
} else if (fail) {
|
// if (c->send.len == 0) mg_iobuf_resize(&c->send, 0);
|
||||||
c->is_closing = 1;
|
|
||||||
}
|
}
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void close_conn(struct mg_connection *c) {
|
static void close_conn(struct mg_connection *c) {
|
||||||
// Unlink this connection from the list
|
// Unlink this connection from the list
|
||||||
LIST_DELETE(struct mg_connection, &c->mgr->conns, c);
|
|
||||||
mg_resolve_cancel(c);
|
mg_resolve_cancel(c);
|
||||||
|
LIST_DELETE(struct mg_connection, &c->mgr->conns, c);
|
||||||
if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL;
|
if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL;
|
||||||
if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL;
|
if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL;
|
||||||
mg_call(c, MG_EV_CLOSE, NULL);
|
mg_call(c, MG_EV_CLOSE, NULL);
|
||||||
@@ -273,7 +289,7 @@ static void close_conn(struct mg_connection *c) {
|
|||||||
LOG(LL_DEBUG, ("%lu closed", c->id));
|
LOG(LL_DEBUG, ("%lu closed", c->id));
|
||||||
if (FD(c) != INVALID_SOCKET) {
|
if (FD(c) != INVALID_SOCKET) {
|
||||||
closesocket(FD(c));
|
closesocket(FD(c));
|
||||||
#if MG_ARCH == MG_ARCH_FREERTOS
|
#if MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||||
FreeRTOS_FD_CLR(c->fd, c->mgr->ss, eSELECT_ALL);
|
FreeRTOS_FD_CLR(c->fd, c->mgr->ss, eSELECT_ALL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -285,8 +301,8 @@ static void close_conn(struct mg_connection *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void setsockopts(struct mg_connection *c) {
|
static void setsockopts(struct mg_connection *c) {
|
||||||
#if MG_ARCH == MG_ARCH_FREERTOS
|
#if MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||||
FreeRTOS_FD_SET(c->fd, c->mgr->ss, eSELECT_READ | eSELECT_EXCEPT);
|
(void) c;
|
||||||
#else
|
#else
|
||||||
int on = 1;
|
int on = 1;
|
||||||
#if !defined(SOL_TCP)
|
#if !defined(SOL_TCP)
|
||||||
@@ -301,7 +317,7 @@ static void setsockopts(struct mg_connection *c) {
|
|||||||
int idle = 60;
|
int idle = 60;
|
||||||
setsockopt(FD(c), IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle));
|
setsockopt(FD(c), IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle));
|
||||||
#endif
|
#endif
|
||||||
#ifndef _WIN32
|
#if !defined(_WIN32) && !defined(__QNX__)
|
||||||
{
|
{
|
||||||
int cnt = 3, intvl = 20;
|
int cnt = 3, intvl = 20;
|
||||||
setsockopt(FD(c), IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt));
|
setsockopt(FD(c), IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt));
|
||||||
@@ -314,12 +330,12 @@ static void setsockopts(struct mg_connection *c) {
|
|||||||
void mg_connect_resolved(struct mg_connection *c) {
|
void mg_connect_resolved(struct mg_connection *c) {
|
||||||
char buf[40];
|
char buf[40];
|
||||||
int type = c->is_udp ? SOCK_DGRAM : SOCK_STREAM;
|
int type = c->is_udp ? SOCK_DGRAM : SOCK_STREAM;
|
||||||
int af = AF_INET;
|
int rc, af = AF_INET;
|
||||||
#if MG_ENABLE_IPV6
|
#if MG_ENABLE_IPV6
|
||||||
if (c->peer.is_ip6) af = AF_INET6;
|
if (c->peer.is_ip6) af = AF_INET6;
|
||||||
#endif
|
#endif
|
||||||
mg_straddr(c, buf, sizeof(buf));
|
mg_straddr(c, buf, sizeof(buf));
|
||||||
c->fd = (void *) (long) socket(af, type, 0);
|
c->fd = sock2ptr(socket(af, type, 0));
|
||||||
if (FD(c) == INVALID_SOCKET) {
|
if (FD(c) == INVALID_SOCKET) {
|
||||||
mg_error(c, "socket(): %d", MG_SOCK_ERRNO);
|
mg_error(c, "socket(): %d", MG_SOCK_ERRNO);
|
||||||
return;
|
return;
|
||||||
@@ -329,19 +345,16 @@ void mg_connect_resolved(struct mg_connection *c) {
|
|||||||
mg_call(c, MG_EV_RESOLVE, NULL);
|
mg_call(c, MG_EV_RESOLVE, NULL);
|
||||||
if (type == SOCK_STREAM) {
|
if (type == SOCK_STREAM) {
|
||||||
union usa usa = tousa(&c->peer);
|
union usa usa = tousa(&c->peer);
|
||||||
socklen_t slen =
|
socklen_t slen = sizeof(usa.sin);
|
||||||
#if MG_ENABLE_IPV6
|
#if MG_ENABLE_IPV6
|
||||||
c->peer.is_ip6 ? sizeof(usa.sin6) :
|
if (c->peer.is_ip6) slen = sizeof(usa.sin6);
|
||||||
#endif
|
#endif
|
||||||
sizeof(usa.sin);
|
if ((rc = connect(FD(c), &usa.sa, slen)) == 0 || mg_sock_would_block()) {
|
||||||
int rc = connect(FD(c), &usa.sa, slen);
|
|
||||||
int fail = rc < 0 && mg_sock_failed() ? MG_SOCK_ERRNO : 0;
|
|
||||||
if (fail) {
|
|
||||||
mg_error(c, "connect: %d", MG_SOCK_ERRNO);
|
|
||||||
} else {
|
|
||||||
setsockopts(c);
|
setsockopts(c);
|
||||||
|
if (rc != 0) c->is_connecting = 1;
|
||||||
|
} else {
|
||||||
|
mg_error(c, "connect: %d", MG_SOCK_ERRNO);
|
||||||
}
|
}
|
||||||
if (rc < 0) c->is_connecting = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,8 +383,8 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
|
|||||||
SOCKET fd = accept(FD(lsn), &usa.sa, &sa_len);
|
SOCKET fd = accept(FD(lsn), &usa.sa, &sa_len);
|
||||||
if (fd == INVALID_SOCKET) {
|
if (fd == INVALID_SOCKET) {
|
||||||
LOG(LL_ERROR, ("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERRNO));
|
LOG(LL_ERROR, ("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERRNO));
|
||||||
#if !defined(_WIN32)
|
#if (!defined(_WIN32) && (MG_ARCH != MG_ARCH_FREERTOS_TCP))
|
||||||
} else if (fd >= FD_SETSIZE) {
|
} else if ((long) fd >= FD_SETSIZE) {
|
||||||
LOG(LL_ERROR, ("%ld > %ld", (long) fd, (long) FD_SETSIZE));
|
LOG(LL_ERROR, ("%ld > %ld", (long) fd, (long) FD_SETSIZE));
|
||||||
closesocket(fd);
|
closesocket(fd);
|
||||||
#endif
|
#endif
|
||||||
@@ -449,30 +462,33 @@ bool mg_socketpair(int *s1, int *s2) {
|
|||||||
struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
|
struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
|
||||||
mg_event_handler_t fn, void *fn_data) {
|
mg_event_handler_t fn, void *fn_data) {
|
||||||
struct mg_connection *c = NULL;
|
struct mg_connection *c = NULL;
|
||||||
int is_udp = strncmp(url, "udp:", 4) == 0;
|
bool is_udp = strncmp(url, "udp:", 4) == 0;
|
||||||
SOCKET fd = mg_open_listener(url);
|
struct mg_addr addr;
|
||||||
|
SOCKET fd = mg_open_listener(url, &addr);
|
||||||
if (fd == INVALID_SOCKET) {
|
if (fd == INVALID_SOCKET) {
|
||||||
} else if ((c = alloc_conn(mgr, 0, fd)) == NULL) {
|
} else if ((c = alloc_conn(mgr, 0, fd)) == NULL) {
|
||||||
LOG(LL_ERROR, ("OOM %s", url));
|
LOG(LL_ERROR, ("OOM %s", url));
|
||||||
closesocket(fd);
|
closesocket(fd);
|
||||||
} else {
|
} else {
|
||||||
c->fd = (void *) (long) fd;
|
memcpy(&c->peer, &addr, sizeof(struct mg_addr));
|
||||||
|
c->fd = sock2ptr(fd);
|
||||||
c->is_listening = 1;
|
c->is_listening = 1;
|
||||||
c->is_udp = is_udp;
|
c->is_udp = is_udp;
|
||||||
setsockopts(c);
|
|
||||||
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
|
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
|
||||||
c->fn = fn;
|
c->fn = fn;
|
||||||
c->fn_data = fn_data;
|
c->fn_data = fn_data;
|
||||||
LOG(LL_INFO, ("%lu accepting on %s", c->id, url));
|
LOG(LL_INFO,
|
||||||
|
("%lu accepting on %s (port %u)", c->id, url, mg_ntohs(c->peer.port)));
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
||||||
#if MG_ARCH == MG_ARCH_FREERTOS
|
#if MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||||
struct mg_connection *c;
|
struct mg_connection *c;
|
||||||
for (c = mgr->conns; c != NULL; c = c->next) {
|
for (c = mgr->conns; c != NULL; c = c->next) {
|
||||||
FreeRTOS_FD_CLR(c->fd, mgr->ss, eSELECT_WRITE);
|
if (c->is_closing || c->is_resolving || FD(c) == INVALID_SOCKET) continue;
|
||||||
|
FreeRTOS_FD_SET(c->fd, mgr->ss, eSELECT_READ | eSELECT_EXCEPT);
|
||||||
if (c->is_connecting || (c->send.len > 0 && c->is_tls_hs == 0))
|
if (c->is_connecting || (c->send.len > 0 && c->is_tls_hs == 0))
|
||||||
FreeRTOS_FD_SET(c->fd, mgr->ss, eSELECT_WRITE);
|
FreeRTOS_FD_SET(c->fd, mgr->ss, eSELECT_WRITE);
|
||||||
}
|
}
|
||||||
@@ -481,6 +497,8 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
|||||||
EventBits_t bits = FreeRTOS_FD_ISSET(c->fd, mgr->ss);
|
EventBits_t bits = FreeRTOS_FD_ISSET(c->fd, mgr->ss);
|
||||||
c->is_readable = bits & (eSELECT_READ | eSELECT_EXCEPT) ? 1 : 0;
|
c->is_readable = bits & (eSELECT_READ | eSELECT_EXCEPT) ? 1 : 0;
|
||||||
c->is_writable = bits & eSELECT_WRITE ? 1 : 0;
|
c->is_writable = bits & eSELECT_WRITE ? 1 : 0;
|
||||||
|
FreeRTOS_FD_CLR(c->fd, mgr->ss,
|
||||||
|
eSELECT_READ | eSELECT_EXCEPT | eSELECT_WRITE);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct timeval tv = {ms / 1000, (ms % 1000) * 1000};
|
struct timeval tv = {ms / 1000, (ms % 1000) * 1000};
|
||||||
@@ -521,8 +539,10 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
|
|||||||
|
|
||||||
static void connect_conn(struct mg_connection *c) {
|
static void connect_conn(struct mg_connection *c) {
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
#if MG_ARCH != MG_ARCH_FREERTOS_TCP
|
||||||
socklen_t len = sizeof(rc);
|
socklen_t len = sizeof(rc);
|
||||||
if (getsockopt(FD(c), SOL_SOCKET, SO_ERROR, (char *) &rc, &len)) rc = 1;
|
if (getsockopt(FD(c), SOL_SOCKET, SO_ERROR, (char *) &rc, &len)) rc = 1;
|
||||||
|
#endif
|
||||||
if (rc == EAGAIN || rc == EWOULDBLOCK) rc = 0;
|
if (rc == EAGAIN || rc == EWOULDBLOCK) rc = 0;
|
||||||
c->is_connecting = 0;
|
c->is_connecting = 0;
|
||||||
if (rc) {
|
if (rc) {
|
||||||
@@ -559,7 +579,7 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
|
|||||||
} else if (c->is_tls_hs) {
|
} else if (c->is_tls_hs) {
|
||||||
if ((c->is_readable || c->is_writable)) mg_tls_handshake(c);
|
if ((c->is_readable || c->is_writable)) mg_tls_handshake(c);
|
||||||
} else {
|
} else {
|
||||||
if (c->is_readable) read_conn(c, ll_read);
|
if (c->is_readable) read_conn(c);
|
||||||
if (c->is_writable) write_conn(c);
|
if (c->is_writable) write_conn(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "log.h"
|
|
||||||
#include "ssi.h"
|
#include "ssi.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#ifndef MG_MAX_SSI_DEPTH
|
#ifndef MG_MAX_SSI_DEPTH
|
||||||
#define MG_MAX_SSI_DEPTH 5
|
#define MG_MAX_SSI_DEPTH 5
|
||||||
@@ -15,9 +16,10 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
|
|||||||
size_t len = 0, align = MG_IO_SIZE;
|
size_t len = 0, align = MG_IO_SIZE;
|
||||||
while ((ch = fgetc(fp)) != EOF) {
|
while ((ch = fgetc(fp)) != EOF) {
|
||||||
if (intag && ch == '>' && buf[len - 1] == '-' && buf[len - 2] == '-') {
|
if (intag && ch == '>' && buf[len - 1] == '-' && buf[len - 2] == '-') {
|
||||||
buf[len++] = ch & 0xff;
|
buf[len++] = (char) (ch & 0xff);
|
||||||
if (sscanf(buf, "<!--#include file=\"%[^\"]", arg)) {
|
if (sscanf(buf, "<!--#include file=\"%[^\"]", arg)) {
|
||||||
char tmp[PATH_MAX], *p = (char *) path + strlen(path), *data;
|
char tmp[MG_PATH_MAX + BUFSIZ + 10],
|
||||||
|
*p = (char *) path + strlen(path), *data;
|
||||||
while (p > path && p[-1] != MG_DIRSEP && p[-1] != '/') p--;
|
while (p > path && p[-1] != MG_DIRSEP && p[-1] != '/') p--;
|
||||||
snprintf(tmp, sizeof(tmp), "%.*s%s", (int) (p - path), path, arg);
|
snprintf(tmp, sizeof(tmp), "%.*s%s", (int) (p - path), path, arg);
|
||||||
if (depth < MG_MAX_SSI_DEPTH &&
|
if (depth < MG_MAX_SSI_DEPTH &&
|
||||||
@@ -28,7 +30,7 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
|
|||||||
LOG(LL_ERROR, ("%s: file=%s error or too deep", path, arg));
|
LOG(LL_ERROR, ("%s: file=%s error or too deep", path, arg));
|
||||||
}
|
}
|
||||||
} else if (sscanf(buf, "<!--#include virtual=\"%[^\"]", arg)) {
|
} else if (sscanf(buf, "<!--#include virtual=\"%[^\"]", arg)) {
|
||||||
char tmp[PATH_MAX], *data;
|
char tmp[MG_PATH_MAX + BUFSIZ + 10], *data;
|
||||||
snprintf(tmp, sizeof(tmp), "%s%s", root, arg);
|
snprintf(tmp, sizeof(tmp), "%s%s", root, arg);
|
||||||
if (depth < MG_MAX_SSI_DEPTH &&
|
if (depth < MG_MAX_SSI_DEPTH &&
|
||||||
(data = mg_ssi(tmp, root, depth + 1)) != NULL) {
|
(data = mg_ssi(tmp, root, depth + 1)) != NULL) {
|
||||||
@@ -48,7 +50,7 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
|
|||||||
intag = 1;
|
intag = 1;
|
||||||
if (len > 0) mg_iobuf_append(&b, buf, len, align);
|
if (len > 0) mg_iobuf_append(&b, buf, len, align);
|
||||||
len = 0;
|
len = 0;
|
||||||
buf[len++] = ch & 0xff;
|
buf[len++] = (char) (ch & 0xff);
|
||||||
} else if (intag) {
|
} else if (intag) {
|
||||||
if (len == 5 && strncmp(buf, "<!--#", 5) != 0) {
|
if (len == 5 && strncmp(buf, "<!--#", 5) != 0) {
|
||||||
intag = 0;
|
intag = 0;
|
||||||
@@ -56,9 +58,9 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
|
|||||||
LOG(LL_ERROR, ("%s: SSI tag is too large", path));
|
LOG(LL_ERROR, ("%s: SSI tag is too large", path));
|
||||||
len = 0;
|
len = 0;
|
||||||
}
|
}
|
||||||
buf[len++] = ch & 0xff;
|
buf[len++] = (char) (ch & 0xff);
|
||||||
} else {
|
} else {
|
||||||
buf[len++] = ch & 0xff;
|
buf[len++] = (char) (ch & 0xff);
|
||||||
if (len >= sizeof(buf)) {
|
if (len >= sizeof(buf)) {
|
||||||
mg_iobuf_append(&b, buf, len, align);
|
mg_iobuf_append(&b, buf, len, align);
|
||||||
len = 0;
|
len = 0;
|
||||||
@@ -76,8 +78,9 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
|
|||||||
|
|
||||||
void mg_http_serve_ssi(struct mg_connection *c, const char *root,
|
void mg_http_serve_ssi(struct mg_connection *c, const char *root,
|
||||||
const char *fullpath) {
|
const char *fullpath) {
|
||||||
|
const char *headers = "Content-Type: text/html; charset=utf-8\r\n";
|
||||||
char *data = mg_ssi(fullpath, root, 0);
|
char *data = mg_ssi(fullpath, root, 0);
|
||||||
mg_http_reply(c, 200, "", "%s", data == NULL ? "" : data);
|
mg_http_reply(c, 200, headers, "%s", data == NULL ? "" : data);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "str.h"
|
#include "str.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
struct mg_str mg_str(const char *s) {
|
struct mg_str mg_str_s(const char *s) {
|
||||||
struct mg_str str = {s, s == NULL ? 0 : strlen(s)};
|
struct mg_str str = {s, s == NULL ? 0 : strlen(s)};
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ int mg_vcasecmp(const struct mg_str *str1, const char *str2) {
|
|||||||
struct mg_str mg_strdup(const struct mg_str s) {
|
struct mg_str mg_strdup(const struct mg_str s) {
|
||||||
struct mg_str r = {NULL, 0};
|
struct mg_str r = {NULL, 0};
|
||||||
if (s.len > 0 && s.ptr != NULL) {
|
if (s.len > 0 && s.ptr != NULL) {
|
||||||
char *sc = (char *) malloc(s.len + 1);
|
char *sc = (char *) calloc(1, s.len + 1);
|
||||||
if (sc != NULL) {
|
if (sc != NULL) {
|
||||||
memcpy(sc, s.ptr, s.len);
|
memcpy(sc, s.ptr, s.len);
|
||||||
sc[s.len] = '\0';
|
sc[s.len] = '\0';
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ struct mg_str {
|
|||||||
#define MG_NULL_STR \
|
#define MG_NULL_STR \
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
|
|
||||||
|
// Using macro to avoid shadowing C++ struct constructor, see #1298
|
||||||
|
#define mg_str(s) mg_str_s(s)
|
||||||
|
|
||||||
struct mg_str mg_str(const char *s);
|
struct mg_str mg_str(const char *s);
|
||||||
struct mg_str mg_str_n(const char *s, size_t n);
|
struct mg_str mg_str_n(const char *s, size_t n);
|
||||||
int mg_lower(const char *s);
|
int mg_lower(const char *s);
|
||||||
|
|||||||
+2
-2
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
struct mg_timer *g_timers;
|
struct mg_timer *g_timers;
|
||||||
|
|
||||||
void mg_timer_init(struct mg_timer *t, int ms, int flags, void (*fn)(void *),
|
void mg_timer_init(struct mg_timer *t, unsigned long ms, unsigned flags,
|
||||||
void *arg) {
|
void (*fn)(void *), void *arg) {
|
||||||
struct mg_timer tmp = {ms, flags, fn, arg, 0UL, g_timers};
|
struct mg_timer tmp = {ms, flags, fn, arg, 0UL, g_timers};
|
||||||
*t = tmp;
|
*t = tmp;
|
||||||
g_timers = t;
|
g_timers = t;
|
||||||
|
|||||||
+5
-4
@@ -1,18 +1,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
struct mg_timer {
|
struct mg_timer {
|
||||||
int period_ms; // Timer period in milliseconds
|
unsigned long period_ms; // Timer period in milliseconds
|
||||||
int flags; // Possible flags values below
|
unsigned flags; // Possible flags values below
|
||||||
#define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once
|
#define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once
|
||||||
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
|
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
|
||||||
void (*fn)(void *); // Function to call
|
void (*fn)(void *); // Function to call
|
||||||
void *arg; // Function agrument
|
void *arg; // Function argument
|
||||||
unsigned long expire; // Expiration timestamp in milliseconds
|
unsigned long expire; // Expiration timestamp in milliseconds
|
||||||
struct mg_timer *next; // Linkage in g_timers list
|
struct mg_timer *next; // Linkage in g_timers list
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct mg_timer *g_timers; // Global list of timers
|
extern struct mg_timer *g_timers; // Global list of timers
|
||||||
|
|
||||||
void mg_timer_init(struct mg_timer *, int ms, int, void (*fn)(void *), void *);
|
void mg_timer_init(struct mg_timer *, unsigned long ms, unsigned,
|
||||||
|
void (*fn)(void *), void *);
|
||||||
void mg_timer_free(struct mg_timer *);
|
void mg_timer_free(struct mg_timer *);
|
||||||
void mg_timer_poll(unsigned long uptime_ms);
|
void mg_timer_poll(unsigned long uptime_ms);
|
||||||
@@ -8,7 +8,6 @@
|
|||||||
#include <mbedtls/debug.h>
|
#include <mbedtls/debug.h>
|
||||||
#include <mbedtls/ssl.h>
|
#include <mbedtls/ssl.h>
|
||||||
|
|
||||||
// Different versions have those in different files, so declare here
|
|
||||||
#ifndef EXTERN_C
|
#ifndef EXTERN_C
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define EXTERN_C extern "C"
|
#define EXTERN_C extern "C"
|
||||||
@@ -17,6 +16,13 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||||
|
#define RNG , rng_get, NULL
|
||||||
|
#else
|
||||||
|
#define RNG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Different versions have those in different files, so declare here
|
||||||
EXTERN_C int mbedtls_net_recv(void *, unsigned char *, size_t);
|
EXTERN_C int mbedtls_net_recv(void *, unsigned char *, size_t);
|
||||||
EXTERN_C int mbedtls_net_send(void *, const unsigned char *, size_t);
|
EXTERN_C int mbedtls_net_send(void *, const unsigned char *, size_t);
|
||||||
|
|
||||||
@@ -29,7 +35,7 @@ struct mg_tls {
|
|||||||
mbedtls_pk_context pk; // Private key context
|
mbedtls_pk_context pk; // Private key context
|
||||||
};
|
};
|
||||||
|
|
||||||
int mg_tls_handshake(struct mg_connection *c) {
|
void mg_tls_handshake(struct mg_connection *c) {
|
||||||
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
||||||
int rc;
|
int rc;
|
||||||
mbedtls_ssl_set_bio(&tls->ssl, &c->fd, mbedtls_net_send, mbedtls_net_recv, 0);
|
mbedtls_ssl_set_bio(&tls->ssl, &c->fd, mbedtls_net_send, mbedtls_net_recv, 0);
|
||||||
@@ -44,7 +50,6 @@ int mg_tls_handshake(struct mg_connection *c) {
|
|||||||
} else {
|
} else {
|
||||||
mg_error(c, "TLS handshake: -%#x", -rc); // Error
|
mg_error(c, "TLS handshake: -%#x", -rc); // Error
|
||||||
}
|
}
|
||||||
return rc == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mbed_rng(void *ctx, unsigned char *buf, size_t len) {
|
static int mbed_rng(void *ctx, unsigned char *buf, size_t len) {
|
||||||
@@ -54,30 +59,48 @@ static int mbed_rng(void *ctx, unsigned char *buf, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void debug_cb(void *c, int lev, const char *s, int n, const char *s2) {
|
static void debug_cb(void *c, int lev, const char *s, int n, const char *s2) {
|
||||||
n = strlen(s2) - 1;
|
n = (int) strlen(s2) - 1;
|
||||||
LOG(LL_VERBOSE_DEBUG, ("%p %.*s", ((struct mg_connection *) c)->fd, n, s2));
|
LOG(LL_VERBOSE_DEBUG, ("%p %.*s", ((struct mg_connection *) c)->fd, n, s2));
|
||||||
(void) s;
|
(void) s;
|
||||||
(void) c;
|
(void) c;
|
||||||
(void) lev;
|
(void) lev;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
|
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||||
|
static int rng_get(void *p_rng, unsigned char *buf, size_t len) {
|
||||||
|
(void) p_rng;
|
||||||
|
mg_random(buf, len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
|
||||||
struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls));
|
struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls));
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
const char *ca = opts->ca == NULL ? "-"
|
||||||
|
: opts->ca[0] == '-' ? "(emb)"
|
||||||
|
: opts->ca;
|
||||||
|
const char *cert = opts->cert == NULL ? "-"
|
||||||
|
: opts->cert[0] == '-' ? "(emb)"
|
||||||
|
: opts->cert;
|
||||||
|
const char *certkey = opts->certkey == NULL ? "-"
|
||||||
|
: opts->certkey[0] == '-' ? "(emb)"
|
||||||
|
: opts->certkey;
|
||||||
if (tls == NULL) {
|
if (tls == NULL) {
|
||||||
mg_error(c, "TLS OOM");
|
mg_error(c, "TLS OOM");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
LOG(LL_DEBUG, ("%lu Setting TLS, CA: %s, cert: %s, key: %s", c->id,
|
LOG(LL_DEBUG, ("%lu Setting TLS, CA: %s, cert: %s, key: %s", c->id, ca,
|
||||||
opts->ca == NULL ? "null" : opts->ca,
|
cert, certkey));
|
||||||
opts->cert == NULL ? "null" : opts->cert,
|
|
||||||
opts->certkey == NULL ? "null" : opts->certkey));
|
|
||||||
mbedtls_ssl_init(&tls->ssl);
|
mbedtls_ssl_init(&tls->ssl);
|
||||||
mbedtls_ssl_config_init(&tls->conf);
|
mbedtls_ssl_config_init(&tls->conf);
|
||||||
|
mbedtls_x509_crt_init(&tls->ca);
|
||||||
|
mbedtls_x509_crt_init(&tls->cert);
|
||||||
|
mbedtls_pk_init(&tls->pk);
|
||||||
mbedtls_ssl_conf_dbg(&tls->conf, debug_cb, c);
|
mbedtls_ssl_conf_dbg(&tls->conf, debug_cb, c);
|
||||||
#if !defined(ESP_PLATFORM)
|
//#if !defined(ESP_PLATFORM)
|
||||||
mbedtls_debug_set_threshold(5);
|
// mbedtls_debug_set_threshold(5);
|
||||||
#endif
|
//#endif
|
||||||
if ((rc = mbedtls_ssl_config_defaults(
|
if ((rc = mbedtls_ssl_config_defaults(
|
||||||
&tls->conf,
|
&tls->conf,
|
||||||
c->is_client ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
|
c->is_client ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
|
||||||
@@ -94,30 +117,47 @@ int mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
|
|||||||
tls->cafile = strdup(opts->ca);
|
tls->cafile = strdup(opts->ca);
|
||||||
rc = mbedtls_ssl_conf_ca_chain_file(&tls->conf, tls->cafile, NULL);
|
rc = mbedtls_ssl_conf_ca_chain_file(&tls->conf, tls->cafile, NULL);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
mg_error(c, "parse on-disk chain(%s) err %#x", opts->ca, -rc);
|
mg_error(c, "parse on-disk chain(%s) err %#x", ca, -rc);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
mbedtls_x509_crt_init(&tls->ca);
|
rc = opts->ca[0] == '-'
|
||||||
if ((rc = mbedtls_x509_crt_parse_file(&tls->ca, opts->ca)) != 0) {
|
? mbedtls_x509_crt_parse(&tls->ca, (uint8_t *) opts->ca,
|
||||||
mg_error(c, "parse(%s) err %#x", opts->ca, -rc);
|
strlen(opts->ca) + 1)
|
||||||
|
: mbedtls_x509_crt_parse_file(&tls->ca, opts->ca);
|
||||||
|
if (rc != 0) {
|
||||||
|
mg_error(c, "parse(%s) err %#x", ca, -rc);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
mbedtls_ssl_conf_ca_chain(&tls->conf, &tls->ca, NULL);
|
mbedtls_ssl_conf_ca_chain(&tls->conf, &tls->ca, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
if (opts->srvname.len > 0) {
|
||||||
|
char mem[128], *buf = mem;
|
||||||
|
mg_asprintf(&buf, sizeof(mem), "%.*s", (int) opts->srvname.len, opts->srvname.ptr);
|
||||||
|
mbedtls_ssl_set_hostname(&tls->ssl, buf);
|
||||||
|
if (buf != mem) free(buf);
|
||||||
|
}
|
||||||
mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||||
}
|
}
|
||||||
if (opts->cert != NULL && opts->cert[0] != '\0') {
|
if (opts->cert != NULL && opts->cert[0] != '\0') {
|
||||||
const char *key = opts->certkey;
|
const char *key = opts->certkey;
|
||||||
if (key == NULL) key = opts->cert;
|
if (key == NULL) {
|
||||||
mbedtls_x509_crt_init(&tls->cert);
|
key = opts->cert;
|
||||||
mbedtls_pk_init(&tls->pk);
|
certkey = cert;
|
||||||
if ((rc = mbedtls_x509_crt_parse_file(&tls->cert, opts->cert)) != 0) {
|
}
|
||||||
mg_error(c, "parse(%s) err %#x", opts->cert, -rc);
|
rc = opts->cert[0] == '-'
|
||||||
|
? mbedtls_x509_crt_parse(&tls->cert, (uint8_t *) opts->cert,
|
||||||
|
strlen(opts->cert) + 1)
|
||||||
|
: mbedtls_x509_crt_parse_file(&tls->cert, opts->cert);
|
||||||
|
if (rc != 0) {
|
||||||
|
mg_error(c, "parse(%s) err %#x", cert, -rc);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if ((rc = mbedtls_pk_parse_keyfile(&tls->pk, key, NULL)) != 0) {
|
rc = key[0] == '-' ? mbedtls_pk_parse_key(&tls->pk, (uint8_t *) key,
|
||||||
mg_error(c, "tls key(%s) %#x", key, -rc);
|
strlen(key) + 1, NULL, 0 RNG)
|
||||||
|
: mbedtls_pk_parse_keyfile(&tls->pk, key, NULL RNG);
|
||||||
|
if (rc != 0) {
|
||||||
|
mg_error(c, "tls key(%s) %#x", certkey, -rc);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
rc = mbedtls_ssl_conf_own_cert(&tls->conf, &tls->cert, &tls->pk);
|
rc = mbedtls_ssl_conf_own_cert(&tls->conf, &tls->cert, &tls->pk);
|
||||||
@@ -136,49 +176,40 @@ int mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
|
|||||||
if (c->is_client && c->is_resolving == 0 && c->is_connecting == 0) {
|
if (c->is_client && c->is_resolving == 0 && c->is_connecting == 0) {
|
||||||
mg_tls_handshake(c);
|
mg_tls_handshake(c);
|
||||||
}
|
}
|
||||||
return 1;
|
return;
|
||||||
fail:
|
fail:
|
||||||
c->is_closing = 1;
|
c->is_closing = 1;
|
||||||
free(tls);
|
free(tls);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_tls_recv(struct mg_connection *c, void *buf, size_t len, int *fail) {
|
long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
|
||||||
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
||||||
int n = mbedtls_ssl_read(&tls->ssl, (unsigned char *) buf, len);
|
long n = mbedtls_ssl_read(&tls->ssl, (unsigned char *) buf, len);
|
||||||
*fail = (n == 0) || (n < 0 && n != MBEDTLS_ERR_SSL_WANT_READ);
|
return n == 0 ? -1 : n == MBEDTLS_ERR_SSL_WANT_READ ? 0 : n;
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_tls_send(struct mg_connection *c, const void *buf, size_t len,
|
long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||||
int *fail) {
|
|
||||||
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
||||||
int n = mbedtls_ssl_write(&tls->ssl, (unsigned char *) buf, len);
|
long n = mbedtls_ssl_write(&tls->ssl, (unsigned char *) buf, len);
|
||||||
*fail = (n == 0) || (n < 0 && n != MBEDTLS_ERR_SSL_WANT_WRITE);
|
return n == 0 ? -1 : n == MBEDTLS_ERR_SSL_WANT_WRITE ? 0 : n;
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_tls_free(struct mg_connection *c) {
|
void mg_tls_free(struct mg_connection *c) {
|
||||||
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
||||||
if (tls == NULL) return 0;
|
if (tls == NULL) return;
|
||||||
free(tls->cafile);
|
free(tls->cafile);
|
||||||
mbedtls_x509_crt_free(&tls->ca);
|
|
||||||
mbedtls_x509_crt_free(&tls->cert);
|
|
||||||
mbedtls_ssl_free(&tls->ssl);
|
mbedtls_ssl_free(&tls->ssl);
|
||||||
mbedtls_pk_free(&tls->pk);
|
mbedtls_pk_free(&tls->pk);
|
||||||
|
mbedtls_x509_crt_free(&tls->ca);
|
||||||
|
mbedtls_x509_crt_free(&tls->cert);
|
||||||
mbedtls_ssl_config_free(&tls->conf);
|
mbedtls_ssl_config_free(&tls->conf);
|
||||||
free(tls);
|
free(tls);
|
||||||
return 1;
|
c->tls = NULL;
|
||||||
}
|
}
|
||||||
#elif MG_ENABLE_OPENSSL ///////////////////////////////////////// OPENSSL
|
#elif MG_ENABLE_OPENSSL ///////////////////////////////////////// OPENSSL
|
||||||
|
|
||||||
|
#include <openssl/err.h>
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1700
|
|
||||||
typedef long ssize_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void ERR_clear_error(void); // Defined in openssl/err.h, but
|
|
||||||
extern void ERR_print_errors_fp(FILE *fp); // declare here for krypton
|
|
||||||
|
|
||||||
struct mg_tls {
|
struct mg_tls {
|
||||||
SSL_CTX *ctx;
|
SSL_CTX *ctx;
|
||||||
@@ -201,7 +232,7 @@ static int mg_tls_err(struct mg_tls *tls, int res) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
|
void mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
|
||||||
struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls));
|
struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls));
|
||||||
const char *id = "mongoose";
|
const char *id = "mongoose";
|
||||||
static unsigned char s_initialised = 0;
|
static unsigned char s_initialised = 0;
|
||||||
@@ -226,11 +257,13 @@ int mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
|
|||||||
mg_error(c, "SSL_new");
|
mg_error(c, "SSL_new");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
SSL_set_session_id_context(tls->ssl, (const uint8_t *) id, strlen(id));
|
SSL_set_session_id_context(tls->ssl, (const uint8_t *) id,
|
||||||
|
(unsigned) strlen(id));
|
||||||
// Disable deprecated protocols
|
// Disable deprecated protocols
|
||||||
SSL_set_options(tls->ssl, SSL_OP_NO_SSLv2);
|
SSL_set_options(tls->ssl, SSL_OP_NO_SSLv2);
|
||||||
SSL_set_options(tls->ssl, SSL_OP_NO_SSLv3);
|
SSL_set_options(tls->ssl, SSL_OP_NO_SSLv3);
|
||||||
SSL_set_options(tls->ssl, SSL_OP_NO_TLSv1);
|
SSL_set_options(tls->ssl, SSL_OP_NO_TLSv1);
|
||||||
|
SSL_set_options(tls->ssl, SSL_OP_NO_TLSv1_1);
|
||||||
#ifdef MG_ENABLE_OPENSSL_NO_COMPRESSION
|
#ifdef MG_ENABLE_OPENSSL_NO_COMPRESSION
|
||||||
SSL_set_options(tls->ssl, SSL_OP_NO_COMPRESSION);
|
SSL_set_options(tls->ssl, SSL_OP_NO_COMPRESSION);
|
||||||
#endif
|
#endif
|
||||||
@@ -238,9 +271,9 @@ int mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
|
|||||||
SSL_set_options(tls->ssl, SSL_OP_CIPHER_SERVER_PREFERENCE);
|
SSL_set_options(tls->ssl, SSL_OP_CIPHER_SERVER_PREFERENCE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SSL_set_verify(tls->ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
|
|
||||||
0);
|
|
||||||
if (opts->ca != NULL && opts->ca[0] != '\0') {
|
if (opts->ca != NULL && opts->ca[0] != '\0') {
|
||||||
|
SSL_set_verify(tls->ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
|
||||||
|
NULL);
|
||||||
if ((rc = SSL_CTX_load_verify_locations(tls->ctx, opts->ca, NULL)) != 1) {
|
if ((rc = SSL_CTX_load_verify_locations(tls->ctx, opts->ca, NULL)) != 1) {
|
||||||
mg_error(c, "parse(%s): err %d", opts->ca, mg_tls_err(tls, rc));
|
mg_error(c, "parse(%s): err %d", opts->ca, mg_tls_err(tls, rc));
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -255,7 +288,7 @@ int mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
|
|||||||
} else if ((rc = SSL_use_PrivateKey_file(tls->ssl, key, 1)) != 1) {
|
} else if ((rc = SSL_use_PrivateKey_file(tls->ssl, key, 1)) != 1) {
|
||||||
mg_error(c, "Invalid SSL key, err %d", mg_tls_err(tls, rc));
|
mg_error(c, "Invalid SSL key, err %d", mg_tls_err(tls, rc));
|
||||||
goto fail;
|
goto fail;
|
||||||
#if OPENSSL_VERSION_NUMBER > 0x10002000L
|
#if OPENSSL_VERSION_NUMBER > 0x10100000L
|
||||||
} else if ((rc = SSL_use_certificate_chain_file(tls->ssl, opts->cert)) !=
|
} else if ((rc = SSL_use_certificate_chain_file(tls->ssl, opts->cert)) !=
|
||||||
1) {
|
1) {
|
||||||
mg_error(c, "Invalid CA, err %d", mg_tls_err(tls, rc));
|
mg_error(c, "Invalid CA, err %d", mg_tls_err(tls, rc));
|
||||||
@@ -269,7 +302,12 @@ int mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opts->ciphers != NULL) SSL_set_cipher_list(tls->ssl, opts->ciphers);
|
if (opts->ciphers != NULL) SSL_set_cipher_list(tls->ssl, opts->ciphers);
|
||||||
if (opts->srvname != NULL) SSL_set_tlsext_host_name(tls->ssl, opts->srvname);
|
if (opts->srvname.len > 0) {
|
||||||
|
char mem[128], *buf = mem;
|
||||||
|
mg_asprintf(&buf, sizeof(mem), "%.*s", (int) opts->srvname.len, opts->srvname.ptr);
|
||||||
|
SSL_set_tlsext_host_name(tls->ssl, buf);
|
||||||
|
if (buf != mem) free(buf);
|
||||||
|
}
|
||||||
c->tls = tls;
|
c->tls = tls;
|
||||||
c->is_tls = 1;
|
c->is_tls = 1;
|
||||||
c->is_tls_hs = 1;
|
c->is_tls_hs = 1;
|
||||||
@@ -278,75 +316,65 @@ int mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
|
|||||||
}
|
}
|
||||||
c->is_hexdumping = 1;
|
c->is_hexdumping = 1;
|
||||||
LOG(LL_DEBUG, ("%lu SSL %s OK", c->id, c->is_accepted ? "accept" : "client"));
|
LOG(LL_DEBUG, ("%lu SSL %s OK", c->id, c->is_accepted ? "accept" : "client"));
|
||||||
return 1;
|
return;
|
||||||
fail:
|
fail:
|
||||||
c->is_closing = 1;
|
c->is_closing = 1;
|
||||||
free(tls);
|
free(tls);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_tls_handshake(struct mg_connection *c) {
|
void mg_tls_handshake(struct mg_connection *c) {
|
||||||
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
||||||
int rc;
|
int rc;
|
||||||
SSL_set_fd(tls->ssl, (ssize_t) c->fd);
|
SSL_set_fd(tls->ssl, (int) (long) c->fd);
|
||||||
rc = c->is_client ? SSL_connect(tls->ssl) : SSL_accept(tls->ssl);
|
rc = c->is_client ? SSL_connect(tls->ssl) : SSL_accept(tls->ssl);
|
||||||
if (rc == 1) {
|
if (rc == 1) {
|
||||||
LOG(LL_DEBUG, ("%lu success", c->id));
|
LOG(LL_DEBUG, ("%lu success", c->id));
|
||||||
c->is_tls_hs = 0;
|
c->is_tls_hs = 0;
|
||||||
return 1;
|
|
||||||
} else {
|
} else {
|
||||||
int code;
|
int code;
|
||||||
ERR_print_errors_fp(stderr);
|
ERR_print_errors_fp(stderr);
|
||||||
code = mg_tls_err(tls, rc);
|
code = mg_tls_err(tls, rc);
|
||||||
if (code != 0) mg_error(c, "tls hs: rc %d, err %d", rc, code);
|
if (code != 0) mg_error(c, "tls hs: rc %d, err %d", rc, code);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_tls_free(struct mg_connection *c) {
|
void mg_tls_free(struct mg_connection *c) {
|
||||||
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
||||||
if (tls == NULL) return 0;
|
if (tls == NULL) return;
|
||||||
SSL_free(tls->ssl);
|
SSL_free(tls->ssl);
|
||||||
SSL_CTX_free(tls->ctx);
|
SSL_CTX_free(tls->ctx);
|
||||||
free(tls);
|
free(tls);
|
||||||
return 1;
|
c->tls = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_tls_recv(struct mg_connection *c, void *buf, size_t len, int *fail) {
|
long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
|
||||||
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
||||||
int n = SSL_read(tls->ssl, buf, len);
|
int n = SSL_read(tls->ssl, buf, (int) len);
|
||||||
*fail = (n == 0) || (n < 0 && mg_tls_err(tls, n) != 0);
|
return n == 0 ? -1 : n < 0 && mg_tls_err(tls, n) == 0 ? 0 : n;
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_tls_send(struct mg_connection *c, const void *buf, size_t len,
|
long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||||
int *fail) {
|
|
||||||
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
struct mg_tls *tls = (struct mg_tls *) c->tls;
|
||||||
int n = SSL_write(tls->ssl, buf, len);
|
int n = SSL_write(tls->ssl, buf, (int) len);
|
||||||
*fail = (n == 0) || (n < 0 && mg_tls_err(tls, n) != 0);
|
return n == 0 ? -1 : n < 0 && mg_tls_err(tls, n) == 0 ? 0 : n;
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else ////////////////////////////////////////// NO TLS
|
#else ////////////////////////////////////////// NO TLS
|
||||||
|
|
||||||
int mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
|
void mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
|
||||||
(void) opts;
|
(void) opts;
|
||||||
mg_error(c, "TLS is not enabled");
|
mg_error(c, "TLS is not enabled");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
int mg_tls_handshake(struct mg_connection *c) {
|
void mg_tls_handshake(struct mg_connection *c) {
|
||||||
return c != NULL;
|
(void) c;
|
||||||
}
|
}
|
||||||
int mg_tls_free(struct mg_connection *c) {
|
void mg_tls_free(struct mg_connection *c) {
|
||||||
return c != NULL;
|
(void) c;
|
||||||
}
|
}
|
||||||
int mg_tls_recv(struct mg_connection *c, void *buf, size_t len, int *fail) {
|
long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
|
||||||
*fail = 1;
|
|
||||||
return c == NULL || buf == NULL || len == 0 ? 0 : -1;
|
return c == NULL || buf == NULL || len == 0 ? 0 : -1;
|
||||||
}
|
}
|
||||||
int mg_tls_send(struct mg_connection *c, const void *buf, size_t len,
|
long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||||
int *fail) {
|
|
||||||
*fail = 1;
|
|
||||||
return c == NULL || buf == NULL || len == 0 ? 0 : -1;
|
return c == NULL || buf == NULL || len == 0 ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,15 @@
|
|||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
|
||||||
struct mg_tls_opts {
|
struct mg_tls_opts {
|
||||||
const char *ca; // CA certificate file. For both listeners and clients
|
const char *ca; // CA certificate file. For both listeners and clients
|
||||||
const char *cert; // Certificate
|
const char *cert; // Certificate
|
||||||
const char *certkey; // Certificate key
|
const char *certkey; // Certificate key
|
||||||
const char *ciphers; // Cipher list
|
const char *ciphers; // Cipher list
|
||||||
const char *srvname; // If not NULL, enables server name verification
|
struct mg_str srvname; // If not empty, enables server name verification
|
||||||
};
|
};
|
||||||
|
|
||||||
int mg_tls_init(struct mg_connection *, struct mg_tls_opts *);
|
void mg_tls_init(struct mg_connection *, struct mg_tls_opts *);
|
||||||
int mg_tls_free(struct mg_connection *);
|
void mg_tls_free(struct mg_connection *);
|
||||||
int mg_tls_send(struct mg_connection *, const void *buf, size_t len, int *fail);
|
long mg_tls_send(struct mg_connection *, const void *buf, size_t len);
|
||||||
int mg_tls_recv(struct mg_connection *, void *buf, size_t len, int *fail);
|
long mg_tls_recv(struct mg_connection *, void *buf, size_t len);
|
||||||
int mg_tls_handshake(struct mg_connection *);
|
void mg_tls_handshake(struct mg_connection *);
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
#include "url.h"
|
#include "url.h"
|
||||||
|
|
||||||
struct url {
|
struct url {
|
||||||
int key, user, pass, host, port, uri, end;
|
size_t key, user, pass, host, port, uri, end;
|
||||||
};
|
};
|
||||||
|
|
||||||
int mg_url_is_ssl(const char *url) {
|
int mg_url_is_ssl(const char *url) {
|
||||||
@@ -12,23 +12,23 @@ int mg_url_is_ssl(const char *url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct url urlparse(const char *url) {
|
static struct url urlparse(const char *url) {
|
||||||
int i;
|
size_t i;
|
||||||
struct url u;
|
struct url u;
|
||||||
memset(&u, 0, sizeof(u));
|
memset(&u, 0, sizeof(u));
|
||||||
for (i = 0; url[i] != '\0'; i++) {
|
for (i = 0; url[i] != '\0'; i++) {
|
||||||
if (i > 0 && url[i - 1] == '/' && url[i] == '/') {
|
if (i > 0 && u.host == 0 && url[i - 1] == '/' && url[i] == '/') {
|
||||||
u.host = i + 1;
|
u.host = i + 1;
|
||||||
u.port = 0;
|
u.port = 0;
|
||||||
} else if (url[i] == ']') {
|
} else if (url[i] == ']') {
|
||||||
u.port = 0; // IPv6 URLs, like http://[::1]/bar
|
u.port = 0; // IPv6 URLs, like http://[::1]/bar
|
||||||
} else if (url[i] == ':') {
|
} else if (url[i] == ':' && u.port == 0) {
|
||||||
u.port = i + 1;
|
u.port = i + 1;
|
||||||
} else if (url[i] == '@') {
|
} else if (url[i] == '@' && u.user == 0 && u.pass == 0) {
|
||||||
u.user = u.host;
|
u.user = u.host;
|
||||||
u.pass = u.port;
|
u.pass = u.port;
|
||||||
u.host = i + 1;
|
u.host = i + 1;
|
||||||
u.port = 0;
|
u.port = 0;
|
||||||
} else if (u.host && !u.uri && url[i] == '/') {
|
} else if (u.host && u.uri == 0 && url[i] == '/') {
|
||||||
u.uri = i;
|
u.uri = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -41,8 +41,9 @@ static struct url urlparse(const char *url) {
|
|||||||
|
|
||||||
struct mg_str mg_url_host(const char *url) {
|
struct mg_str mg_url_host(const char *url) {
|
||||||
struct url u = urlparse(url);
|
struct url u = urlparse(url);
|
||||||
int n =
|
size_t n = u.port ? u.port - u.host - 1
|
||||||
u.port ? u.port - u.host - 1 : u.uri ? u.uri - u.host : u.end - u.host;
|
: u.uri ? u.uri - u.host
|
||||||
|
: u.end - u.host;
|
||||||
struct mg_str s = mg_str_n(url + u.host, n);
|
struct mg_str s = mg_str_n(url + u.host, n);
|
||||||
if (s.len > 2 && s.ptr[0] == '[' && s.ptr[s.len - 1] == ']') {
|
if (s.len > 2 && s.ptr[0] == '[' && s.ptr[s.len - 1] == ']') {
|
||||||
s.len -= 2;
|
s.len -= 2;
|
||||||
@@ -63,7 +64,7 @@ unsigned short mg_url_port(const char *url) {
|
|||||||
if (memcmp(url, "wss:", 4) == 0 || memcmp(url, "https:", 6) == 0) port = 443;
|
if (memcmp(url, "wss:", 4) == 0 || memcmp(url, "https:", 6) == 0) port = 443;
|
||||||
if (memcmp(url, "mqtt:", 5) == 0) port = 1883;
|
if (memcmp(url, "mqtt:", 5) == 0) port = 1883;
|
||||||
if (memcmp(url, "mqtts:", 6) == 0) port = 8883;
|
if (memcmp(url, "mqtts:", 6) == 0) port = 8883;
|
||||||
if (u.port) port = atoi(url + u.port);
|
if (u.port) port = (unsigned short) atoi(url + u.port);
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ struct mg_str mg_url_user(const char *url) {
|
|||||||
struct url u = urlparse(url);
|
struct url u = urlparse(url);
|
||||||
struct mg_str s = mg_str("");
|
struct mg_str s = mg_str("");
|
||||||
if (u.user && (u.pass || u.host)) {
|
if (u.user && (u.pass || u.host)) {
|
||||||
int n = u.pass ? u.pass - u.user - 1 : u.host - u.user - 1;
|
size_t n = u.pass ? u.pass - u.user - 1 : u.host - u.user - 1;
|
||||||
s = mg_str_n(url + u.user, n);
|
s = mg_str_n(url + u.user, n);
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
@@ -79,9 +80,9 @@ struct mg_str mg_url_user(const char *url) {
|
|||||||
|
|
||||||
struct mg_str mg_url_pass(const char *url) {
|
struct mg_str mg_url_pass(const char *url) {
|
||||||
struct url u = urlparse(url);
|
struct url u = urlparse(url);
|
||||||
struct mg_str s = mg_str("");
|
struct mg_str s = mg_str_n("", 0UL);
|
||||||
if (u.pass && u.host) {
|
if (u.pass && u.host) {
|
||||||
int n = u.host - u.pass - 1;
|
size_t n = u.host - u.pass - 1;
|
||||||
s = mg_str_n(url + u.pass, n);
|
s = mg_str_n(url + u.pass, n);
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
|
|||||||
+119
-62
@@ -1,27 +1,41 @@
|
|||||||
|
#include "config.h" // Must go first - important for test++
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
size_t mg_file_size(const char *path) {
|
#if MG_ENABLE_FS
|
||||||
#if MG_ARCH == MG_ARCH_FREERTOS
|
int mg_stat(const char *path, mg_stat_t *st) {
|
||||||
struct FF_STAT st;
|
#ifdef _WIN32
|
||||||
return ff_stat(path, &st) == 0 ? st.st_size : 0;
|
wchar_t tmp[MG_PATH_MAX];
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, path, -1, tmp, sizeof(tmp) / sizeof(tmp[0]));
|
||||||
|
return _wstati64(tmp, st);
|
||||||
#else
|
#else
|
||||||
struct stat st;
|
return stat(path, st);
|
||||||
return stat(path, &st) == 0 ? st.st_size : 0;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
char *mg_file_read(const char *path) {
|
int64_t mg_file_size(const char *path) {
|
||||||
|
#if MG_ARCH == MG_ARCH_FREERTOS_TCP && defined(MG_ENABLE_FF)
|
||||||
|
struct FF_STAT st;
|
||||||
|
return ff_stat(path, &st) == 0 ? st.st_size : 0;
|
||||||
|
#else
|
||||||
|
mg_stat_t st;
|
||||||
|
return mg_stat(path, &st) == 0 ? st.st_size : 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
char *mg_file_read(const char *path, size_t *sizep) {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *data = NULL;
|
char *data = NULL;
|
||||||
size_t size = mg_file_size(path);
|
size_t size = (size_t) mg_file_size(path);
|
||||||
if ((fp = fopen(path, "rb")) != NULL) {
|
if ((fp = fopen(path, "rb")) != NULL) {
|
||||||
data = (char *) malloc(size + 1);
|
data = (char *) calloc(1, size + 1);
|
||||||
if (data != NULL) {
|
if (data != NULL) {
|
||||||
if (fread(data, 1, size, fp) != size) {
|
if (fread(data, 1, size, fp) != size) {
|
||||||
free(data);
|
free(data);
|
||||||
data = NULL;
|
data = NULL;
|
||||||
} else {
|
} else {
|
||||||
data[size] = '\0';
|
data[size] = '\0';
|
||||||
|
if (sizep != NULL) *sizep = size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@@ -29,36 +43,60 @@ char *mg_file_read(const char *path) {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_file_write(const char *path, const char *fmt, ...) {
|
bool mg_file_write(const char *path, const void *buf, size_t len) {
|
||||||
char tmp[100];
|
bool result = false;
|
||||||
int written = 0;
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
char tmp[MG_PATH_MAX];
|
||||||
snprintf(tmp, sizeof(tmp), "%s.%d", path, rand());
|
snprintf(tmp, sizeof(tmp), "%s.%d", path, rand());
|
||||||
fp = fopen(tmp, "wb");
|
fp = fopen(tmp, "wb");
|
||||||
if (fp != NULL) {
|
if (fp != NULL) {
|
||||||
va_list ap;
|
result = fwrite(buf, 1, len, fp) == len;
|
||||||
va_start(ap, fmt);
|
|
||||||
written = vfprintf(fp, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
remove(path);
|
if (result) {
|
||||||
rename(tmp, path);
|
remove(path);
|
||||||
|
rename(tmp, path);
|
||||||
|
} else {
|
||||||
|
remove(tmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return written;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mg_file_printf(const char *path, const char *fmt, ...) {
|
||||||
|
char tmp[256], *buf = tmp;
|
||||||
|
bool result;
|
||||||
|
int len;
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
len = mg_vasprintf(&buf, sizeof(tmp), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
result = mg_file_write(path, buf, len > 0 ? (size_t) len : 0);
|
||||||
|
if (buf != tmp) free(buf);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif // MG_ENABLE_FS
|
||||||
|
|
||||||
void mg_random(void *buf, size_t len) {
|
void mg_random(void *buf, size_t len) {
|
||||||
|
bool done = false;
|
||||||
|
unsigned char *p = (unsigned char *) buf;
|
||||||
|
#if MG_ARCH == MG_ARCH_ESP32
|
||||||
|
while (len--) *p++ = (unsigned char) (esp_random() & 255);
|
||||||
|
#elif MG_ARCH == MG_ARCH_WIN32
|
||||||
|
#elif MG_ARCH_UNIX && MG_ENABLE_FS
|
||||||
FILE *fp = fopen("/dev/urandom", "rb");
|
FILE *fp = fopen("/dev/urandom", "rb");
|
||||||
size_t i, n = 0;
|
if (fp != NULL) {
|
||||||
if (fp != NULL) n = fread(buf, 1, len, fp);
|
if (fread(buf, 1, len, fp) == len) done = true;
|
||||||
if (fp == NULL || n <= 0) {
|
fclose(fp);
|
||||||
for (i = 0; i < len; i++) ((unsigned char *) buf)[i] = rand() % 0xff;
|
}
|
||||||
|
#endif
|
||||||
|
// Fallback to a pseudo random gen
|
||||||
|
if (!done) {
|
||||||
|
while (len--) *p++ = (unsigned char) (rand() & 255);
|
||||||
}
|
}
|
||||||
if (fp != NULL) fclose(fp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mg_globmatch(const char *s1, int n1, const char *s2, int n2) {
|
bool mg_globmatch(const char *s1, size_t n1, const char *s2, size_t n2) {
|
||||||
int i = 0, j = 0, ni = 0, nj = 0;
|
size_t i = 0, j = 0, ni = 0, nj = 0;
|
||||||
while (i < n1 || j < n2) {
|
while (i < n1 || j < n2) {
|
||||||
if (i < n1 && j < n2 && (s1[i] == '?' || s2[j] == s1[i])) {
|
if (i < n1 && j < n2 && (s1[i] == '?' || s2[j] == s1[i])) {
|
||||||
i++, j++;
|
i++, j++;
|
||||||
@@ -73,21 +111,22 @@ bool mg_globmatch(const char *s1, int n1, const char *s2, int n2) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mg_nextcommaentry(const char *s, int slen, int ofs, int *koff,
|
static size_t mg_nce(const char *s, size_t n, size_t ofs, size_t *koff,
|
||||||
int *klen, int *voff, int *vlen) {
|
size_t *klen, size_t *voff, size_t *vlen) {
|
||||||
int kvlen, kl;
|
size_t kvlen, kl;
|
||||||
for (kvlen = 0; ofs + kvlen < slen && s[ofs + kvlen] != ',';) kvlen++;
|
for (kvlen = 0; ofs + kvlen < n && s[ofs + kvlen] != ',';) kvlen++;
|
||||||
for (kl = 0; kl < kvlen && s[ofs + kl] != '=';) kl++;
|
for (kl = 0; kl < kvlen && s[ofs + kl] != '=';) kl++;
|
||||||
if (koff != NULL) *koff = ofs;
|
if (koff != NULL) *koff = ofs;
|
||||||
if (klen != NULL) *klen = kl;
|
if (klen != NULL) *klen = kl;
|
||||||
if (voff != NULL) *voff = kl < kvlen ? ofs + kl + 1 : 0;
|
if (voff != NULL) *voff = kl < kvlen ? ofs + kl + 1 : 0;
|
||||||
if (vlen != NULL) *vlen = kl < kvlen ? kvlen - kl - 1 : 0;
|
if (vlen != NULL) *vlen = kl < kvlen ? kvlen - kl - 1 : 0;
|
||||||
return ofs >= slen ? slen : ofs + kvlen + 1;
|
ofs += kvlen + 1;
|
||||||
|
return ofs > n ? n : ofs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mg_next_comma_entry(struct mg_str *s, struct mg_str *k, struct mg_str *v) {
|
bool mg_next_comma_entry(struct mg_str *s, struct mg_str *k, struct mg_str *v) {
|
||||||
int koff, klen, voff, vlen;
|
size_t koff = 0, klen = 0, voff = 0, vlen = 0;
|
||||||
int off = mg_nextcommaentry(s->ptr, s->len, 0, &koff, &klen, &voff, &vlen);
|
size_t off = mg_nce(s->ptr, s->len, 0, &koff, &klen, &voff, &vlen);
|
||||||
if (k != NULL) *k = mg_str_n(s->ptr + koff, klen);
|
if (k != NULL) *k = mg_str_n(s->ptr + koff, klen);
|
||||||
if (v != NULL) *v = mg_str_n(s->ptr + voff, vlen);
|
if (v != NULL) *v = mg_str_n(s->ptr + voff, vlen);
|
||||||
*s = mg_str_n(s->ptr + off, s->len - off);
|
*s = mg_str_n(s->ptr + off, s->len - off);
|
||||||
@@ -97,45 +136,47 @@ bool mg_next_comma_entry(struct mg_str *s, struct mg_str *k, struct mg_str *v) {
|
|||||||
uint32_t mg_ntohl(uint32_t net) {
|
uint32_t mg_ntohl(uint32_t net) {
|
||||||
uint8_t data[4] = {0, 0, 0, 0};
|
uint8_t data[4] = {0, 0, 0, 0};
|
||||||
memcpy(&data, &net, sizeof(data));
|
memcpy(&data, &net, sizeof(data));
|
||||||
return ((uint32_t) data[3] << 0) | ((uint32_t) data[2] << 8) |
|
return (((uint32_t) data[3]) << 0) | (((uint32_t) data[2]) << 8) |
|
||||||
((uint32_t) data[1] << 16) | ((uint32_t) data[0] << 24);
|
(((uint32_t) data[1]) << 16) | (((uint32_t) data[0]) << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t mg_ntohs(uint16_t net) {
|
uint16_t mg_ntohs(uint16_t net) {
|
||||||
uint8_t data[2] = {0, 0};
|
uint8_t data[2] = {0, 0};
|
||||||
memcpy(&data, &net, sizeof(data));
|
memcpy(&data, &net, sizeof(data));
|
||||||
return ((uint16_t) data[1] << 0) | ((uint32_t) data[0] << 8);
|
return (uint16_t)((uint16_t) data[1] | (((uint16_t) data[0]) << 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
char *mg_hexdump(const void *buf, size_t len) {
|
char *mg_hexdump(const void *buf, size_t len) {
|
||||||
const unsigned char *p = (const unsigned char *) buf;
|
const unsigned char *p = (const unsigned char *) buf;
|
||||||
size_t i, idx, n = 0, ofs = 0, dlen = len * 5 + 100;
|
size_t i, idx, n = 0, ofs = 0, dlen = len * 5 + 100;
|
||||||
char ascii[17] = "", *dst = (char *) malloc(dlen);
|
char ascii[17] = "", *dst = (char *) calloc(1, dlen);
|
||||||
if (dst == NULL) return dst;
|
if (dst == NULL) return dst;
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
idx = i % 16;
|
idx = i % 16;
|
||||||
if (idx == 0) {
|
if (idx == 0) {
|
||||||
if (i > 0 && dlen > n) n += snprintf(dst + n, dlen - n, " %s\n", ascii);
|
if (i > 0 && dlen > n)
|
||||||
if (dlen > n) n += snprintf(dst + n, dlen - n, "%04x ", (int) (i + ofs));
|
n += (size_t) snprintf(dst + n, dlen - n, " %s\n", ascii);
|
||||||
|
if (dlen > n)
|
||||||
|
n += (size_t) snprintf(dst + n, dlen - n, "%04x ", (int) (i + ofs));
|
||||||
}
|
}
|
||||||
if (dlen < n) break;
|
if (dlen < n) break;
|
||||||
n += snprintf(dst + n, dlen - n, " %02x", p[i]);
|
n += (size_t) snprintf(dst + n, dlen - n, " %02x", p[i]);
|
||||||
ascii[idx] = p[i] < 0x20 || p[i] > 0x7e ? '.' : p[i];
|
ascii[idx] = (char) (p[i] < 0x20 || p[i] > 0x7e ? '.' : p[i]);
|
||||||
ascii[idx + 1] = '\0';
|
ascii[idx + 1] = '\0';
|
||||||
}
|
}
|
||||||
while (i++ % 16) {
|
while (i++ % 16) {
|
||||||
if (n < dlen) n += snprintf(dst + n, dlen - n, "%s", " ");
|
if (n < dlen) n += (size_t) snprintf(dst + n, dlen - n, "%s", " ");
|
||||||
}
|
}
|
||||||
if (n < dlen) n += snprintf(dst + n, dlen - n, " %s\n", ascii);
|
if (n < dlen) n += (size_t) snprintf(dst + n, dlen - n, " %s\n", ascii);
|
||||||
if (n > dlen - 1) n = dlen - 1;
|
if (n > dlen - 1) n = dlen - 1;
|
||||||
dst[n] = '\0';
|
dst[n] = '\0';
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *mg_hex(const void *buf, int len, char *to) {
|
char *mg_hex(const void *buf, size_t len, char *to) {
|
||||||
const unsigned char *p = (const unsigned char *) buf;
|
const unsigned char *p = (const unsigned char *) buf;
|
||||||
static const char *hex = "0123456789abcdef";
|
static const char *hex = "0123456789abcdef";
|
||||||
int i = 0;
|
size_t i = 0;
|
||||||
for (; len--; p++) {
|
for (; len--; p++) {
|
||||||
to[i++] = hex[p[0] >> 4];
|
to[i++] = hex[p[0] >> 4];
|
||||||
to[i++] = hex[p[0] & 0x0f];
|
to[i++] = hex[p[0] & 0x0f];
|
||||||
@@ -144,19 +185,20 @@ char *mg_hex(const void *buf, int len, char *to) {
|
|||||||
return to;
|
return to;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long mg_unhexn(const char *s, int len) {
|
static unsigned char mg_unhex_nimble(unsigned char c) {
|
||||||
|
return (c >= '0' && c <= '9') ? (unsigned char) (c - '0')
|
||||||
|
: (c >= 'A' && c <= 'F') ? (unsigned char) (c - '7')
|
||||||
|
: (unsigned char) (c - 'W');
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long mg_unhexn(const char *s, size_t len) {
|
||||||
unsigned long i = 0, v = 0;
|
unsigned long i = 0, v = 0;
|
||||||
for (i = 0; i < (unsigned long) len; i++) {
|
for (i = 0; i < len; i++) v <<= 4, v |= mg_unhex_nimble(((uint8_t *) s)[i]);
|
||||||
int c = s[i];
|
|
||||||
if (i > 0) v <<= 4;
|
|
||||||
v |= (c >= '0' && c <= '9') ? c - '0'
|
|
||||||
: (c >= 'A' && c <= 'F') ? c - '7' : c - 'W';
|
|
||||||
}
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_unhex(const char *buf, int len, unsigned char *to) {
|
void mg_unhex(const char *buf, size_t len, unsigned char *to) {
|
||||||
int i;
|
size_t i;
|
||||||
for (i = 0; i < len; i += 2) {
|
for (i = 0; i < len; i += 2) {
|
||||||
to[i >> 1] = (unsigned char) mg_unhexn(&buf[i], 2);
|
to[i >> 1] = (unsigned char) mg_unhexn(&buf[i], 2);
|
||||||
}
|
}
|
||||||
@@ -180,7 +222,7 @@ int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap) {
|
|||||||
free(*buf);
|
free(*buf);
|
||||||
if (size == 0) size = 5;
|
if (size == 0) size = 5;
|
||||||
size *= 2;
|
size *= 2;
|
||||||
if ((*buf = (char *) malloc(size)) == NULL) {
|
if ((*buf = (char *) calloc(1, size)) == NULL) {
|
||||||
len = -1;
|
len = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -194,11 +236,11 @@ int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap) {
|
|||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
} else if (len >= (int) size) {
|
} else if (len >= (int) size) {
|
||||||
/// Standard-compliant code path. Allocate a buffer that is large enough
|
/// Standard-compliant code path. Allocate a buffer that is large enough
|
||||||
if ((*buf = (char *) malloc(len + 1)) == NULL) {
|
if ((*buf = (char *) calloc(1, (size_t) len + 1)) == NULL) {
|
||||||
len = -1; // LCOV_EXCL_LINE
|
len = -1; // LCOV_EXCL_LINE
|
||||||
} else { // LCOV_EXCL_LINE
|
} else { // LCOV_EXCL_LINE
|
||||||
va_copy(ap_copy, ap);
|
va_copy(ap_copy, ap);
|
||||||
len = vsnprintf(*buf, len + 1, fmt, ap_copy);
|
len = vsnprintf(*buf, (size_t) len + 1, fmt, ap_copy);
|
||||||
va_end(ap_copy);
|
va_end(ap_copy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,11 +258,12 @@ int mg_asprintf(char **buf, size_t size, const char *fmt, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t mg_to64(struct mg_str str) {
|
int64_t mg_to64(struct mg_str str) {
|
||||||
int64_t result = 0, neg = 1;
|
int64_t result = 0, neg = 1, max = 922337203685477570 /* INT64_MAX/10-10 */;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while (i < str.len && (str.ptr[i] == ' ' || str.ptr[i] == '\t')) i++;
|
while (i < str.len && (str.ptr[i] == ' ' || str.ptr[i] == '\t')) i++;
|
||||||
if (i < str.len && str.ptr[i] == '-') neg = -1, i++;
|
if (i < str.len && str.ptr[i] == '-') neg = -1, i++;
|
||||||
while (i < str.len && str.ptr[i] >= '0' && str.ptr[i] <= '9') {
|
while (i < str.len && str.ptr[i] >= '0' && str.ptr[i] <= '9') {
|
||||||
|
if (result > max) return 0;
|
||||||
result *= 10;
|
result *= 10;
|
||||||
result += (str.ptr[i] - '0');
|
result += (str.ptr[i] - '0');
|
||||||
i++;
|
i++;
|
||||||
@@ -228,6 +271,16 @@ int64_t mg_to64(struct mg_str str) {
|
|||||||
return result * neg;
|
return result * neg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len) {
|
||||||
|
int i;
|
||||||
|
crc = ~crc;
|
||||||
|
while (len--) {
|
||||||
|
crc ^= *(unsigned char *) buf++;
|
||||||
|
for (i = 0; i < 8; i++) crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
|
||||||
|
}
|
||||||
|
return ~crc;
|
||||||
|
}
|
||||||
|
|
||||||
double mg_time(void) {
|
double mg_time(void) {
|
||||||
#if MG_ARCH == MG_ARCH_WIN32
|
#if MG_ARCH == MG_ARCH_WIN32
|
||||||
SYSTEMTIME sysnow;
|
SYSTEMTIME sysnow;
|
||||||
@@ -246,6 +299,8 @@ double mg_time(void) {
|
|||||||
((int64_t) ftime.dwHighDateTime << 32)) /
|
((int64_t) ftime.dwHighDateTime << 32)) /
|
||||||
10000000.0) -
|
10000000.0) -
|
||||||
11644473600;
|
11644473600;
|
||||||
|
#elif MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||||
|
return mg_millis() / 1000.0;
|
||||||
#else
|
#else
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
if (gettimeofday(&tv, NULL /* tz */) != 0) return 0;
|
if (gettimeofday(&tv, NULL /* tz */) != 0) return 0;
|
||||||
@@ -258,8 +313,10 @@ void mg_usleep(unsigned long usecs) {
|
|||||||
Sleep(usecs / 1000);
|
Sleep(usecs / 1000);
|
||||||
#elif MG_ARCH == MG_ARCH_ESP8266
|
#elif MG_ARCH == MG_ARCH_ESP8266
|
||||||
ets_delay_us(usecs);
|
ets_delay_us(usecs);
|
||||||
|
#elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_FREERTOS_LWIP
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(usecs / 1000));
|
||||||
#else
|
#else
|
||||||
usleep(usecs);
|
usleep((useconds_t) usecs);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,13 +326,13 @@ unsigned long mg_millis(void) {
|
|||||||
#elif MG_ARCH == MG_ARCH_ESP32
|
#elif MG_ARCH == MG_ARCH_ESP32
|
||||||
return esp_timer_get_time() / 1000;
|
return esp_timer_get_time() / 1000;
|
||||||
#elif MG_ARCH == MG_ARCH_ESP8266
|
#elif MG_ARCH == MG_ARCH_ESP8266
|
||||||
// return system_get_time() / 1000;
|
|
||||||
return xTaskGetTickCount() * portTICK_PERIOD_MS;
|
return xTaskGetTickCount() * portTICK_PERIOD_MS;
|
||||||
#elif MG_ARCH == MG_ARCH_FREERTOS
|
#elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_FREERTOS_LWIP
|
||||||
return xTaskGetTickCount() * portTICK_PERIOD_MS;
|
return xTaskGetTickCount() * portTICK_PERIOD_MS;
|
||||||
#else
|
#else
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
clock_gettime(CLOCK_REALTIME, &ts);
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
|
return (unsigned long) ((uint64_t) ts.tv_sec * 1000 +
|
||||||
|
(uint64_t) ts.tv_nsec / 1000000);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
+37
-27
@@ -3,18 +3,33 @@
|
|||||||
#include "arch.h"
|
#include "arch.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
|
|
||||||
char *mg_file_read(const char *path);
|
// WEAK symbol makes it possible to define a "default" function implementation,
|
||||||
size_t mg_file_size(const char *path);
|
// which could be overridden by the user who can define a function with the
|
||||||
int mg_file_write(const char *path, const char *fmt, ...);
|
// same name without linking conflict
|
||||||
void mg_random(void *buf, size_t len);
|
#if !defined(WEAK)
|
||||||
bool mg_globmatch(const char *pattern, int plen, const char *s, int n);
|
#if (defined(__GNUC__) || defined(__clang__) || \
|
||||||
|
defined(__TI_COMPILER_VERSION__)) && \
|
||||||
|
!defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
#define WEAK __attribute__((weak))
|
||||||
|
#else
|
||||||
|
#define WEAK
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char *mg_file_read(const char *path, size_t *size);
|
||||||
|
int64_t mg_file_size(const char *path);
|
||||||
|
bool mg_file_write(const char *path, const void *buf, size_t len);
|
||||||
|
bool mg_file_printf(const char *path, const char *fmt, ...);
|
||||||
|
void mg_random(void *buf, size_t len) WEAK;
|
||||||
|
bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n);
|
||||||
bool mg_next_comma_entry(struct mg_str *s, struct mg_str *k, struct mg_str *v);
|
bool mg_next_comma_entry(struct mg_str *s, struct mg_str *k, struct mg_str *v);
|
||||||
uint16_t mg_ntohs(uint16_t net);
|
uint16_t mg_ntohs(uint16_t net);
|
||||||
uint32_t mg_ntohl(uint32_t net);
|
uint32_t mg_ntohl(uint32_t net);
|
||||||
|
uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
|
||||||
char *mg_hexdump(const void *buf, size_t len);
|
char *mg_hexdump(const void *buf, size_t len);
|
||||||
char *mg_hex(const void *buf, int len, char *dst);
|
char *mg_hex(const void *buf, size_t len, char *dst);
|
||||||
void mg_unhex(const char *buf, int len, unsigned char *to);
|
void mg_unhex(const char *buf, size_t len, unsigned char *to);
|
||||||
unsigned long mg_unhexn(const char *s, int len);
|
unsigned long mg_unhexn(const char *s, size_t len);
|
||||||
int mg_asprintf(char **buf, size_t size, const char *fmt, ...);
|
int mg_asprintf(char **buf, size_t size, const char *fmt, ...);
|
||||||
int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap);
|
int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap);
|
||||||
int64_t mg_to64(struct mg_str str);
|
int64_t mg_to64(struct mg_str str);
|
||||||
@@ -22,23 +37,18 @@ double mg_time(void);
|
|||||||
unsigned long mg_millis(void);
|
unsigned long mg_millis(void);
|
||||||
void mg_usleep(unsigned long usecs);
|
void mg_usleep(unsigned long usecs);
|
||||||
|
|
||||||
|
#if MG_ENABLE_FS
|
||||||
|
#ifdef _WIN32
|
||||||
|
typedef struct _stati64 mg_stat_t;
|
||||||
|
#else
|
||||||
|
typedef struct stat mg_stat_t;
|
||||||
|
#endif
|
||||||
|
int mg_stat(const char *path, mg_stat_t *);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define mg_htons(x) mg_ntohs(x)
|
#define mg_htons(x) mg_ntohs(x)
|
||||||
#define mg_htonl(x) mg_ntohl(x)
|
#define mg_htonl(x) mg_ntohl(x)
|
||||||
|
|
||||||
#define MG_SWAP16(x) ((((x) >> 8) & 255) | ((x & 255) << 8))
|
|
||||||
#define MG_SWAP32(x) \
|
|
||||||
(((x) >> 24) | (((x) &0xff0000) >> 8) | (((x) &0xff00) << 8) | ((x) << 24))
|
|
||||||
|
|
||||||
#if !defined(WEAK)
|
|
||||||
#if (defined(__GNUC__) || defined(__clang__) || \
|
|
||||||
defined(__TI_COMPILER_VERSION__)) && \
|
|
||||||
!defined(_WIN32)
|
|
||||||
#define WEAK __attribute__((weak))
|
|
||||||
#else
|
|
||||||
#define WEAK
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Expands to a string representation of its argument: e.g.
|
// Expands to a string representation of its argument: e.g.
|
||||||
// MG_STRINGIFY_LITERAL(5) expands to "5"
|
// MG_STRINGIFY_LITERAL(5) expands to "5"
|
||||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||||
@@ -46,7 +56,12 @@ void mg_usleep(unsigned long usecs);
|
|||||||
#else
|
#else
|
||||||
#define MG_STRINGIFY_LITERAL(x) #x
|
#define MG_STRINGIFY_LITERAL(x) #x
|
||||||
#endif
|
#endif
|
||||||
|
// Expands to a string representation of its argument, which can be a macro:
|
||||||
|
// #define FOO 123
|
||||||
|
// MG_STRINGIFY_MACRO(FOO) // Expands to 123
|
||||||
|
#define MG_STRINGIFY_MACRO(x) MG_STRINGIFY_LITERAL(x)
|
||||||
|
|
||||||
|
// Linked list management macros
|
||||||
#define LIST_ADD_HEAD(type_, head_, elem_) \
|
#define LIST_ADD_HEAD(type_, head_, elem_) \
|
||||||
do { \
|
do { \
|
||||||
(elem_)->next = (*head_); \
|
(elem_)->next = (*head_); \
|
||||||
@@ -66,8 +81,3 @@ void mg_usleep(unsigned long usecs);
|
|||||||
while (*h != (elem_)) h = &(*h)->next; \
|
while (*h != (elem_)) h = &(*h)->next; \
|
||||||
*h = (elem_)->next; \
|
*h = (elem_)->next; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
// Expands to a string representation of its argument, which can be a macro:
|
|
||||||
// #define FOO 123
|
|
||||||
// MG_STRINGIFY_MACRO(FOO) // Expands to 123
|
|
||||||
#define MG_STRINGIFY_MACRO(x) MG_STRINGIFY_LITERAL(x)
|
|
||||||
+9
-2
@@ -1,2 +1,9 @@
|
|||||||
#pragma once
|
|
||||||
#define MG_VERSION "7.1"
|
#ifndef MONGOOSE_H
|
||||||
|
#define MONGOOSE_H
|
||||||
|
|
||||||
|
#define MG_VERSION "7.3"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
@@ -54,7 +54,7 @@ static size_t ws_process(uint8_t *buf, size_t len, struct ws_msg *msg) {
|
|||||||
} else if (len >= 10 + mask_len) {
|
} else if (len >= 10 + mask_len) {
|
||||||
msg->header_len = 10 + mask_len;
|
msg->header_len = 10 + mask_len;
|
||||||
msg->data_len =
|
msg->data_len =
|
||||||
(int) (((uint64_t) mg_ntohl(*(uint32_t *) &buf[2])) << 32) +
|
(size_t)(((uint64_t) mg_ntohl(*(uint32_t *) &buf[2])) << 32) +
|
||||||
mg_ntohl(*(uint32_t *) &buf[6]);
|
mg_ntohl(*(uint32_t *) &buf[6]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,7 +124,7 @@ static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data,
|
|||||||
c->is_websocket = 1;
|
c->is_websocket = 1;
|
||||||
mg_call(c, MG_EV_WS_OPEN, &hm);
|
mg_call(c, MG_EV_WS_OPEN, &hm);
|
||||||
}
|
}
|
||||||
mg_iobuf_delete(&c->recv, n);
|
mg_iobuf_delete(&c->recv, (size_t) n);
|
||||||
} else {
|
} else {
|
||||||
return; // A request is not yet received
|
return; // A request is not yet received
|
||||||
}
|
}
|
||||||
@@ -134,6 +134,9 @@ static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data,
|
|||||||
char *s = (char *) c->recv.buf + msg.header_len;
|
char *s = (char *) c->recv.buf + msg.header_len;
|
||||||
struct mg_ws_message m = {{s, msg.data_len}, msg.flags};
|
struct mg_ws_message m = {{s, msg.data_len}, msg.flags};
|
||||||
switch (msg.flags & WEBSOCKET_FLAGS_MASK_OP) {
|
switch (msg.flags & WEBSOCKET_FLAGS_MASK_OP) {
|
||||||
|
case WEBSOCKET_OP_CONTINUE:
|
||||||
|
mg_call(c, MG_EV_WS_CTL, &m);
|
||||||
|
break;
|
||||||
case WEBSOCKET_OP_PING:
|
case WEBSOCKET_OP_PING:
|
||||||
LOG(LL_DEBUG, ("%s", "WS PONG"));
|
LOG(LL_DEBUG, ("%s", "WS PONG"));
|
||||||
mg_ws_send(c, s, msg.data_len, WEBSOCKET_OP_PONG);
|
mg_ws_send(c, s, msg.data_len, WEBSOCKET_OP_PONG);
|
||||||
@@ -142,15 +145,19 @@ static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data,
|
|||||||
case WEBSOCKET_OP_PONG:
|
case WEBSOCKET_OP_PONG:
|
||||||
mg_call(c, MG_EV_WS_CTL, &m);
|
mg_call(c, MG_EV_WS_CTL, &m);
|
||||||
break;
|
break;
|
||||||
|
case WEBSOCKET_OP_TEXT:
|
||||||
|
case WEBSOCKET_OP_BINARY:
|
||||||
|
mg_call(c, MG_EV_WS_MSG, &m);
|
||||||
|
break;
|
||||||
case WEBSOCKET_OP_CLOSE:
|
case WEBSOCKET_OP_CLOSE:
|
||||||
LOG(LL_ERROR, ("%lu Got WS CLOSE", c->id));
|
LOG(LL_ERROR, ("%lu Got WS CLOSE", c->id));
|
||||||
mg_call(c, MG_EV_WS_CTL, &m);
|
mg_call(c, MG_EV_WS_CTL, &m);
|
||||||
c->is_closing = 1;
|
c->is_closing = 1;
|
||||||
return;
|
|
||||||
default: {
|
|
||||||
mg_call(c, MG_EV_WS_MSG, &m);
|
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
|
// Per RFC6455, close conn when an unknown op is recvd
|
||||||
|
mg_error(c, "unknown WS op %d", msg.flags & WEBSOCKET_FLAGS_MASK_OP);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
mg_iobuf_delete(&c->recv, msg.header_len + msg.data_len);
|
mg_iobuf_delete(&c->recv, msg.header_len + msg.data_len);
|
||||||
}
|
}
|
||||||
@@ -188,7 +195,7 @@ struct mg_connection *mg_ws_connect(struct mg_mgr *mgr, const char *url,
|
|||||||
"Sec-WebSocket-Key: %s\r\n"
|
"Sec-WebSocket-Key: %s\r\n"
|
||||||
"\r\n",
|
"\r\n",
|
||||||
mg_url_uri(url), (int) host.len, host.ptr, n1, buf1, key);
|
mg_url_uri(url), (int) host.len, host.ptr, n1, buf1, key);
|
||||||
mg_send(c, buf2, n2);
|
mg_send(c, buf2, n2 > 0 ? (size_t) n2 : 0);
|
||||||
if (buf1 != mem1) free(buf1);
|
if (buf1 != mem1) free(buf1);
|
||||||
if (buf2 != mem2) free(buf2);
|
if (buf2 != mem2) free(buf2);
|
||||||
c->pfn = mg_ws_cb;
|
c->pfn = mg_ws_cb;
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
secret
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
є
|
||||||
Loaded 100 of 185 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user