int llread(int fd,unsigned char* buffer) { int num_chars_read = 0, aux_num_chars = 0; int Type; unsigned char aux[MAX_SIZE]; linkLayer.sequenceNumber = 0; do { Type= receiveframe(aux, &aux_num_chars); if(Type == DATA_RECEIVED) { linkLayer.sequenceNumber = linkLayer.sequenceNumber ^ 1; sendSupervisionFrame(linkLayer.fd, RR); memcpy(buffer + num_chars_read, aux, aux_num_chars); num_chars_read += aux_num_chars; aux_num_chars = 0; } else if(Type == BAD_DATA_RECEIVED) { rej_send_received++; sendSupervisionFrame(linkLayer.fd, REJ); } else if(Type == DISC_RECEIVED) { llclose(linkLayer.fd); return num_chars_read; } } while(1); return -1; }
int llopen(int fd, int txrx) { printf("[LLOPEN] START\n"); linkLayer.sequenceNumber = 0; if(txrx == TRANSMITTER) { int tmpvar; (void) signal(SIGALRM, atende); linkLayer.numTransmissions = 0; linkLayer.timeout = MAXT; printf("[llopen] Send SET\n"); sendSupervisionFrame(fd, SET); alarm(linkLayer.timeout); printf("[llopen] EXPETING UA\n"); tmpvar = receiveframe(NULL,NULL); if( tmpvar != UA_RECEIVED ){ printf("[LLOPEN - TRANSMITTER] NOT UA\n"); return -1; //return error } else if(tmpvar == UA_RECEIVED) { printf("[LLOPEN - TRANSMITTER] UA RECEIVED\n"); return fd; //retorn file ID } return -1; } else if (txrx == RECEIVER) { printf("Waiting for SET\n"); if(receiveframe(NULL,NULL) == SET_RECEIVED) printf("SET_RECEIVED"); sendSupervisionFrame(fd,UA); printf("UA sent\n"); return fd; } return 0; }
int llopen(char* port, int txrx) { int tmpvar; linkLayer.fd = config(port); linkLayer.State = txrx; linkLayer.numTransmissions = 0; linkLayer.timeout = MAXT; linkLayer.frame = (unsigned char*) malloc((2*MAX_SIZE)+6); linkLayer.alarm_char = SET; linkLayer.alarm_inf = FALSE; //printf("[RS-232] Port open - Starting"); if(txrx == TRANSMITTER) { linkLayer.State = TRANSMITTER; (void) signal(SIGALRM, Timeout); sendSupervisionFrame(linkLayer.fd, SET); alarm(linkLayer.timeout); tmpvar = receiveframe(NULL,NULL); if( tmpvar != UA_RECEIVED ) return -1; //return error else if(tmpvar == UA_RECEIVED) { (void) signal(SIGALRM, SIG_IGN); return linkLayer.fd; //retorn file ID } return -1; } else if (txrx == RECEIVER) { linkLayer.State = RECEIVER; if(receiveframe(NULL,NULL) != SET_RECEIVED) { return -1; } sendSupervisionFrame(linkLayer.fd,UA); return linkLayer.fd; } return 1; }
void atende() { if(linkLayer.numTransmissions < MAXR){ printf("[DEBUG] Timeout %d waiting for UA, re-sending SET\n", linkLayer.numTransmissions); sendSupervisionFrame(linkLayer.fd, SET); alarm(linkLayer.timeout); }else{ printf("[DEBUG] Receiver doesnt seem to like me, I give up :(\n"); //llclose(); } linkLayer.numTransmissions++; }
int llclose(int fd) { int tmp; (void) signal(SIGALRM, Timeout); linkLayer.alarm_char = DISC; if (linkLayer.State == TRANSMITTER) { sendSupervisionFrame(fd, DISC); alarm(linkLayer.timeout); //starting timout for DISC tmp = receiveframe(NULL,NULL); //waiting for DISC if (tmp == DISC_RECEIVED) { (void) signal(SIGALRM, SIG_IGN); //closing Timeout if received sendSupervisionFrame(fd, UA); sleep(1); close(fd); return 1; } else{ return -1; } } else if (linkLayer.State == RECEIVER) { linkLayer.alarm_char = DISC; sendSupervisionFrame(fd, DISC); alarm(linkLayer.timeout); //starting timout for DISC tmp = receiveframe(NULL,NULL); if (tmp == UA_RECEIVED) { (void) signal(SIGALRM, SIG_IGN); //closing Timeout if received close(fd); return 1; } else return -1; } else return -1; }
void Timeout() { if(linkLayer.numTransmissions < MAXR-1){ printf("[TIMEOUT] Timeout %d -> ", linkLayer.numTransmissions); if(!linkLayer.alarm_inf){ printf("Sending Supervision Frame\n"); if(!sendSupervisionFrame(linkLayer.fd, linkLayer.alarm_char)) exit(-1); } else if(linkLayer.alarm_inf) { printf("Sending Informacion Frame\n"); if(!sendInformationFrame(linkLayer.frame, linkLayer.frameLength)) exit(-1); } else exit(-1); alarm(linkLayer.timeout); } else if (linkLayer.numTransmissions == MAXR-1) { printf("[TIMEOUT] Port closing, didn't get any response\n"); close(linkLayer.fd); exit(-1); } linkLayer.numTransmissions++; timeout_time++; //for external variable }
int receiveframe(unsigned char *data, int* length) { int state = 0; //state machine state int stop = FALSE; //control flag int Rreturn; //for return int Type; //type of frame received int num_chars_read = 0; //number of chars read unsigned char* charread = malloc(1); //char in serial port unsigned char Aread, Cread; //adress and command received++; //State machine while(stop == FALSE) { Rreturn = read(linkLayer.fd, charread, 1); //keeps waiting for 1 char if (Rreturn < 0) return -1; //nothing switch(state) { case 0:{ //State Start if(*charread == FLAG) state = 1; if(*charread == A) state =1; break; } case 1:{ //Read Flag -> Expecting address if(*charread == A) { state = 2; Aread = *charread; } else if(*charread == FLAG) state = 1; //another flag break; } case 2:{ //Read Address -> Expecting Command Cread = *charread; if(*charread == SET) { Type = SET_RECEIVED; state = 3; } else if(*charread == UA) { Type = UA_RECEIVED; state = 3; } else if(*charread == DISC) { Type = DISC_RECEIVED; state = 3; } else if(*charread == (RR | ((linkLayer.sequenceNumber) << 7))) { Type = BAD_RR_RECEIVED; state = 3; } else if(*charread == (RR | ((linkLayer.sequenceNumber^1) << 7))) { //BAD RR Type = RR_RECEIVED; state = 3; } else if(*charread == (REJ | (linkLayer.sequenceNumber << 7))) { Type = BAD_REJ_RECEIVED; state = 3; } else if(*charread == (REJ | ((linkLayer.sequenceNumber^1) << 7))) { Type = REJ_RECEIVED; state = 3; } //If I0 fails we must receive a REJ0 and send I0 again! else if(*charread == ((linkLayer.sequenceNumber^1) << 6)) { Type = BAD_DATA_RECEIVED; state = 3; } else if(*charread == (linkLayer.sequenceNumber << 6)) { Type = DATA_RECEIVED; state = 3; } else if(*charread == FLAG) state = 1; //error else state = 0; //error break; } case 3:{ //Read Command -> Expecting BBC1 if(*charread == FLAG) state = 1; else if(*charread != (Aread ^ Cread)) { if(Type == DATA) { sendSupervisionFrame(linkLayer.fd,REJ); state = 2; } Type = BAD_BBC_RECEIVED; } else { if(Type == DATA_RECEIVED || Type == BAD_DATA_RECEIVED) state = 4; else state = 6; } break; } case 4:{ //BCC1 correct -> Data expected if (*charread == FLAG) { unsigned char BCC2exp = data[0]; int j; for(j = 1;j < num_chars_read - 1; j++) BCC2exp = (BCC2exp ^ data[j]); if(data[num_chars_read -1] != BCC2exp) { state = 1; num_chars_read = 0; Type = BAD_BBC_RECEIVED; } else //BCC2 Correct { *length = num_chars_read - 1; free(charread); return Type; } } else if(*charread == ESC) state = 5; //deshuffel o proximo else { data[num_chars_read] = *charread; num_chars_read++; state = 4; } break; } case 5:{ //Destuffing data[num_chars_read] = *charread ^ STFF; num_chars_read++; state = 4; break; } case 6:{ //Flag if(*charread == FLAG) { //flag stop = TRUE; state = 0; } else state = 0; break; } } } free(charread); return Type; }
int receiveframe(char *data, int * length) { printf("[receiveframe] START\n"); char* charread = malloc(1); //char in serial port int state = 0; //state machine state char Aread, Cread; //adress and command int stop = FALSE; //control flag int Rreturn; //for return int Type; //type of frame received int num_chars_read = 0; //number of chars read //State machine while(stop == FALSE) { //printf("[receiveframe] State machine -> %d\n", state); Rreturn = read(linkLayer.fd, charread, 1); //read 1 char if (Rreturn == 1) printf("[Receiveframe] read -> %x (%d)\n", *charread, Rreturn); if (Rreturn < 0) return -1; //nothing switch(state) { case 0:{ //State Start printf("[receiveframe] START, char = %x\n", *charread); if(*charread == FLAG) state = 1; break; } case 1:{ //Flag -> expect address if(*charread == A) { printf("[receiveframe] ADRESS, char = %x\n", *charread); state = 2; Aread = *charread; } else if(*charread == FLAG) state = 1; //another flag break; } case 2:{ //Address -> Command (many commands possible) printf("[receiveframe] COMMAND, char = %x ->", *charread); Cread = *charread; if(*charread == SET) { printf("SET\n"); Type = SET_RECEIVED; state = 3; } else if(*charread == UA) { printf("UA\n"); Type = UA_RECEIVED; state = 3; } else if(*charread == DISC) { printf("DISC\n"); Type = DISC_RECEIVED; state = 3; } else if(*charread == (RR | (linkLayer.sequenceNumber << 7))) { printf("RR\n"); Type = RR_RECEIVED; state = 3; } else if(*charread == (REJ | (linkLayer.sequenceNumber << 7))) { printf("REJ\n"); Type = REJ_RECEIVED; state = 3; } else if(*charread == (linkLayer.sequenceNumber << 6)) { printf("DATA\n"); Type = DATA_RECEIVED; state = 3; } else if(*charread == FLAG) state = 1; else state = 0; break; } case 3:{ //command -> BBC1 printf("[receiveframe] BCC, char = %x\n", *charread); if(*charread == FLAG) state = 1; else if(*charread != (Aread ^ Cread)) { printf("[receiveframe] BCC INCORRECT\n"); state = 0; //bcc } else { printf("[receiveframe] BCC CORRECT\n"); if(Type == DATA_RECEIVED) state = 4; else state = 6; } break; } case 4:{ //Data expected printf("[receiveframe] DATA EXPECTED\n"); if (*charread == FLAG) { char BCC2exp = data[0]; int j; for(j = 1;j < num_chars_read - 1; j++) BCC2exp = (BCC2exp ^ data[j]); if(data[num_chars_read -1] != BCC2exp) { sendSupervisionFrame(linkLayer.fd,REJ); return -1; } else { *length = num_chars_read - 1; sendSupervisionFrame(linkLayer.fd, RR); linkLayer.sequenceNumber = linkLayer.sequenceNumber ^ 1; } stop = TRUE; state = 0; } else if(*charread == ESC) state = 5; //deshuffel o proximo else { data[num_chars_read] = *charread; num_chars_read++; state = 4; } break; } case 5:{ //Destuffing data[num_chars_read] = *charread ^ STFF; num_chars_read++; state = 4; break; } case 6:{ //Flag if(*charread == FLAG) { //flag stop = TRUE; state = 0; } else state = 0; break; } printf(",%d]", state); } } printf("[receiveframe] STOP -> %d\n", Type); free(charread); return Type; }