// test_etcp_simple.c - Simple test to verify ETCP sender-receiver communication #define ETCP_DEBUG 1 #include "etcp.h" #include "u_async.h" #include "ll_queue.h" #include "simple_uasync.h" #include #include #include #include // Sender's TX callback - just forward to receiver static void sender_tx_callback(struct ETCP_CONN* epkt, uint8_t* data, uint16_t len, void* arg) { (void)epkt; struct ETCP_CONN* receiver = (struct ETCP_CONN*)arg; printf("Sender TX callback: sending %u bytes to receiver\n", len); // Forward directly to receiver (no loss, no delay) etcp_rx_input(receiver, data, len); } // Receiver's TX callback - would send ACKs back to sender in real scenario static void receiver_tx_callback(struct ETCP_CONN* epkt, uint8_t* data, uint16_t len, void* arg) { (void)epkt; (void)data; (void)len; (void)arg; printf("Receiver TX callback: ACK sent back\n"); } int main(void) { printf("Simple ETCP sender-receiver test\n"); // Initialize uasync instance uasync_t* ua = uasync_create(); if (!ua) { fprintf(stderr, "Failed to create uasync instance\n"); return 1; } uasync_init_instance(ua); // Create ETCP instances struct ETCP_CONN* sender = etcp_create(ua); struct ETCP_CONN* receiver = etcp_create(ua); if (!sender || !receiver) { printf("ERROR: Failed to create ETCP instances\n"); return 1; } // Set up callbacks etcp_set_callback(sender, sender_tx_callback, receiver); etcp_set_callback(receiver, receiver_tx_callback, sender); // Send a simple packet const char* test_data = "Hello, ETCP!"; uint16_t data_len = strlen(test_data); uint8_t* data = malloc(data_len); memcpy(data, test_data, data_len); printf("Sending test packet: %s\n", test_data); if (etcp_tx_put(sender, data, data_len) != 0) { printf("ERROR: Failed to queue packet\n"); free(data); etcp_free(sender); etcp_free(receiver); return 1; } free(data); // etcp_tx_put makes its own copy // Advance time to allow transmission printf("Advancing time...\n"); for (int i = 0; i < 10; i++) { simple_uasync_advance_time(10); // 1ms each // Process any timers (retransmissions, etc.) } // Check receiver's output queue ll_queue_t* output_queue = etcp_get_output_queue(receiver); if (!output_queue) { printf("ERROR: Receiver output queue is NULL\n"); etcp_free(sender); etcp_free(receiver); return 1; } ll_entry_t* entry = queue_entry_get(output_queue); if (!entry) { printf("FAIL: No packet in receiver output queue\n"); // Debug: check queue size printf("Queue size check: %d\n", queue_entry_count(output_queue)); etcp_free(sender); etcp_free(receiver); return 1; } uint8_t* received_data = ll_entry_data(entry); uint16_t received_len = ll_entry_size(entry); printf("SUCCESS: Received packet of length %u\n", received_len); printf("Data: "); for (uint16_t i = 0; i < received_len; i++) { printf("%c", received_data[i]); } printf("\n"); if (received_len == data_len && memcmp(received_data, test_data, data_len) == 0) { printf("PASS: Data matches!\n"); } else { printf("FAIL: Data doesn't match\n"); } queue_entry_free(entry); etcp_free(sender); etcp_free(receiver); uasync_destroy(ua); return 0; }