-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathespnow_test.cc
More file actions
333 lines (283 loc) · 12.7 KB
/
espnow_test.cc
File metadata and controls
333 lines (283 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
#include "espnow_test.h"
#include "espnow_manager.h"
#include "board.h"
#include "system_info.h"
#include <esp_log.h>
#include <esp_wifi.h>
#include <esp_event.h>
#include <nvs_flash.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#define TAG "EspNowTest"
using namespace espnow;
static bool test_running = false;
// Serial input helper
static int read_serial_mac(char* buffer, size_t max_len, uint32_t timeout_ms) {
int idx = 0;
uint32_t start_time = esp_timer_get_time() / 1000;
while (idx < max_len - 1) {
// Check timeout
if ((esp_timer_get_time() / 1000 - start_time) > timeout_ms) {
break;
}
int c = fgetc(stdin);
if (c == '\n' || c == '\r') {
break;
}
if (c != EOF && c != -1) {
buffer[idx++] = c;
fputc(c, stdout); // Echo character
fflush(stdout);
}
vTaskDelay(pdMS_TO_TICKS(10));
}
buffer[idx] = '\0';
printf("\n");
return idx;
}
// Print peer list
static void print_peers() {
auto& manager = EspNowManager::GetInstance();
auto peers = manager.GetPairedDevices();
if (peers.empty()) {
ESP_LOGI(TAG, "No paired devices");
return;
}
ESP_LOGI(TAG, "========== Paired Devices (%zu) ==========", peers.size());
for (const auto& peer : peers) {
ESP_LOGI(TAG, " MAC: %s", EspNowManager::MacToString(peer.mac).c_str());
ESP_LOGI(TAG, " Name: %s", peer.name.c_str());
ESP_LOGI(TAG, " UUID: %s", peer.uuid.c_str());
if (!peer.agentmail_inbox.empty()) {
ESP_LOGI(TAG, " AgentMail: %s", peer.agentmail_inbox.c_str());
}
ESP_LOGI(TAG, " RSSI: %d dBm", peer.rssi);
ESP_LOGI(TAG, " Last seen: %u ms ago",
(uint32_t)(esp_timer_get_time() / 1000) - peer.last_seen);
ESP_LOGI(TAG, " ---");
}
ESP_LOGI(TAG, "=======================================");
}
// Periodic status update task
static void status_task(void* arg) {
while (test_running) {
print_peers();
vTaskDelay(pdMS_TO_TICKS(10000)); // Every 10 seconds
}
vTaskDelete(NULL);
}
// Test message sender task
static void message_sender_task(void* arg) {
auto& manager = EspNowManager::GetInstance();
auto& board = Board::GetInstance();
std::string device_uuid = board.GetUuid();
std::string device_name = "PlaiPin-" + device_uuid.substr(0, 6);
int message_count = 0;
while (test_running) {
vTaskDelay(pdMS_TO_TICKS(15000)); // Every 15 seconds
auto peers = manager.GetPairedDevices();
if (!peers.empty()) {
message_count++;
char msg_text[128];
snprintf(msg_text, sizeof(msg_text), "Test message #%d from %s",
message_count, device_name.c_str());
ESP_LOGI(TAG, "📤 Broadcasting: %s", msg_text);
if (manager.BroadcastTextMessage(device_uuid, device_name, msg_text)) {
ESP_LOGI(TAG, "✅ Message sent to %zu peer(s)", peers.size());
} else {
ESP_LOGE(TAG, "❌ Failed to send message");
}
}
}
vTaskDelete(NULL);
}
void start_espnow_test() {
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "╔═══════════════════════════════════════════════════════╗");
ESP_LOGI(TAG, "║ ESP-NOW COMMUNICATION TEST MODE ║");
ESP_LOGI(TAG, "╚═══════════════════════════════════════════════════════╝");
ESP_LOGI(TAG, "");
// Initialize NVS
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
ESP_LOGI(TAG, "✓ NVS initialized");
// Initialize WiFi (required for ESP-NOW)
ESP_LOGI(TAG, "Initializing WiFi...");
ESP_ERROR_CHECK(esp_netif_init());
// Create event loop (may already exist in IDF 5.5)
ret = esp_event_loop_create_default();
if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) {
ESP_LOGE(TAG, "Failed to create event loop: %s", esp_err_to_name(ret));
return;
}
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
ESP_ERROR_CHECK(esp_wifi_start());
// Set WiFi channel to 1 (or any fixed channel)
ESP_ERROR_CHECK(esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE));
ESP_LOGI(TAG, "✓ WiFi initialized (STA mode, Channel 1)");
// Get device info
auto& board = Board::GetInstance();
std::string device_uuid = board.GetUuid();
std::string device_name = "PlaiPin-" + device_uuid.substr(0, 6);
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "Device Information:");
ESP_LOGI(TAG, " UUID: %s", device_uuid.c_str());
ESP_LOGI(TAG, " Name: %s", device_name.c_str());
ESP_LOGI(TAG, " MAC: %s", SystemInfo::GetMacAddress().c_str());
ESP_LOGI(TAG, "");
// Initialize ESP-NOW
ESP_LOGI(TAG, "Initializing ESP-NOW...");
auto& manager = EspNowManager::GetInstance();
if (!manager.Initialize()) {
ESP_LOGE(TAG, "❌ Failed to initialize ESP-NOW!");
ESP_LOGE(TAG, "Test FAILED. Restarting in 10 seconds...");
vTaskDelay(pdMS_TO_TICKS(10000));
esp_restart();
return;
}
ESP_LOGI(TAG, "✓ ESP-NOW initialized");
ESP_LOGI(TAG, " Local MAC: %s", manager.GetLocalMacString().c_str());
ESP_LOGI(TAG, "");
// Set up callbacks
ESP_LOGI(TAG, "Setting up callbacks...");
// Handle pairing requests
manager.OnPairingRequest([&](const uint8_t* mac, const PairingRequestPayload& payload) {
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "📨 PAIRING REQUEST received!");
ESP_LOGI(TAG, " From: %s", EspNowManager::MacToString(mac).c_str());
ESP_LOGI(TAG, " Device: %s", payload.device_name);
ESP_LOGI(TAG, " UUID: %s", payload.device_uuid);
ESP_LOGI(TAG, " RSSI: %d dBm", payload.rssi);
if (strlen(payload.agentmail_inbox) > 0) {
ESP_LOGI(TAG, " AgentMail: %s", payload.agentmail_inbox);
}
// Auto-accept pairing
ESP_LOGI(TAG, " ✅ AUTO-ACCEPTING pairing...");
if (manager.SendPairingResponse(mac, device_uuid, device_name, "", true)) {
ESP_LOGI(TAG, " ✓ Pairing response sent");
} else {
ESP_LOGE(TAG, " ✗ Failed to send pairing response");
}
ESP_LOGI(TAG, "");
});
// Handle pairing responses
manager.OnPairingResponse([](const uint8_t* mac, const PairingResponsePayload& payload) {
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "📨 PAIRING RESPONSE received!");
ESP_LOGI(TAG, " From: %s", EspNowManager::MacToString(mac).c_str());
ESP_LOGI(TAG, " Device: %s", payload.device_name);
ESP_LOGI(TAG, " UUID: %s", payload.device_uuid);
ESP_LOGI(TAG, " Status: %s", payload.accepted ? "ACCEPTED ✅" : "REJECTED ❌");
ESP_LOGI(TAG, "");
});
// Handle text messages
manager.OnTextMessage([](const uint8_t* mac, const TextMessagePayload& payload) {
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "💬 TEXT MESSAGE received!");
ESP_LOGI(TAG, " From: %s (%s)", payload.sender_name, EspNowManager::MacToString(mac).c_str());
ESP_LOGI(TAG, " Message: \"%s\"", payload.message_text);
ESP_LOGI(TAG, "");
});
// Handle send status
manager.OnSend([](const uint8_t* mac, esp_now_send_status_t status) {
if (status != ESP_NOW_SEND_SUCCESS) {
ESP_LOGW(TAG, "Send to %s: %s",
EspNowManager::MacToString(mac).c_str(),
status == ESP_NOW_SEND_SUCCESS ? "SUCCESS" : "FAILED");
}
});
ESP_LOGI(TAG, "✓ Callbacks configured");
ESP_LOGI(TAG, "");
// Peer device configuration
ESP_LOGI(TAG, "╔═══════════════════════════════════════════════════════╗");
ESP_LOGI(TAG, "║ PEER DEVICE CONFIGURATION ║");
ESP_LOGI(TAG, "╚═══════════════════════════════════════════════════════╝");
ESP_LOGI(TAG, "");
// Check for pre-configured peer MAC (Kconfig)
#ifdef CONFIG_ESPNOW_TEST_MANUAL_KCONFIG
const char* preconfigured_mac = CONFIG_ESPNOW_TEST_PEER_MAC;
if (preconfigured_mac && strlen(preconfigured_mac) > 0) {
ESP_LOGI(TAG, "📋 Pre-configured peer MAC: %s", preconfigured_mac);
uint8_t peer_mac[6];
if (EspNowManager::StringToMac(preconfigured_mac, peer_mac)) {
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "✓ Initiating pairing with pre-configured peer");
ESP_LOGI(TAG, "");
if (manager.SendPairingRequest(peer_mac, device_uuid, device_name, "", 0)) {
ESP_LOGI(TAG, "✓ Pairing request sent");
} else {
ESP_LOGE(TAG, "✗ Failed to send pairing request");
}
} else {
ESP_LOGE(TAG, "✗ Invalid pre-configured MAC address format!");
ESP_LOGI(TAG, " Expected format: XX:XX:XX:XX:XX:XX");
ESP_LOGI(TAG, " Falling back to passive mode");
ESP_LOGI(TAG, "");
}
} else {
ESP_LOGI(TAG, "⏸ No peer MAC configured, entering passive mode");
ESP_LOGI(TAG, "");
}
#else
// Prompt for peer MAC address via serial
ESP_LOGI(TAG, "Enter peer MAC address (XX:XX:XX:XX:XX:XX)");
ESP_LOGI(TAG, "Or enter '-' for passive mode (wait for pairing)");
ESP_LOGI(TAG, "");
printf("> ");
fflush(stdout);
char mac_input[18] = {0};
int len = read_serial_mac(mac_input, sizeof(mac_input), 10000); // 10 second timeout
// Check for passive mode trigger
if (len == 1 && mac_input[0] == '-') {
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "⏸ Passive mode explicitly requested");
} else if (len > 0) {
uint8_t peer_mac[6];
if (EspNowManager::StringToMac(mac_input, peer_mac)) {
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "✓ Initiating pairing with: %s", mac_input);
ESP_LOGI(TAG, "");
if (manager.SendPairingRequest(peer_mac, device_uuid, device_name, "", 0)) {
ESP_LOGI(TAG, "✓ Pairing request sent");
} else {
ESP_LOGE(TAG, "✗ Failed to send pairing request");
}
} else {
ESP_LOGE(TAG, "✗ Invalid MAC address format");
ESP_LOGI(TAG, " Expected format: XX:XX:XX:XX:XX:XX");
ESP_LOGI(TAG, " Falling back to passive mode");
}
} else {
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "⏸ No input received, entering passive mode");
}
ESP_LOGI(TAG, "");
#endif
// Start test tasks
test_running = true;
xTaskCreate(status_task, "status", 4096, NULL, 5, NULL);
xTaskCreate(message_sender_task, "sender", 4096, NULL, 5, NULL);
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "╔═══════════════════════════════════════════════════════╗");
ESP_LOGI(TAG, "║ ESP-NOW TEST MODE ACTIVE ║");
ESP_LOGI(TAG, "╠═══════════════════════════════════════════════════════╣");
ESP_LOGI(TAG, "║ Listening for pairing requests... ║");
ESP_LOGI(TAG, "║ Will auto-accept and exchange messages ║");
ESP_LOGI(TAG, "║ ║");
ESP_LOGI(TAG, "║ Status updates: Every 10 seconds ║");
ESP_LOGI(TAG, "║ Test messages: Every 15 seconds (to paired devices) ║");
ESP_LOGI(TAG, "╚═══════════════════════════════════════════════════════╝");
ESP_LOGI(TAG, "");
// Main loop - just keep running
while (true) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}