mdns: Add host test using linux target

pull/10408/head
David Cermak 2021-06-30 18:39:29 +02:00 zatwierdzone przez David Čermák
rodzic 09f10f326a
commit fc7e2d9e90
34 zmienionych plików z 1174 dodań i 7 usunięć

Wyświetl plik

@ -1,7 +1,22 @@
idf_component_register(SRCS "mdns.c"
"mdns_console.c"
"mdns_networking.c"
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "private_include"
REQUIRES lwip console esp_netif
PRIV_REQUIRES esp_timer)
if(CONFIG_MDNS_NETWORKING_SOCKET)
set(MDNS_NETWORKING "mdns_networking_socket.c")
else()
set(MDNS_NETWORKING "mdns_networking_lwip.c")
endif()
idf_build_get_property(target IDF_TARGET)
if(${target} STREQUAL "linux")
set(dependencies esp_system_protocols_linux)
set(srcs "mdns.c" ${MDNS_NETWORKING})
else()
set(dependencies lwip console esp_netif)
set(private_dependencies esp_timer)
set(srcs "mdns.c" ${MDNS_NETWORKING} "mdns_console.c")
endif()
idf_component_register(
SRCS ${srcs}
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "private_include"
REQUIRES ${dependencies}
PRIV_REQUIRES ${private_dependencies})

Wyświetl plik

@ -75,4 +75,13 @@ menu "mDNS"
Configures period of mDNS timer, which periodically transmits packets
and schedules mDNS searches.
config MDNS_NETWORKING_SOCKET
bool "Use BSD sockets for mdns networking"
default n
help
Enables optional mdns networking implementation using BSD sockets
in UDP multicast mode.
This option creates a new thread to serve receiving packets (TODO).
This option uses additional N sockets, where N is number of interfaces.
endmenu

Wyświetl plik

@ -1,2 +1,7 @@
ifdef CONFIG_MDNS_NETWORKING_SOCKET
COMPONENT_OBJEXCLUDE := mdns_networking_lwip.o
else
COMPONENT_OBJEXCLUDE := mdns_networking_socket.o
endif
COMPONENT_ADD_INCLUDEDIRS := include
COMPONENT_PRIV_INCLUDEDIRS := private_include

Wyświetl plik

@ -0,0 +1,5 @@
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(COMPONENTS main)
project(mdns_host)

Wyświetl plik

@ -0,0 +1,25 @@
# Setup dummy network interfaces
```
sudo ip link add eth2 type dummy
sudo ip addr add 192.168.1.200/24 dev eth2
sudo ip link set eth2 up
sudo ifconfig eth2 multicast
```
# Dig on a specified interface
```
dig +short -b 192.168.1.200 -p 5353 @224.0.0.251 myesp.local
```
# Run avahi to browse services
Avahi needs the netif to have the "multicast" flag set
```bash
david@david-comp:~/esp/idf (feature/mdns_networking_socket)$ avahi-browse -a -r -p
+;eth2;IPv6;myesp-service2;Web Site;local
+;eth2;IPv4;myesp-service2;Web Site;local
=;eth2;IPv6;myesp-service2;Web Site;local;myesp.local;192.168.1.200;80;"board=esp32" "u=user" "p=password"
=;eth2;IPv4;myesp-service2;Web Site;local;myesp.local;192.168.1.200;80;"board=esp32" "u=user" "p=password"
```

Wyświetl plik

@ -0,0 +1,3 @@
idf_component_register(SRCS esp_event_mock.c
INCLUDE_DIRS include
REQUIRES esp_system_protocols_linux)

Wyświetl plik

@ -0,0 +1,29 @@
// Copyright 2021 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 "esp_err.h"
#include "esp_event.h"
const char * WIFI_EVENT = "WIFI_EVENT";
const char * IP_EVENT = "IP_EVENT";
esp_err_t esp_event_handler_register(const char * event_base, int32_t event_id, void* event_handler, void* event_handler_arg)
{
return ESP_OK;
}
esp_err_t esp_event_handler_unregister(const char * event_base, int32_t event_id, void* event_handler)
{
return ESP_OK;
}

