Peer to peer communication

Hello everyone i trying to implement the peer to peer communication among my devices i can able to identify the other device in my network and also able to send the data to them but when i try to receive the data from other device i can’t abl to receive any data from other device can you please guide me to make the proper receive function to receive the data correctly

#include <user_app_thread.h>

#include “board_cfg.h”

#include “FreeRTOS_IP.h”

#include “FreeRTOS_IP_Private.h”

#include “FreeRTOS_Sockets.h”

#include “common_utils.h”

#include “littlefs_app.h”

#include “adc_app.h”

#include “core_http_client.h”

#include “transport_mbedtls_pkcs11.h”

#include “user_app.h”

extern TaskHandle_t user_app_thread;

ping_data_t ping_data = { RESET_VALUE, RESET_VALUE, RESET_VALUE };

IPV4Parameters_t xNd = {RESET_VALUE, RESET_VALUE, RESET_VALUE, {RESET_VALUE, RESET_VALUE}, RESET_VALUE, RESET_VALUE};

uint32_t dhcp_in_use = RESET_VALUE;

float mcu_die_temp  = RESET_VALUE;

void restart_complete_thread(void);

void print_heap_statistics(uint32_t heartbeat_count);

void cleanup_network_resources(void);

BaseType_t send_heartbeat_with_retry(TransportInterface_t \*pTransportInterface,

HTTPRequestHeaders_t \*pRequestHeaders,

HTTPResponse_t \*pResponse,

uint8_t \*resUserBuffer,

uint8_t \*reqUserBuffer);

#define FREERTOS_SOL_SOCKET    0

#define FREERTOS_SO_BROADCAST  6

//#define FREERTOS_SO_RCVTIMEO   12

#define DISCOVERY_PORT 8081

#define BROADCAST_IP “255.255.255.255”

#define MAX_PEERS 10

#define DEVICE_ID 3  // Change this for each device

#define DISCOVERY_INTERVAL_MS 10000  // 10 seconds

#define STATUS_CHECK_INTERVAL_MS 30000  // 30 seconds

#define ACCESS_CONTROL_PORT 8080  // For data communication (different from discovery port)

#define DATA_BUFFER_SIZE 256

#define PEER_SEND_INTERVAL_MS 15000

static Socket_t data_socket = NULL;

// Buffer for received data

static char data_receive_buffer\[DATA_BUFFER_SIZE\];

// Structure to track discovered peers

typedef struct {

char ip_address\[16\];

uint8_t device_id;

bool is_active;

uint32_t last_seen;

} peer_info_t;

// Global variables for peer management

static peer_info_t discovered_peers\[MAX_PEERS\];

static int peer_count = 0;

char current_device_ip\[16\] = “0.0.0.0”;

// Discovery socket handle

static Socket_t discovery_socket = NULL;

// Timers for discovery operations

static TickType_t last_broadcast_time = 0;

static TickType_t last_status_check_time = 0;

#define FREERTOS_SO_REUSEADDR 4

char \*domain_name = HTTPS_HOST_ADDRESS;

char remote_ip_address[ ] = HTTPS_TEST_PING_IP;

uint8_t ucMACAddress\[6\] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x54 };

uint8_t ucIPAddress\[4\] = { RESET_VALUE };

uint8_t ucNetMask\[4\] = { 255, 255, 255, 0 };

uint8_t ucGatewayAddress\[4\] = { RESET_VALUE };

uint8_t ucDNSServerAddress\[4\] = { RESET_VALUE };

char id\[SIZE_32\] = { RESET_VALUE };

bool is_get_called = false;

bool ID_alive=false;

struct NetworkContext

{

TlsTransportParams_t \* pParams;

};

static void display_discovered_peers(void);

static void broadcast_device_info(void);

static BaseType_t data_server_init(void);

static BaseType_t send_data_to_peer(uint8_t peer_index, const char\* data);

static void handle_incoming_data(void);

// Initialize the data communication server

static BaseType_t data_server_init(void) {

struct freertos_sockaddr server_addr;

BaseType_t result;

APP_PRINT(“\\r\\n=== DEBUG: Initializing Data Server ===\\r\\n”);

// Step 1: Create socket

APP_PRINT(“Step 1: Creating socket…\\r\\n”);

data_socket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP);

if (data_socket == FREERTOS_INVALID_SOCKET) {

APP_ERR_PRINT(“❌ FAILED: FreeRTOS_socket() returned INVALID_SOCKET\\r\\n”);

return pdFAIL;

}

if (data_socket == NULL) {

APP_ERR_PRINT(“❌ FAILED: FreeRTOS_socket() returned NULL\\r\\n”);

return pdFAIL;

}

APP_PRINT(“✅ SUCCESS: Socket created: %p\\r\\n”, data_socket);

// Step 2: Set socket options

APP_PRINT(“Step 2: Setting socket options…\\r\\n”);

BaseType_t reuse_addr = 1;

result = FreeRTOS_setsockopt(data_socket, 0, FREERTOS_SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));

APP_PRINT("   SO_REUSEADDR result: %d\\r\\n", (int)result);

TickType_t accept_timeout = pdMS_TO_TICKS(10);

result = FreeRTOS_setsockopt(data_socket, 0, FREERTOS_SO_RCVTIMEO, &accept_timeout, sizeof(accept_timeout));

