handle pinging of unknown agents in AgentList thread

This commit is contained in:
Stephen Birarda 2013-04-10 12:37:14 -07:00
parent de358d4bf6
commit fcee05e9f0
4 changed files with 65 additions and 35 deletions

View file

@ -66,7 +66,7 @@ void *sendAvatarData(void *args) {
timeval startTime;
unsigned char *broadcastPacket = new unsigned char[MAX_PACKET_SIZE];
*broadcastPacket = PACKET_HEADER_HEAD_DATA;
*broadcastPacket = PACKET_HEADER_AVATAR_SERVER;
unsigned char* currentBufferPosition = NULL;
@ -78,15 +78,19 @@ void *sendAvatarData(void *args) {
for (std::vector<Agent>::iterator avatarAgent = agentList.getAgents().begin();
avatarAgent != agentList.getAgents().end();
avatarAgent++) {
currentBufferPosition = addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent);
if (avatarAgent->getLinkedData() != NULL) {
currentBufferPosition = addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent);
}
}
for (std::vector<Agent>::iterator avatarAgent = agentList.getAgents().begin();
avatarAgent != agentList.getAgents().end();
avatarAgent++) {
agentList.getAgentSocket().send(avatarAgent->getPublicSocket(),
broadcastPacket,
currentBufferPosition - broadcastPacket);
if (avatarAgent->getActiveSocket()) {
agentList.getAgentSocket().send(avatarAgent->getPublicSocket(),
broadcastPacket,
currentBufferPosition - broadcastPacket);
}
}
double usecToSleep = BROADCAST_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&startTime));
@ -111,6 +115,7 @@ int main(int argc, char* argv[])
agentList.startDomainServerCheckInThread();
agentList.startSilentAgentRemovalThread();
agentList.startPingUnknownAgentsThread();
sockaddr *agentAddress = new sockaddr;
char *packetData = new char[MAX_PACKET_SIZE];
@ -133,6 +138,7 @@ int main(int argc, char* argv[])
agentList.stopDomainServerCheckInThread();
agentList.stopSilentAgentRemovalThread();
agentList.stopPingUnknownAgentsThread();
pthread_join(sendAvatarDataThread, NULL);
return 0;

View file