Wyświetl plik

@ -0,0 +1,32 @@
// Copyright 2021 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.
#pragma once
#include "stdbool.h"
#include "esp_err.h"
#include "esp_event_base.h"
#include "bsd_strings.h"
#define ESP_EVENT_DECLARE_BASE(x)
#define ESP_EVENT_ANY_ID (-1)
typedef void * esp_event_base_t;
typedef void * system_event_t;
const char* WIFI_EVENT;
const char* IP_EVENT;
esp_err_t esp_event_handler_register(const char * event_base, int32_t event_id, void* event_handler, void* event_handler_arg);
esp_err_t esp_event_handler_unregister(const char * event_base, int32_t event_id, void* event_handler);

Wyświetl plik

@ -0,0 +1,21 @@
// Copyright 2021 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.
#pragma once
typedef enum {
WIFI_EVENT_STA_CONNECTED, /**< ESP32 station connected to AP */
WIFI_EVENT_STA_DISCONNECTED, /**< ESP32 station disconnected from AP */
WIFI_EVENT_AP_START, /**< ESP32 soft-AP start */
WIFI_EVENT_AP_STOP, /**< ESP32 soft-AP stop */
} mdns_used_event_t;

Wyświetl plik

@ -0,0 +1,3 @@
idf_component_register(SRCS esp_netif_linux.c
INCLUDE_DIRS include
REQUIRES esp_system_protocols_linux)

Wyświetl plik

@ -0,0 +1,9 @@
menu "LWIP-MOCK-CONFIG"
config LWIP_IPV6
bool "Enable IPv6"
default true
help
Enable/disable IPv6
endmenu

Wyświetl plik