APP_PRINT("   SO_RCVTIMEO result: %d\\r\\n", (int)result);

// Step 3: Bind

APP_PRINT(“Step 3: Binding to port %d…\\r\\n”, ACCESS_CONTROL_PORT);

memset(&server_addr, 0, sizeof(server_addr));

server_addr.sin_family = FREERTOS_AF_INET;

server_addr.sin_port = FreeRTOS_htons(ACCESS_CONTROL_PORT);

server_addr.sin_addr = FreeRTOS_htonl(FREERTOS_INADDR_ANY);

result = FreeRTOS_bind(data_socket, &server_addr, sizeof(server_addr));

if (result != 0) {

APP_ERR_PRINT(“❌ FAILED: Bind failed with error: %d\\r\\n”, (int)result);

APP_ERR_PRINT("   Possible causes:\\r\\n");

APP_ERR_PRINT("   - Port %d already in use\\r\\n", ACCESS_CONTROL_PORT);

APP_ERR_PRINT("   - Network not ready\\r\\n");

FreeRTOS_closesocket(data_socket);

data_socket = NULL;

return pdFAIL;

}

APP_PRINT(“✅ SUCCESS: Bound to port %d\\r\\n”, ACCESS_CONTROL_PORT);

// Step 4: Listen

APP_PRINT(“Step 4: Starting to listen…\\r\\n”);

result = FreeRTOS_listen(data_socket, 5);

if (result != 0) {

APP_ERR_PRINT(“❌ FAILED: Listen failed with error: %d\\r\\n”, (int)result);

FreeRTOS_closesocket(data_socket);

data_socket = NULL;

return pdFAIL;

}

APP_PRINT(“✅ SUCCESS: Listening on port %d\\r\\n”, ACCESS_CONTROL_PORT);

APP_PRINT(“\\r\\n🎉 DATA SERVER INITIALIZED SUCCESSFULLY!\\r\\n”);

APP_PRINT("   Socket: %p\\r\\n", data_socket);

APP_PRINT("   Port: %d\\r\\n", ACCESS_CONTROL_PORT);

APP_PRINT("   IP: %s\\r\\n", current_device_ip);

APP_PRINT(“==========================================\\r\\n”);

return pdPASS;

}

// Add this function after data_server_init()

static void test_server_connectivity(void) {

APP_PRINT(“\\r\\n=== Testing Server Connectivity ===\\r\\n”);

if (data_socket == NULL || data_socket == FREERTOS_INVALID_SOCKET) {

APP_ERR_PRINT(“Server socket is invalid!\\r\\n”);

return;

}

APP_PRINT(“Server socket handle: %p\\r\\n”, data_socket);

APP_PRINT(“Listening on: %s:%d\\r\\n”, current_device_ip, ACCESS_CONTROL_PORT);

APP_PRINT(“Ready to accept connections!\\r\\n”);

APP_PRINT(“===================================\\r\\n”);

}

// Send data to a specific peer

static BaseType_t send_data_to_peer(uint8_t peer_index, const char\* data) {

Socket_t client_socket;

struct freertos_sockaddr peer_addr;

BaseType_t status = pdFAIL;

if (peer_index >= peer_count || !discovered_peers\[peer_index\].is_active) {

APP_ERR_PRINT(“Invalid or inactive peer index %d\\r\\n”, peer_index);

return pdFAIL;

}

APP_PRINT(“\\r\\nAttempting to send to peer %d (%s:%d)…\\r\\n”,

discovered_peers\[peer_index\].device_id,

discovered_peers\[peer_index\].ip_address,

ACCESS_CONTROL_PORT);

// Create client socket

client_socket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP);

if (client_socket == FREERTOS_INVALID_SOCKET) {

APP_ERR_PRINT(“Failed to create client socket\\r\\n”);

return pdFAIL;

}

// Set connection and send timeout

TickType_t xTimeout = pdMS_TO_TICKS(5000); // 5 seconds

FreeRTOS_setsockopt(client_socket, 0, FREERTOS_SO_RCVTIMEO, &xTimeout, sizeof(xTimeout));

FreeRTOS_setsockopt(client_socket, 0, FREERTOS_SO_SNDTIMEO, &xTimeout, sizeof(xTimeout));

// Set up peer address

peer_addr.sin_port = FreeRTOS_htons(ACCESS_CONTROL_PORT);

peer_addr.sin_addr = FreeRTOS_inet_addr(discovered_peers\[peer_index\].ip_address);

APP_PRINT(“Connecting…\\r\\n”);

// Connect to peer

if (FreeRTOS_connect(client_socket, &peer_addr, sizeof(peer_addr)) == 0) {

APP_PRINT(“Connected successfully, sending data…\\r\\n”);

// Add small delay to ensure connection is fully established

vTaskDelay(pdMS_TO_TICKS(10));

// Send data

BaseType_t sent_bytes = FreeRTOS_send(client_socket, data, strlen(data), 0);

if (sent_bytes > 0) {

APP_PRINT(“✓ Sent %d bytes to peer %d (ID: %d, IP: %s)\\r\\n”,

(int)sent_bytes,

peer_index,

discovered_peers\[peer_index\].device_id,

discovered_peers\[peer_index\].ip_address);

status = pdPASS;

} else {

APP_ERR_PRINT(“Failed to send data (error: %d)\\r\\n”, (int)sent_bytes);

}

// Add delay before closing to ensure data is transmitted

vTaskDelay(pdMS_TO_TICKS(50));

} else {

APP_ERR_PRINT(“Failed to connect to peer %d\\r\\n”, peer_index);

discovered_peers\[peer_index\].is_active = false;

}

