Page 1 of 1

sendto sending duplicate packets?

Posted: Sun Sep 30, 2018 1:29 pm
by dieguito
Hello all.

This simple program attempts to connect to a wifi network and send out a simple 16-byte (+ overhead) UDP datagram to the network's broadcast address on port 9999:

Code: Select all

#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "esp_log.h"
#include "esp_err.h"
#include "esp_event_loop.h"
#include "esp_wifi.h"
#include <tcpip_adapter.h>
#include <lwip/ip_addr.h>
#include <lwip/sockets.h>
#include <string.h>

static const int CONNECTED_BIT = BIT0;
static const unsigned short UDP_PORT = 9999;

static EventGroupHandle_t wifi_event_group;

static esp_err_t event_handler(void *ctx, system_event_t *event)
{
	switch (event->event_id) {
	case SYSTEM_EVENT_STA_START:
		esp_wifi_connect();
		break;
	case SYSTEM_EVENT_STA_GOT_IP:
		xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
		break;
	case SYSTEM_EVENT_STA_DISCONNECTED:
		esp_wifi_connect();
		xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
		break;
	default:
		break;
	}
	return ESP_OK;
}

void app_main()
{
	unsigned char data[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
	wifi_config_t wifi_config = { .sta = { .ssid = "WIFI_SSID",.password = "WIFI_PASS" } };
	tcpip_adapter_ip_info_t ip_info;
	struct sockaddr_in addr;
	esp_err_t err;
	int s;

	// Init NVS
	ESP_LOGI("udp_test", "init NVS");
	err = nvs_flash_init();
	if (err == ESP_ERR_NVS_NO_FREE_PAGES) {
		ESP_ERROR_CHECK(nvs_flash_erase());
		err = nvs_flash_init();
	}
	ESP_ERROR_CHECK(err);

	// Init Wifi
	ESP_LOGI("udp_test", "init wifi");
	wifi_event_group = xEventGroupCreate();
	tcpip_adapter_init();
	esp_event_loop_init(event_handler, NULL);
	wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
	esp_wifi_init(&cfg);
	esp_wifi_set_storage(WIFI_STORAGE_RAM);
	esp_wifi_set_mode(WIFI_MODE_STA);
	esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
	esp_wifi_start();
	xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);

	// Get IP info
	ESP_LOGI("udp_test", "get IP info");
	if (tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info) == ESP_OK) {

		// Send UDP data
		ESP_LOGI("udp_test", "send UDP data");
		s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
		if (s > 0) {

			// Destination: broadcast
			ESP_LOGI("udp_test", "set destination address");
			memset(&addr, 0, sizeof(addr));
			addr.sin_family = AF_INET;
			addr.sin_addr.s_addr = (ip_info.ip.addr & ip_info.netmask.addr) | ~ip_info.netmask.addr;
			addr.sin_port = htons(UDP_PORT);

			sendto(s, data, sizeof(data), 0, (struct sockaddr*)&addr, sizeof(addr));
			ESP_LOGI("udp_test", "data sent");
			close(s);

			// Endless loop
			while (1) vTaskDelay(1000 / portTICK_PERIOD_MS);
		}
	}

	// If amything failed, try again
	esp_restart();
}
Upon execution, the following serial port information is displayed:

Code: Select all

I (28) boot: ESP-IDF v3.2-dev-1055-g3276a1316-dirty 2nd stage bootloader
I (28) boot: compile time 13:25:20
I (29) boot: Enabling RNG early entropy source...
I (35) boot: SPI Speed      : 40MHz
I (39) boot: SPI Mode       : DIO
I (43) boot: SPI Flash Size : 4MB
I (47) boot: Partition Table:
I (50) boot: ## Label            Usage          Type ST Offset   Length
I (58) boot: 0 nvs              WiFi data        01 02 00009000 00006000
I (65) boot: 1 phy_init         RF data          01 01 0000f000 00001000
I (73) boot: 2 factory          factory app      00 00 00010000 00100000
I (80) boot: End of partition table
I (84) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x14c44 ( 85060) map
I (123) esp_image: segment 1: paddr=0x00024c6c vaddr=0x3ffb0000 size=0x03384 ( 13188) load
I (128) esp_image: segment 2: paddr=0x00027ff8 vaddr=0x3ffb3384 size=0x00000 (     0) load
I (130) esp_image: segment 3: paddr=0x00028000 vaddr=0x40080000 size=0x00400 ( 1024) load
0x40080000: _WindowOverflow4 at $IDF_PATH/components/freertos/xtensa_vectors.S:1685
 