@ -0,0 +1,163 @@
// Copyright 2021 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<stdio.h>
#include <stdlib.h>
#include "esp_netif.h"
#include "esp_err.h"
#include <string.h> //strlen
#include <sys/socket.h>
#include <arpa/inet.h> //inet_addr
#include <sys/types.h>
#include <ifaddrs.h>
#include <net/if.h>
#include "esp_netif_types.h"
#define MAX_NETIFS 4
static esp_netif_t* s_netif_list[MAX_NETIFS] = { 0 };
struct esp_netif_obj
{
const char *if_key;
const char *if_desc;
};
esp_netif_t *esp_netif_get_handle_from_ifkey(const char *if_key)
{
for (int i=0; i<MAX_NETIFS; ++i) {
if (s_netif_list[i] && strcmp(s_netif_list[i]->if_key, if_key) == 0) {
return s_netif_list[i];
}
}
return NULL;
}
esp_err_t esp_netif_get_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info)
{
if (esp_netif == NULL) {
return ESP_ERR_INVALID_STATE;
}
struct ifaddrs *addrs, *tmp;
getifaddrs(&addrs);
tmp = addrs;
while (tmp) {
if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_INET) {
char addr[20];
struct sockaddr_in *pAddr = (struct sockaddr_in *) tmp->ifa_addr;
inet_ntop(AF_INET, &pAddr->sin_addr, addr, sizeof(addr) );
if (strcmp(esp_netif->if_desc, tmp->ifa_name) == 0) {
printf("AF_INET: %s: %s\n", tmp->ifa_name, addr);
memcpy(&ip_info->ip.addr, &pAddr->sin_addr, 4);
break;
}
}
tmp = tmp->ifa_next;
}
return ESP_OK;
}
esp_err_t esp_netif_dhcpc_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status)
{
return ESP_OK;
}
esp_err_t esp_netif_get_ip6_linklocal(esp_netif_t *esp_netif, esp_ip6_addr_t *if_ip6)
{
if (esp_netif == NULL) {
return ESP_ERR_INVALID_STATE;
}
struct ifaddrs *addrs, *tmp;
getifaddrs(&addrs);
tmp = addrs;
while (tmp)
{
if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_INET6) {
char addr[64];
struct sockaddr_in6 *pAddr = (struct sockaddr_in6 *)tmp->ifa_addr;
inet_ntop(AF_INET6, &pAddr->sin6_addr, addr, sizeof(addr) );
if (strcmp(esp_netif->if_desc, tmp->ifa_name) == 0) {
printf("AF_INET6: %s: %s\n", tmp->ifa_name, addr);
memcpy(if_ip6->addr, &pAddr->sin6_addr, 4*4);
break;
}
}
tmp = tmp->ifa_next;
}
freeifaddrs(addrs);
return ESP_OK;
}
int esp_netif_get_netif_impl_index(esp_netif_t *esp_netif)
{
if (esp_netif == NULL) {
return -1;
}
uint32_t interfaceIndex = if_nametoindex(esp_netif->if_desc);
return interfaceIndex;
}
esp_err_t esp_netif_get_netif_impl_name(esp_netif_t *esp_netif, char* name)
{
if (esp_netif == NULL) {
return ESP_ERR_INVALID_STATE;
}
strcpy(name, esp_netif->if_desc);
return ESP_OK;
}
const char *esp_netif_get_desc(esp_netif_t *esp_netif)
{
if (esp_netif == NULL) {
return NULL;
}
return esp_netif->if_desc;
}
esp_netif_t *esp_netif_new(const esp_netif_config_t *config)
{
if (esp_netif_get_handle_from_ifkey(config->base->if_key)) {
return NULL;
}
esp_netif_t* netif = calloc(1, sizeof(struct esp_netif_obj));
if (netif) {
netif->if_desc = config->base->if_desc;
netif->if_key = config->base->if_key;
}
for (int i=0; i<MAX_NETIFS; ++i) {
if (s_netif_list[i] == NULL) {
s_netif_list[i] = netif;
break;
}
}
return netif;
}
void esp_netif_destroy(esp_netif_t *esp_netif)
{
for (int i=0; i<MAX_NETIFS; ++i) {
if (s_netif_list[i] == esp_netif) {
s_netif_list[i] = NULL;
break;
}
}
free(esp_netif);
}

Wyświetl plik

@ -0,0 +1,15 @@
// Copyright 2021 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.
#pragma once
#include "esp_event.h"

Wyświetl plik

@ -0,0 +1,3 @@
idf_component_register(SRCS esp_log_impl.c strlcat.c
INCLUDE_DIRS include
REQUIRES esp_netif_linux esp_timer_linux freertos_linux esp_event_mock esp_netif log esp_common)

Wyświetl plik

@ -0,0 +1,35 @@
// Copyright 2021 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 "esp_err.h"
#include "esp_log.h"
#include <stdlib.h>
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression)
{
ESP_LOGE("ESP_ERROR_CHECK", "Failed with esp_err_t: 0x%x", rc);
ESP_LOGE("ESP_ERROR_CHECK", "Expression: %s", expression);
ESP_LOGE("ESP_ERROR_CHECK", "Functions: %s %s(%d)", function, file, line);
abort();
}
void esp_log_buffer_hexdump_internal(const char *tag, const void *buffer, uint16_t buff_len, esp_log_level_t log_level)
{
if ( LOG_LOCAL_LEVEL >= log_level ) {
ESP_LOG_LEVEL(log_level, tag, "Buffer:%p length:%d", buffer, buff_len);
for (int i=0; i<buff_len; ++i) {
printf("%02x ", ((uint8_t*)buffer)[i]);
}
printf("\n");
}
}

Wyświetl plik

@ -0,0 +1,16 @@
// Copyright 2021 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.
#pragma once
size_t strlcat(char *dest, const char *src, size_t size);

Wyświetl plik

@ -0,0 +1,16 @@
// Copyright 2021 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.
#pragma once
#include_next "endian.h"

Wyświetl plik