// Close client socket

FreeRTOS_closesocket(client_socket);

return status;

}

// Handle incoming data connections

static void handle_incoming_data(void) {

struct freertos_sockaddr client_addr;

Socket_t client_socket;

socklen_t addr_len = sizeof(client_addr);

if (data_socket == NULL || data_socket == FREERTOS_INVALID_SOCKET) {

return;

}

// Accept incoming connection (NON-BLOCKING - this is crucial)

client_socket = FreeRTOS_accept(data_socket, &client_addr, &addr_len);

if (client_socket != FREERTOS_INVALID_SOCKET && client_socket != NULL) {

APP_PRINT(“\\r\\n\*\*\* NEW CONNECTION ACCEPTED \*\*\*\\r\\n”);

// Get client IP

uint32_t client_ip_addr = FreeRTOS_ntohl(client_addr.sin_addr);

char client_ip\[16\];

snprintf(client_ip, sizeof(client_ip), “%d.%d.%d.%d”,

(client_ip_addr >> 24) & 0xFF,

(client_ip_addr >> 16) & 0xFF,

(client_ip_addr >> 8) & 0xFF,

client_ip_addr & 0xFF);

APP_PRINT(“Client IP: %s\\r\\n”, client_ip);

// \*\*CRITICAL: Set socket to NON-BLOCKING with short timeout\*\*

TickType_t xReceiveTimeout = pdMS_TO_TICKS(100); // 100ms timeout

FreeRTOS_setsockopt(client_socket, 0, FREERTOS_SO_RCVTIMEO,

&xReceiveTimeout, sizeof(xReceiveTimeout));

// \*\*CRITICAL: NO DELAY here - receive immediately\*\*

char temp_buffer\[256\];

memset(temp_buffer, 0, sizeof(temp_buffer));

// Try to receive data immediately

BaseType_t recv_len = FreeRTOS_recv(client_socket, temp_buffer, sizeof(temp_buffer) - 1, 0);

if (recv_len > 0) {

temp_buffer\[recv_len\] = ‘\\0’;

APP_PRINT(“✅ DATA RECEIVED: %d bytes\\r\\n”, (int)recv_len);

APP_PRINT(“📨 Content: %s\\r\\n”, temp_buffer);

// Store in your main buffer if needed

strncpy(data_receive_buffer, temp_buffer, DATA_BUFFER_SIZE);

} else if (recv_len == 0) {

APP_PRINT(“❌ Connection closed by peer\\r\\n”);

} else {

APP_PRINT(“❌ No data available (error: %d)\\r\\n”, (int)recv_len);

}

// Close client socket

FreeRTOS_closesocket(client_socket);

APP_PRINT(“Connection closed\\r\\n\\r\\n”);

}

}

// Send a test message to all active peers

static void send_test_message_to_peers(void) {

char test_message\[64\];

//    time_t current_time;

static uint32_t message_counter = 1;

// Generate a test message with timestamp and counter

snprintf(test_message, sizeof(test_message),

“HELLO_FROM_DEVICE:%d:MSG:%lu”,

DEVICE_ID, message_counter++);

APP_PRINT(“\\r\\nSending test message to all peers: %s\\r\\n”, test_message);

// Send to all active peers

int success_count = 0;

for (int i = 0; i < peer_count; i++) {

if (discovered_peers\[i\].is_active) {

if (send_data_to_peer(i, test_message) == pdPASS) {

success_count++;

}

}

}

APP_PRINT(“Message sent to %d of %d active peers\\r\\n”, success_count, peer_count);

}

void print_heap_statistics(uint32_t heartbeat_count)

