From ecb75b69fde194afbe7ed1a6f9c839ab866f30fb Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Sat, 1 Apr 2017 17:17:57 +0800 Subject: [PATCH 1/7] component/bt : modify bluetooth task priority --- components/bt/bluedroid/osi/include/thread.h | 8 ++++---- components/esp32/include/esp_task.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/components/bt/bluedroid/osi/include/thread.h b/components/bt/bluedroid/osi/include/thread.h index 01df95388..2b900c72d 100644 --- a/components/bt/bluedroid/osi/include/thread.h +++ b/components/bt/bluedroid/osi/include/thread.h @@ -44,23 +44,23 @@ enum { }; #define HCI_HOST_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE) -#define HCI_HOST_TASK_PRIO (configMAX_PRIORITIES - 2) +#define HCI_HOST_TASK_PRIO (configMAX_PRIORITIES - 3) #define HCI_HOST_TASK_NAME "hciHostT" #define HCI_HOST_QUEUE_NUM 40 #define HCI_H4_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE) -#define HCI_H4_TASK_PRIO (configMAX_PRIORITIES - 3) +#define HCI_H4_TASK_PRIO (configMAX_PRIORITIES - 4) #define HCI_H4_TASK_NAME "hciH4T" #define HCI_H4_QUEUE_NUM 60 #define BTU_TASK_STACK_SIZE (3584 + BT_TASK_EXTRA_STACK_SIZE) -#define BTU_TASK_PRIO (configMAX_PRIORITIES - 4) +#define BTU_TASK_PRIO (configMAX_PRIORITIES - 5) #define BTU_TASK_NAME "btuT" #define BTU_QUEUE_NUM 50 #define BTC_TASK_STACK_SIZE (CONFIG_BTC_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) //by menuconfig #define BTC_TASK_NAME "btcT" -#define BTC_TASK_PRIO (configMAX_PRIORITIES - 5) +#define BTC_TASK_PRIO (configMAX_PRIORITIES - 6) #define BTC_TASK_QUEUE_NUM 20 void btu_task_post(uint32_t sig); diff --git a/components/esp32/include/esp_task.h b/components/esp32/include/esp_task.h index bd2636264..522067ca7 100644 --- a/components/esp32/include/esp_task.h +++ b/components/esp32/include/esp_task.h @@ -33,7 +33,7 @@ /* Bt contoller Task */ /* controller */ -#define ESP_TASK_BT_CONTROLLER_PRIO (ESP_TASK_PRIO_MAX - 1) +#define ESP_TASK_BT_CONTROLLER_PRIO (ESP_TASK_PRIO_MAX - 2) #ifdef CONFIG_NEWLIB_NANO_FORMAT #define BT_TASK_EXTRA_STACK_SIZE (0) #else From 99d39909c4f19c63909d663e927ac0a8933a3ed5 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 3 Apr 2017 16:45:59 +0300 Subject: [PATCH 2/7] implement fixes for issues found while fuzz testing --- components/mdns/mdns.c | 65 +++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c index 953ed64b9..6467a5534 100644 --- a/components/mdns/mdns.c +++ b/components/mdns/mdns.c @@ -269,18 +269,18 @@ esp_err_t _mdns_server_deinit(mdns_server_t * server) */ static size_t _mdns_server_write(mdns_server_t * server, uint8_t * data, size_t len) { - struct pbuf* pbt = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - if (pbt != NULL) { - uint8_t* dst = (uint8_t *)pbt->payload; - memcpy(dst, data, len); - err_t err = udp_sendto(server->pcb, pbt, &(server->pcb->remote_ip), server->pcb->remote_port); - pbuf_free(pbt); - if (err) { - return 0; - } - return len; - } - return 0; + struct pbuf* pbt = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (pbt == NULL) { + return 0; + } + uint8_t* dst = (uint8_t *)pbt->payload; + memcpy(dst, data, len); + err_t err = udp_sendto(server->pcb, pbt, &(server->pcb->remote_ip), server->pcb->remote_port); + pbuf_free(pbt); + if (err) { + return 0; + } + return len; } /* @@ -391,11 +391,11 @@ static esp_err_t _mdns_server_add(mdns_server_t * server) */ static esp_err_t _mdns_server_remove(mdns_server_t * server) { + _mdns_servers[server->tcpip_if] = NULL; + //stop UDP _mdns_server_deinit(server); - _mdns_servers[server->tcpip_if] = NULL; - if (xQueueRemoveFromSet(server->queue, _mdns_queue_set) != pdPASS) { return ESP_FAIL; } @@ -1309,11 +1309,13 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz if (questions) { uint8_t qs = questions; - mdns_answer_item_t * answers = NULL; + mdns_answer_item_t * answer_items = NULL; while(qs--) { content = _mdns_parse_fqdn(data, content, name); if (!content) { + answers = 0; + additional = 0; break;//error } @@ -1323,7 +1325,7 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz if (!name->service[0] || !name->proto[0]) { if (type == MDNS_TYPE_A || type == MDNS_TYPE_AAAA || type == MDNS_TYPE_ANY) {//send A + AAAA if (name->host[0] && server->hostname && server->hostname[0] && !strcmp(name->host, server->hostname)) { - answers = _mdns_add_answer(answers, NULL, MDNS_ANSWER_A); + answer_items = _mdns_add_answer(answer_items, NULL, MDNS_ANSWER_A); } } continue; @@ -1336,7 +1338,7 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz mdns_srv_item_t * s = server->services; while(s) { if (s->service->service && s->service->proto) { - answers = _mdns_add_answer(answers, s->service, MDNS_ANSWER_SDPTR); + answer_items = _mdns_add_answer(answer_items, s->service, MDNS_ANSWER_SDPTR); } s = s->next; } @@ -1354,7 +1356,7 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz } if (type == MDNS_TYPE_PTR) { - answers = _mdns_add_answer(answers, si->service, MDNS_ANSWER_ALL); + answer_items = _mdns_add_answer(answer_items, si->service, MDNS_ANSWER_ALL); } else if (type == MDNS_TYPE_TXT) { //match instance/host const char * host = (si->service->instance)?si->service->instance @@ -1363,7 +1365,7 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz if (!host || !host[0] || !name->host[0] || strcmp(name->host, host)) { continue; } - answers = _mdns_add_answer(answers, si->service, MDNS_ANSWER_TXT); + answer_items = _mdns_add_answer(answer_items, si->service, MDNS_ANSWER_TXT); } else if (type == MDNS_TYPE_SRV) { //match instance/host const char * host = (si->service->instance)?si->service->instance @@ -1372,16 +1374,16 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz if (!host || !host[0] || !name->host[0] || strcmp(name->host, host)) { continue; } - answers = _mdns_add_answer(answers, si->service, MDNS_ANSWER_SRV | MDNS_ANSWER_A); + answer_items = _mdns_add_answer(answer_items, si->service, MDNS_ANSWER_SRV | MDNS_ANSWER_A); } else if (type == MDNS_TYPE_ANY) {//send all //match host if (!name->host[0] || !server->hostname || !server->hostname[0] || strcmp(name->host, server->hostname)) { - answers = _mdns_add_answer(answers, si->service, MDNS_ANSWER_ALL); + answer_items = _mdns_add_answer(answer_items, si->service, MDNS_ANSWER_ALL); } } } - if (answers) { - _mdns_send_answers(server, answers); + if (answer_items) { + _mdns_send_answers(server, answer_items); } } @@ -1392,7 +1394,7 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz while(content < (data + len)) { content = _mdns_parse_fqdn(data, content, name); if (!content) { - break;//error + return;//error } uint16_t type = _mdns_read_u16(content, MDNS_TYPE_OFFSET); uint16_t data_len = _mdns_read_u16(content, MDNS_LEN_OFFSET); @@ -1400,6 +1402,10 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz content = data_ptr + data_len; + if(content > (data + len)){ + return; + } + if (type == MDNS_TYPE_PTR) { if (!_mdns_parse_fqdn(data, data_ptr, name)) { continue;//error @@ -1444,6 +1450,9 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz uint16_t i=0,b=0, y; while(i < data_len) { uint8_t partLen = data_ptr[i++]; + if((i+partLen) > data_len){ + break;//error + } //check if partLen will fit in the buffer if (partLen > (MDNS_TXT_MAX_LEN - b - 1)) { break; @@ -1611,12 +1620,11 @@ esp_err_t mdns_set_hostname(mdns_server_t * server, const char * hostname) } MDNS_MUTEX_LOCK(); free((char*)server->hostname); - server->hostname = (char *)malloc(strlen(hostname)+1); + server->hostname = strndup(hostname, MDNS_NAME_BUF_LEN - 1); if (!server->hostname) { MDNS_MUTEX_UNLOCK(); return ESP_ERR_NO_MEM; } - strlcpy((char *)server->hostname, hostname, MDNS_NAME_BUF_LEN); MDNS_MUTEX_UNLOCK(); return ERR_OK; } @@ -1631,12 +1639,11 @@ esp_err_t mdns_set_instance(mdns_server_t * server, const char * instance) } MDNS_MUTEX_LOCK(); free((char*)server->instance); - server->instance = (char *)malloc(strlen(instance)+1); + server->instance = strndup(instance, MDNS_NAME_BUF_LEN - 1); if (!server->instance) { MDNS_MUTEX_UNLOCK(); return ESP_ERR_NO_MEM; } - strlcpy((char *)server->instance, instance, MDNS_NAME_BUF_LEN); MDNS_MUTEX_UNLOCK(); return ERR_OK; } @@ -1812,7 +1819,7 @@ esp_err_t mdns_service_remove_all(mdns_server_t * server) * MDNS QUERY * */ -uint32_t mdns_query(mdns_server_t * server, const char * service, const char * proto, uint32_t timeout) +size_t mdns_query(mdns_server_t * server, const char * service, const char * proto, uint32_t timeout) { if (!server || !service) { return 0; From 4c2622755d92efa1818d062d433725553437993c Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 3 Apr 2017 16:50:12 +0300 Subject: [PATCH 3/7] Add AFL fuzz test --- components/mdns/include/mdns.h | 4 + components/mdns/mdns.c | 56 ++++-- components/mdns/test_afl_fuzz_host/Makefile | 35 ++++ components/mdns/test_afl_fuzz_host/README.md | 58 ++++++ .../mdns/test_afl_fuzz_host/esp32_compat.h | 129 ++++++++++++++ .../mdns/test_afl_fuzz_host/in/test-14.bin | Bin 0 -> 568 bytes .../mdns/test_afl_fuzz_host/in/test-15.bin | Bin 0 -> 524 bytes .../mdns/test_afl_fuzz_host/in/test-16.bin | Bin 0 -> 254 bytes .../mdns/test_afl_fuzz_host/in/test-28.bin | Bin 0 -> 62 bytes .../mdns/test_afl_fuzz_host/in/test-29.bin | Bin 0 -> 39 bytes .../mdns/test_afl_fuzz_host/in/test-31.bin | Bin 0 -> 91 bytes .../mdns/test_afl_fuzz_host/in/test-53.bin | Bin 0 -> 140 bytes .../mdns/test_afl_fuzz_host/in/test-56.bin | Bin 0 -> 262 bytes .../mdns/test_afl_fuzz_host/in/test-63.bin | Bin 0 -> 147 bytes .../mdns/test_afl_fuzz_host/in/test-83.bin | Bin 0 -> 105 bytes .../mdns/test_afl_fuzz_host/in/test-88.bin | Bin 0 -> 48 bytes .../mdns/test_afl_fuzz_host/in/test-89.bin | Bin 0 -> 459 bytes .../mdns/test_afl_fuzz_host/in/test-95.bin | Bin 0 -> 286 bytes .../mdns/test_afl_fuzz_host/in/test-96.bin | Bin 0 -> 319 bytes .../mdns/test_afl_fuzz_host/input_packets.txt | 166 ++++++++++++++++++ components/mdns/test_afl_fuzz_host/test.c | 113 ++++++++++++ 21 files changed, 542 insertions(+), 19 deletions(-) create mode 100644 components/mdns/test_afl_fuzz_host/Makefile create mode 100644 components/mdns/test_afl_fuzz_host/README.md create mode 100644 components/mdns/test_afl_fuzz_host/esp32_compat.h create mode 100755 components/mdns/test_afl_fuzz_host/in/test-14.bin create mode 100755 components/mdns/test_afl_fuzz_host/in/test-15.bin create mode 100755 components/mdns/test_afl_fuzz_host/in/test-16.bin create mode 100755 components/mdns/test_afl_fuzz_host/in/test-28.bin create mode 100755 components/mdns/test_afl_fuzz_host/in/test-29.bin create mode 100755 components/mdns/test_afl_fuzz_host/in/test-31.bin create mode 100755 components/mdns/test_afl_fuzz_host/in/test-53.bin create mode 100755 components/mdns/test_afl_fuzz_host/in/test-56.bin create mode 100755 components/mdns/test_afl_fuzz_host/in/test-63.bin create mode 100755 components/mdns/test_afl_fuzz_host/in/test-83.bin create mode 100755 components/mdns/test_afl_fuzz_host/in/test-88.bin create mode 100755 components/mdns/test_afl_fuzz_host/in/test-89.bin create mode 100755 components/mdns/test_afl_fuzz_host/in/test-95.bin create mode 100755 components/mdns/test_afl_fuzz_host/in/test-96.bin create mode 100644 components/mdns/test_afl_fuzz_host/input_packets.txt create mode 100644 components/mdns/test_afl_fuzz_host/test.c diff --git a/components/mdns/include/mdns.h b/components/mdns/include/mdns.h index 58e588e3e..c0855466a 100644 --- a/components/mdns/include/mdns.h +++ b/components/mdns/include/mdns.h @@ -18,7 +18,11 @@ extern "C" { #endif +#ifndef MDNS_TEST_MODE #include +#else +#include "esp32_compat.h" +#endif struct mdns_server_s; typedef struct mdns_server_s mdns_server_t; diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c index 6467a5534..39cc01829 100644 --- a/components/mdns/mdns.c +++ b/components/mdns/mdns.c @@ -14,6 +14,7 @@ #include "mdns.h" #include +#ifndef MDNS_TEST_MODE #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/queue.h" @@ -23,6 +24,7 @@ #include "lwip/igmp.h" #include "lwip/udp.h" #include "esp_wifi.h" +#endif #define MDNS_FLAGS_AUTHORITATIVE 0x8400 @@ -162,6 +164,9 @@ static const char * MDNS_DEFAULT_DOMAIN = "local"; static const char * MDNS_SUB_STR = "_sub"; static mdns_server_t * _mdns_servers[TCPIP_ADAPTER_IF_MAX] = {0,0,0}; + +#ifndef MDNS_TEST_MODE + static TaskHandle_t _mdns_service_task_handle = NULL; static QueueSetHandle_t _mdns_queue_set = NULL; @@ -257,6 +262,7 @@ esp_err_t _mdns_server_deinit(mdns_server_t * server) } return ESP_OK; } +#endif /** * @brief send packet over UDP @@ -269,25 +275,28 @@ esp_err_t _mdns_server_deinit(mdns_server_t * server) */ static size_t _mdns_server_write(mdns_server_t * server, uint8_t * data, size_t len) { - struct pbuf* pbt = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - if (pbt == NULL) { - return 0; - } - uint8_t* dst = (uint8_t *)pbt->payload; - memcpy(dst, data, len); - err_t err = udp_sendto(server->pcb, pbt, &(server->pcb->remote_ip), server->pcb->remote_port); - pbuf_free(pbt); - if (err) { - return 0; - } - return len; +#ifndef MDNS_TEST_MODE + struct pbuf* pbt = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (pbt == NULL) { + return 0; + } + uint8_t* dst = (uint8_t *)pbt->payload; + memcpy(dst, data, len); + err_t err = udp_sendto(server->pcb, pbt, &(server->pcb->remote_ip), server->pcb->remote_port); + pbuf_free(pbt); + if (err) { + return 0; + } +#endif + return len; } /* * MDNS Servers * */ -static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, size_t len); +#ifndef MDNS_TEST_MODE +void mdns_parse_packet(mdns_server_t * server, const uint8_t * data, size_t len); /** * @brief the main MDNS service task. Packets are received and parsed here @@ -305,7 +314,7 @@ static void _mdns_service_task(void *pvParameters) mdns_server_t * server = _mdns_servers[i]; if (server && server->queue == queue) { MDNS_MUTEX_LOCK(); - _mdns_parse_packet(server, (uint8_t*)pb->payload, pb->len); + mdns_parse_packet(server, (uint8_t*)pb->payload, pb->len); MDNS_MUTEX_UNLOCK(); break; } @@ -314,6 +323,7 @@ static void _mdns_service_task(void *pvParameters) } } } +#endif /** * @brief get the server assigned to particular interface @@ -342,6 +352,7 @@ static mdns_server_t * _mdns_server_get(tcpip_adapter_if_t tcpip_if) */ static esp_err_t _mdns_server_add(mdns_server_t * server) { +#ifndef MDNS_TEST_MODE if (!_mdns_service_semaphore) { _mdns_service_semaphore = xSemaphoreCreateMutex(); if (!_mdns_service_semaphore) { @@ -374,7 +385,7 @@ static esp_err_t _mdns_server_add(mdns_server_t * server) if (err) { return err; } - +#endif _mdns_servers[server->tcpip_if] = server; return ESP_OK; @@ -392,7 +403,7 @@ static esp_err_t _mdns_server_add(mdns_server_t * server) static esp_err_t _mdns_server_remove(mdns_server_t * server) { _mdns_servers[server->tcpip_if] = NULL; - +#ifndef MDNS_TEST_MODE //stop UDP _mdns_server_deinit(server); @@ -417,7 +428,7 @@ static esp_err_t _mdns_server_remove(mdns_server_t * server) } MDNS_SERVICE_UNLOCK(); } - +#endif return ESP_OK; } @@ -1294,7 +1305,7 @@ static inline uint16_t _mdns_read_u16(const uint8_t * packet, uint16_t index) * @param data byte array holding the packet data * @param len length of the byte array */ -static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, size_t len) +void mdns_parse_packet(mdns_server_t * server, const uint8_t * data, size_t len) { static mdns_name_t n; static mdns_result_temp_t a; @@ -1401,7 +1412,6 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz const uint8_t * data_ptr = content + MDNS_DATA_OFFSET; content = data_ptr + data_len; - if(content > (data + len)){ return; } @@ -1410,18 +1420,22 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz if (!_mdns_parse_fqdn(data, data_ptr, name)) { continue;//error } +#ifndef MDNS_TEST_MODE if (server->search.host[0] || (strcmp(name->service, server->search.service) != 0) || (strcmp(name->proto, server->search.proto) != 0)) { continue;//not searching for service or wrong service/proto } +#endif strlcpy(answer->instance, name->host, MDNS_NAME_BUF_LEN); } else if (type == MDNS_TYPE_SRV) { +#ifndef MDNS_TEST_MODE if (server->search.host[0] || (strcmp(name->service, server->search.service) != 0) || (strcmp(name->proto, server->search.proto) != 0)) { continue;//not searching for service or wrong service/proto } +#endif if (answer->instance[0]) { if (strcmp(answer->instance, name->host) != 0) { continue;//instance name is not the same as the one in the PTR record @@ -1468,9 +1482,11 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz answer->txt[b] = 0; } else if (type == MDNS_TYPE_AAAA) { if (server->search.host[0]) { +#ifndef MDNS_TEST_MODE if (strcmp(name->host, server->search.host) != 0) { continue;//wrong host } +#endif } else if (!answer->ptr) { strlcpy(answer->host, name->host, MDNS_NAME_BUF_LEN); } else if (strcmp(answer->host, name->host) != 0) { @@ -1479,9 +1495,11 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz memcpy(answer->addrv6, data_ptr, sizeof(ip6_addr_t)); } else if (type == MDNS_TYPE_A) { if (server->search.host[0]) { +#ifndef MDNS_TEST_MODE if (strcmp(name->host, server->search.host) != 0) { continue;//wrong host } +#endif } else if (!answer->ptr) { strlcpy(answer->host, name->host, MDNS_NAME_BUF_LEN); } else if (strcmp(answer->host, name->host) != 0) { diff --git a/components/mdns/test_afl_fuzz_host/Makefile b/components/mdns/test_afl_fuzz_host/Makefile new file mode 100644 index 000000000..65a318ef2 --- /dev/null +++ b/components/mdns/test_afl_fuzz_host/Makefile @@ -0,0 +1,35 @@ +TEST_NAME=test +FUZZ=afl-fuzz +CC=afl-clang-fast +CPP=$(CC) +LD=$(CC) +OBJECTS=mdns.o test.o +CFLAGS=-DMDNS_TEST_MODE -I. -I../include + +OS := $(shell uname) +ifeq ($(OS),Darwin) + LDLIBS= +else + LDLIBS=-lbsd + CFLAGS+=-DUSE_BSD_STRING +endif + +all: $(TEST_NAME) + +%.o: %.c + @echo "[CC] $<" + @$(CC) $(CFLAGS) -c $< -o $@ + +mdns.o: ../mdns.c + @echo "[CC] $<" + @$(CC) $(CFLAGS) -c $< -o $@ + +$(TEST_NAME): $(OBJECTS) + @echo "[LD] $@" + @$(LD) $(LDLIBS) $(OBJECTS) -o $@ + +fuzz: $(TEST_NAME) + @$(FUZZ) -i "in" -o "out" -- ./$(TEST_NAME) + +clean: + @rm -rf *.o *.SYM $(TEST_NAME) out diff --git a/components/mdns/test_afl_fuzz_host/README.md b/components/mdns/test_afl_fuzz_host/README.md new file mode 100644 index 000000000..7d78bab55 --- /dev/null +++ b/components/mdns/test_afl_fuzz_host/README.md @@ -0,0 +1,58 @@ +## Introduction +This test uses [american fuzzy lop](http://lcamtuf.coredump.cx/afl/) to mangle real mdns packets and look for exceptions caused by the parser. + +A few actuall packets are collected and exported as bins in the ```in``` folder, which is then passed as input to AFL when testing. The setup procedure for the test includes all possible services and scenarios that could be used with the given input packets. Output of the parser before fuzzing can be found in [input_packets.txt](input_packets.txt) + +## Installing AFL +To run the test yourself, you need to dounload the [latest afl archive](http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz) and extract it to a folder on your computer. + +The rest of the document will refer to that folder as ```PATH_TO_AFL```. + +### Preparation +- On Mac, you will need to insall the latest Xcode and llvm support from [Homebrew](https://brew.sh) + + ```bash + /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" + brew install --with-clang --with-lld --HEAD llvm + export PATH="/usr/local/opt/llvm/bin:$PATH" + ``` + +- On Ubuntu you need the following packages: + + ```bash + sudo apt-get install make clang llvm libbsd-dev + ``` + +### Compile AFL +Compiling AFL is as easy as running make: + +```bash +cd [PATH_TO_AFL] +make +cd llvm_mode/ +make +``` + +After successful compilation, you can export the following variables to your shell (you can also add them to your profile if you want to use afl in other projects) + +```bash +export AFL_PATH=[PATH_TO_AFL] +export PATH="$AFL_PATH:$PATH" +``` + +## Running the test +Apple has a crash reporting service that could interfere with AFLs normal operation. To turn that off, run the following command: + +```bash +launchctl unload -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist +sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist +``` + +Ubuntu has a similar service. To turn that off, run as root: + +```bash +echo core >/proc/sys/kernel/core_pattern +``` + +After going through all of the requirements above, you can ```cd``` into this test's folder and simply run ```make fuzz```. + diff --git a/components/mdns/test_afl_fuzz_host/esp32_compat.h b/components/mdns/test_afl_fuzz_host/esp32_compat.h new file mode 100644 index 000000000..d6a913a3c --- /dev/null +++ b/components/mdns/test_afl_fuzz_host/esp32_compat.h @@ -0,0 +1,129 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _ESP32_COMPAT_H_ +#define _ESP32_COMPAT_H_ + +#ifdef MDNS_TEST_MODE + +#ifdef USE_BSD_STRING +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +#define ERR_OK 0 +#define ESP_OK 0 +#define ESP_FAIL -1 + +#define ESP_ERR_NO_MEM 0x101 +#define ESP_ERR_INVALID_ARG 0x102 +#define ESP_ERR_INVALID_STATE 0x103 +#define ESP_ERR_INVALID_SIZE 0x104 +#define ESP_ERR_NOT_FOUND 0x105 +#define ESP_ERR_NOT_SUPPORTED 0x106 +#define ESP_ERR_TIMEOUT 0x107 +#define ESP_ERR_INVALID_RESPONSE 0x108 +#define ESP_ERR_INVALID_CRC 0x109 + +#define pdTRUE true +#define pdFALSE false + +#define portMAX_DELAY 0xFFFFFFFF +#define portTICK_PERIOD_MS 1 + +#define xSemaphoreTake(s,d) +#define xSemaphoreGive(s) +#define xSemaphoreCreateMutex() malloc(1) +#define vSemaphoreDelete(s) free(s) +#define xQueueCreate(n,s) malloc((n)*(s)) +#define vQueueDelete(q) free(q) +#define xQueueReceive(q, d, t) (ESP_OK) +#define vTaskDelay(m) usleep((m)*1000) +#define pbuf_free(p) free(p) + +#define tcpip_adapter_get_ip_info(i,d) +#define tcpip_adapter_get_ip6_linklocal(i,d) (ESP_OK) +#define tcpip_adapter_get_hostname(i, n) *(n) = "esp32-0123456789AB" + +#define IP4_ADDR(ipaddr, a,b,c,d) \ + (ipaddr)->addr = ((uint32_t)((d) & 0xff) << 24) | \ + ((uint32_t)((c) & 0xff) << 16) | \ + ((uint32_t)((b) & 0xff) << 8) | \ + (uint32_t)((a) & 0xff) + +typedef uint32_t esp_err_t; + +typedef void * xSemaphoreHandle; +typedef void * xQueueHandle; + +typedef enum { + TCPIP_ADAPTER_IF_STA = 0, /**< ESP32 station interface */ + TCPIP_ADAPTER_IF_AP, /**< ESP32 soft-AP interface */ + TCPIP_ADAPTER_IF_ETH, /**< ESP32 ethernet interface */ + TCPIP_ADAPTER_IF_MAX +} tcpip_adapter_if_t; + +typedef enum { + WIFI_MODE_NULL = 0, /**< null mode */ + WIFI_MODE_STA, /**< WiFi station mode */ + WIFI_MODE_AP, /**< WiFi soft-AP mode */ + WIFI_MODE_APSTA, /**< WiFi station + soft-AP mode */ + WIFI_MODE_MAX +} wifi_mode_t; + +struct udp_pcb { + uint8_t dummy; +}; + +struct ip4_addr { + uint32_t addr; +}; +typedef struct ip4_addr ip4_addr_t; + +struct ip6_addr { + uint32_t addr[4]; +}; +typedef struct ip6_addr ip6_addr_t; + +typedef struct { + ip4_addr_t ip; + ip4_addr_t netmask; + ip4_addr_t gw; +} tcpip_adapter_ip_info_t; + +inline esp_err_t esp_wifi_get_mode(wifi_mode_t * mode) +{ + *mode = WIFI_MODE_APSTA; + return ESP_OK; +} + +inline uint32_t xTaskGetTickCount() +{ + struct timeval tv; + struct timezone tz; + if (gettimeofday(&tv, &tz) == 0) { + return (tv.tv_sec * 1000) + (tv.tv_usec / 1000); + } + return 0; +} + +#endif //MDNS_TEST_MODE + +#endif //_ESP32_COMPAT_H_ diff --git a/components/mdns/test_afl_fuzz_host/in/test-14.bin b/components/mdns/test_afl_fuzz_host/in/test-14.bin new file mode 100755 index 0000000000000000000000000000000000000000..b9d059d8202682602e7232a8505c495a3047e3a4 GIT binary patch literal 568 zcmaiwPfNov7{)Vc-GqW7j)|wjsGcf~S~hRiF&W~a2k#+k0~WgWB}sAnMEe#aev*0f zYnYmKpg5L8@;*Gj_g@gw=M=T;r$cDQq2$scG66d;6PhFBpq5SEqy*Ki;|>9y6_W8k z(juaoD$gKwot!QVViQiwP4*$FL_!N=w2csr$^a@cZR*xs(X_FMHk)!f+~gb+NOM1> zk_yQgof*O+&`j$PkuwH9@N&MeNR@)Rs7LhfhXIZT<8b&C;fD#&geg za3+LG&Fd@xs>KLTNcn;-*5pXh{6Hl3Gf@0Bv?l!J7wTd;niT zpQFAGPvJB)ejMCnH#5JT{b&BO0M9^cBj1M?YNV6sL|5fVbt9Ej+lyF*S{proq+$Y_ zy(EZB<0$aQ0F|dTfW0^Pc%S>15?e0gf=P$9ZRU2E6gBl1yUeqg)y}c?t9peygs&#} z7|j&Zdeo=X8zO0VLkn$-((43yUL=X?$Ick}!j;^kSawken}R!yj@dNbnpQ!IPSfSw z6t(+@>poibXblSGtk>cz>tEHauqc}6a-MwrlizE$|MzI+T(JBX1>O+*nyq$)j zQylnX9d7k~Ow=qiw8BP1a9+~%qG`nQ)xD8Uv1!|NXD5mA#_QH@&$~uSCEPYe#h+j? zazWa{-WhziU)BS1Dn2W)3#)mrXUl8}NBQ(&0aZF-|Mg&HNV7tR6XMi3VDD9S7@$yYB{2+7P%Rd7x$C@#%O<%mzrEGoz^Dq)E)NiJZ`$xlwq zVPFtw0BRAO!mwg_d7`hQt+|1&xv{RZldhAAuCt}Cld(<_s<4x;fr+lGIY`(DNi{^+ z0x0a4YnzvpS*%-zV0U=oA+vm)V+|Sr{1T8R{fu1*g~=8yw(a(1*I26Ub&|U}#`) F005APLjnK* literal 0 HcmV?d00001 diff --git a/components/mdns/test_afl_fuzz_host/in/test-28.bin b/components/mdns/test_afl_fuzz_host/in/test-28.bin new file mode 100755 index 0000000000000000000000000000000000000000..537352ae67db92f820ff0d1299dae3534eef1f48 GIT binary patch literal 62 zcmZQz00Kr3!N4HuQIuI+lCNH@5R#djs^FYhP+Xdm${nAWR*+woT2zu;z!DE6Sab4| L6LT0C6dM=;y^9dW literal 0 HcmV?d00001 diff --git a/components/mdns/test_afl_fuzz_host/in/test-29.bin b/components/mdns/test_afl_fuzz_host/in/test-29.bin new file mode 100755 index 0000000000000000000000000000000000000000..837737b32e12e3f33ff3f1c3b59f6ff351b05fba GIT binary patch literal 39 qcmZQz00Jfu!N9XCLm_y%+1WpOe@MPsbbB^PfpBXV328G1WHse2>fdR(m)`h7xI6{k-wY= bco-O=ax4c{{1X83^`U$YAe+U3fq?@6q#+cG literal 0 HcmV?d00001 diff --git a/components/mdns/test_afl_fuzz_host/in/test-53.bin b/components/mdns/test_afl_fuzz_host/in/test-53.bin new file mode 100755 index 0000000000000000000000000000000000000000..73181ea8c378d33efed725aa209387113edffdd3 GIT binary patch literal 140 zcmZQz00Jf;1Ok@$;@l*b_>$xT)|~w0#2f|&9tKA7;QX}A%0ykyvc$anvczIt-^666 z{QT?#VhoH7j0bo?Y8V)}zcR>5K~yS0RX%E%S*!q4%mY{WjX^@xqbReuBwxK)AtW<5 PRlzy2ptv+A^#Bh5gdisG literal 0 HcmV?d00001 diff --git a/components/mdns/test_afl_fuzz_host/in/test-56.bin b/components/mdns/test_afl_fuzz_host/in/test-56.bin new file mode 100755 index 0000000000000000000000000000000000000000..980b6516a20908c4b681b1cf3717c7ef35f062b6 GIT binary patch literal 262 zcmZQzXkh>XCLm@L_9)6MF3Eq?Ftb>}H!)cuH#0AjCq5;$EHgP(H#09SpC!H|xqvk% zKRGdnfkA+Qk%2*Q3WJP5ZhlH?jxA6JNQ0S<5m$b3MOkW5v8|yQOMG!|(g9rt9;jk5 zY<3)oKTyCR&;T)xkpak21aTND7=%D>W8BLLGB~X$v!v>P(SfB5GEiB8e+?jc1_lwm xkpDZ5{N)77F+$~74y^bm05nM-YAh#^&C0;gz~BH>1QrAu&jDn!I5049006}!N5=pF literal 0 HcmV?d00001 diff --git a/components/mdns/test_afl_fuzz_host/in/test-63.bin b/components/mdns/test_afl_fuzz_host/in/test-63.bin new file mode 100755 index 0000000000000000000000000000000000000000..883d444ba269c8938aa87f3ba8da53a1305f9763 GIT binary patch literal 147 zcmZQz00Jf;1Oo2(#I%C^vecrIAisgkVmtU4x ztm~VY?3ACMeL$9hk%9354@eEr1V;v0DTqo1sLDqTGm8~qig}O}N{D(CWfqs@s~0PT SWag$SI42eqm*%7%-~j;3q9}|2 literal 0 HcmV?d00001 diff --git a/components/mdns/test_afl_fuzz_host/in/test-83.bin b/components/mdns/test_afl_fuzz_host/in/test-83.bin new file mode 100755 index 0000000000000000000000000000000000000000..c6cc159a2597bc35b4316a796af18534bfee7dc3 GIT binary patch literal 105 zcmZQzXkh>XMj&Pq56(}^tW4DPEKAJGFH0=e^-WB6%FoYc&B;$r%mFHD04b|rU^%ej opU43o1{o+{;9mn!90-_XHvj*(sc11!P9G}A0c5i{Ffecc09-p6=Kufz literal 0 HcmV?d00001 diff --git a/components/mdns/test_afl_fuzz_host/in/test-88.bin b/components/mdns/test_afl_fuzz_host/in/test-88.bin new file mode 100755 index 0000000000000000000000000000000000000000..fcbb384438a28961526215b8b66e32193b6fd0e8 GIT binary patch literal 48 xcmZQz00Jfu!N9;0UzC=_5?_*Bz?zevoS4JFz{9}E5ucb@RFGd(azGHo1pvO@39SGC literal 0 HcmV?d00001 diff --git a/components/mdns/test_afl_fuzz_host/in/test-89.bin b/components/mdns/test_afl_fuzz_host/in/test-89.bin new file mode 100755 index 0000000000000000000000000000000000000000..d60a987cad92fe5e9e86e83ea8d2ee16f7fe93e2 GIT binary patch literal 459 zcmZut!AiqG6nsjH6?&*>t%!$uQZQS0laj>4LYts?QG|-ulBSVH(x&XjT5mmg=~3_> ztY`gzT*ZHizSvY0e6Z}id9$-S3-AC~%eYnwZO0eGP(-mV!P{&eAgrX;5v-UP|9p7oBgos1w8f0EOdo2ePiw} zNje}4^KDp~;Po(uTs%uyd;q1i$LGwR@0_zHHz+YQVq3(j6Z?o*nj-$v7NK==Y^1dM zOFgGeq|f_&(D5aSJQ-nY_c&vUuzMxFc@pCZ#o|bZ%N*uF-f3J6VQOGQliZLVkQEZ||>|XE&P_Qhxn0o}&II^Gj0M Z$Nq4kL7Zy<6!6?PhySpOI1ey^#uu&jeZK$z literal 0 HcmV?d00001 diff --git a/components/mdns/test_afl_fuzz_host/in/test-95.bin b/components/mdns/test_afl_fuzz_host/in/test-95.bin new file mode 100755 index 0000000000000000000000000000000000000000..26553090fa6d7cddb5fb7c748fc72d8d20c77364 GIT binary patch literal 286 zcmZQz00L$PHW0-fpO{vVUzS=_l3c(N4XCLm@O^(e|LF3DFfRtU+=O;vDCEGRC`N#%)8NiEAvPSwrKOUq}8FG((7 z&B;$r%wb>1yv^6)dGB>tzcCvCZv2wPwax&IQObK(dHK;H&FfedS$u_cu z^DV$~ezs8iK?*}{O-<7hlaefwbQ8^tlXOi@Obm4`EzC`H%~Dg6Obtv@lZ*`#fi^3G pY-XrnkOhSV1E&Zi7>ad4{?UaRc)$dxP#@| +#include +#include +#include +#include + +#include "mdns.h" + +void mdns_parse_packet(mdns_server_t * server, const uint8_t * data, size_t len); + +int main(int argc, char** argv) +{ + const char * mdns_hostname = "minifritz"; + const char * mdns_instance = "Hristo's Time Capsule"; + const char * arduTxtData[4] = { + "board=esp32", + "tcp_check=no", + "ssh_upload=no", + "auth_upload=no" + }; + const uint8_t mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x32}; + + mdns_server_t * mdns = NULL; + uint8_t buf[1460]; + char winstance[21+strlen(mdns_hostname)]; + + sprintf(winstance, "%s [%02x:%02x:%02x:%02x:%02x:%02x]", mdns_hostname, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + if (mdns_init(TCPIP_ADAPTER_IF_ETH, &mdns)) { + abort(); + } + + if (mdns_set_hostname(mdns, mdns_hostname)) { + abort(); + } + + if (mdns_set_instance(mdns, mdns_instance)) { + abort(); + } + + if (mdns_service_add(mdns, "_workstation", "_tcp", 9)) { + abort(); + } + + if (mdns_service_instance_set(mdns, "_workstation", "_tcp", winstance)) { + abort(); + } + + if (mdns_service_add(mdns, "_arduino", "_tcp", 3232)) { + abort(); + } + + if (mdns_service_txt_set(mdns, "_arduino", "_tcp", 4, arduTxtData)) { + abort(); + } + + if (mdns_service_add(mdns, "_http", "_tcp", 80)) { + abort(); + } + + if (mdns_service_instance_set(mdns, "_http", "_tcp", "ESP WebServer")) { + abort(); + } + + if ( + mdns_service_add(mdns, "_afpovertcp", "_tcp", 548) + || mdns_service_add(mdns, "_rfb", "_tcp", 885) + || mdns_service_add(mdns, "_smb", "_tcp", 885) + || mdns_service_add(mdns, "_adisk", "_tcp", 885) + || mdns_service_add(mdns, "_airport", "_tcp", 885) + || mdns_service_add(mdns, "_printer", "_tcp", 885) + || mdns_service_add(mdns, "_airplay", "_tcp", 885) + || mdns_service_add(mdns, "_raop", "_tcp", 885) + || mdns_service_add(mdns, "_uscan", "_tcp", 885) + || mdns_service_add(mdns, "_uscans", "_tcp", 885) + || mdns_service_add(mdns, "_ippusb", "_tcp", 885) + || mdns_service_add(mdns, "_scanner", "_tcp", 885) + || mdns_service_add(mdns, "_ipp", "_tcp", 885) + || mdns_service_add(mdns, "_ipps", "_tcp", 885) + || mdns_service_add(mdns, "_pdl-datastream", "_tcp", 885) + || mdns_service_add(mdns, "_ptp", "_tcp", 885) + || mdns_service_add(mdns, "_sleep-proxy", "_udp", 885)) + { + abort(); + } + + while (__AFL_LOOP(1000)) { + memset(buf, 0, 1460); + size_t len = read(0, buf, 1460); + mdns_query(mdns, "_afpovertcp", "_tcp", 0); + mdns_parse_packet(mdns, buf, len); + mdns_query_end(mdns); + } + return 0; +} + +#endif From f5ebeb4c4db8cea3b5caed3f0d9a729847287cae Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Thu, 16 Mar 2017 17:14:20 +0800 Subject: [PATCH 4/7] component/bt : add uart(1/2) as HCI IO directly --- components/bt/Kconfig | 59 ++++++++++++++----- components/bt/bt.c | 36 +++++++++-- components/bt/lib | 2 +- .../bluetooth/controller_hci_uart/Makefile | 8 +++ .../bluetooth/controller_hci_uart/README.rst | 7 +++ .../controller_hci_uart/main/component.mk | 4 ++ .../bluetooth/controller_hci_uart/main/main.c | 44 ++++++++++++++ .../controller_hci_uart/sdkconfig.defaults | 10 ++++ 8 files changed, 151 insertions(+), 19 deletions(-) create mode 100644 examples/bluetooth/controller_hci_uart/Makefile create mode 100644 examples/bluetooth/controller_hci_uart/README.rst create mode 100644 examples/bluetooth/controller_hci_uart/main/component.mk create mode 100644 examples/bluetooth/controller_hci_uart/main/main.c create mode 100644 examples/bluetooth/controller_hci_uart/sdkconfig.defaults diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 9b329e61e..92d060999 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -11,27 +11,58 @@ config BLUEDROID_ENABLED This enables the default Bluedroid Bluetooth stack config BTC_TASK_STACK_SIZE - int "Bluetooth event (callback to application) task stack size" + int "Bluetooth event (callback to application) task stack size" depends on BT_ENABLED - default 3072 - help - This select btc task stack size + default 3072 + help + This select btc task stack size config BLUEDROID_MEM_DEBUG - bool "Bluedroid memory debug" + bool "Bluedroid memory debug" depends on BT_ENABLED - default n - help - Bluedroid memory debug + default n + help + Bluedroid memory debug config BT_DRAM_RELEASE - bool "Release DRAM from Classic BT controller" + bool "Release DRAM from Classic BT controller" depends on BT_ENABLED - default n - help - This option should only be used when BLE only. - Open this option will release about 30K DRAM from Classic BT. - The released DRAM will be used as system heap memory. + default n + help + This option should only be used when BLE only. + Open this option will release about 30K DRAM from Classic BT. + The released DRAM will be used as system heap memory. + +#config BTDM_CONTROLLER_RUN_APP_CPU +# bool "Run controller on APP CPU" +# depends on BT_ENABLED +# default n +# help +# Run controller on APP CPU. + +menuconfig HCI_UART + bool "HCI use UART as IO" + depends on BT_ENABLED + default n + help + Default HCI use VHCI, if this option choose, HCI will use UART(0/1/2) as IO. + Besides, it can set uart number and uart baudrate. + +config HCI_UART_NO + int "UART Number for HCI" + depends on HCI_UART + range 1 2 + default 1 + help + Uart number for HCI. + +config HCI_UART_BAUDRATE + int "UART Baudrate for HCI" + depends on HCI_UART + range 115200 921600 + default 921600 + help + UART Baudrate for HCI. Please use standard baudrate. # Memory reserved at start of DRAM for Bluetooth stack config BT_RESERVE_DRAM diff --git a/components/bt/bt.c b/components/bt/bt.c index e8f4204ef..6182c5eb5 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -33,13 +33,21 @@ #if CONFIG_BT_ENABLED /* Bluetooth system and controller config */ -#define BTDM_CFG_BT_EM_RELEASE (1<<0) -#define BTDM_CFG_BT_DATA_RELEASE (1<<1) +#define BTDM_CFG_BT_EM_RELEASE (1<<0) +#define BTDM_CFG_BT_DATA_RELEASE (1<<1) +#define BTDM_CFG_HCI_UART (1<<2) +#define BTDM_CFG_CONTROLLER_RUN_APP_CPU (1<<3) /* Other reserved for future */ +/* Controller config options, depend on config mask */ +struct btdm_config_options { + uint8_t hci_uart_no; + uint32_t hci_uart_baudrate; +}; + /* not for user call, so don't put to include file */ extern void btdm_osi_funcs_register(void *osi_funcs); -extern void btdm_controller_init(uint32_t config_mask); +extern void btdm_controller_init(uint32_t config_mask, struct btdm_config_options *opts); extern void btdm_controller_schedule(void); extern void btdm_controller_deinit(void); extern int btdm_controller_enable(esp_bt_mode_t mode); @@ -170,18 +178,38 @@ static uint32_t btdm_config_mask_load(void) #ifdef CONFIG_BT_DRAM_RELEASE mask |= (BTDM_CFG_BT_EM_RELEASE | BTDM_CFG_BT_DATA_RELEASE); +#endif +#ifdef CONFIG_HCI_UART + mask |= BTDM_CFG_HCI_UART; +#endif +#ifdef CONFIG_BTDM_CONTROLLER_RUN_APP_CPU + mask |= BTDM_CFG_CONTROLLER_RUN_APP_CPU; #endif return mask; } +static void btdm_config_opts_load(struct btdm_config_options *opts) +{ + if (opts == NULL) { + return; + } +#ifdef CONFIG_HCI_UART + opts->hci_uart_no = CONFIG_HCI_UART_NO; + opts->hci_uart_baudrate = CONFIG_HCI_UART_BAUDRATE; +#endif +} + static void bt_controller_task(void *pvParam) { + struct btdm_config_options btdm_cfg_opts; uint32_t btdm_cfg_mask = 0; btdm_osi_funcs_register(&osi_funcs); btdm_cfg_mask = btdm_config_mask_load(); - btdm_controller_init(btdm_cfg_mask); + btdm_config_opts_load(&btdm_cfg_opts); + + btdm_controller_init(btdm_cfg_mask, &btdm_cfg_opts); btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; diff --git a/components/bt/lib b/components/bt/lib index 9a4bb1d52..f1c0c6517 160000 --- a/components/bt/lib +++ b/components/bt/lib @@ -1 +1 @@ -Subproject commit 9a4bb1d5287572664f170f9df4dbfd71babdfc68 +Subproject commit f1c0c65171e5bd02e1d63137b3582af3bcbb85a4 diff --git a/examples/bluetooth/controller_hci_uart/Makefile b/examples/bluetooth/controller_hci_uart/Makefile new file mode 100644 index 000000000..077393199 --- /dev/null +++ b/examples/bluetooth/controller_hci_uart/Makefile @@ -0,0 +1,8 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := controller_hci_uart + +include $(IDF_PATH)/make/project.mk diff --git a/examples/bluetooth/controller_hci_uart/README.rst b/examples/bluetooth/controller_hci_uart/README.rst new file mode 100644 index 000000000..f51c6c2c6 --- /dev/null +++ b/examples/bluetooth/controller_hci_uart/README.rst @@ -0,0 +1,7 @@ +ESP-IDF UART HCI Controller +=========================== + +This is a btdm controller use UART as HCI IO. This require the UART device support RTS/CTS mandatory. +It can do the configuration of UART number and UART baudrate by menuconfig. + + diff --git a/examples/bluetooth/controller_hci_uart/main/component.mk b/examples/bluetooth/controller_hci_uart/main/component.mk new file mode 100644 index 000000000..a98f634ea --- /dev/null +++ b/examples/bluetooth/controller_hci_uart/main/component.mk @@ -0,0 +1,4 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/bluetooth/controller_hci_uart/main/main.c b/examples/bluetooth/controller_hci_uart/main/main.c new file mode 100644 index 000000000..3f6de6f47 --- /dev/null +++ b/examples/bluetooth/controller_hci_uart/main/main.c @@ -0,0 +1,44 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "bt.h" +#include "driver/uart.h" +#include "esp_log.h" + +static const char *tag = "CONTROLLER_UART_HCI"; + +static void uart_gpio_reset(void) +{ + ESP_LOGI(tag, "HCI UART Pin select: TX 5, RX, 18, CTS 23, RTS 19\n"); + +#if CONFIG_HCI_UART_NO + uart_set_pin(CONFIG_HCI_UART_NO, 5, 18, 19, 23); +#endif +} + +void app_main() +{ + /* As the UART1/2 pin conflict with flash pin, so do matrix of the signal and pin */ + uart_gpio_reset(); + + esp_bt_controller_init(); + + if (esp_bt_controller_enable(ESP_BT_MODE_BTDM) != ESP_OK) { + return; + } +} + diff --git a/examples/bluetooth/controller_hci_uart/sdkconfig.defaults b/examples/bluetooth/controller_hci_uart/sdkconfig.defaults new file mode 100644 index 000000000..4e1001ba4 --- /dev/null +++ b/examples/bluetooth/controller_hci_uart/sdkconfig.defaults @@ -0,0 +1,10 @@ +# Override some defaults so BT stack is enabled +# in this example + +# +# BT config +# +CONFIG_BT_ENABLED=y +CONFIG_HCI_UART=y +CONFIG_HCI_UART_NO=1 +CONFIG_HCI_UART_BAUDRATE=921600 From 95d691afdb092382f683c70cf83099fe39591780 Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Fri, 24 Mar 2017 14:57:07 +0800 Subject: [PATCH 5/7] component/bt : support UART HCI and fix some bugs 1. support UART HCI, devolper need not to make a bridge between VHCI and UART. 2. fix bug of rand/srand called in ISR. 3. fix bug of BLE rx packets may cause assert. --- components/bt/Kconfig | 12 ++++++------ components/bt/bt.c | 22 +++++++++++++++++++++- components/bt/lib | 2 +- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 92d060999..5490ba99b 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -33,12 +33,12 @@ config BT_DRAM_RELEASE Open this option will release about 30K DRAM from Classic BT. The released DRAM will be used as system heap memory. -#config BTDM_CONTROLLER_RUN_APP_CPU -# bool "Run controller on APP CPU" -# depends on BT_ENABLED -# default n -# help -# Run controller on APP CPU. +config BTDM_CONTROLLER_RUN_APP_CPU + bool "Run controller on APP CPU" + depends on BT_ENABLED && !FREERTOS_UNICORE && 0 + default n + help + Run controller on APP CPU. menuconfig HCI_UART bool "HCI use UART as IO" diff --git a/components/bt/bt.c b/components/bt/bt.c index 6182c5eb5..f1676107c 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -87,6 +87,8 @@ struct osi_funcs_t { int32_t (*_mutex_lock)(void *mutex); int32_t (*_mutex_unlock)(void *mutex); int32_t (* _read_efuse_mac)(uint8_t mac[6]); + void (* _srand)(unsigned int seed); + int (* _rand)(void); }; /* Static variable declare */ @@ -142,6 +144,16 @@ static int32_t IRAM_ATTR read_mac_wrapper(uint8_t mac[6]) return esp_read_mac(mac, ESP_MAC_BT); } +static void IRAM_ATTR srand_wrapper(unsigned int seed) +{ + /* empty function */ +} + +static int IRAM_ATTR rand_wrapper(void) +{ + return (int)esp_random(); +} + static struct osi_funcs_t osi_funcs = { ._set_isr = xt_set_interrupt_handler, ._ints_on = xt_ints_on, @@ -154,7 +166,9 @@ static struct osi_funcs_t osi_funcs = { ._mutex_create = mutex_create_wrapper, ._mutex_lock = mutex_lock_wrapper, ._mutex_unlock = mutex_unlock_wrapper, - ._read_efuse_mac = read_mac_wrapper + ._read_efuse_mac = read_mac_wrapper, + ._srand = srand_wrapper, + ._rand = rand_wrapper, }; bool esp_vhci_host_check_send_available(void) @@ -223,9 +237,15 @@ void esp_bt_controller_init() return; } +#ifdef CONFIG_BTDM_CONTROLLER_RUN_APP_CPU + xTaskCreatePinnedToCore(bt_controller_task, "btController", + ESP_TASK_BT_CONTROLLER_STACK, NULL, + ESP_TASK_BT_CONTROLLER_PRIO, &btControllerTaskHandle, 1); +#else xTaskCreatePinnedToCore(bt_controller_task, "btController", ESP_TASK_BT_CONTROLLER_STACK, NULL, ESP_TASK_BT_CONTROLLER_PRIO, &btControllerTaskHandle, 0); +#endif } void esp_bt_controller_deinit(void) diff --git a/components/bt/lib b/components/bt/lib index f1c0c6517..0986936c6 160000 --- a/components/bt/lib +++ b/components/bt/lib @@ -1 +1 @@ -Subproject commit f1c0c65171e5bd02e1d63137b3582af3bcbb85a4 +Subproject commit 0986936c6d21a009d7d4249cbae8a23b0f3bd20b From d90a35af19728a810d73e1209d671de1e2c73c5b Mon Sep 17 00:00:00 2001 From: Tian Hao Date: Wed, 5 Apr 2017 21:19:15 +0800 Subject: [PATCH 6/7] component/bt : modify bluetooth config style --- components/bt/Kconfig | 23 ++++--- components/bt/bt.c | 61 ++++++++----------- components/bt/include/bt.h | 38 +++++++++++- docs/api/bluetooth/controller_vhci.rst | 3 + examples/bluetooth/ble_adv/main/app_bt.c | 13 +++- .../bluetooth/blufi/main/blufi_example_main.c | 6 +- .../{main.c => controller_hci_uart_demo.c} | 21 +++++-- .../controller_hci_uart/sdkconfig.defaults | 6 +- .../bluetooth/gatt_client/main/gattc_demo.c | 3 +- .../bluetooth/gatt_server/main/gatts_demo.c | 7 ++- .../main/gatts_table_creat_demo.c | 7 ++- 11 files changed, 128 insertions(+), 60 deletions(-) rename examples/bluetooth/controller_hci_uart/main/{main.c => controller_hci_uart_demo.c} (61%) diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 5490ba99b..5b2cc3e6a 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -29,10 +29,11 @@ config BT_DRAM_RELEASE depends on BT_ENABLED default n help - This option should only be used when BLE only. - Open this option will release about 30K DRAM from Classic BT. - The released DRAM will be used as system heap memory. + This option should only be used when BLE only. + Open this option will release about 30K DRAM from Classic BT. + The released DRAM will be used as system heap memory. +#disable now for app cpu due to a known issue config BTDM_CONTROLLER_RUN_APP_CPU bool "Run controller on APP CPU" depends on BT_ENABLED && !FREERTOS_UNICORE && 0 @@ -40,7 +41,13 @@ config BTDM_CONTROLLER_RUN_APP_CPU help Run controller on APP CPU. -menuconfig HCI_UART +config BTDM_CONTROLLER_RUN_CPU + int + depends on BT_ENABLED + default 1 if BTDM_CONTROLLER_RUN_APP_CPU + default 0 + +menuconfig BT_HCI_UART bool "HCI use UART as IO" depends on BT_ENABLED default n @@ -48,17 +55,17 @@ menuconfig HCI_UART Default HCI use VHCI, if this option choose, HCI will use UART(0/1/2) as IO. Besides, it can set uart number and uart baudrate. -config HCI_UART_NO +config BT_HCI_UART_NO int "UART Number for HCI" - depends on HCI_UART + depends on BT_HCI_UART range 1 2 default 1 help Uart number for HCI. -config HCI_UART_BAUDRATE +config BT_HCI_UART_BAUDRATE int "UART Baudrate for HCI" - depends on HCI_UART + depends on BT_HCI_UART range 115200 921600 default 921600 help diff --git a/components/bt/bt.c b/components/bt/bt.c index f1676107c..34b29b9c0 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -39,15 +40,9 @@ #define BTDM_CFG_CONTROLLER_RUN_APP_CPU (1<<3) /* Other reserved for future */ -/* Controller config options, depend on config mask */ -struct btdm_config_options { - uint8_t hci_uart_no; - uint32_t hci_uart_baudrate; -}; - /* not for user call, so don't put to include file */ extern void btdm_osi_funcs_register(void *osi_funcs); -extern void btdm_controller_init(uint32_t config_mask, struct btdm_config_options *opts); +extern void btdm_controller_init(uint32_t config_mask, esp_bt_controller_config_t *config_opts); extern void btdm_controller_schedule(void); extern void btdm_controller_deinit(void); extern int btdm_controller_enable(esp_bt_mode_t mode); @@ -94,7 +89,7 @@ struct osi_funcs_t { /* Static variable declare */ static bool btdm_bb_init_flag = false; static esp_bt_controller_status_t btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; - +static esp_bt_controller_config_t btdm_cfg_opts; static xTaskHandle btControllerTaskHandle; static portMUX_TYPE global_int_mux = portMUX_INITIALIZER_UNLOCKED; @@ -193,7 +188,7 @@ static uint32_t btdm_config_mask_load(void) #ifdef CONFIG_BT_DRAM_RELEASE mask |= (BTDM_CFG_BT_EM_RELEASE | BTDM_CFG_BT_DATA_RELEASE); #endif -#ifdef CONFIG_HCI_UART +#ifdef CONFIG_BT_HCI_UART mask |= BTDM_CFG_HCI_UART; #endif #ifdef CONFIG_BTDM_CONTROLLER_RUN_APP_CPU @@ -202,54 +197,50 @@ static uint32_t btdm_config_mask_load(void) return mask; } -static void btdm_config_opts_load(struct btdm_config_options *opts) -{ - if (opts == NULL) { - return; - } -#ifdef CONFIG_HCI_UART - opts->hci_uart_no = CONFIG_HCI_UART_NO; - opts->hci_uart_baudrate = CONFIG_HCI_UART_BAUDRATE; -#endif -} - static void bt_controller_task(void *pvParam) { - struct btdm_config_options btdm_cfg_opts; uint32_t btdm_cfg_mask = 0; - btdm_osi_funcs_register(&osi_funcs); - btdm_cfg_mask = btdm_config_mask_load(); - btdm_config_opts_load(&btdm_cfg_opts); + + btdm_osi_funcs_register(&osi_funcs); btdm_controller_init(btdm_cfg_mask, &btdm_cfg_opts); btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; - /* Loop */ btdm_controller_schedule(); } -void esp_bt_controller_init() +esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) { + BaseType_t ret; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { - return; + return ESP_ERR_INVALID_STATE; } -#ifdef CONFIG_BTDM_CONTROLLER_RUN_APP_CPU - xTaskCreatePinnedToCore(bt_controller_task, "btController", + if (cfg == NULL) { + return ESP_ERR_INVALID_ARG; + } + + memcpy(&btdm_cfg_opts, cfg, sizeof(esp_bt_controller_config_t)); + + ret = xTaskCreatePinnedToCore(bt_controller_task, "btController", ESP_TASK_BT_CONTROLLER_STACK, NULL, - ESP_TASK_BT_CONTROLLER_PRIO, &btControllerTaskHandle, 1); -#else - xTaskCreatePinnedToCore(bt_controller_task, "btController", - ESP_TASK_BT_CONTROLLER_STACK, NULL, - ESP_TASK_BT_CONTROLLER_PRIO, &btControllerTaskHandle, 0); -#endif + ESP_TASK_BT_CONTROLLER_PRIO, &btControllerTaskHandle, CONFIG_BTDM_CONTROLLER_RUN_CPU); + + if (ret != pdPASS) { + memset(&btdm_cfg_opts, 0x0, sizeof(esp_bt_controller_config_t)); + return ESP_ERR_NO_MEM; + } + + return ESP_OK; } void esp_bt_controller_deinit(void) { + memset(&btdm_cfg_opts, 0x0, sizeof(esp_bt_controller_config_t)); vTaskDelete(btControllerTaskHandle); btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; } diff --git a/components/bt/include/bt.h b/components/bt/include/bt.h index e3bd7f084..5a244e0c8 100644 --- a/components/bt/include/bt.h +++ b/components/bt/include/bt.h @@ -18,11 +18,44 @@ #include #include #include "esp_err.h" +#include "sdkconfig.h" #ifdef __cplusplus extern "C" { #endif +/** + * @brief Controller config options, depend on config mask. + * Config mask indicate which functions enabled, this means + * some options or parameters of some functions enabled by config mask. + */ +typedef struct { + uint8_t hci_uart_no; /*!< If use UART1/2 as HCI IO interface, indicate UART number */ + uint32_t hci_uart_baudrate; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */ +} esp_bt_controller_config_t; + +#ifdef CONFIG_BT_ENABLED + +#ifdef CONFIG_BT_HCI_UART_NO +#define BT_HCI_UART_NO_DEFAULT CONFIG_BT_HCI_UART_NO +#else +#define BT_HCI_UART_NO_DEFAULT 1 +#endif /* BT_HCI_UART_NO_DEFAULT */ + +#ifdef CONFIG_BT_HCI_UART_BAUDRATE +#define BT_HCI_UART_BAUDRATE_DEFAULT CONFIG_BT_HCI_UART_BAUDRATE +#else +#define BT_HCI_UART_BAUDRATE_DEFAULT 921600 +#endif /* BT_HCI_UART_BAUDRATE_DEFAULT */ + +#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \ + .hci_uart_no = BT_HCI_UART_NO_DEFAULT,\ + .hci_uart_baudrate = BT_HCI_UART_BAUDRATE_DEFAULT,\ +}; +#else +#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() {0}; _Static_assert(0, "please enable bluetooth in menuconfig to use bt.h"); +#endif + /** * @brief Bluetooth mode for controller enable/disable */ @@ -45,10 +78,11 @@ typedef enum { /** * @brief Initialize BT controller to allocate task and other resource. - * + * @param cfg: Initial configuration of BT controller. * This function should be called only once, before any other BT functions are called. + * @return ESP_OK - success, other - failed */ -void esp_bt_controller_init(void); +esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg); /** * @brief De-initialize BT controller to free resource and delete task. diff --git a/docs/api/bluetooth/controller_vhci.rst b/docs/api/bluetooth/controller_vhci.rst index 9fc5910c2..6241adfbd 100644 --- a/docs/api/bluetooth/controller_vhci.rst +++ b/docs/api/bluetooth/controller_vhci.rst @@ -38,6 +38,9 @@ Enumerations Structures ^^^^^^^^^^ +.. doxygenstruct:: esp_bt_controller_config_t + :members: + .. doxygenstruct:: esp_vhci_host_callback :members: diff --git a/examples/bluetooth/ble_adv/main/app_bt.c b/examples/bluetooth/ble_adv/main/app_bt.c index 67ab2c8fe..31e8f2fa0 100644 --- a/examples/bluetooth/ble_adv/main/app_bt.c +++ b/examples/bluetooth/ble_adv/main/app_bt.c @@ -13,10 +13,13 @@ // limitations under the License. #include +#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "bt.h" -#include +#include "esp_log.h" + +static const char *tag = "BLE_ADV"; #define HCI_H4_CMD_PREAMBLE_SIZE (4) @@ -214,9 +217,15 @@ void bleAdvtTask(void *pvParameters) void app_main() { - esp_bt_controller_init(); + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + + if (esp_bt_controller_init(&bt_cfg) != ESP_OK) { + ESP_LOGI(tag, "Bluetooth controller initialize failed"); + return; + } if (esp_bt_controller_enable(ESP_BT_MODE_BTDM) != ESP_OK) { + ESP_LOGI(tag, "Bluetooth controller enable failed"); return; } diff --git a/examples/bluetooth/blufi/main/blufi_example_main.c b/examples/bluetooth/blufi/main/blufi_example_main.c index 05f39c485..2a3f2ce62 100644 --- a/examples/bluetooth/blufi/main/blufi_example_main.c +++ b/examples/bluetooth/blufi/main/blufi_example_main.c @@ -315,7 +315,11 @@ void app_main() ESP_ERROR_CHECK( nvs_flash_init() ); initialise_wifi(); - esp_bt_controller_init(); + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + BLUFI_ERROR("%s initialize bt controller failed\n", __func__); + } ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); if (ret) { diff --git a/examples/bluetooth/controller_hci_uart/main/main.c b/examples/bluetooth/controller_hci_uart/main/controller_hci_uart_demo.c similarity index 61% rename from examples/bluetooth/controller_hci_uart/main/main.c rename to examples/bluetooth/controller_hci_uart/main/controller_hci_uart_demo.c index 3f6de6f47..6270596d9 100644 --- a/examples/bluetooth/controller_hci_uart/main/main.c +++ b/examples/bluetooth/controller_hci_uart/main/controller_hci_uart_demo.c @@ -23,21 +23,30 @@ static const char *tag = "CONTROLLER_UART_HCI"; static void uart_gpio_reset(void) { - ESP_LOGI(tag, "HCI UART Pin select: TX 5, RX, 18, CTS 23, RTS 19\n"); +#if CONFIG_BT_HCI_UART_NO + ESP_LOGI(tag, "HCI UART%d Pin select: TX 5, RX, 18, CTS 23, RTS 19", CONFIG_BT_HCI_UART_NO); -#if CONFIG_HCI_UART_NO - uart_set_pin(CONFIG_HCI_UART_NO, 5, 18, 19, 23); + uart_set_pin(CONFIG_BT_HCI_UART_NO, 5, 18, 19, 23); #endif } void app_main() { + esp_err_t ret; + /* As the UART1/2 pin conflict with flash pin, so do matrix of the signal and pin */ uart_gpio_reset(); - - esp_bt_controller_init(); - if (esp_bt_controller_enable(ESP_BT_MODE_BTDM) != ESP_OK) { + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret != ESP_OK) { + ESP_LOGE(tag, "Bluetooth Controller initialize failed, ret %d", ret); + return; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); + if (ret != ESP_OK) { + ESP_LOGE(tag, "Bluetooth Controller initialize failed, ret %d", ret); return; } } diff --git a/examples/bluetooth/controller_hci_uart/sdkconfig.defaults b/examples/bluetooth/controller_hci_uart/sdkconfig.defaults index 4e1001ba4..32a86537f 100644 --- a/examples/bluetooth/controller_hci_uart/sdkconfig.defaults +++ b/examples/bluetooth/controller_hci_uart/sdkconfig.defaults @@ -5,6 +5,6 @@ # BT config # CONFIG_BT_ENABLED=y -CONFIG_HCI_UART=y -CONFIG_HCI_UART_NO=1 -CONFIG_HCI_UART_BAUDRATE=921600 +CONFIG_BT_HCI_UART=y +CONFIG_BT_HCI_UART_NO_DEFAULT=1 +CONFIG_BT_HCI_UART_BAUDRATE_DEFAULT=921600 diff --git a/examples/bluetooth/gatt_client/main/gattc_demo.c b/examples/bluetooth/gatt_client/main/gattc_demo.c index 290448491..9985ccdc3 100644 --- a/examples/bluetooth/gatt_client/main/gattc_demo.c +++ b/examples/bluetooth/gatt_client/main/gattc_demo.c @@ -402,7 +402,8 @@ void gattc_client_test(void) void app_main() { - esp_bt_controller_init(); + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + esp_bt_controller_init(&bt_cfg); esp_bt_controller_enable(ESP_BT_MODE_BTDM); gattc_client_test(); diff --git a/examples/bluetooth/gatt_server/main/gatts_demo.c b/examples/bluetooth/gatt_server/main/gatts_demo.c index 39d33286a..934078aa7 100644 --- a/examples/bluetooth/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/gatt_server/main/gatts_demo.c @@ -398,7 +398,12 @@ void app_main() { esp_err_t ret; - esp_bt_controller_init(); + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(GATTS_TAG, "%s initialize controller failed\n", __func__); + return; + } ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); if (ret) { diff --git a/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c b/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c index 9bb03e7e8..291d9f594 100644 --- a/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c +++ b/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c @@ -313,7 +313,12 @@ void app_main() { esp_err_t ret; - esp_bt_controller_init(); + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(GATTS_TABLE_TAG, "%s enable controller failed\n", __func__); + return; + } ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); if (ret) { From c142b9b9e5daf6fd66dcc01104abb0d9e428e8d8 Mon Sep 17 00:00:00 2001 From: Alexey Gerenkov Date: Wed, 29 Mar 2017 21:09:47 +0300 Subject: [PATCH 7/7] esp32: RWDT is used to reboot system in case of panic handler crash also fixes TG1WDG protection bug in panic handler --- components/esp32/cpu_start.c | 23 +++++++++++++- components/esp32/include/esp_panic.h | 5 ++++ components/esp32/include/soc/rtc_cntl_reg.h | 6 ++++ components/esp32/panic.c | 33 ++++++++++++++++++++- 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 495a17803..9c06a49f2 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -55,6 +55,7 @@ #include "esp_task_wdt.h" #include "esp_phy_init.h" #include "esp_coexist.h" +#include "esp_panic.h" #include "esp_core_dump.h" #include "trax.h" @@ -92,6 +93,11 @@ static const char* TAG = "cpu_start"; void IRAM_ATTR call_start_cpu0() { +#if CONFIG_FREERTOS_UNICORE + RESET_REASON rst_reas[1]; +#else + RESET_REASON rst_reas[2]; +#endif cpu_configure_region_protection(); //Move exception vectors to IRAM @@ -99,10 +105,25 @@ void IRAM_ATTR call_start_cpu0() "wsr %0, vecbase\n" \ ::"r"(&_init_start)); + rst_reas[0] = rtc_get_reset_reason(0); +#if !CONFIG_FREERTOS_UNICORE + rst_reas[1] = rtc_get_reset_reason(1); +#endif + // from panic handler we can be reset by RWDT or TG0WDT + if (rst_reas[0] == RTCWDT_SYS_RESET || rst_reas[0] == TG0WDT_SYS_RESET +#if !CONFIG_FREERTOS_UNICORE + || rst_reas[1] == RTCWDT_SYS_RESET || rst_reas[1] == TG0WDT_SYS_RESET +#endif + ) { + // stop wdt in case of any + ESP_EARLY_LOGI(TAG, "Stop panic WDT"); + esp_panic_wdt_stop(); + } + memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start)); /* Unless waking from deep sleep (implying RTC memory is intact), clear RTC bss */ - if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET) { + if (rst_reas[0] != DEEPSLEEP_RESET) { memset(&_rtc_bss_start, 0, (&_rtc_bss_end - &_rtc_bss_start) * sizeof(_rtc_bss_start)); } diff --git a/components/esp32/include/esp_panic.h b/components/esp32/include/esp_panic.h index e9668facc..c9ee14099 100644 --- a/components/esp32/include/esp_panic.h +++ b/components/esp32/include/esp_panic.h @@ -61,6 +61,11 @@ esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags); void esp_clear_watchpoint(int no); +/** + * @brief Stops panic WDT + */ +void esp_panic_wdt_stop(void); + #endif #ifdef __cplusplus diff --git a/components/esp32/include/soc/rtc_cntl_reg.h b/components/esp32/include/soc/rtc_cntl_reg.h index 40d65f21f..ae287fd67 100644 --- a/components/esp32/include/soc/rtc_cntl_reg.h +++ b/components/esp32/include/soc/rtc_cntl_reg.h @@ -1650,6 +1650,12 @@ #define RTC_CNTL_WDT_PAUSE_IN_SLP_M (BIT(7)) #define RTC_CNTL_WDT_PAUSE_IN_SLP_V 0x1 #define RTC_CNTL_WDT_PAUSE_IN_SLP_S 7 +/* RTC_CNTL_WDT_STGX : */ +/*description: stage action selection values */ +#define RTC_WDT_STG_SEL_OFF 0 +#define RTC_WDT_STG_SEL_INT 1 +#define RTC_WDT_STG_SEL_RESET_CPU 2 +#define RTC_WDT_STG_SEL_RESET_SYSTEM 3 #define RTC_CNTL_WDTCONFIG1_REG (DR_REG_RTCCNTL_BASE + 0x90) /* RTC_CNTL_WDT_STG0_HOLD : R/W ;bitpos:[31:0] ;default: 32'd128000 ; */ diff --git a/components/esp32/panic.c b/components/esp32/panic.c index cd426344e..753851c11 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -284,11 +284,37 @@ static void disableAllWdts() TIMERG0.wdt_wprotect = 0; TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE; TIMERG1.wdt_config0.en = 0; - TIMERG0.wdt_wprotect = 0; + TIMERG1.wdt_wprotect = 0; } #endif +static void esp_panic_wdt_start() +{ + if (REG_GET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN)) { + return; + } + WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE); + WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1); + REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_SYS_RESET_LENGTH, 7); + REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_CPU_RESET_LENGTH, 7); + REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_RESET_SYSTEM); + // 64KB of core dump data (stacks of about 30 tasks) will produce ~85KB base64 data. + // @ 115200 UART speed it will take more than 6 sec to print them out. + WRITE_PERI_REG(RTC_CNTL_WDTCONFIG1_REG, RTC_CNTL_SLOWCLK_FREQ*7); + REG_SET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN); + WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0); +} + +void esp_panic_wdt_stop() +{ + WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE); + WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1); + REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_OFF); + REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN); + WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0); +} + static inline bool stackPointerIsSane(uint32_t sp) { return !(sp < 0x3ffae010 || sp > 0x3ffffff0 || ((sp & 0xf) != 0)); @@ -343,6 +369,9 @@ static void commonErrorHandler(XtExcFrame *frame) "A14 ", "A15 ", "SAR ", "EXCCAUSE", "EXCVADDR", "LBEG ", "LEND ", "LCOUNT " }; + // start panic WDT to restart system if we hang in this handler + esp_panic_wdt_start(); + //Feed the watchdogs, so they will give us time to print out debug info reconfigureAllWdts(); @@ -370,6 +399,7 @@ static void commonErrorHandler(XtExcFrame *frame) #if CONFIG_ESP32_PANIC_GDBSTUB disableAllWdts(); + esp_panic_wdt_stop(); panicPutStr("Entering gdb stub now.\r\n"); esp_gdbstub_panic_handler(frame); #else @@ -383,6 +413,7 @@ static void commonErrorHandler(XtExcFrame *frame) #endif reconfigureAllWdts(); #endif + esp_panic_wdt_stop(); #if CONFIG_ESP32_PANIC_PRINT_REBOOT || CONFIG_ESP32_PANIC_SILENT_REBOOT panicPutStr("Rebooting...\r\n"); esp_restart_noos();