@ -0,0 +1,68 @@
/* $OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $ */
/*-
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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.
*/
#include "string.h"
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
strlcat(dst, src, siz)
char *dst;
const char *src;
size_t siz;
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}

Wyświetl plik

@ -0,0 +1,5 @@
idf_component_register(SRCS esp_timer_linux.c timer_task.cpp
INCLUDE_DIRS include
REQUIRES esp_system_protocols_linux freertos_linux)
target_compile_features(${COMPONENT_LIB} PRIVATE cxx_std_17)

Wyświetl plik

@ -0,0 +1,47 @@
// Copyright 2021 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 "esp_err.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
void * create_tt(esp_timer_cb_t cb);
void destroy_tt(void* tt);
void set_tout(void* tt, uint32_t ms);
esp_err_t esp_timer_create(const esp_timer_create_args_t* create_args,
esp_timer_handle_t* out_handle)
{
*out_handle = (esp_timer_handle_t)create_tt(create_args->callback);
return ESP_OK;
}
esp_err_t esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t period)
{
set_tout(timer, period/1000);
return ESP_OK;
}
esp_err_t esp_timer_stop(esp_timer_handle_t timer)
{
return ESP_OK;
}
esp_err_t esp_timer_delete(esp_timer_handle_t timer)
{
destroy_tt(timer);
return ESP_OK;
}

Wyświetl plik

@ -0,0 +1,41 @@
// Copyright 2021 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.
#pragma once
#include <stdbool.h>
#include <stdint.h>
typedef struct esp_timer* esp_timer_handle_t;
typedef void (*esp_timer_cb_t)(void* arg);
typedef enum {
ESP_TIMER_TASK,
} esp_timer_dispatch_t;
typedef struct {
esp_timer_cb_t callback; //!< Function to call when timer expires
void* arg; //!< Argument to pass to the callback
esp_timer_dispatch_t dispatch_method; //!< Call the callback from task or from ISR
const char* name; //!< Timer name, used in esp_timer_dump function
bool skip_unhandled_events; //!< Skip unhandled events for periodic timers
} esp_timer_create_args_t;
esp_err_t esp_timer_create(const esp_timer_create_args_t* create_args,
esp_timer_handle_t* out_handle);
esp_err_t esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t period);
esp_err_t esp_timer_stop(esp_timer_handle_t timer);
esp_err_t esp_timer_delete(esp_timer_handle_t timer);

Wyświetl plik

@ -0,0 +1,38 @@
// Copyright 2021 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 "timer_task.hpp"
#include <cstdint>
#include <vector>
#include <memory>
#include <cstring>
extern "C" void * create_tt(cb_t cb)
{
auto * tt = new TimerTaskMock(cb);
return tt;
}
extern "C" void destroy_tt(void* tt)
{
auto * timer_task = static_cast<TimerTaskMock *>(tt);
delete(timer_task);
}
extern "C" void set_tout(void* tt, uint32_t ms)
{
auto * timer_task = static_cast<TimerTaskMock *>(tt);
timer_task->SetTimeout(ms);
}

Wyświetl plik

@ -0,0 +1,61 @@
// Copyright 2021 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.
#pragma once
#include <queue>
#include <mutex>
#include <condition_variable>
#include <memory>
#include <thread>
#include <atomic>
typedef void (*cb_t)(void* arg);
class TimerTaskMock
{
public:
TimerTaskMock(cb_t cb): cb(cb), t(run_static, this), active(false), ms(INT32_MAX) {}
~TimerTaskMock(void) { active = false; t.join(); }
void SetTimeout(uint32_t m)
{
ms = m;
active = true;
}
private:
static void run_static(TimerTaskMock* timer)
{
timer->run();
}
void run(void)
{
while (!active.load()) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
while (active.load()) {
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
cb(nullptr);
}
}
cb_t cb;
std::thread t;
std::atomic<bool> active;
uint32_t ms;
};

Wyświetl plik