{

size_t current_free_heap = xPortGetFreeHeapSize();

size_t minimum_ever_free_heap = xPortGetMinimumEverFreeHeapSize();

APP_PRINT(“\\r\\n=== HEAP STATISTICS - Heartbeat #%lu ===\\r\\n”, heartbeat_count);

APP_PRINT(“Current Free Heap: %u bytes\\r\\n”, (unsigned int)current_free_heap);

APP_PRINT(“Minimum Ever Free Heap: %u bytes\\r\\n”, (unsigned int)minimum_ever_free_heap);

// Get detailed heap statistics using vPortGetHeapStats

HeapStats_t heap_stats;

vPortGetHeapStats(&heap_stats);

APP_PRINT(“=== DETAILED HEAP STATISTICS ===\\r\\n”);

APP_PRINT(“Available Heap Space: %u bytes\\r\\n”, (unsigned int)heap_stats.xAvailableHeapSpaceInBytes);

APP_PRINT(“Size of Largest Free Block: %u bytes\\r\\n”, (unsigned int)heap_stats.xSizeOfLargestFreeBlockInBytes);

APP_PRINT(“Size of Smallest Free Block: %u bytes\\r\\n”, (unsigned int)heap_stats.xSizeOfSmallestFreeBlockInBytes);

APP_PRINT(“Number of Free Blocks: %u\\r\\n”, (unsigned int)heap_stats.xNumberOfFreeBlocks);

APP_PRINT(“Minimum Number of Free Bytes: %u\\r\\n”, (unsigned int)heap_stats.xMinimumEverFreeBytesRemaining);

APP_PRINT(“Number of Successful Allocations: %u\\r\\n”, (unsigned int)heap_stats.xNumberOfSuccessfulAllocations);

APP_PRINT(“Number of Successful Frees: %u\\r\\n”, (unsigned int)heap_stats.xNumberOfSuccessfulFrees);

// Calculate heap usage percentage

size_t total_heap = configTOTAL_HEAP_SIZE; // Assuming this is defined in your FreeRTOSConfig.h

size_t used_heap = total_heap - current_free_heap;

uint32_t usage_percentage = (used_heap \* 100) / total_heap;

APP_PRINT(“Total Heap Size: %u bytes\\r\\n”, (unsigned int)total_heap);

APP_PRINT(“Used Heap: %u bytes (%u%%)\\r\\n”, (unsigned int)used_heap, usage_percentage);

// Warning if heap usage is high

if (usage_percentage > 80)

{

APP_PRINT(“\*\*\* WARNING: High heap usage detected! \*\*\*\\r\\n”);

}

if (current_free_heap < 1024) // Less than 1KB free

{

APP_PRINT(“\*\*\* CRITICAL: Very low free heap! \*\*\*\\r\\n”);

}

APP_PRINT(“=====================================\\r\\n”);

}

static BaseType_t init_peer_discovery(void) {

struct freertos_sockaddr bind_addr;

// Update current device IP from global IP address

snprintf(current_device_ip, sizeof(current_device_ip), “%d.%d.%d.%d”,

ucIPAddress\[0\], ucIPAddress\[1\], ucIPAddress\[2\], ucIPAddress\[3\]);

APP_PRINT(“\\r\\n=== Initializing Peer Discovery ===”);

APP_PRINT(“\\r\\nDevice ID: %d”, DEVICE_ID);

APP_PRINT(“\\r\\nDevice IP: %s”, current_device_ip);

// Create UDP socket for discovery

discovery_socket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP);

if (discovery_socket == FREERTOS_INVALID_SOCKET) {

APP_ERR_PRINT(“\\r\\nFailed to create discovery socket”);

return pdFAIL;

}

// Set socket timeout for non-blocking operation

TickType_t xReceiveTimeOut = pdMS_TO_TICKS(10);  // 10ms timeout

FreeRTOS_setsockopt(discovery_socket, FREERTOS_SOL_SOCKET, FREERTOS_SO_RCVTIMEO,

&xReceiveTimeOut, sizeof(xReceiveTimeOut));

// Bind to discovery port

bind_addr.sin_port = FreeRTOS_htons(DISCOVERY_PORT);

bind_addr.sin_addr = FreeRTOS_htonl(FREERTOS_INADDR_ANY);

if (FreeRTOS_bind(discovery_socket, &bind_addr, sizeof(bind_addr)) != 0) {

APP_ERR_PRINT(“\\r\\nFailed to bind discovery socket”);

FreeRTOS_closesocket(discovery_socket);

discovery_socket = NULL;

return pdFAIL;

}

// Initialize timing variables

last_broadcast_time = xTaskGetTickCount();

last_status_check_time = xTaskGetTickCount();

APP_PRINT(“\\r\\nPeer discovery initialized successfully”);

return pdPASS;

}

// Function to broadcast device info

// Function to check for discovery messages

static void check_for_peer_messages(void) {

struct freertos_sockaddr client_addr;

socklen_t addr_len = sizeof(client_addr);

char rx_buffer\[128\];

int recv_len;

if (discovery_socket == NULL) {

return;

}

// Check for incoming messages (non-blocking due to socket timeout)

recv_len = FreeRTOS_recvfrom(discovery_socket, rx_buffer, sizeof(rx_buffer) - 1, 0,

&client_addr, &addr_len);

if (recv_len > 0) {

rx_buffer\[recv_len\] = 0; // Null terminate

// Convert IP address

uint32_t peer_ip_addr = FreeRTOS_ntohl(client_addr.sin_addr);

char peer_ip\[16\];

sprintf(peer_ip, “%d.%d.%d.%d”,

(peer_ip_addr >> 24) & 0xFF,

(peer_ip_addr >> 16) & 0xFF,

(peer_ip_addr >> 8) & 0xFF,

peer_ip_addr & 0xFF);

// Check if it’s a valid discovery message

if (strncmp(rx_buffer, “ACCESS_DEVICE:”, 14) == 0) {

// Parse device ID and IP

char\* id_start = rx_buffer + 14;

char\* colon = strchr(id_start, ‘:’);

if (colon) {

\*colon = ‘\\0’;

int discovered_device_id = atoi(id_start);

char\* discovered_ip = colon + 1;

// Skip our own broadcasts

if (discovered_device_id == DEVICE_ID) {

return;

}

// Check if peer already exists

bool found = false;

for (int i = 0; i < peer_count; i++) {

if (discovered_peers\[i\].device_id == discovered_device_id) {

strcpy(discovered_peers\[i\].ip_address, discovered_ip);

discovered_peers\[i\].last_seen = xTaskGetTickCount();

discovered_peers\[i\].is_active = true;

found = true;

APP_PRINT(“\\r\\nUpdated peer device %d at %s”,

discovered_device_id, discovered_ip);

break;

}

}

// Add new peer if not found and we have space

if (!found && peer_count < MAX_PEERS) {

strcpy(discovered_peers\[peer_count\].ip_address, discovered_ip);

discovered_peers\[peer_count\].device_id = discovered_device_id;

discovered_peers\[peer_count\].is_active = true;

discovered_peers\[peer_count\].last_seen = xTaskGetTickCount();

peer_count++;

APP_PRINT(“\\r\\nDiscovered new peer device %d at %s”,

discovered_device_id, discovered_ip);

// Display current peer list after new discovery

display_discovered_peers();

}

}

}

}

}

