Exemplo n.º 1
0
void interrupt timer0(void)
{
	RC0 = 1;

	if (T0IF==1)
	{
		TMR0 = timer_ini;
		receive0();
		receive2();
		receive1();
		if (sending==0) CheckIfSomethingToBeSent();
		cpt_led++;
		T0IF = 0;
	}
	if (TXIF==1)
	{
		TXIF=0;
		CheckIfSomethingToBeSent();
	}
        TODO
	//JM RAIF=0;
	EEIF=0;

	RC0 = 0;
}
Exemplo n.º 2
0
int main(int argc, char *argv[])
{
	int sockfd;
	struct addrinfo hints, *servinfo, *p;
	int rv;
	int numbytes;
	struct sockaddr_storage their_addr;
	char buf[MAXBUFLEN+HEADERSIZE];
	socklen_t addr_len;
	char s[INET6_ADDRSTRLEN];
	int cwnd;
	double pl, pc;

	// extract argument parameters
	if (argc != 5)
	{
		fprintf(stderr,"usage: receiver <portnumber> <CWnd> <Pl> <Pc>\n");
		exit(1);
	}

	char *port = argv[1];
	cwnd = atoi(argv[2]);
	pl = atof(argv[3]);
	pc = atof(argv[4]);

	if(pl < 0 || pc < 0 || pl > 1 || pc > 1)
	{
		fprintf(stderr,"Pl and Pc must be between 0 and 1!\n");
		exit(1);
	}

	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_flags = AI_PASSIVE; // use my IP

	if ((rv = getaddrinfo(NULL, port, &hints, &servinfo)) != 0)
	{
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
		return 1;
	}

	// loop through all the results and bind to the first we can
	for(p = servinfo; p != NULL; p = p->ai_next)
	{
		if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
		{
			perror("sender: socket");
			continue;
		}

		if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1)
		{
			close(sockfd);
			perror("sender: bind");
			continue;
		}

		break;
	}

	if (p == NULL)
	{
		fprintf(stderr, "Error: sender failed to bind socket\n");
		return 2;
	}

	freeaddrinfo(servinfo);

	printf("Waiting for requested filename...\n");

	addr_len = sizeof their_addr;

	if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1)
	{
		printf("Error: failed to receive filename\n");
		exit(1);
	}

	printf("Received filename from %s\n", inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s));
	buf[numbytes] = '\0';
	printf("Requested filename: \"%s\"\n", buf);

	// buf contains requested file name; if it exists, send back packets (up to 1 KB at a time) to receiver

	// create source buffer to fopen and fread designated file
	char *source = NULL;
	char sourcePacket[MAXBUFLEN+HEADERSIZE];
	FILE *fp = fopen(buf, "r");
	size_t sourceLength;

	if (fp==NULL)
	{
		// send any packet with seq=0 and fin=1 to represent no file found
		send2(sockfd, buf, strlen(buf), (struct sockaddr *)&their_addr, addr_len, 0, 0, 1, 0, 0, 0);
		printf("Error: file not found!\n");
		exit(1);
	}

	if (fseek(fp, 0L, SEEK_END) == 0)
	{
		// set fsize to file size
	        long fsize = ftell(fp);

	        if (fsize == -1)
		{
			// send any packet with seq=0 and fin=1 to represent no file found
			send2(sockfd, buf, strlen(buf), (struct sockaddr *)&their_addr, addr_len, 0, 0, 1, 0, 0, 0);
			printf("Error: file size error!\n");
			exit(1);
		}

		// allocate source buffer to filesize
		source = malloc(sizeof(char) * (fsize + 1));

		// return to front of file
		if (fseek(fp, 0L, SEEK_SET) != 0)
		{
			// send any packet with seq=0 and fin=1 to represent no file found
			send2(sockfd, buf, strlen(buf), (struct sockaddr *)&their_addr, addr_len, 0, 0, 1, 0, 0, 0);
			free(source);
			printf("Error: file size error!\n");
			exit(1);
		}

		// set source to file data
		sourceLength = fread(source, sizeof(char), fsize, fp);

		// check file source for fread errors
		if (sourceLength == 0)
		{
			// send any packet with seq=0 and fin=1 to represent no file found
			send2(sockfd, buf, strlen(buf), (struct sockaddr *)&their_addr, addr_len, 0, 0, 1, 0, 0, 0);
			free(source);
			printf("Error: file reading error!\n");
			exit(1);
		}

		// NULL-terminate the source
		source[sourceLength] = '\0';
	}

	// close file
	fclose(fp);

	// initialize variables for sending/receiving acks
	int seq=0;
	int ack=0;
	size_t len=0;
	short fin=0;
	short crc=0;
	int expectedAck=0;

	int windowPosition=0;
	int tempPosition=0;

	while(fin!=1)
	{
		int numPacketsSent = 0;
		tempPosition = windowPosition;

		// check that more packets need to be sent and we have not exceeded our send window
		while(tempPosition<sourceLength && numPacketsSent<cwnd)
		{
			// determine size (since it may be less than MAXBUFLEN if last packet to be sent)
			int size = MAXBUFLEN;
			if(sourceLength-tempPosition<MAXBUFLEN)
				size = sourceLength-tempPosition;

			// create temp array holding data to be sent
			char temp[MAXBUFLEN];
			bzero(temp, MAXBUFLEN);
			memcpy(temp, source+tempPosition, size);

			// send packet with headers and data
			numbytes = send2(sockfd, temp, size, (struct sockaddr *)&their_addr, addr_len, tempPosition, seq+len, (tempPosition+MAXBUFLEN>=sourceLength), 0, pl, pc);

//printf("Sent packet of %d-bytes\n", size);

			if (numbytes == -1)
			{
				printf("Packet with sequence #%d lost!\n", tempPosition);
			}
			else if(numbytes == -2)
			{
				printf("Packet with sequence #%d corrupted!\n", tempPosition);
			}
			else
				printf("Sent %d bytes with sequence #%d\n", numbytes, tempPosition);

			// increment position of data to send
			tempPosition+=MAXBUFLEN;
			
			// increment number of packets sent this round
			numPacketsSent++;
		}

		int numAcksReceived=0;

		// check that acks of packets sent have been received
		while(numAcksReceived < numPacketsSent)
		{
			// initialize variables
			fd_set inSet;
			struct timeval timeout;
			int received;

			FD_ZERO(&inSet);
			FD_SET(sockfd, &inSet); 

			// wait for specified time
			timeout.tv_sec = WAITS;
			timeout.tv_usec = WAITU;

			// check for acks
			received = select(sockfd+1, &inSet, NULL, NULL, &timeout);

			// if timeout and no acks were received, break and maintain window position
			if(received < 1)
			{
				printf("Timed out while waiting for ACK!\n");
				break;
			}

			// otherwise, fetch the ack
			numbytes = receive2(sockfd, buf, &len, (struct sockaddr *)&their_addr, &addr_len, &seq, &ack, &fin, &crc);

			//printf("got ack with: %d/%d/%d/%d (s/a/f/c)\n", seq, ack, fin, crc);
		
			if(fin == 1)
			{
				printf("ACK #%d received!\n", ack);

				// FIN rides on the back of the last data packet
				printf("FIN sent!\n");

				// FINACK is guaranteed to arrive; packet loss/corruption disabled
				printf("FINACK received!\n");
				break;
			}
			// ignore ack if it's corrupted (we define this as crc == 1); break and maintain window position
			if(crc == 1)
			{
				printf("ACK #%d is corrupted! Ignoring it.\n", ack);
				break;
			}

			// ack is the one we were expecting, so we can increment windowPosition and expect the next ack
			// true if ack is at most expectedAck and more than expectedAck-MAXBUFLEN
			if(ack > expectedAck && ack <= expectedAck + MAXBUFLEN)
			{
				printf("ACK #%d received!\n", ack);
				numAcksReceived++;
				expectedAck += MAXBUFLEN; // expect the next ack (assume it's a MAXBUFLEN-byte packet)
				windowPosition += MAXBUFLEN;
			}

		}

		// at this point, if we didn't receive the expected ACK, continue
	}	

	printf("File finished transmitting! Sender terminating...\n");

	// free file source and close socket
	free(source);
	close(sockfd);

	return 0;
}