/** Send a packet and wait the response
  *
  * This function send the given packet over the network and wait for
  * the response. When the response is given, we return the time elapsed
  * in miliseconds.
  *
  * \param p The packet to send
  * \param reliable Is this packet sent in reliable mode ?
  *
  * \return The time elapsed between the packet was sent and the response
  *         was received in miliseconds
  *
  */
int RainbruRPG::Network::EnetFlooderClient::
sendPacketAndWaitResponse(NetPacketFlooderBase* p, bool reliable){
  LOGI("sendPacketAndWaitResponse called");

  // To be sure the packet is (or not) reliable
  p->setReliable(reliable);
  p->netSerialize();

  ENetPacket * packet;

  if (p->isReliable()){
    packet= enet_packet_create 
      (p->getData(), p->getDataLength(), ENET_PACKET_FLAG_RELIABLE);
  }
  else{
    packet = enet_packet_create 
      (p->getData(), p->getDataLength(), 0);

  }

  if (peer==NULL){
    LOGE("Enet peer not initialized, the program will probably crash");
  }

  if (packet==NULL){
    LOGE("Enet packet not initialized, the program will probably crash");
  }

  enet_peer_send (peer, 0, packet);
  enet_host_flush (client);
  //  bool ret=waitPacket(p->getIdentifier(), p->getResponseId());
  bool ret=waitPacket(p->getIdentifier(), p->getResponseId());

  if (ret){
    LOGI("The packet is comming back");
  }


}
Exemple #2
0
int main(int argc, char **argv) {
	ACQ_MessagePacketType *packet;
	int currentPacket, intSlot;
	int lastId;
	int numChannels, numSamples, sampleNumber;
	host_t host;
	pthread_t tcpserverThread, convertThread;
	
	/* Parse command line arguments */
	if (argc == 1) {
		/* Put defaults in case no arguments given */
		strcpy(host.name, "-");
		host.port = 1972;
	} else if (argc == 3) {
		strncpy(host.name, argv[1], sizeof(host.name));
		host.name[sizeof(host.name)-1]=0;
		
		host.port = atoi(argv[2]);
		if (host.port <= 0) {
			fputs("Port number must be positive\n\n",stderr);
			fputs(usage, stderr);
			return 1;
		}
	} else {
		fputs(usage, stderr);
		return 1;
	}
	
	/* Create socket pair */
	if (socketpair(AF_UNIX, SOCK_STREAM, 0, mySockets)) {
		perror("Could not create socket pair for internal communication: ");
		return 1;
	}
	
	/*  Internal ringbuffer uses same mechanism as Acq: free slots are
		marked with ACQ_MSGQ_INVALID. To avoid polling in the converter thread,
		the main thread sends the index of the latest slot over the socket pair.
		If the converter thread does not manage to clear the ringbuffer quickly
		enough, the program will report an error. */
	for (intSlot=0;intSlot<INT_RB_SIZE;intSlot++) {
		intPackets[intSlot].message_type = ACQ_MSGQ_INVALID;
	}
	
	/* Spawn conversion thread */
	if (pthread_create(&convertThread, NULL, dataToFieldTripThread, NULL)) {
		fprintf(stderr, "Could not spawn conversion thread\n");
		return 1;
	}
	
	/* Spawn tcpserver or connect to remote buffer */
	if (strcmp(host.name, "-") == 0) {
		int rc;
		
		rc = pthread_create(&tcpserverThread, NULL, tcpserver, &host);
		if (rc) {
			fprintf(stderr, "Could not spawn tcpserver thread (%d)\n", rc);
			return 1;
		}
		ftSocket = 0; /* dma */
	} else {
		ftSocket = open_connection(host.name, host.port);
		
		if (ftSocket < 0) {
			fprintf(stderr, "Could not connect to remote buffer\n");
			return 1;
		}
	}		
	
	printf("Trying to set up shared memory...\n");
	packet = createSharedMem();
	if (packet == NULL) {
		fprintf(stderr, "Could not set up shared memory - exiting\n");
		exit(1);
	}
	initSharedMem(packet);
	
	/* register CTRL-C handler */
	signal(SIGINT, abortHandler);
	
	/* Both ringbuffers start at 0 */
	currentPacket = intSlot = 0;
	
	printf("Entering main loop. Press CTRL-C to stop operation.\n\n");
	while (keepRunning) {
		int size;
		char *dataset;
		int code = waitPacket(&packet[currentPacket].message_type);
		
		switch(code) {
			case ACQ_MSGQ_SETUP_COLLECTION:
				lastId = packet[currentPacket].messageId;
				dataset = (char *) packet[currentPacket].data;
				printf("Setup | ID=%i | %.255s\n", lastId, dataset);
				
				size = 5*sizeof(int) + strlen(dataset) + 1;
				if (size >= sizeof(ACQ_MessagePacketType)) {
					fprintf(stderr, "Dataset name not zero-terminated -- ignoring\n");
					continue;
				}
				
				if (intPackets[intSlot].message_type != ACQ_MSGQ_INVALID) {
					fprintf(stderr, "Internal converter thread does not keep up with the load.\n");
				} else {
					memcpy(&intPackets[intSlot], &packet[currentPacket], size);
					write(mySockets[0], &intSlot, sizeof(int));
					if (++intSlot == INT_RB_SIZE) intSlot=0;
				}
				
				packet[currentPacket].message_type = ACQ_MSGQ_INVALID;
				if (++currentPacket == ACQ_MSGQ_SIZE) currentPacket=0;
				break;
			case ACQ_MSGQ_DATA:
				lastId = packet[currentPacket].messageId;
				numChannels  = packet[currentPacket].numChannels;
				numSamples   = packet[currentPacket].numSamples;
				sampleNumber = packet[currentPacket].sampleNumber;
				printf("Data | %3i channels x %3i samples | nr = %6i | ID=%4i | slot=%3i\n", numChannels, numSamples, sampleNumber, lastId, currentPacket);
								
				size = 5*sizeof(int) + numSamples*numChannels*sizeof(int);
				
				if (size > sizeof(ACQ_OverAllocType)) {
					fprintf(stderr, "Acq wrote far too much data -- cannot handle this\n");
				} else {
					if (intPackets[intSlot].message_type != ACQ_MSGQ_INVALID) {
						fprintf(stderr, "Internal converter thread does not keep up with the load.\n");
					} else {
						memcpy(&intPackets[intSlot], &packet[currentPacket], size);
						write(mySockets[0], &intSlot, sizeof(int));
						if (++intSlot == INT_RB_SIZE) intSlot=0;
					}
				}				
				
				if (numSamples * numChannels > 28160) {
					fprintf(stderr, "Warning: Acq wrote too much data into this block!\n");
            
					/* clear this packet */
					packet[currentPacket].message_type = ACQ_MSGQ_INVALID;
					/* next packet last in ringbuffer? */ 
					if (++currentPacket == ACQ_MSGQ_SIZE) {
						currentPacket = 0;
					} else {
						/* make sure the next packet is marked as free */
						packet[currentPacket].message_type = ACQ_MSGQ_INVALID;
					}
				} else {
					packet[currentPacket].message_type = ACQ_MSGQ_INVALID;
					if (++currentPacket == ACQ_MSGQ_SIZE) currentPacket=0;
				}
				break;
			case ACQ_MSGQ_CLOSE_CONNECTION:
				printf("Stop | ID=%i \n", lastId);
				
				/* Does this mean anything for the buffer as well ? */
				
				packet[currentPacket].message_type = ACQ_MSGQ_INVALID;
				currentPacket = 0;
				break;
			case ACQ_MSGQ_INVALID:
				printf("Waiting (on %i)\n",currentPacket);
				break;
			default:
				fprintf(stderr, "Warning: Unexpected ID in packet %i\n", currentPacket);
				break;
		}
	}
	printf("Closing sockets / stopping tcpserver...\n");
	close(mySockets[0]); /* the other one will be closed in the thread */
	if (ftSocket > 0) {
		close_connection(ftSocket);
	} else {
		pthread_cancel(tcpserverThread);
		pthread_detach(tcpserverThread);
	}
	printf("Closing shared memory...\n");
	closeSharedMem(packet);
	printf("Joining conversion thread...\n");
	pthread_join(convertThread, NULL);
	printf("Done.\n");
	return 0;
}