// Function to check peer status and update active flags

static void check_peer_status(void) {

TickType_t current_ticks = xTaskGetTickCount();

bool status_changed = false;

for (int i = 0; i < peer_count; i++) {

// Mark peer as inactive if not seen for 60 seconds

if (current_ticks - discovered_peers\[i\].last_seen > pdMS_TO_TICKS(60000)) {

if (discovered_peers\[i\].is_active) {

discovered_peers\[i\].is_active = false;

status_changed = true;

APP_PRINT(“\\r\\nPeer device %d marked inactive (timeout)”,

discovered_peers\[i\].device_id);

}

}

}

if (status_changed) {

display_discovered_peers();

}

}

// Function to display discovered peers

// Function to handle peer discovery operations

static void process_peer_discovery(void) {

TickType_t current_time = xTaskGetTickCount();

// Check for incoming discovery messages

check_for_peer_messages();

// Broadcast our device info periodically

if ((current_time - last_broadcast_time) >= pdMS_TO_TICKS(DISCOVERY_INTERVAL_MS)) {

broadcast_device_info();

last_broadcast_time = current_time;

}

// Check peer status periodically

if ((current_time - last_status_check_time) >= pdMS_TO_TICKS(STATUS_CHECK_INTERVAL_MS)) {

check_peer_status();

last_status_check_time = current_time;

}

}

HTTPStatus_t reconnect_with_cleanup(NetworkContext_t \*pNetworkContext, TransportInterface_t \*pTransportInterface)

{

HTTPStatus_t status = HTTPSuccess;

uint32_t retry_count = 0;

const uint32_t MAX_RECONNECT_RETRIES = 3;

APP_PRINT(“=== Starting Enhanced Reconnection Process ===\\r\\n”);

// Step 1: Clean up existing connection

if (pNetworkContext->pParams != NULL)

{

APP_PRINT(“Disconnecting existing TLS connection…\\r\\n”);

TLS_FreeRTOS_Disconnect(pNetworkContext);

// Small delay to ensure cleanup completes

vTaskDelay(pdMS_TO_TICKS(1000));

}

// Step 2: Reset contexts

memset(pNetworkContext, 0, sizeof(NetworkContext_t));

memset(pTransportInterface, 0, sizeof(TransportInterface_t));

// Step 3: Check heap status before reconnection attempts

size_t heap_before_reconnect = xPortGetFreeHeapSize();

APP_PRINT(“Heap before reconnection attempts: %u bytes\\r\\n”, (unsigned int)heap_before_reconnect);

// Step 4: Attempt reconnection with retries

for (retry_count = 1; retry_count <= MAX_RECONNECT_RETRIES; retry_count++)

{

APP_PRINT(“Reconnection attempt %lu/%lu\\r\\n”, retry_count, MAX_RECONNECT_RETRIES);

// Wait before each attempt (except first)

if (retry_count > 1)

{

uint32_t delay_ms = retry_count \* 2000; // Exponential backoff

APP_PRINT(“Waiting %lu ms before retry…\\r\\n”, delay_ms);

vTaskDelay(pdMS_TO_TICKS(delay_ms));

}

// Attempt connection

status = connect_aws_https_client(pNetworkContext);

if (status == HTTPSuccess)

{

APP_PRINT(“Reconnection successful on attempt %lu\\r\\n”, retry_count);

// Reset transport interface

pTransportInterface->pNetworkContext = pNetworkContext;

pTransportInterface->send = TLS_FreeRTOS_send;

pTransportInterface->recv = TLS_FreeRTOS_recv;

// Check heap after successful reconnection

size_t heap_after_reconnect = xPortGetFreeHeapSize();

APP_PRINT(“Heap after successful reconnection: %u bytes\\r\\n”, (unsigned int)heap_after_reconnect);

return HTTPSuccess;

}

else

{

APP_ERR_PRINT(“Reconnection attempt %lu failed with status: %d\\r\\n”, retry_count, status);

// Clean up any partial connection state

if (pNetworkContext->pParams != NULL)

{

TLS_FreeRTOS_Disconnect(pNetworkContext);

memset(pNetworkContext, 0, sizeof(NetworkContext_t));

}

}

}

APP_ERR_PRINT(“All reconnection attempts failed\\r\\n”);

return status;

}

// Discovery initialization - ADD THIS TO YOUR CODE

