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
}
}