//void writeSystemTime(struct timespec * p) //{ // assert(!clock_settime(CLOCK_REALTIME, p)); //} // Function for filling the packet structure void ModbusClientV1::fillTheCommonPacketHeader(RSPacket::PacketStruct & p, int cmd) { struct timespec time; time.tv_sec = 0x55; time.tv_nsec = 0x66; p.header.errorcode = 0; p.header.cmd = cmd; readSystemTime(&time); setPacketTime(p, time); }
void flushUpload(int sock) { int i = 0; Packet *pkt; connUp *pool = uploadPool; for(i = 0; i < peerInfo.numPeer; i++) { int peerID = peerInfo.peerList[i].peerID; Packet *ack = peek(pool[peerID].ackWaitQueue); if(ack != NULL) { struct timeval curTime; gettimeofday(&curTime, NULL); long dt = diffTimeval(&curTime, &(ack->timestamp)); if(dt > DATA_TIMEOUT_SEC) { pool[peerID].timeoutCount++; fprintf(stderr,"Timeout while waiting ACK %d\n", getPacketSeq(ack)); if(pool[peerID].timeoutCount == 3) { fprintf(stderr,"Receiver ID %d timed out 3 times. Closing connection!\n", peerID); numConnUp--; cleanUpConnUp(&(pool[peerID])); continue; } fprintf(stderr,"Data timed out. Resizing window.\n"); shrinkWindow(&(pool[peerID].sw.ctrl)); mergeAtFront(pool[peerID].ackWaitQueue, pool[peerID].dataQueue); } } pkt = peek(pool[peerID].dataQueue); while(pkt != NULL && (getPacketSeq(pkt) <= pool[peerID].sw.lastPacketAvailable)) { peerList_t *p = &(peerInfo.peerList[i]); int retVal = spiffy_sendto(sock, pkt->payload, getPacketSize(pkt), 0, (struct sockaddr *) & (p->addr), sizeof(p->addr)); setPacketTime(pkt); fprintf(stderr,"Sent data %d. last available %d\n", getPacketSeq(pkt), pool[peerID].sw.lastPacketAvailable); if(retVal == -1) { // If spiffy_sendto doesn't f*****g work (AND IT DOESN'T!) fprintf(stderr,"spiffy_sendto() returned -1.\n"); enqueue(pool[peerID].dataQueue, dequeue(pool[peerID].dataQueue)); } else { dequeue(pool[peerID].dataQueue); pool[peerID].sw.lastPacketSent = getPacketSeq(pkt); enqueue(pool[peerID].ackWaitQueue, pkt); pkt = peek(pool[peerID].dataQueue); } } } }
int _tmain(int argc, char *argv[]) { WSADATA wsaData; int iResult; int packetCount = 0; SOCKET ListenSocket = INVALID_SOCKET; SOCKET ClientSocket = INVALID_SOCKET; struct addrinfo *result = NULL; struct addrinfo hints; int iSendResult; int sendHK = 1; if ( _debug ) fprintf( stderr, "%s started.\n\n", argv[0] ); fprintf( stderr, "This is the EPM/GRIP packet server emulator.\n" ); fprintf( stderr, "It waits for a client to connect and then sends\n out HK and RT packets at 0.5 and 1 Hz respectively.\n" ); fprintf( stderr, "\n" ); // Prepare the packets. memcpy( &hkPacket, &hkHeader, sizeof( hkHeader ) ); memcpy( &rtPacket, &rtHeader, sizeof( rtHeader ) ); // Initialize Winsock iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { fprintf( stderr, "WSAStartup failed with error: %d\n", iResult ); return 1; } else if ( _debug ) fprintf( stderr, "WSAStartup() OK.\n" ); ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; // Resolve the server address and port iResult = getaddrinfo(NULL, EPMport, &hints, &result); if ( iResult != 0 ) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); return 2; } else if ( _debug ) fprintf( stderr, "getaddrinfo() OK.\n" ); // Create a SOCKET for connecting to server ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (ListenSocket == INVALID_SOCKET) { printf("socket failed with error: %ld\n", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); return 3; } else if ( _debug ) fprintf( stderr, "ListenSocket() OK.\n" ); // Setup the TCP listening socket iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen); if (iResult == SOCKET_ERROR) { printf("bind failed with error: %d\n", WSAGetLastError()); freeaddrinfo(result); closesocket(ListenSocket); WSACleanup(); return 4; } else if ( _debug ) fprintf( stderr, "bind() OK.\n" ); // We don't need the address info anymore, so free it. freeaddrinfo(result); // Enter an infinite loop that listens for connections, // outputs packets as long as the connection is valid and // then exits. // The only way out is to kill the program (<ctrl-c>). // NB We effectively only allow one client at a time. while ( 1 ) { // Listen until we get a connection. fprintf( stderr, "Listening for a connection ... " ); iResult = listen(ListenSocket, SOMAXCONN); if (iResult == SOCKET_ERROR) { printf("listen failed with error: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 5; } else if ( _debug ) fprintf( stderr, "listen() OK " ); // Accept a client socket ClientSocket = accept(ListenSocket, NULL, NULL); if (ClientSocket == INVALID_SOCKET) { fprintf( stderr, "accept failed with error: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 6; } else if ( _debug ) fprintf( stderr, "acceot() OK " ); fprintf( stderr, "connected.\n" ); // Send packets until the peer shuts down the connection while ( 1 ) { // RT packets get sent out by GRIP twice per second. // This is a trick to avoid drift in the rate. // We compute the number of milliseconds to sleep to get back to a 500 ms boundary. Sleep( 10 ); struct __timeb32 utctime; _ftime32_s( &utctime ); Sleep( (1000 - utctime.millitm ) % 500 ); // Insert the current packet count and time into the packet. rtPacket.header.TMCounter = packetCount++; setPacketTime( &rtPacket ); // Send out a realtime data packet. iSendResult = send( ClientSocket, rtPacket.buffer, rtPacketLengthInBytes, 0 ); // If we get a socket error it is probably because the client has closed the connection. // So we break out of the loop. if (iSendResult == SOCKET_ERROR) { fprintf( stderr, "RT packet send failed with error: %3d\n", WSAGetLastError()); break; } fprintf( stderr, " RT packet %3d Bytes sent: %3d\n", packetCount, iSendResult); // HK packets get sent once every 2 seconds. // The BOOL sendHK is used to turn off and on for each RT cycle. if ( sendHK ) { // Insert the current packet count and time into the packet. hkPacket.header.TMCounter = packetCount++; setPacketTime( &hkPacket ); // Send out a housekeeping packet. iSendResult = send( ClientSocket, hkPacket.buffer, hkPacketLengthInBytes, 0 ); // If we get a socket error it is probably because the client has closed the connection. // So we break out of the loop. if (iSendResult == SOCKET_ERROR) { fprintf( stderr, "HK send failed with error: %3d\n", WSAGetLastError()); break; } fprintf( stderr, " HK packet %3d Bytes sent: %3d\n", packetCount, iSendResult); } sendHK = !sendHK; // Toggle enable flag so that we do one out of two cycles. // Every once in a while, pause a bit to simulate breaks between tasks. if ( (packetCount % 20) == 0 ) { fprintf( stderr, "\nSimulating inter-trial pause.\n\n" ); Sleep( 5000 ); } } while (iResult > 0); // shutdown the connection since we're done iResult = shutdown(ClientSocket, SD_SEND); if (iResult == SOCKET_ERROR) { fprintf( stderr, "shutdown() failed with error: %d\n", WSAGetLastError()); closesocket(ClientSocket); WSACleanup(); return 7; } else if ( _debug ) fprintf( stderr, "shutdown() OK n" ); fprintf( stderr, " Total packets sent: %d\n\n", hkPacket.header.TMCounter + rtPacket.header.TMCounter ); hkPacket.header.TMCounter = 0; rtPacket.header.TMCounter = 0; } // cleanup closesocket(ListenSocket); closesocket(ClientSocket); WSACleanup(); return 0; }
void flushDownload(int sock) { int i = 0; int idx; uint8_t *hash; Packet *pkt; connDown *pool = downloadPool; for(i = 0; i < peerInfo.numPeer; i++) { int peerID = peerInfo.peerList[i].peerID; Packet *ack = peek(pool[peerID].ackSendQueue); while(ack != NULL) { peerList_t *p = &(peerInfo.peerList[i]); fprintf(stderr,"Sending ACK %d\n", getPacketAck(ack)); int retVal = spiffy_sendto(sock, ack->payload, getPacketSize(ack), 0, (struct sockaddr *) & (p->addr), sizeof(p->addr)); fprintf(stderr,"Sent ACK %d\n", getPacketAck(ack)); if(retVal == -1) { // spiffy_sendto() does not work!! fprintf(stderr,"spiffy_sendto() returned -1.\n"); enqueue(pool[peerID].ackSendQueue, dequeue(pool[peerID].ackSendQueue)); } else { dequeue(pool[peerID].ackSendQueue); freePacket(ack); ack = dequeue(pool[peerID].ackSendQueue); } } switch(pool[peerID].state) { case 0: // Ready pkt = dequeue(pool[peerID].getQueue); while(pkt != NULL) { hash = getPacketHash(pkt, 0); printHash(hash); idx = searchHash(hash, &getChunk, 0); if(idx == -1) { // Someone else is sending or has sent this chunk freePacket(pkt); pkt = dequeue(pool[peerID].getQueue); } else if(numConnDown < maxConn){ getChunk.list[idx].fetchState = 2; if(downloadPool[peerID].connected == 1) fprintf(stderr,"NOT SUPPOSED TO BE CONNECTEED! \n\n\n\n\n\n"); downloadPool[peerID].connected = 1; numConnDown++; break; } else { // Cannot allow more download connections fprintf(stderr,"->No more download connection allowed!\n"); pool[peerID].state = 2; break; } } if(pool[peerID].state == 2) break; if(pkt != NULL) { fprintf(stderr,"Sending a GET\n"); peerList_t *p = &(peerInfo.peerList[i]); hash = pkt->payload + 16; char buf[50]; bzero(buf, 50); binary2hex(hash, 20, buf); fprintf(stderr,"GET hash:%s\n", buf); pool[peerID].curChunkID = searchHash(hash, &getChunk, -1); int retVal = spiffy_sendto(sock, pkt->payload, getPacketSize(pkt), 0, (struct sockaddr *) & (p->addr), sizeof(p->addr)); if(retVal == -1) { // Spiffy is broken! fprintf(stderr,"spiffy_snetto() returned -1.\n"); newPacketWHOHAS(nonCongestQueue); freePacket(pkt); cleanUpConnDown(&(pool[peerID])); numConnDown--; return; } setPacketTime(pkt); enqueue(pool[peerID].timeoutQueue, pkt); pool[peerID].state = 1; } break; case 1: { // Downloading pkt = peek(pool[peerID].timeoutQueue); struct timeval curTime; gettimeofday(&curTime, NULL); long dt = diffTimeval(&curTime, &(pkt->timestamp)); if(dt > GET_TIMEOUT_SEC) { pool[peerID].timeoutCount++; fprintf(stderr,"GET request timed out %d times!\n", pool[peerID].timeoutCount); setPacketTime(pkt); if(pool[peerID].timeoutCount == 3) { getChunk.list[pool[peerID].curChunkID].fetchState = 0; pool[peerID].state = 0; newPacketWHOHAS(nonCongestQueue); freePacket(pkt); cleanUpConnDown(&(pool[peerID])); numConnDown--; } } break; } case 2: { break; } default: break; } } }