static BaseType_t discovery_server_init(void) {

struct freertos_sockaddr server_addr;

// \*\*\* FIX: Update current_device_ip with ACTUAL IP (not 0.0.0.0) \*\*\*

APP_PRINT(“\\r\\n=== Initializing Peer Discovery ===\\r\\n”);

APP_PRINT(“Current ucIPAddress: %d.%d.%d.%d\\r\\n”,

ucIPAddress\[0\], ucIPAddress\[1\], ucIPAddress\[2\], ucIPAddress\[3\]);

// Update current_device_ip

snprintf(current_device_ip, sizeof(current_device_ip), “%d.%d.%d.%d”,

ucIPAddress\[0\], ucIPAddress\[1\], ucIPAddress\[2\], ucIPAddress\[3\]);

APP_PRINT(“Device ID: %d\\r\\n”, DEVICE_ID);

APP_PRINT(“Device IP: %s\\r\\n”, current_device_ip);

// Verify IP is valid (not 0.0.0.0)

if (ucIPAddress\[0\] == 0 && ucIPAddress\[1\] == 0 &&

ucIPAddress\[2\] == 0 && ucIPAddress\[3\] == 0) {

APP_ERR_PRINT(“ERROR: IP address is 0.0.0.0! Network not ready.\\r\\n”);

return pdFAIL;

}

// Create UDP socket

discovery_socket = FreeRTOS_socket(FREERTOS_AF_INET,

FREERTOS_SOCK_DGRAM,

FREERTOS_IPPROTO_UDP);

if (discovery_socket == FREERTOS_INVALID_SOCKET) {

APP_ERR_PRINT(“Failed to create discovery socket\\r\\n”);

return pdFAIL;

}

// Set non-blocking mode

TickType_t xReceiveTimeout = 0;

FreeRTOS_setsockopt(discovery_socket, 0, FREERTOS_SO_RCVTIMEO,

&xReceiveTimeout, sizeof(xReceiveTimeout));

// Enable broadcast

BaseType_t xBroadcast = pdTRUE;

FreeRTOS_setsockopt(discovery_socket, 0, FREERTOS_SO_BROADCAST,

&xBroadcast, sizeof(xBroadcast));

// Bind to discovery port

memset(&server_addr, 0, sizeof(server_addr));

server_addr.sin_port = FreeRTOS_htons(DISCOVERY_PORT);

server_addr.sin_addr = FreeRTOS_htonl(FREERTOS_INADDR_ANY);

if (FreeRTOS_bind(discovery_socket, &server_addr, sizeof(server_addr)) != 0) {

APP_ERR_PRINT(“Failed to bind discovery socket to port %d\\r\\n”, DISCOVERY_PORT);

FreeRTOS_closesocket(discovery_socket);

discovery_socket = NULL;

return pdFAIL;

}

APP_PRINT(“Discovery server bound to port %d\\r\\n”, DISCOVERY_PORT);

APP_PRINT(“Discovery server initialized successfully\\r\\n”);

// Send initial broadcast

broadcast_device_info();

return pdPASS;

}

// Broadcast our device information to the network

static void broadcast_device_info(void) {

struct freertos_sockaddr broadcast_addr;

char discovery_msg\[64\];

if (discovery_socket == NULL) {

return;

}

// Set up broadcast address

broadcast_addr.sin_port = FreeRTOS_htons(DISCOVERY_PORT);

broadcast_addr.sin_addr = FreeRTOS_inet_addr(BROADCAST_IP);

// Format discovery message

snprintf(discovery_msg, sizeof(discovery_msg), “ACCESS_DEVICE:%d:%s”, DEVICE_ID, current_device_ip);

// Send broadcast

if (FreeRTOS_sendto(discovery_socket, discovery_msg, strlen(discovery_msg), 0,

&broadcast_addr, sizeof(broadcast_addr)) > 0) {

APP_PRINT(“Broadcast discovery message sent: %s\\r\\n”, discovery_msg);

} else {

APP_ERR_PRINT(“Failed to send broadcast message\\r\\n”);

}

}

// Process incoming discovery messages

static void handle_discovery_messages(void) {

struct freertos_sockaddr client_addr;

BaseType_t addr_len = sizeof(client_addr);

char rx_buffer\[128\];

BaseType_t recv_len;

if (discovery_socket == NULL) {

return;

}

// Try to receive a message (will return immediately if none available)

recv_len = FreeRTOS_recvfrom(discovery_socket, rx_buffer, sizeof(rx_buffer) - 1, 0,

&client_addr, &addr_len);

if (recv_len > 0) {

rx_buffer\[recv_len\] = 0; // Null terminate

// Convert peer IP address

uint32_t peer_ip_addr = FreeRTOS_ntohl(client_addr.sin_addr);

char peer_ip\[16\];

snprintf(peer_ip, sizeof(peer_ip), “%d.%d.%d.%d”,

(peer_ip_addr >> 24) & 0xFF,

(peer_ip_addr >> 16) & 0xFF,

(peer_ip_addr >> 8) & 0xFF,

peer_ip_addr & 0xFF);

// Check if it’s a valid discovery message

if (strncmp(rx_buffer, “ACCESS_DEVICE:”, 14) == 0) {

char\* id_start = rx_buffer + 14;

char\* colon = strchr(id_start, ‘:’);

if (colon) {

\*colon = ‘\\0’;

int discovered_device_id = atoi(id_start);

char\* discovered_ip = colon + 1;

// Skip our own broadcasts

if (discovered_device_id == DEVICE_ID) {

return;

}

// Check if we already know this peer

bool found = false;

for (int i = 0; i < peer_count; i++) {

if (discovered_peers\[i\].device_id == discovered_device_id) {

// Update peer information

strcpy(discovered_peers\[i\].ip_address, discovered_ip);

discovered_peers\[i\].last_seen = xTaskGetTickCount();

discovered_peers\[i\].is_active = true;

found = true;

APP_PRINT(“Updated peer device %d at %s\\r\\n”,

discovered_device_id, discovered_ip);

break;

}

}

// Add new peer if not already known

if (!found && peer_count < MAX_PEERS) {

strcpy(discovered_peers\[peer_count\].ip_address, discovered_ip);

discovered_peers\[peer_count\].device_id = discovered_device_id;

discovered_peers\[peer_count\].is_active = true;

discovered_peers\[peer_count\].last_seen = xTaskGetTickCount();

peer_count++;

APP_PRINT(“Discovered new peer device %d at %s\\r\\n”,

discovered_device_id, discovered_ip);

// Show updated peer list

display_discovered_peers();

}

}

}

}

}