I (139) esp_image: segment 4: paddr=0x00028408 vaddr=0x40080400 size=0x07c08 ( 31752) load
I (161) esp_image: segment 5: paddr=0x00030018 vaddr=0x400d0018 size=0x65830 (415792) map
0x400d0018: _stext at ??:?
 
I (307) esp_image: segment 6: paddr=0x00095850 vaddr=0x40088008 size=0x088ac ( 34988) load
0x40088008: rcGetSched at ??:?
 
I (322) esp_image: segment 7: paddr=0x0009e104 vaddr=0x400c0000 size=0x00000 (     0) load
I (322) esp_image: segment 8: paddr=0x0009e10c vaddr=0x50000000 size=0x00000 (     0) load
I (338) boot: Loaded app from partition at offset 0x10000
I (338) boot: Disabling RNG early entropy source...
I (340) cpu_start: Pro cpu up.
I (344) cpu_start: Starting app cpu, entry point is 0x40080ff8
0x40080ff8: call_start_cpu1 at $IDF_PATH/components/esp32/cpu_start.c:228
 
I (0) cpu_start: App cpu up.
I (354) heap_init: Initializing. RAM available for dynamic allocation:
I (361) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (367) heap_init: At 3FFB9400 len 00026C00 (155 KiB): DRAM
I (373) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
I (379) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (386) heap_init: At 400908B4 len 0000F74C (61 KiB): IRAM
I (392) cpu_start: Pro cpu start user code
I (75) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (76) udp_test: init NVS
I (126) udp_test: init wifi
I (126) wifi: wifi driver task: 3ffc1054, prio:23, stack:3584, core=0
I (136) wifi: wifi firmware version: d8b211c
I (136) wifi: config NVS flash: enabled
I (136) wifi: config nano formating: disabled
I (136) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (146) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (176) wifi: Init dynamic tx buffer num: 32
I (176) wifi: Init data frame dynamic rx buffer num: 32
I (176) wifi: Init management frame dynamic rx buffer num: 32
I (186) wifi: Init static rx buffer size: 1600
I (186) wifi: Init static rx buffer num: 10
I (196) wifi: Init dynamic rx buffer num: 32
I (276) phy: phy_version: 4000, b6198fa, Sep 3 2018, 15:11:06, 0, 0
I (276) wifi: mode : sta (30:ae:a4:47:65:00)
I (1006) wifi: n:6 0, o:1 0, ap:255 255, sta:6 0, prof:1
I (1986) wifi: state: init -> auth (b0)
I (2006) wifi: state: auth -> assoc (0)
I (2006) wifi: state: assoc -> run (10)
I (6026) wifi: connected with WIFI_SSID, channel 6
I (6026) wifi: pm start, type: 1
 
I (7126) event: sta ip: 192.168.1.102, mask: 255.255.255.0, gw: 192.168.1.1
I (7126) udp_test: get IP info
I (7126) udp_test: send UDP data
I (7126) udp_test: set destination address
I (7136) udp_test: data sent
I would expect this program to send out a single packet with its content as defined, however it yields two identical packets about 300 usec apart.

I'm very new to ESP-IDF and my prior experience with sockets was under Windows, where things aren't quite the same, so I wonder whether I am doing something wrong and this is the expected behaviour, or whether this is something that needs to be corrected in the appropriate libraries.

Has anyone come across a similar problem?

Thanks!