From d81e52f6d706a88d086ca068a07e2cfd5907770f Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Tue, 12 Feb 2013 22:10:44 -0600 Subject: [PATCH 01/15] Bringing spaceserver into interface repo - adding CMake target --- CMakeLists.txt | 3 +- space/CMakeLists.txt | 7 ++ space/src/space.cpp | 262 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 271 insertions(+), 1 deletion(-) create mode 100644 space/CMakeLists.txt create mode 100644 space/src/space.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index cc2635f36b..57fb6959e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,4 +12,5 @@ file(GLOB HIFI_SHARED_SRCS ${HIFI_SHARED_DIR}/*.cpp ${HIFI_SHARED_DIR}/*.h) add_subdirectory(interface) add_subdirectory(domain) -add_subdirectory(mixer) \ No newline at end of file +add_subdirectory(mixer) +add_subdirectory(space) diff --git a/space/CMakeLists.txt b/space/CMakeLists.txt new file mode 100644 index 0000000000..4ad405d64c --- /dev/null +++ b/space/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 2.8) + +project(space) + +file(GLOB DOMAIN_SRCS src/*.cpp src/*.h) + +add_executable(space ${DOMAIN_SRCS}) diff --git a/space/src/space.cpp b/space/src/space.cpp new file mode 100644 index 0000000000..9c5119a2ce --- /dev/null +++ b/space/src/space.cpp @@ -0,0 +1,262 @@ +// +// spaceserver.cpp +// interface +// +// Created by Leonardo Murillo on 2/6/13. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const int CHILDREN_PER_NODE = 8; +const char *CONFIG_FILE = "/etc/below92/spaceserver.data.txt"; +const int UDP_PORT = 55551; +std::vector< std::vector > configData; +sockaddr_in address, dest_address; +socklen_t destLength = sizeof(dest_address); +const int BUFFER_LENGTH_BYTES = 1024; +const int BUFFER_LENGTH_SAMPLES = BUFFER_LENGTH_BYTES / sizeof(int16_t); + +std::string EMPTY_STRING = ""; + +std::string ROOT_HOSTNAME = "root.highfidelity.co"; +std::string ROOT_NICKNAME = "root"; +std::string *LAST_KNOWN_HOSTNAME = new std::string(); + +class treeNode { +public: + treeNode *child[CHILDREN_PER_NODE]; + std::string *hostname; + std::string *nickname; + int domain_id; + treeNode() { + for (int i = 0; i < CHILDREN_PER_NODE; ++i) { + child[i] = NULL; + } + hostname = &EMPTY_STRING; + nickname = &EMPTY_STRING; + } +}; + +treeNode rootNode; + +void printBinaryValue(char element) { + std::bitset<8> x(element); + std::cout << "Printing binary value: " << x << std::endl; +} + +int create_socket() +{ + // Create socket + int handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + + if (handle <= 0) { + printf("Failed to create socket: %d\n", handle); + return false; + } + + return handle; +} + +int network_init() +{ + int handle = create_socket(); + + // Bind socket to port + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons( (unsigned short) UDP_PORT ); + + if (bind(handle, (const sockaddr*) &address, sizeof(sockaddr_in)) < 0) { + printf( "failed to bind socket\n" ); + return false; + } + + return handle; +} + +treeNode *FindOrCreateNode(unsigned long lengthInBits, + unsigned char *addressBytes, + std::string *hostname, + std::string *nickname, + int domain_id) { + + treeNode *currentNode = &rootNode; + + for (int i = 0; i < lengthInBits; i += 3) { + unsigned char octetA; + unsigned char octetB; + unsigned char octet; + + /* + * @TODO Put those shifts into a nice single statement, leaving as is for now + */ + if (i%8 < 6) { + octetA = addressBytes[i/8] << i%8; + octet = octetA >> (5); + } else { + octetA = addressBytes[i/8] << i; + octetA = octetA >> (11 - i); + octetB = addressBytes[i/8 + 1] >> (11 - i + 2); + octet = octetA | octetB; + } + + printBinaryValue(octet); + + if (currentNode->child[octet] == NULL) { + currentNode->child[octet] = new treeNode; + } else if (!currentNode->child[octet]->hostname->empty()) { + LAST_KNOWN_HOSTNAME = currentNode->child[octet]->hostname; + } + + currentNode = currentNode->child[octet]; + } + + if (currentNode->hostname->empty()) { + currentNode->hostname = hostname; + currentNode->nickname = nickname; + } + + return currentNode; +}; + +bool LoadSpaceData(void) { + std::ifstream configFile(CONFIG_FILE); + std::string line; + + if (configFile.is_open()) { + while (getline(configFile, line)) { + std::istringstream iss(line); + std::vector thisEntry; + copy(std::istream_iterator(iss), + std::istream_iterator(), + std::back_inserter(thisEntry)); + configData.push_back(thisEntry); + thisEntry.clear(); + } + } else { + std::cout << "Unable to load config file\n"; + return false; + } + + for (std::vector< std::vector >::iterator it = configData.begin(); it != configData.end(); ++it) { + std::string *thisAddress = &(*it)[1]; + std::string *thisHostname = &(*it)[2]; + std::string *thisNickname = &(*it)[3]; + + char lengthByteString[8]; + unsigned long lengthByte; + unsigned long bitsInAddress; + std::size_t bytesForAddress; + + std::size_t lengthByteSlice = (*thisAddress).copy(lengthByteString, 8, 0); + lengthByteString[lengthByteSlice] = '\0'; + lengthByte = strtoul(lengthByteString, NULL, 2); + + bitsInAddress = lengthByte * 3; + bytesForAddress = (((bitsInAddress + 7) & ~7)); + char *addressBitStream = new char(); + std::size_t addressBitSlice = (*thisAddress).copy(addressBitStream, (*thisAddress).length(), 8); + + if (bitsInAddress != addressBitSlice) { + std::cout << "[FATAL] Mismatching byte length: " << bitsInAddress + << " and address bits: " << sizeof(addressBitStream) << std::endl; + return false; + } + + char paddedBitString[bytesForAddress]; + strcpy(paddedBitString, addressBitStream); + for (unsigned long i = addressBitSlice; i < bytesForAddress; ++i ) { + paddedBitString[i] = '0'; + } + paddedBitString[bytesForAddress] = '\0'; + + std::string byteBufferHolder = *new std::string(paddedBitString); + unsigned char addressBytes[bytesForAddress / 8]; + addressBytes[bytesForAddress / 8] = '\0'; + int j = 0; + + for (unsigned long i = 0; i < bytesForAddress; i += 8) { + char *byteHolder = new char; + unsigned long thisByte; + byteBufferHolder.copy(byteHolder, 8, i); + thisByte = strtoul(byteHolder, NULL, 2); + addressBytes[j] = thisByte; + ++j; + } + + FindOrCreateNode(bitsInAddress, addressBytes, thisHostname, thisNickname, 0); + } + return true; +} + +int main (int argc, const char *argv[]) { + int handle = network_init(); + unsigned char packet_data[BUFFER_LENGTH_SAMPLES]; + long received_bytes = 0; + + if (!handle) { + std::cout << "[FATAL] Failed to create UDP listening socket" << std::endl; + return 0; + } else { + std::cout << "[DEBUG] Socket started" << std::endl; + } + + rootNode.hostname = &ROOT_HOSTNAME; + rootNode.nickname = &ROOT_NICKNAME; + + LoadSpaceData(); + + std::cout << "[DEBUG] Listening for Datagrams" << std::endl; + + while (true) { + received_bytes = recvfrom(handle, (unsigned char*)packet_data, BUFFER_LENGTH_BYTES, 0, (sockaddr*)&dest_address, &destLength); + if (received_bytes > 0) { + unsigned long lengthInBits; + // I assume this will be asted to long properly... + lengthInBits = packet_data[0] * 3; + unsigned char addressData[sizeof(packet_data)-1]; + for (int i = 0; i < sizeof(packet_data)-1; ++i) { + addressData[i] = packet_data[i+1]; + } + std::string thisHostname; + std::string thisNickname; + std::string hostnameHolder; + int domain_id = 0; + long sentBytes; + + treeNode thisNode = *FindOrCreateNode(lengthInBits, addressData, &thisHostname, &thisNickname, domain_id); + + if (thisNode.hostname->empty()) { + hostnameHolder = *LAST_KNOWN_HOSTNAME; + } else { + hostnameHolder = *thisNode.hostname; + } + + char hostname[hostnameHolder.size() + 1]; + std::copy(hostnameHolder.begin(), hostnameHolder.end(), hostname); + hostname[hostnameHolder.size()] = '\0'; + + sentBytes = sendto(handle, &hostname, BUFFER_LENGTH_BYTES, + 0, (sockaddr*)&dest_address, sizeof(dest_address)); + } + } +} + From d3348f4de2dfbc863373208bc07a30d31a7a7b1b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 13 Feb 2013 12:50:26 -0800 Subject: [PATCH 02/15] make changes suggested in PR #9 --- space/CMakeLists.txt | 2 +- space/src/{space.cpp => main.cpp} | 24 ++++++++++-------------- 2 files changed, 11 insertions(+), 15 deletions(-) rename space/src/{space.cpp => main.cpp} (93%) diff --git a/space/CMakeLists.txt b/space/CMakeLists.txt index 4ad405d64c..fd33179c76 100644 --- a/space/CMakeLists.txt +++ b/space/CMakeLists.txt @@ -2,6 +2,6 @@ cmake_minimum_required(VERSION 2.8) project(space) -file(GLOB DOMAIN_SRCS src/*.cpp src/*.h) +file(GLOB SPACE_SRCS src/*.cpp src/*.h) add_executable(space ${DOMAIN_SRCS}) diff --git a/space/src/space.cpp b/space/src/main.cpp similarity index 93% rename from space/src/space.cpp rename to space/src/main.cpp index 9c5119a2ce..9710385263 100644 --- a/space/src/space.cpp +++ b/space/src/main.cpp @@ -1,6 +1,6 @@ // -// spaceserver.cpp -// interface +// main.cpp +// space // // Created by Leonardo Murillo on 2/6/13. // Copyright (c) 2013 HighFidelity, Inc. All rights reserved. @@ -29,10 +29,8 @@ const int CHILDREN_PER_NODE = 8; const char *CONFIG_FILE = "/etc/below92/spaceserver.data.txt"; const int UDP_PORT = 55551; std::vector< std::vector > configData; -sockaddr_in address, dest_address; -socklen_t destLength = sizeof(dest_address); -const int BUFFER_LENGTH_BYTES = 1024; -const int BUFFER_LENGTH_SAMPLES = BUFFER_LENGTH_BYTES / sizeof(int16_t); +sockaddr_in address, destAddress; +socklen_t destLength = sizeof(destAddress); std::string EMPTY_STRING = ""; @@ -92,7 +90,7 @@ int network_init() return handle; } -treeNode *FindOrCreateNode(unsigned long lengthInBits, +treeNode *findOrCreateNode(unsigned long lengthInBits, unsigned char *addressBytes, std::string *hostname, std::string *nickname, @@ -118,8 +116,6 @@ treeNode *FindOrCreateNode(unsigned long lengthInBits, octet = octetA | octetB; } - printBinaryValue(octet); - if (currentNode->child[octet] == NULL) { currentNode->child[octet] = new treeNode; } else if (!currentNode->child[octet]->hostname->empty()) { @@ -137,7 +133,7 @@ treeNode *FindOrCreateNode(unsigned long lengthInBits, return currentNode; }; -bool LoadSpaceData(void) { +bool loadSpaceData(void) { std::ifstream configFile(CONFIG_FILE); std::string line; @@ -202,7 +198,7 @@ bool LoadSpaceData(void) { ++j; } - FindOrCreateNode(bitsInAddress, addressBytes, thisHostname, thisNickname, 0); + findOrCreateNode(bitsInAddress, addressBytes, thisHostname, thisNickname, 0); } return true; } @@ -222,7 +218,7 @@ int main (int argc, const char *argv[]) { rootNode.hostname = &ROOT_HOSTNAME; rootNode.nickname = &ROOT_NICKNAME; - LoadSpaceData(); + loadSpaceData(); std::cout << "[DEBUG] Listening for Datagrams" << std::endl; @@ -230,8 +226,8 @@ int main (int argc, const char *argv[]) { received_bytes = recvfrom(handle, (unsigned char*)packet_data, BUFFER_LENGTH_BYTES, 0, (sockaddr*)&dest_address, &destLength); if (received_bytes > 0) { unsigned long lengthInBits; - // I assume this will be asted to long properly... lengthInBits = packet_data[0] * 3; + unsigned char addressData[sizeof(packet_data)-1]; for (int i = 0; i < sizeof(packet_data)-1; ++i) { addressData[i] = packet_data[i+1]; @@ -242,7 +238,7 @@ int main (int argc, const char *argv[]) { int domain_id = 0; long sentBytes; - treeNode thisNode = *FindOrCreateNode(lengthInBits, addressData, &thisHostname, &thisNickname, domain_id); + treeNode thisNode = *findOrCreateNode(lengthInBits, addressData, &thisHostname, &thisNickname, domain_id); if (thisNode.hostname->empty()) { hostnameHolder = *LAST_KNOWN_HOSTNAME; From ff4527904fa4db9bba52a84f4a32785fc1a1a5df Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 13 Feb 2013 12:55:03 -0800 Subject: [PATCH 03/15] fix src directory variable name in space CMakeList --- space/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/space/CMakeLists.txt b/space/CMakeLists.txt index fd33179c76..a1e60173a3 100644 --- a/space/CMakeLists.txt +++ b/space/CMakeLists.txt @@ -4,4 +4,4 @@ project(space) file(GLOB SPACE_SRCS src/*.cpp src/*.h) -add_executable(space ${DOMAIN_SRCS}) +add_executable(space ${SPACE_SRCS}) From 3d874357d74e7bcb0a69161c167c6addb2f5a96c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 13 Feb 2013 13:03:03 -0800 Subject: [PATCH 04/15] bust TreeNode out into seperate class --- space/src/TreeNode.cpp | 19 ++++++++++++++++++ space/src/TreeNode.h | 26 ++++++++++++++++++++++++ space/src/main.cpp | 45 ++++++++++++++---------------------------- 3 files changed, 60 insertions(+), 30 deletions(-) create mode 100644 space/src/TreeNode.cpp create mode 100644 space/src/TreeNode.h diff --git a/space/src/TreeNode.cpp b/space/src/TreeNode.cpp new file mode 100644 index 0000000000..7240dacebe --- /dev/null +++ b/space/src/TreeNode.cpp @@ -0,0 +1,19 @@ +// +// TreeNode.cpp +// hifi +// +// Created by Stephen Birarda on 2/13/13. +// +// + +#include "TreeNode.h" + +std::string EMPTY_STRING = ""; + +TreeNode::TreeNode() { + for (int i = 0; i < CHILDREN_PER_NODE; ++i) { + child[i] = NULL; + } + hostname = &EMPTY_STRING; + nickname = &EMPTY_STRING; +} \ No newline at end of file diff --git a/space/src/TreeNode.h b/space/src/TreeNode.h new file mode 100644 index 0000000000..d2668a2588 --- /dev/null +++ b/space/src/TreeNode.h @@ -0,0 +1,26 @@ +// +// TreeNode.h +// hifi +// +// Created by Stephen Birarda on 2/13/13. +// +// + +#ifndef __hifi__TreeNode__ +#define __hifi__TreeNode__ + +#include + +const int CHILDREN_PER_NODE = 8; + +class TreeNode { +public: + TreeNode(); + + TreeNode *child[CHILDREN_PER_NODE]; + std::string *hostname; + std::string *nickname; + int domain_id; +}; + +#endif /* defined(__hifi__TreeNode__) */ diff --git a/space/src/main.cpp b/space/src/main.cpp index 9710385263..1e71592105 100644 --- a/space/src/main.cpp +++ b/space/src/main.cpp @@ -24,36 +24,21 @@ #include #include #include +#include "TreeNode.h" -const int CHILDREN_PER_NODE = 8; const char *CONFIG_FILE = "/etc/below92/spaceserver.data.txt"; const int UDP_PORT = 55551; std::vector< std::vector > configData; sockaddr_in address, destAddress; socklen_t destLength = sizeof(destAddress); -std::string EMPTY_STRING = ""; - std::string ROOT_HOSTNAME = "root.highfidelity.co"; std::string ROOT_NICKNAME = "root"; std::string *LAST_KNOWN_HOSTNAME = new std::string(); -class treeNode { -public: - treeNode *child[CHILDREN_PER_NODE]; - std::string *hostname; - std::string *nickname; - int domain_id; - treeNode() { - for (int i = 0; i < CHILDREN_PER_NODE; ++i) { - child[i] = NULL; - } - hostname = &EMPTY_STRING; - nickname = &EMPTY_STRING; - } -}; +const short PACKET_LENGTH_BYTES = 1024; -treeNode rootNode; +TreeNode rootNode; void printBinaryValue(char element) { std::bitset<8> x(element); @@ -90,13 +75,13 @@ int network_init() return handle; } -treeNode *findOrCreateNode(unsigned long lengthInBits, +TreeNode *findOrCreateNode(unsigned long lengthInBits, unsigned char *addressBytes, std::string *hostname, std::string *nickname, int domain_id) { - treeNode *currentNode = &rootNode; + TreeNode *currentNode = &rootNode; for (int i = 0; i < lengthInBits; i += 3) { unsigned char octetA; @@ -117,7 +102,7 @@ treeNode *findOrCreateNode(unsigned long lengthInBits, } if (currentNode->child[octet] == NULL) { - currentNode->child[octet] = new treeNode; + currentNode->child[octet] = new TreeNode; } else if (!currentNode->child[octet]->hostname->empty()) { LAST_KNOWN_HOSTNAME = currentNode->child[octet]->hostname; } @@ -205,7 +190,7 @@ bool loadSpaceData(void) { int main (int argc, const char *argv[]) { int handle = network_init(); - unsigned char packet_data[BUFFER_LENGTH_SAMPLES]; + unsigned char packetData[PACKET_LENGTH_BYTES]; long received_bytes = 0; if (!handle) { @@ -223,14 +208,14 @@ int main (int argc, const char *argv[]) { std::cout << "[DEBUG] Listening for Datagrams" << std::endl; while (true) { - received_bytes = recvfrom(handle, (unsigned char*)packet_data, BUFFER_LENGTH_BYTES, 0, (sockaddr*)&dest_address, &destLength); + received_bytes = recvfrom(handle, (unsigned char*)packetData, PACKET_LENGTH_BYTES, 0, (sockaddr*)&destAddress, &destLength); if (received_bytes > 0) { unsigned long lengthInBits; - lengthInBits = packet_data[0] * 3; + lengthInBits = packetData[0] * 3; - unsigned char addressData[sizeof(packet_data)-1]; - for (int i = 0; i < sizeof(packet_data)-1; ++i) { - addressData[i] = packet_data[i+1]; + unsigned char addressData[sizeof(packetData)-1]; + for (int i = 0; i < sizeof(packetData)-1; ++i) { + addressData[i] = packetData[i+1]; } std::string thisHostname; std::string thisNickname; @@ -238,7 +223,7 @@ int main (int argc, const char *argv[]) { int domain_id = 0; long sentBytes; - treeNode thisNode = *findOrCreateNode(lengthInBits, addressData, &thisHostname, &thisNickname, domain_id); + TreeNode thisNode = *findOrCreateNode(lengthInBits, addressData, &thisHostname, &thisNickname, domain_id); if (thisNode.hostname->empty()) { hostnameHolder = *LAST_KNOWN_HOSTNAME; @@ -250,8 +235,8 @@ int main (int argc, const char *argv[]) { std::copy(hostnameHolder.begin(), hostnameHolder.end(), hostname); hostname[hostnameHolder.size()] = '\0'; - sentBytes = sendto(handle, &hostname, BUFFER_LENGTH_BYTES, - 0, (sockaddr*)&dest_address, sizeof(dest_address)); + sentBytes = sendto(handle, &hostname, PACKET_LENGTH_BYTES, + 0, (sockaddr*)&destAddress, sizeof(destAddress)); } } } From 09dee912790d4c35503b7221f7d39ee0afdbaa85 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 13 Feb 2013 13:42:23 -0800 Subject: [PATCH 05/15] collect agent address on receive to send back audio --- interface/src/Audio.cpp | 6 +++--- interface/src/main.cpp | 2 +- mixer/src/main.cpp | 19 +++++++++---------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index a0fa6a9660..5764df28a9 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -38,10 +38,10 @@ const short JITTER_BUFFER_SAMPLES = JITTER_BUFFER_LENGTH_MSECS * (SAMPLE_RATE / const short NUM_AUDIO_SOURCES = 2; const short ECHO_SERVER_TEST = 1; -char WORKCLUB_AUDIO_SERVER[] = "192.168.1.19"; +char WORKCLUB_AUDIO_SERVER[] = "0.0.0.0"; char EC2_WEST_AUDIO_SERVER[] = "54.241.92.53"; -const int AUDIO_UDP_LISTEN_PORT = 55444; +const int AUDIO_UDP_LISTEN_PORT = 55446; int starve_counter = 0; @@ -88,7 +88,7 @@ int audioCallback (const void *inputBuffer, // int16_t *inputRight = ((int16_t **) inputBuffer)[1]; if (inputLeft != NULL) { - data->audioSocket->send((char *) EC2_WEST_AUDIO_SERVER, 55443, (void *)inputLeft, BUFFER_LENGTH_BYTES); + data->audioSocket->send((char *) WORKCLUB_AUDIO_SERVER, 55443, (void *)inputLeft, BUFFER_LENGTH_BYTES); // // Measure the loudness of the signal from the microphone and store in audio object // diff --git a/interface/src/main.cpp b/interface/src/main.cpp index d7e62af527..81a2cd23d0 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -158,7 +158,7 @@ int speed; // SerialInterface serialPort; -char serial_portname[] = "/dev/tty.usbmodem411"; +char serial_portname[] = "/dev/tty.usbmodemfd131"; int serial_on = 0; int latency_display = 1; diff --git a/mixer/src/main.cpp b/mixer/src/main.cpp index 7d28742d21..3470de215a 100644 --- a/mixer/src/main.cpp +++ b/mixer/src/main.cpp @@ -36,8 +36,7 @@ const long MIN_SAMPLE_VALUE = std::numeric_limits::min(); const int MAX_SOURCE_BUFFERS = 20; -sockaddr_in address, destAddress; -socklen_t destLength = sizeof(destAddress); +sockaddr_in agentAddress; struct AgentList { char *address; @@ -196,7 +195,7 @@ void *sendBufferThread(void *args) } - audioSocket->send(agents[a].address, agents[a].port, clientMix, BUFFER_LENGTH_BYTES); + audioSocket->send(agents[a].address, agents[a].port, (void *) clientMix, BUFFER_LENGTH_BYTES); if (sentBytes < BUFFER_LENGTH_BYTES) { std::cout << "Error sending mix packet! " << sentBytes << strerror(errno) << "\n"; @@ -222,19 +221,19 @@ void *sendBufferThread(void *args) struct processArgStruct { int16_t *packetData; - sockaddr_in destAddress; + sockaddr_in agentAddress; }; void *processClientPacket(void *args) { struct processArgStruct *processArgs = (struct processArgStruct *) args; - sockaddr_in destAddress = processArgs->destAddress; + sockaddr_in agentAddress = processArgs->agentAddress; - if (addAgent(destAddress, processArgs->packetData)) { + if (addAgent(agentAddress, processArgs->packetData)) { std::cout << "Added agent: " << - inet_ntoa(destAddress.sin_addr) << " on " << - ntohs(destAddress.sin_port) << "\n"; + inet_ntoa(agentAddress.sin_addr) << " on " << + ntohs(agentAddress.sin_port) << "\n"; } pthread_exit(0); @@ -263,10 +262,10 @@ int main(int argc, const char * argv[]) pthread_create(&bufferSendThread, NULL, sendBufferThread, (void *)&sendBufferArgs); while (true) { - if(audioSocket.receive(packetData, &receivedBytes)) { + if(audioSocket.receive(&agentAddress, packetData, &receivedBytes)) { struct processArgStruct args; args.packetData = packetData; - args.destAddress = destAddress; + args.agentAddress = agentAddress; pthread_t clientProcessThread; pthread_create(&clientProcessThread, NULL, processClientPacket, (void *)&args); From 28beb3ecfcd493a943de0652984b43cc205a8b3a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 13 Feb 2013 13:44:26 -0800 Subject: [PATCH 06/15] undo changes to interface constants --- interface/src/Audio.cpp | 6 +++--- interface/src/main.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 5764df28a9..a0fa6a9660 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -38,10 +38,10 @@ const short JITTER_BUFFER_SAMPLES = JITTER_BUFFER_LENGTH_MSECS * (SAMPLE_RATE / const short NUM_AUDIO_SOURCES = 2; const short ECHO_SERVER_TEST = 1; -char WORKCLUB_AUDIO_SERVER[] = "0.0.0.0"; +char WORKCLUB_AUDIO_SERVER[] = "192.168.1.19"; char EC2_WEST_AUDIO_SERVER[] = "54.241.92.53"; -const int AUDIO_UDP_LISTEN_PORT = 55446; +const int AUDIO_UDP_LISTEN_PORT = 55444; int starve_counter = 0; @@ -88,7 +88,7 @@ int audioCallback (const void *inputBuffer, // int16_t *inputRight = ((int16_t **) inputBuffer)[1]; if (inputLeft != NULL) { - data->audioSocket->send((char *) WORKCLUB_AUDIO_SERVER, 55443, (void *)inputLeft, BUFFER_LENGTH_BYTES); + data->audioSocket->send((char *) EC2_WEST_AUDIO_SERVER, 55443, (void *)inputLeft, BUFFER_LENGTH_BYTES); // // Measure the loudness of the signal from the microphone and store in audio object // diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 81a2cd23d0..d7e62af527 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -158,7 +158,7 @@ int speed; // SerialInterface serialPort; -char serial_portname[] = "/dev/tty.usbmodemfd131"; +char serial_portname[] = "/dev/tty.usbmodem411"; int serial_on = 0; int latency_display = 1; From a725db5bd796e5fbc25237140dc286797493408c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 13 Feb 2013 14:06:06 -0800 Subject: [PATCH 07/15] compare ports of same endianess for agent comparison --- mixer/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mixer/src/main.cpp b/mixer/src/main.cpp index 3470de215a..e4a10c840d 100644 --- a/mixer/src/main.cpp +++ b/mixer/src/main.cpp @@ -68,7 +68,7 @@ int addAgent(sockaddr_in agentAddress, void *audioData) { for (i = 0; i < numAgents; i++) { if (strcmp(inet_ntoa(agentAddress.sin_addr), agents[i].address) == 0 - && agentAddress.sin_port == agents[i].port) { + && ntohs(agentAddress.sin_port) == agents[i].port) { break; } } From 5ced381097628fe22cfc165b2f3e69939bcd4a55 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 13 Feb 2013 14:54:39 -0800 Subject: [PATCH 08/15] store number of sentBytes returned from UDPSocket --- mixer/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mixer/src/main.cpp b/mixer/src/main.cpp index e4a10c840d..7fa69dfee1 100644 --- a/mixer/src/main.cpp +++ b/mixer/src/main.cpp @@ -195,7 +195,7 @@ void *sendBufferThread(void *args) } - audioSocket->send(agents[a].address, agents[a].port, (void *) clientMix, BUFFER_LENGTH_BYTES); + sentBytes = audioSocket->send(agents[a].address, agents[a].port, (void *) clientMix, BUFFER_LENGTH_BYTES); if (sentBytes < BUFFER_LENGTH_BYTES) { std::cout << "Error sending mix packet! " << sentBytes << strerror(errno) << "\n"; From 815783732cd758d7447dd0ed991305aae4c98b77 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 13 Feb 2013 15:27:16 -0800 Subject: [PATCH 09/15] make UDPSocket non-blocking, thread receive of data in interface --- interface/src/main.cpp | 101 +++++++++++++++++++++------------------ mixer/src/main.cpp | 6 +-- shared/src/UDPSocket.cpp | 7 --- 3 files changed, 57 insertions(+), 57 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index d7e62af527..dd602bd037 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -63,7 +63,7 @@ const int DOMAINSERVER_PORT = 40102; UDPSocket agentSocket(AGENT_UDP_PORT); // For testing, add milliseconds of delay for received UDP packets -char* incoming_packet; +char* incomingPacket; int packetcount = 0; int packets_per_second = 0; @@ -777,53 +777,57 @@ void key(unsigned char k, int x, int y) // // Receive packets from other agents/servers and decide what to do with them! // -void read_network() +void *networkReceive(void *args) { sockaddr_in senderAddress; - int bytes_recvd; - while (agentSocket.receive(&senderAddress, (void *)incoming_packet, &bytes_recvd)) - { - packetcount++; - bytescount += bytes_recvd; - // If packet is a Mouse data packet, copy it over - if (incoming_packet[0] == 'P') { - // - // Got Ping, reply immediately! - // - //printf("Replying to ping!\n"); - char reply[] = "R"; - agentSocket.send(inet_ntoa(senderAddress.sin_addr), ntohs(senderAddress.sin_port), reply, 1); - } else if (incoming_packet[0] == 'R') { - // - // Got Reply, record as appropriate - // - setAgentPing(inet_ntoa(senderAddress.sin_addr), ntohs(senderAddress.sin_port)); - - } else if (incoming_packet[0] == 'M') { - // - // mouse location packet - // - sscanf(incoming_packet, "M %d %d", &target_x, &target_y); - target_display = 1; - //printf("X = %d Y = %d\n", target_x, target_y); - } else if (incoming_packet[0] == 'D') { - // - // Message from domainserver - // - //printf("agent list received!\n"); - nearbyAgents = update_agents(&incoming_packet[1], bytes_recvd - 1); - } else if (incoming_packet[0] == 'H') { - // - // Broadcast packet from another agent - // - update_agent(inet_ntoa(senderAddress.sin_addr), ntohs(senderAddress.sin_port), &incoming_packet[1], bytes_recvd - 1); - } else if (incoming_packet[0] == 'T') { - // Received a self-test packet (to get one's own IP), copy it to local variable! - printf("My Address: %s:%u\n", - inet_ntoa(senderAddress.sin_addr), - senderAddress.sin_port); + int bytesRecvd; + while (true) { + if (agentSocket.receive(&senderAddress, (void *)incomingPacket, &bytesRecvd)) { + + packetcount++; + bytescount += bytesRecvd; + // If packet is a Mouse data packet, copy it over + if (incomingPacket[0] == 'P') { + // + // Got Ping, reply immediately! + // + //printf("Replying to ping!\n"); + char reply[] = "R"; + agentSocket.send(inet_ntoa(senderAddress.sin_addr), ntohs(senderAddress.sin_port), reply, 1); + } else if (incomingPacket[0] == 'R') { + // + // Got Reply, record as appropriate + // + setAgentPing(inet_ntoa(senderAddress.sin_addr), ntohs(senderAddress.sin_port)); + + } else if (incomingPacket[0] == 'M') { + // + // mouse location packet + // + sscanf(incomingPacket, "M %d %d", &target_x, &target_y); + target_display = 1; + //printf("X = %d Y = %d\n", target_x, target_y); + } else if (incomingPacket[0] == 'D') { + // + // Message from domainserver + // + //printf("agent list received!\n"); + nearbyAgents = update_agents(&incomingPacket[1], bytesRecvd - 1); + } else if (incomingPacket[0] == 'H') { + // + // Broadcast packet from another agent + // + update_agent(inet_ntoa(senderAddress.sin_addr), ntohs(senderAddress.sin_port), &incomingPacket[1], bytesRecvd - 1); + } else if (incomingPacket[0] == 'T') { + // Received a self-test packet (to get one's own IP), copy it to local variable! + printf("My Address: %s:%u\n", + inet_ntoa(senderAddress.sin_addr), + senderAddress.sin_port); + } } } + + pthread_exit(0); } void idle(void) @@ -852,8 +856,6 @@ void idle(void) } - // Read network packets - read_network(); // Read serial data if (serial_on) serialPort.readData(); if (SLEEP) @@ -938,7 +940,7 @@ void *poll_marker_capture(void *threadarg){ int main(int argc, char** argv) { // Create network socket and buffer - incoming_packet = new char[MAX_PACKET_SIZE]; + incomingPacket = new char[MAX_PACKET_SIZE]; // Lookup the IP address of things we have hostnames printf("need to look this one up\n"); @@ -996,6 +998,10 @@ int main(int argc, char** argv) printf("Serial Port Initialized\n"); serial_on = 1; } + + // create thread for receipt of data via UDP + pthread_t networkReceiveThread; + pthread_create(&networkReceiveThread, NULL, networkReceive, NULL); glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); @@ -1045,6 +1051,7 @@ int main(int argc, char** argv) } #endif + pthread_join(networkReceiveThread, NULL); ::terminate(); return EXIT_SUCCESS; } diff --git a/mixer/src/main.cpp b/mixer/src/main.cpp index 7fa69dfee1..2d41511349 100644 --- a/mixer/src/main.cpp +++ b/mixer/src/main.cpp @@ -111,7 +111,7 @@ struct sendBufferStruct { UDPSocket *audioSocket; }; -void *sendBufferThread(void *args) +void *sendBuffer(void *args) { struct sendBufferStruct *bufferArgs = (struct sendBufferStruct *)args; UDPSocket *audioSocket = bufferArgs->audioSocket; @@ -258,8 +258,8 @@ int main(int argc, const char * argv[]) struct sendBufferStruct sendBufferArgs; sendBufferArgs.audioSocket = &audioSocket; - pthread_t bufferSendThread; - pthread_create(&bufferSendThread, NULL, sendBufferThread, (void *)&sendBufferArgs); + pthread_t sendBufferThread; + pthread_create(&sendBufferThread, NULL, sendBuffer, (void *)&sendBufferArgs); while (true) { if(audioSocket.receive(&agentAddress, packetData, &receivedBytes)) { diff --git a/shared/src/UDPSocket.cpp b/shared/src/UDPSocket.cpp index 68c84e2564..2fdbb2f0b7 100644 --- a/shared/src/UDPSocket.cpp +++ b/shared/src/UDPSocket.cpp @@ -41,13 +41,6 @@ UDPSocket::UDPSocket(int listeningPort) { return; } - // set socket as non-blocking - int nonBlocking = 1; - if (fcntl(handle, F_SETFL, O_NONBLOCK, nonBlocking) == -1) { - printf("Failed to set non-blocking socket\n"); - return; - } - printf("Created UDP socket listening on port %d.\n", listeningPort); } From 4fc9dd632368e0b01d72aa5f91fb8a18915dcf0f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 13 Feb 2013 15:29:47 -0800 Subject: [PATCH 10/15] fix use of undeclared identifier --- mixer/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mixer/src/main.cpp b/mixer/src/main.cpp index 2d41511349..ffc6fa7c33 100644 --- a/mixer/src/main.cpp +++ b/mixer/src/main.cpp @@ -273,7 +273,7 @@ int main(int argc, const char * argv[]) } } - pthread_join(bufferSendThread, NULL); + pthread_join(sendBufferThread, NULL); return 0; } From 4270cfe2b49101690f211065afab1f8c6ea32027 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 13 Feb 2013 16:14:04 -0800 Subject: [PATCH 11/15] send client their own packet for solo mixer testing --- mixer/src/main.cpp | 9 +++++---- shared/src/UDPSocket.cpp | 5 +---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/mixer/src/main.cpp b/mixer/src/main.cpp index ffc6fa7c33..9dce08fc94 100644 --- a/mixer/src/main.cpp +++ b/mixer/src/main.cpp @@ -171,10 +171,11 @@ void *sendBuffer(void *args) } for(int as = 0; as < BUFFER_LENGTH_SAMPLES; as++) { - long longSample = previousOutput != NULL - ? masterMix[as] - previousOutput[as] - : masterMix[as]; +// long longSample = previousOutput != NULL +// ? masterMix[as] - previousOutput[as] +// : masterMix[as]; + long longSample = masterMix[as]; int16_t shortSample; @@ -195,7 +196,7 @@ void *sendBuffer(void *args) } - sentBytes = audioSocket->send(agents[a].address, agents[a].port, (void *) clientMix, BUFFER_LENGTH_BYTES); + sentBytes = audioSocket->send(agents[a].address, agents[a].port, clientMix, BUFFER_LENGTH_BYTES); if (sentBytes < BUFFER_LENGTH_BYTES) { std::cout << "Error sending mix packet! " << sentBytes << strerror(errno) << "\n"; diff --git a/shared/src/UDPSocket.cpp b/shared/src/UDPSocket.cpp index 2fdbb2f0b7..edff5740ff 100644 --- a/shared/src/UDPSocket.cpp +++ b/shared/src/UDPSocket.cpp @@ -51,10 +51,7 @@ UDPSocket::~UDPSocket() { // Receive data on this socket with retrieving address of sender bool UDPSocket::receive(void *receivedData, int *receivedBytes) { - *receivedBytes = recvfrom(handle, receivedData, MAX_BUFFER_LENGTH_BYTES, - 0, (sockaddr *)&senderAddress, &addLength); - - return (*receivedBytes > 0); + return receive(&senderAddress, receivedData, receivedBytes); } // Receive data on this socket with the address of the sender From ff8333512340a20f927cc15d0d18d366de3af343 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 13 Feb 2013 16:19:31 -0800 Subject: [PATCH 12/15] undo solo test for mixer, add localhost mixer const to Audio.cpp --- interface/src/Audio.cpp | 7 ++++--- mixer/src/main.cpp | 8 +++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index a0fa6a9660..8d5e0f9647 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -38,8 +38,9 @@ const short JITTER_BUFFER_SAMPLES = JITTER_BUFFER_LENGTH_MSECS * (SAMPLE_RATE / const short NUM_AUDIO_SOURCES = 2; const short ECHO_SERVER_TEST = 1; -char WORKCLUB_AUDIO_SERVER[] = "192.168.1.19"; -char EC2_WEST_AUDIO_SERVER[] = "54.241.92.53"; +char LOCALHOST_MIXER[] = "0.0.0.0"; +char WORKCLUB_MIXER[] = "192.168.1.19"; +char EC2_WEST_MIXER[] = "54.241.92.53"; const int AUDIO_UDP_LISTEN_PORT = 55444; @@ -88,7 +89,7 @@ int audioCallback (const void *inputBuffer, // int16_t *inputRight = ((int16_t **) inputBuffer)[1]; if (inputLeft != NULL) { - data->audioSocket->send((char *) EC2_WEST_AUDIO_SERVER, 55443, (void *)inputLeft, BUFFER_LENGTH_BYTES); + data->audioSocket->send((char *) EC2_WEST_MIXER, 55443, (void *)inputLeft, BUFFER_LENGTH_BYTES); // // Measure the loudness of the signal from the microphone and store in audio object // diff --git a/mixer/src/main.cpp b/mixer/src/main.cpp index 9dce08fc94..c9efe24b93 100644 --- a/mixer/src/main.cpp +++ b/mixer/src/main.cpp @@ -171,12 +171,10 @@ void *sendBuffer(void *args) } for(int as = 0; as < BUFFER_LENGTH_SAMPLES; as++) { -// long longSample = previousOutput != NULL -// ? masterMix[as] - previousOutput[as] -// : masterMix[as]; + long longSample = previousOutput != NULL + ? masterMix[as] - previousOutput[as] + : masterMix[as]; - long longSample = masterMix[as]; - int16_t shortSample; if (longSample < 0) { From 5196a1ba1b2b13ebdf22c0c5e980b84696004a98 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 13 Feb 2013 17:52:10 -0800 Subject: [PATCH 13/15] remove incorrect threaded agent processing, fix agent replacement --- mixer/src/main.cpp | 49 +++++++++++++--------------------------- shared/src/UDPSocket.cpp | 7 +++--- shared/src/UDPSocket.h | 2 +- 3 files changed, 21 insertions(+), 37 deletions(-) diff --git a/mixer/src/main.cpp b/mixer/src/main.cpp index c9efe24b93..d532f521a4 100644 --- a/mixer/src/main.cpp +++ b/mixer/src/main.cpp @@ -61,25 +61,29 @@ double usecTimestamp(timeval *time, double addedUsecs = 0) { return (time->tv_sec * 1000000.0) + time->tv_usec + addedUsecs; } -int addAgent(sockaddr_in agentAddress, void *audioData) { +int addAgent(sockaddr_in *newAddress, void *audioData) { // Search for agent in list and add if needed int is_new = 0; int i = 0; - for (i = 0; i < numAgents; i++) { - if (strcmp(inet_ntoa(agentAddress.sin_addr), agents[i].address) == 0 - && ntohs(agentAddress.sin_port) == agents[i].port) { + for (i = 0; i < numAgents; i++) { + if (strcmp(inet_ntoa(newAddress->sin_addr), agents[i].address) == 0 + && ntohs(newAddress->sin_port) == agents[i].port) { break; } } if ((i == numAgents) || (agents[i].active == false)) { is_new = 1; + + agents[i].address = new char(); + strcpy(agents[i].address, inet_ntoa(newAddress->sin_addr)); + agents[i].bufferTransmitted = false; } - - agents[i].address = inet_ntoa(agentAddress.sin_addr); - agents[i].port = ntohs(agentAddress.sin_port); + + + agents[i].port = ntohs(newAddress->sin_port); agents[i].active = true; gettimeofday(&agents[i].time, NULL); @@ -218,26 +222,6 @@ void *sendBuffer(void *args) pthread_exit(0); } -struct processArgStruct { - int16_t *packetData; - sockaddr_in agentAddress; -}; - -void *processClientPacket(void *args) -{ - struct processArgStruct *processArgs = (struct processArgStruct *) args; - - sockaddr_in agentAddress = processArgs->agentAddress; - - if (addAgent(agentAddress, processArgs->packetData)) { - std::cout << "Added agent: " << - inet_ntoa(agentAddress.sin_addr) << " on " << - ntohs(agentAddress.sin_port) << "\n"; - } - - pthread_exit(0); -} - int main(int argc, const char * argv[]) { timeval lastAgentUpdate; @@ -262,13 +246,12 @@ int main(int argc, const char * argv[]) while (true) { if(audioSocket.receive(&agentAddress, packetData, &receivedBytes)) { - struct processArgStruct args; - args.packetData = packetData; - args.agentAddress = agentAddress; - pthread_t clientProcessThread; - pthread_create(&clientProcessThread, NULL, processClientPacket, (void *)&args); - pthread_join(clientProcessThread, NULL); + if (addAgent(&agentAddress, packetData)) { + std::cout << "Added agent: " << + inet_ntoa(agentAddress.sin_addr) << " on " << + ntohs(agentAddress.sin_port) << "\n"; + } } } diff --git a/shared/src/UDPSocket.cpp b/shared/src/UDPSocket.cpp index edff5740ff..dfb80e8c63 100644 --- a/shared/src/UDPSocket.cpp +++ b/shared/src/UDPSocket.cpp @@ -13,7 +13,6 @@ #include sockaddr_in destSockaddr, senderAddress; -socklen_t addLength = sizeof(senderAddress); UDPSocket::UDPSocket(int listeningPort) { // create the socket @@ -55,10 +54,12 @@ bool UDPSocket::receive(void *receivedData, int *receivedBytes) { } // Receive data on this socket with the address of the sender -bool UDPSocket::receive(sockaddr_in *senderAddress, void *receivedData, int *receivedBytes) { +bool UDPSocket::receive(sockaddr_in *recvAddress, void *receivedData, int *receivedBytes) { + + socklen_t addressSize = sizeof(&recvAddress); *receivedBytes = recvfrom(handle, receivedData, MAX_BUFFER_LENGTH_BYTES, - 0, (sockaddr *)senderAddress, &addLength); + 0, (sockaddr *) recvAddress, &addressSize); return (*receivedBytes > 0); } diff --git a/shared/src/UDPSocket.h b/shared/src/UDPSocket.h index b32267af3b..a559b8d847 100644 --- a/shared/src/UDPSocket.h +++ b/shared/src/UDPSocket.h @@ -21,7 +21,7 @@ class UDPSocket { ~UDPSocket(); int send(char *destAddress, int destPort, const void *data, int byteLength); bool receive(void *receivedData, int *receivedBytes); - bool receive(sockaddr_in *senderAddress, void *receivedData, int *receivedBytes); + bool receive(sockaddr_in *recvAddress, void *receivedData, int *receivedBytes); private: int handle; From 9de42bdf75a36cdc21389236333ccd15171d8358 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 13 Feb 2013 19:36:42 -0800 Subject: [PATCH 14/15] same IP but different port is a new agent --- domain/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain/src/main.cpp b/domain/src/main.cpp index f31f9028da..dc53bbdbaa 100644 --- a/domain/src/main.cpp +++ b/domain/src/main.cpp @@ -103,7 +103,7 @@ int addAgent(uint32_t ip, in_port_t port, char agentType, float x, float y, floa // Search for agent in list and add if needed int i = 0; int is_new = 0; - while ((ip != agents[i].ip) && (i < num_agents)) { + while ((ip != agents[i].ip && port != agents[i].port) && (i < num_agents)) { i++; } if ((i == num_agents) || (agents[i].active == false)) is_new = 1; From 7f35fe9993be039e0168b4dc9f7b794dacc9150f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 13 Feb 2013 20:17:35 -0800 Subject: [PATCH 15/15] fix agent comparison for add of agent --- domain/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain/src/main.cpp b/domain/src/main.cpp index dc53bbdbaa..4202400ece 100644 --- a/domain/src/main.cpp +++ b/domain/src/main.cpp @@ -103,7 +103,7 @@ int addAgent(uint32_t ip, in_port_t port, char agentType, float x, float y, floa // Search for agent in list and add if needed int i = 0; int is_new = 0; - while ((ip != agents[i].ip && port != agents[i].port) && (i < num_agents)) { + while ((ip != agents[i].ip || port != agents[i].port) && (i < num_agents)) { i++; } if ((i == num_agents) || (agents[i].active == false)) is_new = 1;