// Display list of discovered peers

static void display_discovered_peers(void) {

APP_PRINT(“\\r\\n=== DISCOVERED PEERS (Total: %d) ===\\r\\n”, peer_count);

if (peer_count == 0) {

APP_PRINT(“No peers discovered yet\\r\\n”);

} else {

for (int i = 0; i < peer_count; i++) {

APP_PRINT(“\[%d\] ID:%d IP:%s Active:%s\\r\\n”,

i + 1,

discovered_peers\[i\].device_id,

discovered_peers\[i\].ip_address,

discovered_peers\[i\].is_active ? “Yes” : “No”);

}

}

APP_PRINT(“====================================\\r\\n”);

}

/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*//\*\*

\* @briefbrief      This is the User Thread for the EP@param

\* @param\[in\]  Thread specific parameters

\* @retval     None

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/

void user_app_thread_entry(void \*pvParameters)

{

BaseType_t status = pdFALSE;

fsp_pack_version_t version  = { RESET_VALUE };

fsp_err_t err = FSP_SUCCESS;

int ierr = RESET_VALUE;

BaseType_t bt_status = pdFALSE;

uint32_t ip_status = RESET_VALUE;

uint32_t usrPingCount = RESET_VALUE;

/\* HTTPS Client library return status. \*/

//    HTTPStatus_t httpsClientStatus = HTTPSuccess;

//    TransportInterface_t xTransportInterface={RESET_VALUE};

//    NetworkContext_t xNetworkContext={RESET_VALUE};

//    uint8_t resUserBuffer\[USER_BUFF\]={RESET_VALUE};

//    uint8_t reqUserBuffer\[USER_BUFF\]={RESET_VALUE};

/\* HTTP Client library API structs. \*/

//    HTTPRequestInfo_t xRequestInfo={RESET_VALUE};

//    HTTPResponse_t xResponse={RESET_VALUE};

//    HTTPRequestHeaders_t xRequestHeaders={RESET_VALUE};

FSP_PARAMETER_NOT_USED(pvParameters);

R_FSP_VersionGet (&version);

APP_PRINT(BANNER_INFO, EP_VERSION, version.version_id_b.major, version.version_id_b.minor, version.version_id_b.patch);

APP_PRINT(EP_INFO);

err = hal_littlefs_init ();

if (FSP_SUCCESS != err)

{

APP_ERR_PRINT(“\*\* Failed in hsl_littlefs_init() function \*\* \\r\\n”);

APP_ERR_TRAP(err);

}

err = hal_adc_init ();

if (FSP_SUCCESS != err)

{

APP_ERR_PRINT(“\*\* Failed in hal_adc_init() function\*\* \\r\\n”);

hal_littlefs_deinit ();

APP_ERR_TRAP(err);

}

ierr = mbedtls_platform_setup (NULL);

if (FSP_SUCCESS != ierr)

{

APP_ERR_PRINT(“\*\* Failed in mbedtls_platform_setup() function \*\* \\r\\n”);

hal_littlefs_deinit ();

hal_adc_deinit ();

APP_ERR_TRAP(ierr);

}

else

{

APP_PRINT(“\\r\\n mbedtls_platform setup successful”);

}

APP_PRINT(ETH_PREINIT);

print_ipconfig ();

status = FreeRTOS_IPInit (ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress);

if (pdFALSE == status)

{

APP_ERR_PRINT(“FreeRTOS_IPInit Failed”);

hal_littlefs_deinit ();

hal_adc_deinit ();

mbedtls_platform_teardown (NULL);

APP_ERR_TRAP(status);

}

APP_PRINT(“Waiting for network link up…”);

bt_status = xTaskNotifyWait(pdFALSE, pdFALSE, &ip_status, portMAX_DELAY);

if (pdTRUE != bt_status)

{

APP_ERR_PRINT(“xTaskNotifyWait Failed”);

hal_littlefs_deinit ();

hal_adc_deinit ();

mbedtls_platform_teardown (NULL);

APP_ERR_TRAP(bt_status);

}

APP_PRINT(ETH_POSTINIT);

print_ipconfig ();

dnsQuerryFunc (domain_name);

APP_PRINT(“\\r\\nPinging %s:\\r\\n\\r\\n”, (char\* )remote_ip_address);

while (usrPingCount < USR_PING_COUNT)

{

status = vSendPing ((char\*) remote_ip_address);

if (pdFAIL != status)

{

ping_data.sent++;

}

else

{

ping_data.lost++;

}

usrPingCount++;

vTaskDelay (PING_DELAY);

}

print_pingResult ();

status = provision_alt_key ();

if (pdPASS != status)

{

APP_ERR_PRINT("\\r\\n Failed in network_init() function ");

hal_littlefs_deinit ();

hal_adc_deinit ();

mbedtls_platform_teardown (NULL);

APP_ERR_TRAP(status);

}

APP_PRINT(“\\r\\n=== Establishing Persistent Connection ===\\r\\n”);

APP_PRINT(“\\r\\n=== Initializing Peer-to-Peer Communication ===”);

APP_PRINT(“\\r\\n=== Starting Peer-to-Peer Discovery ===\\r\\n”);

// Initialize discovery server

BaseType_t discovery_status = discovery_server_init();

if (discovery_status != pdPASS) {

APP_ERR_PRINT(“Failed to initialize discovery server\\r\\n”);

}

BaseType_t data_status = data_server_init();

if (data_status != pdPASS) {

APP_ERR_PRINT(“Failed to initialize data server\\r\\n”);

} else {

test_server_connectivity();  // ADD THIS LINE

}

APP_PRINT(“\\r\\n=== Starting Heartbeat Loop ===\\r\\n”);

APP_PRINT(“Sending heartbeat every 30 seconds using persistent connection…\\r\\n\\r\\n”);

//    uint32_t heartbeat_count = 0;

//    uint32_t consecutive_failures = 0;

//    const uint32_t MAX_CONSECUTIVE_FAILURES = 3;

//    const uint32_t HEARTBEAT_RETRY_ATTEMPTS = 2;

// \*\*FIX 1: Allocate buffers once and reuse them\*\*

uint8_t \*resUserBuffer = (uint8_t\*)pvPortMalloc(USER_BUFF);

uint8_t \*reqUserBuffer = (uint8_t\*)pvPortMalloc(USER_BUFF);

if (!resUserBuffer || !reqUserBuffer) {

APP_ERR_PRINT(“Failed to allocate buffers\\r\\n”);

if (resUserBuffer) vPortFree(resUserBuffer);

if (reqUserBuffer) vPortFree(reqUserBuffer);

APP_ERR_TRAP(pdFAIL);

}

while (true)

{

R_ETHER_LinkProcess(&g_ether0_ctrl);

// \*\*CRITICAL: Handle discovery messages\*\*

handle_discovery_messages();

// \*\*CRITICAL: Handle incoming data connections - CALL THIS FREQUENTLY\*\*

handle_incoming_data();

static uint32_t last_broadcast_tick = 0;

static uint32_t last_debug_tick = 0;

uint32_t current_tick = xTaskGetTickCount();

// Broadcast every 10 seconds

if ((current_tick - last_broadcast_tick) > pdMS_TO_TICKS(10000)) {

broadcast_device_info();

last_broadcast_tick = current_tick;

}

// Debug info every 30 seconds

if ((current_tick - last_debug_tick) > pdMS_TO_TICKS(30000)) {

APP_PRINT(“\\r\\n=== SYSTEM STATUS ===\\r\\n”);

APP_PRINT(“IP: %s, Data Socket: %p\\r\\n”, current_device_ip, data_socket);

APP_PRINT(“Peers: %d, Server Running: %s\\r\\n”,

peer_count, (data_socket != NULL) ? “YES” : “NO”);

APP_PRINT(“========================\\r\\n”);

last_debug_tick = current_tick;

}

// \*\*CRITICAL: Small delay for frequent polling\*\*

vTaskDelay(pdMS_TO_TICKS(10)); // Check every 10ms

}

}