@ -0,0 +1,9 @@
idf_component_register(SRCS freertos_linux.c queue_unique_ptr.cpp
INCLUDE_DIRS include
REQUIRES esp_system_protocols_linux)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(${COMPONENT_LIB} PRIVATE Threads::Threads)
target_compile_features(${COMPONENT_LIB} PRIVATE cxx_std_17)

Wyświetl plik

@ -0,0 +1,7 @@
menu "FreeRTOS"
config FREERTOS_NO_AFFINITY
hex
default 0x7FFFFFFF
endmenu

Wyświetl plik

@ -0,0 +1,192 @@
// Copyright 2021 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 <unistd.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <pthread.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
void * create_q(void);
void destroy_q(void* q);
bool send_q(void* q, uint8_t *data, size_t len);
bool recv_q(void* q, uint8_t *data, size_t len, uint32_t ms);
static uint64_t s_semaphore_data = 0;
struct queue_handle {
size_t item_size;
void * q;
};
QueueHandle_t xQueueCreate( uint32_t uxQueueLength, uint32_t uxItemSize )
{
struct queue_handle * h = calloc(1, sizeof(struct queue_handle));
h->item_size = uxItemSize;
h->q = create_q();
return (QueueHandle_t)h;
}
uint32_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait)
{
struct queue_handle * h = xQueue;
return send_q(h->q, (uint8_t*)pvItemToQueue, h->item_size) ? pdTRUE : pdFAIL;
}
uint32_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait)
{
struct queue_handle * h = xQueue;
return recv_q(h->q, (uint8_t*)pvBuffer, h->item_size, xTicksToWait) ? pdTRUE : pdFAIL;
}
BaseType_t xSemaphoreGive( QueueHandle_t xQueue)
{
return xQueueSend(xQueue, &s_semaphore_data, portMAX_DELAY);
}
BaseType_t xSemaphoreTake( QueueHandle_t xQueue, TickType_t pvTask )
{
return xQueueReceive(xQueue, &s_semaphore_data, portMAX_DELAY);
}
void vQueueDelete( QueueHandle_t xQueue )
{
struct queue_handle * h = xQueue;
if (h->q) {
destroy_q(h->q);
}
free(xQueue);
}
QueueHandle_t xSemaphoreCreateBinary(void)
{
QueueHandle_t sempaphore = xQueueCreate(1, 1);
return sempaphore;
}
QueueHandle_t xSemaphoreCreateMutex(void)
{
QueueHandle_t sempaphore = xQueueCreate(1, 1);
if (sempaphore) {
xSemaphoreGive(sempaphore);
}
return sempaphore;
}
void vTaskDelete(TaskHandle_t *task)
{
if (task == NULL) {
pthread_exit(0);
}
void *thread_rval = NULL;
pthread_join((pthread_t)task, &thread_rval);
}
TickType_t xTaskGetTickCount( void )
{
struct timespec spec;
clock_gettime(CLOCK_REALTIME, &spec);
return spec.tv_nsec / 1000000 + spec.tv_sec * 1000;
}
void vTaskDelay( const TickType_t xTicksToDelay )
{
usleep(xTicksToDelay*1000);
}
void * pthread_task(void * params)
{
struct {
void * const param;
TaskFunction_t task;
bool started;
} *pthread_params = params;
void * const param = pthread_params->param;
TaskFunction_t task = pthread_params->task;
pthread_params->started = true;
task(param);
return NULL;
}
BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pvTaskCode,
const char * const pcName,
const uint32_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pvCreatedTask,
const BaseType_t xCoreID)
{
xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask);
return pdTRUE;
}
void xTaskCreate(TaskFunction_t pvTaskCode, const char * const pcName, const uint32_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pvCreatedTask)
{
pthread_t new_thread = (pthread_t)NULL;
pthread_attr_t attr;
struct {
void * const param;
TaskFunction_t task;
bool started;
} pthread_params = { .param = pvParameters, .task = pvTaskCode};
int res = pthread_attr_init(&attr);
assert(res == 0);
res = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
assert(res == 0);
res = pthread_create(&new_thread, &attr, pthread_task, &pthread_params);
assert(res == 0);
if (pvCreatedTask) {
*pvCreatedTask = (void*)new_thread;
}
// just wait till the task started so we can unwind params from the stack
while (pthread_params.started == false) {
usleep(1000);
}
}
uint32_t esp_get_free_heap_size(void)
{
return 0;
}
uint32_t esp_random(void)
{
return rand();
}
void xTaskNotifyGive(TaskHandle_t task)
{
}
BaseType_t xTaskNotifyWait(uint32_t bits_entry_clear, uint32_t bits_exit_clear, uint32_t *value, TickType_t wait_time )
{
return true;
}
TaskHandle_t xTaskGetCurrentTaskHandle(void)
{
return NULL;
}

