message type updates

This commit is contained in:
2026-02-01 16:02:18 -08:00
parent bcfaad1817
commit 0e9f494c50
10 changed files with 202 additions and 498 deletions

View File

@@ -51,23 +51,6 @@ void acceptClient(int clientId) {
std::cout << "Client " << clientId << " connected\n";
}
void sendMessage(int clientId) {
if(clientId <= 0 || clientId > clientSockets.size()) return;
const char* msg = "Hello from server";
send(clientSockets[clientId-1], msg, strlen(msg), 0);
std::cout << "Sent message to client " << clientId << "\n";
}
int receiveAck(int clientId) {
if(clientId <= 0 || clientId > clientSockets.size()) return 0;
char buffer[1024];
int len = recv(clientSockets[clientId-1], buffer, sizeof(buffer)-1, 0);
if(len <= 0) return 0;
buffer[len] = '\0';
std::cout << "Received ACK from client " << clientId << ": " << buffer << "\n";
return 1;
}
void closeServer() {
for(auto sock : clientSockets) {
close(sock);
@@ -129,91 +112,61 @@ int loadTargets(const char* filename, double* targets, int maxClients) {
return count;
}
// Send target coordinates to a client
// target points to 3 doubles: [x, y, z]
void sendTarget(int clientId, const double* target) {
if (clientId <= 0 || clientId > (int)clientSockets.size()) return;
char buffer[256];
snprintf(buffer, sizeof(buffer), "TARGET:%.6f,%.6f,%.6f",
target[0], target[1], target[2]);
send(clientSockets[clientId - 1], buffer, strlen(buffer), 0);
std::cout << "Sent target to client " << clientId << ": " << buffer << "\n";
// Message type names for logging
static const char* messageTypeName(uint8_t msgType) {
switch (msgType) {
case 1: return "TARGET";
case 2: return "ACK";
case 3: return "READY";
case 4: return "RTL";
case 5: return "LAND";
default: return "UNKNOWN";
}
}
// Receive and validate ACK:TARGET response
// Returns 1 if ACK:TARGET received, 0 otherwise
int receiveTargetAck(int clientId) {
// Send a single-byte message type to a client
int sendMessageType(int clientId, int msgType) {
if (clientId <= 0 || clientId > (int)clientSockets.size()) return 0;
char buffer[256];
int len = recv(clientSockets[clientId - 1], buffer, sizeof(buffer) - 1, 0);
if (len <= 0) return 0;
buffer[len] = '\0';
std::cout << "Received from client " << clientId << ": " << buffer << "\n";
if (strncmp(buffer, "ACK:TARGET", 10) == 0) {
return 1;
uint8_t msg = (uint8_t)msgType;
ssize_t sent = send(clientSockets[clientId - 1], &msg, 1, 0);
if (sent != 1) {
std::cerr << "Send failed for client " << clientId << "\n";
return 0;
}
return 0;
std::cout << "Sent to client " << clientId << ": " << messageTypeName(msg) << " (" << (int)msg << ")\n";
return 1;
}
// Wait for READY signal from client
// Returns 1 if READY received, 0 otherwise
int waitForReady(int clientId) {
// Send TARGET message with coordinates (1 byte type + 24 bytes coords)
int sendTarget(int clientId, const double* coords) {
if (clientId <= 0 || clientId > (int)clientSockets.size()) return 0;
char buffer[256];
int len = recv(clientSockets[clientId - 1], buffer, sizeof(buffer) - 1, 0);
if (len <= 0) return 0;
buffer[len] = '\0';
// Build message: 1 byte type + 3 doubles (little-endian)
uint8_t buffer[1 + 3 * sizeof(double)];
buffer[0] = 1; // TARGET = 1
memcpy(buffer + 1, coords, 3 * sizeof(double));
std::cout << "Received from client " << clientId << ": " << buffer << "\n";
if (strncmp(buffer, "READY", 5) == 0) {
return 1;
ssize_t sent = send(clientSockets[clientId - 1], buffer, sizeof(buffer), 0);
if (sent != sizeof(buffer)) {
std::cerr << "Send target failed for client " << clientId << "\n";
return 0;
}
return 0;
std::cout << "Sent TARGET to client " << clientId << ": "
<< coords[0] << "," << coords[1] << "," << coords[2] << "\n";
return 1;
}
// Send COMPLETE message to signal graceful shutdown
void sendFinished(int clientId) {
if (clientId <= 0 || clientId > (int)clientSockets.size()) return;
const char* msg = "FINISHED";
send(clientSockets[clientId - 1], msg, strlen(msg), 0);
std::cout << "Sent FINISHED to client " << clientId << "\n";
}
// Send RTL (Return-To-Launch) command to a client
void sendRTL(int clientId) {
if (clientId <= 0 || clientId > (int)clientSockets.size()) return;
const char* msg = "RTL";
send(clientSockets[clientId - 1], msg, strlen(msg), 0);
std::cout << "Sent RTL to client " << clientId << "\n";
}
// Send LAND command to a client
void sendLAND(int clientId) {
if (clientId <= 0 || clientId > (int)clientSockets.size()) return;
const char* msg = "LAND";
send(clientSockets[clientId - 1], msg, strlen(msg), 0);
std::cout << "Sent LAND to client " << clientId << "\n";
}
// Wait for a specific message from ALL clients simultaneously using select()
// Returns 1 if all clients sent the expected message, 0 otherwise
static int waitForAllMessage(int numClients, const char* expectedMessage) {
// Wait for a specific message type from ALL clients simultaneously using select()
// Returns 1 if all clients responded with expected message type, 0 on failure
int waitForAllMessageType(int numClients, int expectedType) {
if (numClients <= 0 || numClients > (int)clientSockets.size()) return 0;
std::vector<std::string> accumulated(numClients);
uint8_t expected = (uint8_t)expectedType;
std::vector<bool> completed(numClients, false);
int completedCount = 0;
char buffer[512];
while (completedCount < numClients) {
// Build fd_set for select()
@@ -235,17 +188,17 @@ static int waitForAllMessage(int numClients, const char* expectedMessage) {
// Check each socket
for (int i = 0; i < numClients; i++) {
if (!completed[i] && FD_ISSET(clientSockets[i], &readfds)) {
int len = recv(clientSockets[i], buffer, sizeof(buffer) - 1, 0);
if (len <= 0) return 0;
buffer[len] = '\0';
std::cout << "Received from client " << (i + 1) << ": " << buffer << "\n";
accumulated[i] += buffer;
uint8_t msgType;
int len = recv(clientSockets[i], &msgType, 1, 0);
if (len != 1) return 0;
// Check if expected message received
if (accumulated[i].find(expectedMessage) != std::string::npos) {
std::cout << "Received from client " << (i + 1) << ": "
<< messageTypeName(msgType) << " (" << (int)msgType << ")\n";
if (msgType == expected) {
completed[i] = true;
completedCount++;
std::cout << "Client " << (i + 1) << " completed " << expectedMessage << "\n";
std::cout << "Client " << (i + 1) << " completed: " << messageTypeName(expected) << "\n";
}
}
}
@@ -254,30 +207,6 @@ static int waitForAllMessage(int numClients, const char* expectedMessage) {
return 1;
}
// Wait for ACK:TARGET from ALL clients simultaneously
// Returns 1 if all clients acknowledged, 0 otherwise
int waitForAllTargetAck(int numClients) {
return waitForAllMessage(numClients, "ACK:TARGET");
}
// Wait for READY from ALL clients simultaneously
// Returns 1 if all clients are ready, 0 otherwise
int waitForAllReady(int numClients) {
return waitForAllMessage(numClients, "READY");
}
// Wait for RTL_COMPLETE from ALL clients simultaneously
// Returns 1 if all clients completed RTL, 0 otherwise
int waitForAllRTLComplete(int numClients) {
return waitForAllMessage(numClients, "RTL_COMPLETE");
}
// Wait for LAND_COMPLETE from ALL clients simultaneously
// Returns 1 if all clients completed LAND, 0 otherwise
int waitForAllLANDComplete(int numClients) {
return waitForAllMessage(numClients, "LAND_COMPLETE");
}
// Wait for user to press Enter
void waitForUserInput() {
std::cout << "Press Enter to close experiment (RTL + LAND)...\n";

View File

@@ -1,34 +1,28 @@
#ifndef CONTROLLER_IMPL_H
#define CONTROLLER_IMPL_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// Server lifecycle
void initServer();
void acceptClient(int clientId);
void sendMessage(int clientId);
int receiveAck(int clientId);
void closeServer();
// Target location protocol functions
// Configuration
int loadTargets(const char* filename, double* targets, int maxClients);
void sendTarget(int clientId, const double* target);
int receiveTargetAck(int clientId);
int waitForReady(int clientId);
void sendFinished(int clientId);
// Parallel wait functions (using select() for simultaneous processing)
int waitForAllTargetAck(int numClients);
int waitForAllReady(int numClients);
int waitForAllRTLComplete(int numClients);
int waitForAllLANDComplete(int numClients);
// RTL and LAND protocol functions
void sendRTL(int clientId);
void sendLAND(int clientId);
// User interaction
void waitForUserInput();
// Binary protocol operations
int sendMessageType(int clientId, int msgType);
int sendTarget(int clientId, const double* coords);
int waitForAllMessageType(int numClients, int expectedType);
#ifdef __cplusplus
}
#endif