Do you see the reply on the network in Wireshark? If so, try increasing the receive timeout and/or looping on the read.

Instead of posting all the code, can you post your receive function related to the issue?

Hello @Mathan, I downloaded your source code and reformatted it for clearness:

Mathan_sample_code.zip (7.9 KB)

I see that the code is full of printf’s. Do you have output from them in a test-run?

Is handle_incoming_data() the function that show problems?

In data_server_init(), you open a server socket.

I would recommend not to use FREERTOS_SO_REUSEADDR until you are fully familiar with FreeRTOS+TCP. When using that option, accepting a connection means that your server socket becomes the child socket. So unless you are very low on RAM, don’t recycle server sockets.

In handle_incoming_data(): within a single function, you want to accept() a connection, wait 100 ms for incoming data, and close the connection. From that moment on, your data_socket is freed, because you call :

FreeRTOS_closesocket( client_socket );

and thanks to FREERTOS_SO_REUSEADDR, the client socket is the server socket. Normally you’d have to finish the client connection, close it, and create brand new server socket.

Does handle_incoming_data() ever receive a valid connection client_socket?

Where is the client located? On your laptop or so? Or is it also a FreeRTOS device? Do you have its +TCP source code?

while( true )
{
    handle_incoming_data();
    <cut>
}

In the above code, data_socket will be valid until accept() succeeds one time. After that, data_socket may not be accessed.