Skip to content

Commit 7dc5076

Browse files
committed
fix sender udp packet drop
1 parent f9ad96b commit 7dc5076

File tree

1 file changed

+55
-3
lines changed

1 file changed

+55
-3
lines changed

main/scream_sender.c

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <lwip/netdb.h>
1414
#include <string.h>
1515
#include <math.h>
16+
#include "esp_rom_sys.h" // For ets_delay_us
1617

1718
#define TAG "scream_sender"
1819

@@ -22,6 +23,11 @@ static const char header[] = {1, 16, 2, 0, 0};
2223
#define CHUNK_SIZE 1152
2324
#define PACKET_SIZE (CHUNK_SIZE + HEADER_SIZE)
2425

26+
// Socket options
27+
#define UDP_TX_BUFFER_SIZE (1024 * 32)
28+
#define UDP_SEND_TIMEOUT_MS 10
29+
#define MAX_SEND_RETRIES 3
30+
2531
// State variables
2632
static bool s_is_sender_initialized = false;
2733
static bool s_is_sender_running = false;
@@ -32,7 +38,7 @@ static struct sockaddr_in s_dest_addr;
3238

3339
// Buffer for audio data
3440
static char s_data_out[PACKET_SIZE];
35-
static char s_data_in[CHUNK_SIZE * 10];
41+
static char s_data_in[CHUNK_SIZE * 16]; // Increased buffer size
3642
static int s_data_in_head = 0;
3743

3844
// UAC callbacks
@@ -48,7 +54,27 @@ static esp_err_t uac_device_output_cb(uint8_t *buf, size_t len, void *arg)
4854
// Process the data in chunks
4955
while (s_data_in_head >= CHUNK_SIZE) {
5056
memcpy(s_data_out + HEADER_SIZE, s_data_in, CHUNK_SIZE);
51-
sendto(s_sock, s_data_out, PACKET_SIZE, 0, (struct sockaddr *)&s_dest_addr, sizeof(s_dest_addr));
57+
58+
// Send with retry logic
59+
int sent = -1;
60+
int retry_count = 0;
61+
62+
while (sent < 0 && retry_count < MAX_SEND_RETRIES) {
63+
sent = sendto(s_sock, s_data_out, PACKET_SIZE, 0,
64+
(struct sockaddr *)&s_dest_addr, sizeof(s_dest_addr));
65+
66+
if (sent < 0) {
67+
ESP_LOGW(TAG, "Failed to send UDP packet: errno %d, retry %d",
68+
errno, retry_count + 1);
69+
retry_count++;
70+
71+
// Small delay before retry (500 microseconds)
72+
esp_rom_delay_us(500);
73+
} else if (sent != PACKET_SIZE) {
74+
ESP_LOGW(TAG, "Incomplete UDP packet sent: %d of %d bytes",
75+
sent, PACKET_SIZE);
76+
}
77+
}
5278

5379
// Move remaining data to the beginning of the buffer
5480
s_data_in_head -= CHUNK_SIZE;
@@ -104,6 +130,32 @@ esp_err_t scream_sender_init(void)
104130
return ESP_FAIL;
105131
}
106132

133+
// Configure socket options for better reliability
134+
int opt_val;
135+
136+
// Increase send buffer size
137+
opt_val = UDP_TX_BUFFER_SIZE;
138+
if (setsockopt(s_sock, SOL_SOCKET, SO_SNDBUF, &opt_val, sizeof(opt_val)) < 0) {
139+
ESP_LOGW(TAG, "Failed to set SO_SNDBUF: errno %d", errno);
140+
}
141+
142+
// Set timeout to prevent blocking too long on send
143+
struct timeval timeout;
144+
timeout.tv_sec = 0;
145+
timeout.tv_usec = UDP_SEND_TIMEOUT_MS * 1000;
146+
if (setsockopt(s_sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0) {
147+
ESP_LOGW(TAG, "Failed to set SO_SNDTIMEO: errno %d", errno);
148+
}
149+
150+
// Set QoS priority for audio traffic
151+
#if defined(IP_TOS) && defined(IPTOS_DSCP_EF)
152+
// Use Expedited Forwarding (EF) for real-time audio
153+
opt_val = IPTOS_DSCP_EF;
154+
if (setsockopt(s_sock, IPPROTO_IP, IP_TOS, &opt_val, sizeof(opt_val)) < 0) {
155+
ESP_LOGW(TAG, "Failed to set IP_TOS: errno %d", errno);
156+
}
157+
#endif
158+
107159
// Initialize the destination address from settings
108160
app_config_t *config = config_manager_get_config();
109161
memset(&s_dest_addr, 0, sizeof(s_dest_addr));
@@ -213,4 +265,4 @@ esp_err_t scream_sender_update_destination(void)
213265

214266
return ESP_OK;
215267
}
216-
#endif
268+
#endif

0 commit comments

Comments
 (0)