Startpunkten
This commit is contained in:
689
link.cpp
Normal file
689
link.cpp
Normal file
@@ -0,0 +1,689 @@
|
||||
#include "physlayer.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include "link_signal.h"
|
||||
#include "link.h"
|
||||
#include "student.h"
|
||||
|
||||
|
||||
const CONTROL_FRAME_SIZE = 14;
|
||||
int PSOCK_FD;
|
||||
int USOCK_FD;
|
||||
|
||||
typedef enum state{IDLE, UICON, UOCON, DATA, UIDCON, UODCON}state;
|
||||
state LINK_STATE = IDLE;
|
||||
|
||||
static action ALIST[] = {
|
||||
{ L_DATA_REQUEST , DataRequest },
|
||||
{ L_DATA_INDICATION , DataIndication },
|
||||
{ L_CONNECT_REQUEST , ConnectRequest },
|
||||
{ L_CONNECT_INDICATION , ConnectIndication },
|
||||
{ L_CONNECT_RESPONSE , ConnectResponse },
|
||||
{ L_CONNECT_CONFIRM , ConnectConfirm },
|
||||
{ L_DISCONNECT_REQUEST , DisconnectRequest },
|
||||
{ L_DISCONNECT_INDICATION , DisconnectIndication },
|
||||
{ L_DISCONNECT_RESPONSE , DisconnectResponse },
|
||||
{ L_DISCONNECT_CONFIRM , DisconnectConfirm },
|
||||
{ L_ABORT_REQUEST , AbortRequest },
|
||||
{ L_ABORT_INDICATION , AbortIndication },
|
||||
{ SYSTEM_FAILURE , SystemError },
|
||||
{ DEFAULT , Default },
|
||||
};
|
||||
|
||||
int incoming_frame_status = 0, incoming_frame_index = 0; // global!
|
||||
int incoming_frame_length = 0;
|
||||
struct Frame
|
||||
{
|
||||
char start_header[6];
|
||||
short control;
|
||||
short length;
|
||||
short cc;
|
||||
char *data;
|
||||
char end_header[6];
|
||||
};
|
||||
|
||||
Frame incoming_frame; // global! (tillfälligt).
|
||||
|
||||
int ConnectRequest(void)
|
||||
{
|
||||
int return_value;
|
||||
|
||||
if(LINK_STATE == IDLE)
|
||||
{
|
||||
return_value = WriteSignaltoSocket(PSOCK_FD, F_CONNECT_REQUEST, SIG_LEN);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
LINK_STATE = UOCON;
|
||||
}
|
||||
else
|
||||
{
|
||||
return_value = Abort(BO);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int ConnectIndication(void)
|
||||
{
|
||||
int return_value;
|
||||
|
||||
if(LINK_STATE == IDLE)
|
||||
{
|
||||
return_value = WriteSignaltoSocket(PSOCK_FD, F_CONNECT_RESPONSE, SIG_LEN);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
LINK_STATE = UICON;
|
||||
}
|
||||
else
|
||||
{
|
||||
return_value = Abort(BO);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int ConnectConfirm(void)
|
||||
{
|
||||
Frame frame;
|
||||
int return_value, frame_length;
|
||||
|
||||
if(LINK_STATE == IDLE)
|
||||
{
|
||||
return_value = Abort(SP);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
else if(LINK_STATE == UOCON)
|
||||
{
|
||||
frame_length = PutDataInFrame("", 0, &frame, SABM);
|
||||
if(frame_length == -10)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
return_value = SendFrame(&frame, PSOCK_FD);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return_value = Abort(BO);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int ConnectResponse(void)
|
||||
{
|
||||
Frame frame;
|
||||
int return_value, frame_length;
|
||||
|
||||
if(LINK_STATE == IDLE)
|
||||
{
|
||||
return_value = Abort(SU);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
else if(LINK_STATE == UICON)
|
||||
{
|
||||
frame_length = PutDataInFrame("", 0, &frame, UA);
|
||||
if(frame_length == -10)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
return_value = SendFrame(&frame, PSOCK_FD);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
LINK_STATE = DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
return_value = Abort(BO);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int DisconnectRequest(void)
|
||||
{
|
||||
Frame frame;
|
||||
int return_value, frame_length;
|
||||
|
||||
if(LINK_STATE == IDLE)
|
||||
{
|
||||
return_value = Abort(SU);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
LINK_STATE = IDLE;
|
||||
}
|
||||
else if(LINK_STATE == DATA)
|
||||
{
|
||||
frame_length = PutDataInFrame("", 0, &frame, DISC);
|
||||
if(frame_length == -10)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
return_value = SendFrame(&frame, PSOCK_FD);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
LINK_STATE = UODCON;
|
||||
}
|
||||
else
|
||||
{
|
||||
return_value = Abort(BO);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int DisconnectIndication(void)
|
||||
{
|
||||
int return_value;
|
||||
|
||||
if(LINK_STATE == IDLE)
|
||||
{
|
||||
return_value = Abort(SP);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
else if(LINK_STATE == UIDCON)
|
||||
{
|
||||
return_value = WriteSignaltoSocket(PSOCK_FD, F_DISCONNECT_RESPONSE, SIG_LEN);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
LINK_STATE = IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return_value = Abort(BO);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int DisconnectResponse(void)
|
||||
{
|
||||
Frame frame;
|
||||
int return_value, frame_length;
|
||||
|
||||
if(LINK_STATE == IDLE)
|
||||
{
|
||||
return_value = Abort(SU);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
LINK_STATE = IDLE;
|
||||
}
|
||||
else if(LINK_STATE == UIDCON)
|
||||
{
|
||||
frame_length = PutDataInFrame("", 0, &frame, UA);
|
||||
if(frame_length == -10)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
return_value = SendFrame(&frame, PSOCK_FD);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return_value = Abort(BO);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int DisconnectConfirm(void)
|
||||
{
|
||||
int return_value;
|
||||
|
||||
if(LINK_STATE == IDLE)
|
||||
{
|
||||
return_value = Abort(SP);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
else if(LINK_STATE == UODCON)
|
||||
LINK_STATE = IDLE;
|
||||
else
|
||||
{
|
||||
return_value = Abort(BO);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int AbortRequest(void)
|
||||
{
|
||||
int return_value;
|
||||
|
||||
if(LINK_STATE == IDLE)
|
||||
// Do nothing.
|
||||
;
|
||||
else
|
||||
{
|
||||
return_value = Abort(SP);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int AbortIndication(void)
|
||||
{
|
||||
int return_value;
|
||||
|
||||
if(LINK_STATE == IDLE)
|
||||
;// Do nothing.
|
||||
|
||||
else
|
||||
{
|
||||
return_value = Abort(SU);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int Status(void)
|
||||
{
|
||||
int return_value;
|
||||
char frame_status;
|
||||
|
||||
frame_status = CheckFrame(&incoming_frame);
|
||||
|
||||
return_value = WriteSignaltoSocket(USOCK_FD, L_STATUS, SIG_LEN);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
return_value = WriteDatatoSocket(USOCK_FD, &frame_status, sizeof(char));
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int Abort(short who)
|
||||
{
|
||||
int return_value;
|
||||
|
||||
if((who == SU) || (who == BO))
|
||||
{
|
||||
return_value = WriteSignaltoSocket(USOCK_FD, L_ABORT_INDICATION, SIG_LEN);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
if((who == SP) || (who == BO))
|
||||
{
|
||||
return_value = WriteSignaltoSocket(PSOCK_FD, F_ABORT_REQUEST, SIG_LEN);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
|
||||
LINK_STATE = IDLE;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int Checksum(int data_length)
|
||||
{
|
||||
int sum;
|
||||
|
||||
// Vet ej varför, men det står i laborationshäftet.
|
||||
sum = data_length % 128;
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
int PutDataInFrame(char *data, short data_length, Frame *frame, short control)
|
||||
{
|
||||
int frame_length, cc = 0;
|
||||
|
||||
strcat(frame->start_header, "DLEST");
|
||||
frame->start_header[5] = 'X';
|
||||
|
||||
frame->control = control;
|
||||
frame->length = data_length;
|
||||
|
||||
if(control == I)
|
||||
cc = Checksum(data_length);
|
||||
else
|
||||
{
|
||||
frame->cc = cc;
|
||||
data_length = sizeof(frame->data);
|
||||
}
|
||||
|
||||
frame->data = data;
|
||||
|
||||
strcat(frame->start_header, "DLEET");
|
||||
frame->end_header[5] = 'X';
|
||||
|
||||
frame_length = 6 + 6 + 2 + 2 + 2 + data_length;
|
||||
|
||||
return frame_length;
|
||||
}
|
||||
|
||||
int ClearFrame(Frame *frame)
|
||||
{
|
||||
frame->start_header[0] = 0;
|
||||
frame->end_header[0] = 0;
|
||||
frame->control = 0;
|
||||
frame->length = 0;
|
||||
frame->cc = 0;
|
||||
if(frame->data != NULL)
|
||||
{
|
||||
delete[] frame->data;
|
||||
frame->data = NULL;
|
||||
}
|
||||
|
||||
incoming_frame_status = 0; // Global variabel.
|
||||
incoming_frame_index = 0; // Global variabel.
|
||||
}
|
||||
|
||||
int FillInFrame(Frame *frame, char data, char *charframe)
|
||||
{
|
||||
int status;
|
||||
|
||||
if(CheckFrame(frame) == -1)
|
||||
return FRAME_ERROR;
|
||||
|
||||
if(incoming_frame_status)
|
||||
return FRAME_IS_FULL;
|
||||
|
||||
if(incoming_frame_index == 12)
|
||||
{
|
||||
if(frame->control == I)
|
||||
{
|
||||
frame->data = new char[frame->length];
|
||||
if(frame->data == NULL)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
charframe[incoming_frame_index] = data;
|
||||
incoming_frame_index++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
charframe[incoming_frame_index] = data;
|
||||
incoming_frame_index++;
|
||||
}
|
||||
|
||||
return CheckFrame(frame);
|
||||
}
|
||||
|
||||
int CheckFrame(Frame *frame)
|
||||
{
|
||||
int start, end, cc;
|
||||
|
||||
if(incoming_frame_index == 10) // HEADER_LENGTH = 22
|
||||
incoming_frame_length = HEADER_LENGTH + frame->length;
|
||||
|
||||
if(incoming_frame_index >= 10)
|
||||
{
|
||||
if(incoming_frame_index == incoming_frame_length)
|
||||
{
|
||||
start = CheckStartHeader((char*)frame);
|
||||
end = CheckEndHeader((char*)frame);
|
||||
cc = CheckCC(frame);
|
||||
FixFrameData(frame); // tar bort de onödiga DLE om det behövs.
|
||||
|
||||
if(start == 0 && end == 0 && cc == 0)
|
||||
{
|
||||
incoming_frame_status = 1;
|
||||
return FRAME_IS_FULL; // frame_is_full = 1
|
||||
}
|
||||
else
|
||||
return FRAME_ERROR; // frame_error = -1
|
||||
}
|
||||
}
|
||||
|
||||
return FRAME_NOT_READY; // frame_not_ready = 0
|
||||
}
|
||||
|
||||
int CheckStartHeader(char *frame)
|
||||
{
|
||||
int index;
|
||||
char start[7];
|
||||
start[7] = '\0';
|
||||
|
||||
for(index = 0; index < 6; index++)
|
||||
start[index] = (char)frame[index];
|
||||
|
||||
return strcmp(start, "DLESTX");
|
||||
}
|
||||
|
||||
int CheckEndHeader(char *frame)
|
||||
{
|
||||
if(incoming_frame_status != 1)
|
||||
return FRAME_ERROR;
|
||||
|
||||
int index;
|
||||
char start[7];
|
||||
start[7] = '\0';
|
||||
|
||||
for(index = 0; index < 6; index++)
|
||||
start[index] = (char)frame[incoming_frame_index - 5 + index];
|
||||
|
||||
return strcmp(start, "DLEETX");
|
||||
}
|
||||
|
||||
int CheckCC(Frame *frame)
|
||||
{
|
||||
int cc;
|
||||
cc = Checksum(frame->length);
|
||||
|
||||
if(cc == frame->cc)
|
||||
return 0;
|
||||
|
||||
return FRAME_ERROR;
|
||||
}
|
||||
|
||||
int FixFrameData(Frame *frame)
|
||||
{
|
||||
char *tmp;
|
||||
int length, index, tmpindex, before = 0;
|
||||
length = frame->length;
|
||||
|
||||
for(index = 0; index < frame->length; index++)
|
||||
{
|
||||
if(frame->data[index] == 'D' && frame->data[index+1] == 'L' && frame->data[index+2]
|
||||
== 'E')
|
||||
{
|
||||
if(before == 1)
|
||||
{ length--; before = 0; }
|
||||
else
|
||||
before = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(length == frame->length)
|
||||
return SUCCESS;
|
||||
|
||||
tmp = new char[length];
|
||||
if(tmp == NULL)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
for(index = 0, tmpindex = 0; index < frame->length; index++, tmpindex++)
|
||||
{
|
||||
if(frame->data[index] == 'D' && frame->data[index+1] == 'L' && frame->data[index+2] == 'E')
|
||||
{
|
||||
if(before == 1)
|
||||
{ before = 0; index += 3; }
|
||||
else
|
||||
before = 1;
|
||||
}
|
||||
|
||||
if(index < frame->length)
|
||||
tmp[tmpindex];
|
||||
}
|
||||
|
||||
delete[] frame->data;
|
||||
frame->data = tmp;
|
||||
frame->length = length;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int SendFrame(Frame *frame, int socket_id)
|
||||
{
|
||||
int frame_length, index = 0, return_value;
|
||||
frame_length = GetFrameLength(frame);
|
||||
|
||||
if(socket_id == USOCK_FD)
|
||||
{
|
||||
return_value = WriteSignaltoSocket(USOCK_FD, L_DATA_INDICATION, SIG_LEN);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
return_value = WriteDatatoSocket(USOCK_FD, frame->data,
|
||||
frame->length);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
else if(socket_id == PSOCK_FD)
|
||||
{
|
||||
for(index = 0; index < frame_length; index++)
|
||||
{
|
||||
return_value = WriteSignaltoSocket(PSOCK_FD, F_DATA_REQUEST, SIG_LEN);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
return_value = WriteDatatoSocket(PSOCK_FD, (char
|
||||
*)&frame[index], sizeof(char));
|
||||
if(return_value < 0)
|
||||
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int DataIndication(void)
|
||||
{
|
||||
/*Frame *frame;
|
||||
char temp = 'a';
|
||||
int return_value, frame_length;
|
||||
|
||||
if(LINK_STATE == IDLE)
|
||||
Abort(SP);
|
||||
else if(LINK_STATE == UICON)
|
||||
{
|
||||
return_value = ReadDatafromSocket(PSOCK_FD, &temp, TWO_BYTES);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
|
||||
return_value = ReadDatafromSocket(PSOCK_FD, temp, BYTE_LEN);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return_value = Abort(BO);
|
||||
if(return_value < 0)
|
||||
return SYSTEM_FAILURE;
|
||||
}
|
||||
|
||||
if(frame != NULL)
|
||||
delete[] frame;
|
||||
*/
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
void main(int argc, char *argv[])
|
||||
{
|
||||
int tmp_fd1, PSOCK;
|
||||
printf("LINK_LAYER har startat...\n");
|
||||
|
||||
if((PSOCK = CreateUnixClientSocket(UPATH)) < 0)
|
||||
{
|
||||
fprintf(stderr, "Can't create unix client signal socket 111\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("LINK_LAYER har skapat FTP_LAYER Socket...\n");
|
||||
if((tmp_fd1 = CreateUnixServerSocket(PPATH)) < 0)
|
||||
{
|
||||
fprintf(stderr, "Can't create unix server signal socket.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("LINK_LAYER har skapat PHYS_LAYER Socket...\n");
|
||||
switch(fork())
|
||||
{
|
||||
case -1:
|
||||
fprintf(stderr, "Fork failed.\n");
|
||||
|
||||
case 0:
|
||||
printf("Fuck you\n\n");
|
||||
close(PSOCK_FD);
|
||||
close(USOCK_FD);
|
||||
execv("./phys_layer", argv);
|
||||
exit(1);
|
||||
|
||||
default:
|
||||
if((PSOCK = AcceptConnection(tmp_fd1)) < 0)
|
||||
{
|
||||
fprintf(stderr, "Can't accept unix client signal socket.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
MainLoop();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void MainLoop(void)
|
||||
{
|
||||
int return_value;
|
||||
do
|
||||
{
|
||||
return_value = PollSocket(PSOCK_FD, USOCK_FD, NULL);
|
||||
if(return_value < 0)
|
||||
return;
|
||||
|
||||
return_value = ReadSignalfromSocket(return_value - 1, SIG_LEN);
|
||||
return_value = (* FindAction(return_value, ALIST))();
|
||||
if(return_value < 0)
|
||||
return ;
|
||||
|
||||
} while(return_value >= 0);
|
||||
|
||||
}
|
||||
|
||||
int DataRequest(void)
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
int Default(void)
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
|
||||
int GetFrameLength(Frame *frame)
|
||||
Reference in New Issue
Block a user