Wyświetl plik

@ -0,0 +1,20 @@
// Copyright 2021 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.
#pragma once
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#define ESP_TASK_PRIO_MAX 25
#define ESP_TASKD_EVENT_PRIO 5

Wyświetl plik

@ -0,0 +1,46 @@
// Copyright 2021 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.
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#define portTICK_PERIOD_MS 1
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
typedef void * xSemaphoreHandle;
typedef void * SemaphoreHandle_t;
typedef void * xQueueHandle;
typedef void * QueueHandle_t;
typedef void * TaskHandle_t;
typedef uint32_t TickType_t;
typedef uint32_t portTickType;
typedef void (*TaskFunction_t)( void * );
typedef unsigned int UBaseType_t;
typedef int BaseType_t;
#define pdFALSE ( ( BaseType_t ) 0 )
#define pdTRUE ( ( BaseType_t ) 1 )
#define pdPASS ( pdTRUE )
#define pdFAIL ( pdFALSE )
#define portTICK_RATE_MS portTICK_PERIOD_MS
#define pdMS_TO_TICKS(tick) (tick)
uint32_t esp_get_free_heap_size(void);
uint32_t esp_random(void);

Wyświetl plik

@ -0,0 +1,58 @@
// Copyright 2021 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.
#pragma once
#include "freertos/FreeRTOS.h"
#define xTaskHandle TaskHandle_t
#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) )
void vTaskDelay( const TickType_t xTicksToDelay );
void xTaskNotifyGive(TaskHandle_t task);
TaskHandle_t xTaskGetCurrentTaskHandle(void);
BaseType_t xTaskNotifyWait(uint32_t bits_entry_clear, uint32_t bits_exit_clear, uint32_t *value, TickType_t wait_time );
BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pvTaskCode,
const char * const pcName,
const uint32_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pvCreatedTask,
const BaseType_t xCoreID);
void xTaskCreate(TaskFunction_t pvTaskCode, const char * const pcName, const uint32_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pvCreatedTask);
TickType_t xTaskGetTickCount( void );
void vQueueDelete( QueueHandle_t xQueue );
QueueHandle_t xSemaphoreCreateBinary(void);
QueueHandle_t xSemaphoreCreateMutex(void);
BaseType_t xSemaphoreGive( QueueHandle_t xQueue);
BaseType_t xSemaphoreTake( QueueHandle_t xQueue, TickType_t pvTask );
void vTaskDelete(TaskHandle_t *task);
QueueHandle_t xQueueCreate( uint32_t uxQueueLength,
uint32_t uxItemSize );
uint32_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait);
uint32_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait);

Wyświetl plik

