Beispiel #1
0
/*
  retorna o tipo de frame verificando o campo de controlo
*/
char * verifyFrameType(char * frame) {
    switch(frame[2]) {
    case C_SET:
        return "set";
        break;
    case C_DISC:
        return "disc";
        break;
    case C_UA:
        return "ua";
        break;
    case RR(1):
        return "rr1";
        break;
    case RR(0):
        return "rr0";
        break;
    case REJ(0):
        return "rej0";
        break;
    case REJ(1):
        return "rej1";
        break;
    case C_I0:
        return "I0";
        break;
    case C_I1:
        return "I1";
        break;
    }
}
Beispiel #2
0
/*
  Cria e envia uma trama do tipo type (Não funcional para tipo I)
*/
int buildFrame(int flag, char * type) {
    info->frameSend[0] = F;
    if (type == "set")
        info->frameSend[2] = C_SET;
    else if (type == "ua")
        info->frameSend[2] = C_UA;
    else if (type == "disc")
        info->frameSend[2] = C_DISC;
    else if (!strcmp(type, "rr1"))
        info->frameSend[2] = RR(1);
    else if (!strcmp(type,"rr0"))
        info->frameSend[2] = RR(0);
    else if (!strcmp(type,"rej0"))
        info->frameSend[2] = REJ(0);
    else if (!strcmp(type,"rej1"))
        info->frameSend[2] = REJ(0);
    else
        return 0;
    info->frameSend[1] = campo_endereco(info->flag, info->frameSend[2]);
    info->frameSend[3] = info->frameSend[1]^info->frameSend[2];
    info->frameSend[4] = F;
    info->frameSendLength = 5;

    //printf("Trama composta %s: 0x%x 0x%x 0x%x 0x%x 0x%x \n", type, info->frameSend[0], info->frameSend[1], info->frameSend[2], info->frameSend[3], info->frameSend[4]);

    return 1;
}
Beispiel #3
0
int llwrite(int fd, unsigned char* buffer, int length){

//printf("entrei no llwrite\n");
	char *bufferStuffed;
	char header[] = { FLAG, 0x03, I(ll.sequenceNumber), header[1]^header[2] };
	char dataBCC = generateBCC((char*)buffer, length);
	char* toStuff = malloc(length+1);
	memcpy(toStuff, buffer, length);
	toStuff[length] = dataBCC;


	int n= byteStuffing(toStuff,  length+1, &bufferStuffed);

	//int k;
	//puts("");
	//for (k=0;k<n;k++){
		//printf("\n%d\n", bufferStuffed[k]);
	//}
	//	puts("");
	char* message = (char*)  malloc(n+6);

	memcpy(message, header, 4);
	memcpy(message+4, bufferStuffed, n);
	message[n+4] = FLAG;
	int wrote = 0;
	while(!wrote)
		wrote = write(fd, message, n+5);
	stats.dataFramesTransmitted++;



//puts("message sent\n");

	free(message);
	free(bufferStuffed);
	alarm(ll.timeOut);
	
	Command command = receiveCommand(fd);
	
	//was asked for new frame
	if (command.command == RR(!ll.sequenceNumber)){
		ll.sequenceNumber = (!ll.sequenceNumber);
		retries = 0;
	//puts("fui confirmado");
		alarm(0);
		return length;
	}
	//frame was rejected, resend
	if (command.command == REJ(ll.sequenceNumber) || (command.command == NONE && ll.numTransmissions > retries)){
		if (command.command == NONE){
			
			stats.timeouts++;
			//printf("\nNumber of retries: %d\n", retries);
			alarm(0);
		}
		//puts("byte was rejected,resending or no response\n");
		stats.rejs++;
		return llwrite(fd, buffer, length);
	}
	else{
		//puts("eu esperei mas o reader nao me quis responder :(");
		return -1;
	}

	return length;
}
Beispiel #4
0
int llread(int fd, unsigned char **buffer){
	//printf("preparing to read frame\n");
	Command command = receiveCommand(fd);
	//puts("llread:received command");
	int repeated;
	if (command.command == I(ll.sequenceNumber))
		repeated = 0;
	else if (command.command == I(!ll.sequenceNumber))
		repeated = 1;
	else if (command.command == DISC){
			//printf("llread: disconnecting\n");
			while(!sendByte(fd, 0x01, DISC)){}
			//puts("llread: disc confirmation sent\n");
			command = receiveCommand(fd);
			if (command.command != UA){
				//puts("llread: didnt receive UA after disc confirmation\n");
				return E_GENERIC;
			}
			else{
				//puts("llread: connection successfully closed\n");
				return E_CLOSED;
			}
	}

	if (command.command == I(0) || command.command == I(1)){
		//puts("llread: received a data frame\n");
		//if we never saw this frame before, consider it
		stats.dataFramesTransmitted++;
		if(!repeated){
			//puts("llread: new data frame\n");
			int length = byteDeStuffing(&(command.data), command.size);
			//puts("llread: destuffing succeeded\n");
			int bccOK = verifyBCC(command.data, length, command.data[length-1]);

			if(getRand() < RANDOM_REJ_CHANCE){
				bccOK = 0;
			//	puts("\n randomly rejecting good packet");
			}

			//Reject frames with wrong BCC
			if(!bccOK){
				//puts("llread: frame was damaged, rejecting and rereading\n");
				stats.rejs++;
				while(!sendByte(fd, 0x03, REJ(ll.sequenceNumber) )){}
					return llread(fd, buffer);

			}

			//accept the frame and confirm it
			//puts("llread: frame bcc ok, accepting\n");
			*buffer = (unsigned char*) malloc(length);
			memcpy(*buffer, command.data, length);
			while(!sendByte(fd,0x03, RR(!ll.sequenceNumber))){}
			//puts("llread: receiver ready sent, message confirmed\n");
			ll.sequenceNumber = !ll.sequenceNumber;
			free(command.data);
			//printf("%d length\n", length);
			return length;

		}
		//this frame is repeated. Confirm it and ask for the new frame
		else{
				//puts("llread: message repeated");
				while(!sendByte(fd, 0x03, RR(ll.sequenceNumber))){}
				return E_GENERIC;
		}

	}

	else{
		//printf("received unexpected command 0x%02x\n",command.command);
		return E_GENERIC;
	}

	return 0;


}
Beispiel #5
0
void state_machine(int state, char signal, char * type) {


    if (state == START) {
        if (signal == F) {
            state = FLAG;
            SET2[0]=signal;
        }
    }
    else if (state == FLAG) {
        if (signal == F)
            state = FLAG;
        else if ((signal == campo_endereco(!info->flag, C_SET) && type == "set")
                 || (signal == campo_endereco(!info->flag, C_UA) && type == "ua")
                 || (signal == campo_endereco(!info->flag, C_DISC) && type == "disc")
                 || (signal == campo_endereco(!info->flag, RR(1)) && type == "rr1")
                 || (signal == campo_endereco(!info->flag, RR(0)) && type == "rr0")
                 || (signal == campo_endereco(!info->flag, REJ(1)) && type == "rej1")
                 || (signal == campo_endereco(!info->flag, REJ(0)) && type == "rej0")
                 || (signal == campo_endereco(!info->flag, C_I0) && type == "I0")
                 || (signal == campo_endereco(!info->flag, C_I1) && type == "I1")) {
            state = A_STATE;
            SET2[1]=signal;
        }
        else
            state = START;
    }
    else if (state == A_STATE) {
        if (signal == F) {
            state = FLAG;
        }
        else if ((signal == C_SET && type == "set")
                 || (signal == C_UA && type == "ua")
                 || (signal == C_DISC && type == "disc")
                 || (signal == RR(1) && type == "rr1")
                 || (signal == RR(0) && type == "rr0")
                 || (signal == REJ(1) && type == "rej1")
                 || (signal == REJ(0) && type == "rej0")
                 || (signal == C_I0 && type == "I0")
                 || (signal == C_I1 && type == "I1")) {
            state = C;
            SET2[2]=signal;
        }
        else
            state = START;
    }
    else if (state == C) {
        if (signal == F)
            state = FLAG;
        else if (signal == (SET2[1]^SET2[2])) {
            state = BCC_STATE;
            SET2[3]=signal;
        }
        else
            state = START;
    }
    else if (state == BCC_STATE) {
        if (signal == F) {
            state = STOP2;
            SET2[4]=signal;
        }
        else
            state = START;
    }
    estado = state;

    //printf("estado: %d \n", estado);
}