@ -222,9 +222,6 @@ void Timer(int extra)
glutTimerFunc(1000,Timer,0);
gettimeofday(&timerStart, NULL);
// Ping the agents we can see
agentList.pingAgents();
// if we haven't detected gyros, check for them now
if (!serialPort.active) {
serialPort.pair();
@ -1250,9 +1247,10 @@ int main(int argc, const char * argv[])
int wsaresult = WSAStartup( MAKEWORD(2,2), &WsaData );
#endif
// start the thread which checks for silent agents
// start the agentList threads
agentList.startSilentAgentRemovalThread();
agentList.startDomainServerCheckInThread();
agentList.startPingUnknownAgentsThread();
glutInit(&argc, (char**)argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);

View file

@ -28,6 +28,7 @@ const int DOMAINSERVER_PORT = 40102;
bool silentAgentThreadStopFlag = false;
bool domainServerCheckinStopFlag = false;
bool pingUnknownAgentThreadStopFlag = false;
pthread_mutex_t vectorChangeMutex = PTHREAD_MUTEX_INITIALIZER;
int unpackAgentId(unsigned char *packedData, uint16_t *agentId) {
@ -50,6 +51,7 @@ AgentList::~AgentList() {
// stop the spawned threads, if they were started
stopSilentAgentRemovalThread();
stopDomainServerCheckInThread();
stopPingUnknownAgentsThread();
}
std::vector<Agent>& AgentList::getAgents() {
@ -209,7 +211,7 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket,
Agent newAgent = Agent(publicSocket, localSocket, agentType, agentId);
if (socketMatch(publicSocket, localSocket)) {
// likely debugging scenario with DS + agent on local network
// likely debugging scenario with two agents on local network
// set the agent active right away
newAgent.activatePublicSocket();
}
@ -222,8 +224,6 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket,
audioMixerSocketUpdate(publicSocketIn->sin_addr.s_addr, publicSocketIn->sin_port);
} else if (newAgent.getType() == AGENT_TYPE_VOXEL) {
newAgent.activatePublicSocket();
} else if (newAgent.getType() == AGENT_TYPE_AVATAR_MIXER) {
newAgent.activatePublicSocket();
}
std::cout << "Added agent - " << &newAgent << "\n";
@ -256,39 +256,64 @@ void AgentList::broadcastToAgents(char *broadcastData, size_t dataBytes, const c
}
}
void AgentList::pingAgents() {
char payload[1];
*payload = PACKET_HEADER_PING;
for(std::vector<Agent>::iterator agent = agents.begin(); agent != agents.end(); agent++) {
if (agent->getType() == AGENT_TYPE_INTERFACE) {
if (agent->getActiveSocket() != NULL) {
// we know which socket is good for this agent, send there
agentSocket.send(agent->getActiveSocket(), payload, 1);
} else {
// ping both of the sockets for the agent so we can figure out
// which socket we can use
agentSocket.send(agent->getPublicSocket(), payload, 1);
agentSocket.send(agent->getLocalSocket(), payload, 1);
}
}
}
}
void AgentList::handlePingReply(sockaddr *agentAddress) {
for(std::vector<Agent>::iterator agent = agents.begin(); agent != agents.end(); agent++) {
// check both the public and local addresses for each agent to see if we find a match
// prioritize the private address so that we prune erroneous local matches
if (socketMatch(agent->getPublicSocket(), agentAddress)) {
agent->activatePublicSocket();
std::cout << "Activated public socket for agent " << &*agent << "\n";
break;
} else if (socketMatch(agent->getLocalSocket(), agentAddress)) {
agent->activateLocalSocket();
std::cout << "Activated local socket for agent " << &*agent << "\n";
break;
}
}
}
void *pingUnknownAgents(void *args) {
AgentList *agentList = (AgentList *)args;
const int PING_INTERVAL_USECS = 1 * 1000000;
timeval lastSend;
while (!pingUnknownAgentThreadStopFlag) {
gettimeofday(&lastSend, NULL);
for(std::vector<Agent>::iterator agent = agentList->getAgents().begin();
agent != agentList->getAgents().end();
agent++) {
if (agent->getType() == AGENT_TYPE_INTERFACE) {
if (agent->getActiveSocket() == NULL) {
// ping both of the sockets for the agent so we can figure out
// which socket we can use
agentList->getAgentSocket().send(agent->getPublicSocket(), &PACKET_HEADER_PING, 1);
agentList->getAgentSocket().send(agent->getLocalSocket(), &PACKET_HEADER_PING, 1);
}
}
}
double usecToSleep = PING_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&lastSend));
if (usecToSleep > 0) {
usleep(usecToSleep);
}
}
return NULL;
}
void AgentList::startPingUnknownAgentsThread() {
pthread_create(&pingUnknownAgentsThread, NULL, pingUnknownAgents, (void *)this);
}
void AgentList::stopPingUnknownAgentsThread() {
pingUnknownAgentThreadStopFlag = true;
pthread_join(pingUnknownAgentsThread, NULL);
}
void *removeSilentAgents(void *args) {
std::vector<Agent> *agents = (std::vector<Agent> *)args;
double checkTimeUSecs, sleepTime;

View file

@ -37,6 +37,7 @@ class AgentList {
uint16_t lastAgentId;
pthread_t removeSilentAgentsThread;
pthread_t checkInWithDomainServerThread;
pthread_t pingUnknownAgentsThread;
void handlePingReply(sockaddr *agentAddress);
public:
@ -66,7 +67,6 @@ public:
void updateAgentWithData(Agent *agent, void *packetData, int dataBytes);
void broadcastToAgents(char *broadcastData, size_t dataBytes, const char* agentTypes);
void pingAgents();
char getOwnerType();
unsigned int getSocketListenPort();
@ -74,10 +74,11 @@ public:
void stopSilentAgentRemovalThread();
void startDomainServerCheckInThread();
void stopDomainServerCheckInThread();
void startPingUnknownAgentsThread();
void stopPingUnknownAgentsThread();
};
int unpackAgentId(char *packedData, uint16_t *agentId);
int packAgentId(char *packStore, uint16_t agentId);
int unpackAgentId(unsigned char *packedData, uint16_t *agentId);
int packAgentId(unsigned char *packStore, uint16_t agentId);
#endif /* defined(__hifi__AgentList__) */