@ -0,0 +1,51 @@
// Copyright 2021 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 "queue_unique_ptr.hpp"
#include <cstdint>
#include <vector>
#include <memory>
#include <cstring>
extern "C" void * create_q(void)
{
auto * q = new QueueMock<std::vector<uint8_t>>();
return q;
}
extern "C" void destroy_q(void* q)
{
auto * queue = static_cast<QueueMock<std::vector<uint8_t>> *>(q);
delete(queue);
}
extern "C" bool send_q(void* q, uint8_t *data, size_t len)
{
auto v = std::make_unique<std::vector<uint8_t>>(len);
v->assign(data, data+len);
auto queue = static_cast<QueueMock<std::vector<uint8_t>> *>(q);
queue->send(std::move(v));
return true;
}
extern "C" bool recv_q(void* q, uint8_t *data, size_t len, uint32_t ms)
{
auto queue = static_cast<QueueMock<std::vector<uint8_t>> *>(q);
auto v = queue->receive(ms);
if (v == nullptr) {
return false;
}
memcpy(data, (void *)v->data(), len);
return true;
}

Wyświetl plik

@ -0,0 +1,55 @@
// Copyright 2021 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.
#pragma once
#include <queue>
#include <mutex>
#include <condition_variable>
#include <memory>
#include <thread>
#include <atomic>
template <class T>
class QueueMock
{
public:
QueueMock(void): q(), m(), c() {}
~QueueMock(void) {}
void send(std::unique_ptr<T> t)
{
std::lock_guard<std::mutex> lock(m);
q.push(std::move(t));
c.notify_one();
}
std::unique_ptr<T> receive(uint32_t ms)
{
std::unique_lock<std::mutex> lock(m);
while(q.empty()) {
if (c.wait_for(lock, std::chrono::milliseconds(ms)) == std::cv_status::timeout) {
return nullptr;
}
}
std::unique_ptr<T> val = std::move(q.front());
q.pop();
return val;
}
private:
std::queue<std::unique_ptr<T>> q;
mutable std::mutex m;
std::condition_variable c;
};

Wyświetl plik

@ -0,0 +1,4 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS
"."
REQUIRES mdns)

Wyświetl plik

@ -0,0 +1,59 @@
#include <stdio.h>
#include "mdns.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static const char *TAG = "mdns-test";
static void query_mdns_host(const char * host_name)
{
ESP_LOGI(TAG, "Query A: %s.local", host_name);
struct esp_ip4_addr addr;
addr.addr = 0;
esp_err_t err = mdns_query_a(host_name, 2000, &addr);
if(err){
if(err == ESP_ERR_NOT_FOUND){
ESP_LOGW(TAG, "%x: Host was not found!", (err));
return;
}
ESP_LOGE(TAG, "Query Failed: %x", (err));
return;
}
ESP_LOGI(TAG, "Query A: %s.local resolved to: " IPSTR, host_name, IP2STR(&addr));
}
int main(int argc , char *argv[])
{
setvbuf(stdout, NULL, _IONBF, 0);
const esp_netif_inherent_config_t base_cg = { .if_key = "WIFI_STA_DEF", .if_desc = "eth2" };
esp_netif_config_t cfg = { .base = &base_cg };
esp_netif_t *sta = esp_netif_new(&cfg);
mdns_init();
mdns_hostname_set("myesp");
ESP_LOGI(TAG, "mdns hostname set to: [%s]", "myesp");
//set default mDNS instance name
mdns_instance_name_set("myesp-inst");
//structure with TXT records
mdns_txt_item_t serviceTxtData[3] = {
{"board","esp32"},
{"u","user"},
{"p","password"}
};
vTaskDelay(1000);
ESP_ERROR_CHECK(mdns_service_add("myesp-service2", "_http", "_tcp", 80, serviceTxtData, 3));
vTaskDelay(2000);
query_mdns_host("david-comp");
vTaskDelay(2000);
esp_netif_destroy(sta);
mdns_free();
ESP_LOGI(TAG, "Exit");
return 0;
}

Wyświetl plik

@ -14,8 +14,10 @@
#ifndef MDNS_PRIVATE_H_
#define MDNS_PRIVATE_H_
#include "sdkconfig.h"
#include "mdns.h"
#include "esp_task.h"
#include "esp_timer.h"
//#define MDNS_ENABLE_DEBUG