Startpunkten
This commit is contained in:
45
body.c
Normal file
45
body.c
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#include "student.h"
|
||||||
|
|
||||||
|
#define PATH ".phys_socket"
|
||||||
|
#define LPATH ".link_socket"
|
||||||
|
|
||||||
|
int PSOCK_FD, LSOCK_FD;
|
||||||
|
|
||||||
|
void do_something(void)
|
||||||
|
{
|
||||||
|
PollSOcket(LSOCK_FD, PSOCK_FD, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int tmp_fd1;
|
||||||
|
|
||||||
|
if((LSOCK_FD = CreateUnixClientSocket(LPATH)) < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't create unix client socket\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((tmp_fd1 = CreateUnixServerSocket(PATH) < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't create unix server socket\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(fork())
|
||||||
|
{
|
||||||
|
case -1: fprintf(stderr, "Fork failed\n");
|
||||||
|
case 0: close(PSOCK_FD);
|
||||||
|
close(LSOCK_FD);
|
||||||
|
execv("./physical_layer", argv);
|
||||||
|
exit(1);
|
||||||
|
default: if((PSOCK_FD = AcceptConnection(tmp_fd1)) < 0
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Can't accept unix client signal socket\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_something();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
362
ftp_app.c
Normal file
362
ftp_app.c
Normal file
@@ -0,0 +1,362 @@
|
|||||||
|
/*================================================================
|
||||||
|
LAB I DATAKOMMUNIKATION
|
||||||
|
FTP_APPLICATION
|
||||||
|
Stefan Sonesson
|
||||||
|
Christian Ohlsson
|
||||||
|
Karlstad 981215
|
||||||
|
-----------------------------------------------------------------*/
|
||||||
|
#include "header_ftp.h"
|
||||||
|
#include "signal_prim.h"
|
||||||
|
#include "state.h"
|
||||||
|
#include "student.h"
|
||||||
|
/*================================================================
|
||||||
|
meny()
|
||||||
|
Skriver ut menyn på skärmen
|
||||||
|
pre : none
|
||||||
|
post : Menyn är utskriven
|
||||||
|
calls: none
|
||||||
|
-----------------------------------------------------------------*/
|
||||||
|
void meny()
|
||||||
|
{
|
||||||
|
printf ("Meny\n");
|
||||||
|
printf ("====\n");
|
||||||
|
printf("1. Send a file\n");
|
||||||
|
printf("2. Quit\n");
|
||||||
|
}
|
||||||
|
/*================================================================
|
||||||
|
sendIt()
|
||||||
|
Skickar en data request, filstorleken (som long), filnamn
|
||||||
|
samt själva datan till ftp-layer så länge som
|
||||||
|
det finns tecken i bufferten.
|
||||||
|
pre : Filen finns
|
||||||
|
post : Filen är skickad
|
||||||
|
calls: WriteDatatoSocket, WriteSignaltoSocket
|
||||||
|
-----------------------------------------------------------------*/
|
||||||
|
void sendIt(long fileSize, char *fileName, int fd)
|
||||||
|
{
|
||||||
|
char buffer[BUFSIZE];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
printf("FileSize: %d\n", fileSize);
|
||||||
|
len = strlen(fileName)+1;
|
||||||
|
WriteSignaltoSocket(FSOCK_FD, AF_Data_Req, SIGLEN);
|
||||||
|
WriteDatatoSocket(FSOCK_FD, (char *)&len, sizeof(long));
|
||||||
|
WriteDatatoSocket(FSOCK_FD, fileName, len);
|
||||||
|
while(fileSize > 0){
|
||||||
|
if((len = read(fd, buffer, BUFSIZE)) == -1){
|
||||||
|
fprintf(stderr, "Can't read from file\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WriteSignaltoSocket(FSOCK_FD, AF_Data_Req, SIGLEN);
|
||||||
|
WriteDatatoSocket(FSOCK_FD, (char *)&len, sizeof(long));
|
||||||
|
WriteDatatoSocket(FSOCK_FD, buffer, len);
|
||||||
|
fileSize -= len;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
/*================================================================
|
||||||
|
sendFile()
|
||||||
|
Ber användaren mata in ett filnamn som skall skickas
|
||||||
|
och ser om filen är öppningsbar. Om filen är
|
||||||
|
öppningsbar anropas sendIt.
|
||||||
|
pre : none
|
||||||
|
post : Filen är öppnad och filstorleken känd
|
||||||
|
calls: sendIt
|
||||||
|
-----------------------------------------------------------------*/
|
||||||
|
void sendFile()
|
||||||
|
{
|
||||||
|
int toSend;
|
||||||
|
long fileSize;
|
||||||
|
char fileName[FNSIZE];
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
printf("Skriv in filnamn: \n");
|
||||||
|
gets(fileName);
|
||||||
|
/*Mata in filnamn*/
|
||||||
|
if((toSend = open(fileName, 0)) == -1){
|
||||||
|
/*Går filen att öppna?*/
|
||||||
|
printf("Unable to open file %s\n", fileName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fstat(toSend, &st);
|
||||||
|
/*Hämta filstorleken*/
|
||||||
|
fileSize = st.st_size;
|
||||||
|
sendIt(fileSize, fileName, toSend);
|
||||||
|
}
|
||||||
|
/*================================================================
|
||||||
|
menu()
|
||||||
|
Ber användaren mata in vilken operation som skall utföras
|
||||||
|
och returnerar valet (om val = 0 avslutas programmet).
|
||||||
|
pre : none
|
||||||
|
post : Menyvalet är gjort
|
||||||
|
calls: Beror på menyvalet
|
||||||
|
-----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
int menu()
|
||||||
|
{
|
||||||
|
char val;
|
||||||
|
|
||||||
|
do{
|
||||||
|
meny();
|
||||||
|
val=getchar();
|
||||||
|
/*Mata in menyval*/
|
||||||
|
switch(val){
|
||||||
|
case '1' : sendFile();break;
|
||||||
|
case '2' : printf ("Programmet avslutat...\n");break;
|
||||||
|
default : printf ("Felaktigt val...\n");break;
|
||||||
|
}
|
||||||
|
fflush(STDIN); /*Ta bort alla tecken utom det första*/
|
||||||
|
}while(val != '1' && val != '2');
|
||||||
|
return (val - 2);
|
||||||
|
}
|
||||||
|
/*================================================================
|
||||||
|
readData()
|
||||||
|
Öppnar en socket och hämtar filstorlek, och sedan
|
||||||
|
själva datan, som den skriver till den nya filen.
|
||||||
|
pre : none
|
||||||
|
post : Filen är överförd
|
||||||
|
calls: Polla, ReadDatafromSocket
|
||||||
|
-----------------------------------------------------------------*/
|
||||||
|
int readData(int fd)
|
||||||
|
{
|
||||||
|
int poll, len;
|
||||||
|
char buffer[BUFSIZE];
|
||||||
|
|
||||||
|
Polla(FSOCK_FD, FSOCK_FD); /*Hämta filstorlek*/
|
||||||
|
ReadDatafromSocket(FSOCK_FD, (char *)&len,sizeof(long));
|
||||||
|
Polla(FSOCK_FD, FSOCK_FD); /*Hämta data*/
|
||||||
|
ReadDatafromSocket(FSOCK_FD,buffer,len);
|
||||||
|
return write(fd,buffer,len) == -1;
|
||||||
|
}
|
||||||
|
/*================================================================
|
||||||
|
Polla()
|
||||||
|
Genomför en PollSocket och om det gick bra
|
||||||
|
returneras socket'ens nummer (+1)
|
||||||
|
pre :
|
||||||
|
post : En socket är öppnad
|
||||||
|
calls: Pollsocket
|
||||||
|
-----------------------------------------------------------------*/
|
||||||
|
int Polla(int fd1,int fd2)
|
||||||
|
{
|
||||||
|
int poll;
|
||||||
|
|
||||||
|
poll = PollSocket(fd1, fd2, NULL); /*Öppna en socket*/
|
||||||
|
if(poll == -1){ /*Gick det bra?*/
|
||||||
|
fprintf(stderr, "PollSocket failed\n");
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
return poll; /*Returnera socket'ens nummer*/
|
||||||
|
}
|
||||||
|
/*================================================================
|
||||||
|
State_IDLE()
|
||||||
|
Om vi i detta tillstånd får en Connect Indication
|
||||||
|
läser vi filstorlek samt själva datan från socket'en
|
||||||
|
pre : none
|
||||||
|
post : TRUE om vi fick en Connect Indication
|
||||||
|
calls: Polla, ReadDatafromSocket, WriteSignaltoSocket
|
||||||
|
-----------------------------------------------------------------*/
|
||||||
|
int State_IDLE(int sig, long len, char buffer[BUFSIZE], int fd)
|
||||||
|
{
|
||||||
|
if(sig == AF_Con_Ind) {
|
||||||
|
Polla(FSOCK_FD, FSOCK_FD);
|
||||||
|
ReadDatafromSocket(FSOCK_FD, (char *)&len, sizeof(long));
|
||||||
|
Polla(FSOCK_FD, FSOCK_FD);
|
||||||
|
ReadDatafromSocket(FSOCK_FD, buffer, len);
|
||||||
|
if((fd = open(buffer, O_WRONLY)) == -1) {
|
||||||
|
printf("Unable to open file.\n");
|
||||||
|
WriteSignaltoSocket(FSOCK_FD, AF_Rej_Req, SIGLEN);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
WriteSignaltoSocket(FSOCK_FD, AF_Con_Resp, SIGLEN);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
/*================================================================
|
||||||
|
State_UUUK()
|
||||||
|
Känner av om vi får en Connect Confirm, då ropar vi
|
||||||
|
på sendFile, annars felhantering
|
||||||
|
pre : none
|
||||||
|
post : state returnerat
|
||||||
|
calls: sendFile, WriteSignaltoSocket
|
||||||
|
-----------------------------------------------------------------*/
|
||||||
|
int State_UUUK(int sig)
|
||||||
|
{
|
||||||
|
int state;
|
||||||
|
|
||||||
|
if(sig == AF_Con_Conf){
|
||||||
|
state = DATA;
|
||||||
|
sendFile();
|
||||||
|
}
|
||||||
|
else if(sig == AF_Rej_Ind){
|
||||||
|
printf("The other side don't wanna play with you...");
|
||||||
|
WriteSignaltoSocket(FSOCK_FD, AF_Rej_Resp, SIGLEN);
|
||||||
|
state = IDLE;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
WriteSignaltoSocket(FSOCK_FD, AF_Abort_Req, SIGLEN);
|
||||||
|
state = IDLE;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
/*================================================================
|
||||||
|
State_DATA()
|
||||||
|
Känner av om vi får en data indication och då läser vi
|
||||||
|
data från socket'en, annars felhantering
|
||||||
|
pre : none
|
||||||
|
post : state returnerat
|
||||||
|
calls: readData, WriteSignaltoSocket
|
||||||
|
-----------------------------------------------------------------*/
|
||||||
|
int State_DATA(int sig, int fd)
|
||||||
|
{
|
||||||
|
int state;
|
||||||
|
|
||||||
|
if(sig == AF_Data_Ind){
|
||||||
|
if(readData(fd)) {
|
||||||
|
WriteSignaltoSocket(FSOCK_FD,AF_Abort_Req,SIGLEN);
|
||||||
|
printf("Can't write to file\n");
|
||||||
|
close(fd);
|
||||||
|
state = IDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(sig == AF_Disc_Ind){
|
||||||
|
close(fd);
|
||||||
|
WriteSignaltoSocket(FSOCK_FD, AF_Disc_Resp, SIGLEN);
|
||||||
|
state = IDLE;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
WriteSignaltoSocket(FSOCK_FD, AF_Abort_Req, SIGLEN);
|
||||||
|
close(fd);
|
||||||
|
state = IDLE;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
/*================================================================
|
||||||
|
State_UUNK()
|
||||||
|
Känner av om vi får en disconnect confirm och ställer
|
||||||
|
oss i IDLE, annars felhantering
|
||||||
|
pre : none
|
||||||
|
post : state returnerat
|
||||||
|
calls: WriteSignaltoSocket
|
||||||
|
-----------------------------------------------------------------*/
|
||||||
|
int State_UUNK(int sig)
|
||||||
|
{
|
||||||
|
int state;
|
||||||
|
|
||||||
|
if(sig == AF_Disc_Conf)
|
||||||
|
state = IDLE;
|
||||||
|
else{
|
||||||
|
WriteSignaltoSocket(FSOCK_FD, AF_Abort_Req, SIGLEN);
|
||||||
|
state = IDLE;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
/*================================================================
|
||||||
|
State_TERR()
|
||||||
|
Känner av om vi får en reject confirm och ställer oss
|
||||||
|
då i IDLE, annars felhantering
|
||||||
|
pre : none
|
||||||
|
post : state returnerat
|
||||||
|
calls: WriteSignaltoSocket
|
||||||
|
-----------------------------------------------------------------*/
|
||||||
|
int State_TERR(int sig)
|
||||||
|
{
|
||||||
|
int state;
|
||||||
|
|
||||||
|
if(sig == AF_Rej_Conf)
|
||||||
|
state = IDLE;
|
||||||
|
else{
|
||||||
|
WriteSignaltoSocket(FSOCK_FD, AF_Abort_Req, SIGLEN);
|
||||||
|
state = IDLE;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
/*================================================================
|
||||||
|
do_something()
|
||||||
|
Ligger hela tiden och känner av vilka signaler
|
||||||
|
som kommer in från socketen och genomför lämpliga
|
||||||
|
operationer beroende på insignalen.
|
||||||
|
pre :
|
||||||
|
post : none
|
||||||
|
calls: Polla, WriteSignaltoSocket, ReadSignalfromSocket,
|
||||||
|
sendFile, ReadDatafromSocket
|
||||||
|
-----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void do_something()
|
||||||
|
{
|
||||||
|
int sig, poll, fd, state = IDLE;
|
||||||
|
long len;
|
||||||
|
char buffer[BUFSIZE];
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
/*Loopa alltid*/
|
||||||
|
poll = Polla(STDIN, FSOCK_FD);
|
||||||
|
if(poll - 1 == STDIN){
|
||||||
|
switch(state)
|
||||||
|
{
|
||||||
|
case IDLE : /*Tillstånd när inget händer*/
|
||||||
|
if(menu()){
|
||||||
|
WriteSignaltoSocket(FSOCK_FD, AF_Con_Req, 3);
|
||||||
|
state = UUUK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
case DATA : /*Datafas*/
|
||||||
|
sendFile();
|
||||||
|
default :
|
||||||
|
fflush(STDIN);
|
||||||
|
menu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(poll - 1 == FSOCK_FD){
|
||||||
|
sig = ReadSignalfromSocket(FSOCK_FD, 3);
|
||||||
|
if(sig == AF_Abort_Ind)
|
||||||
|
state = IDLE;
|
||||||
|
else
|
||||||
|
switch(state)
|
||||||
|
{
|
||||||
|
|
||||||
|
case IDLE :
|
||||||
|
/*Tillstånd när inget händer*/
|
||||||
|
if(State_IDLE(sig, len, buffer, fd))
|
||||||
|
state = DATA;
|
||||||
|
break;
|
||||||
|
case UUUK :
|
||||||
|
/*Under utgående uppkoppling*/
|
||||||
|
state = State_UUUK(sig);
|
||||||
|
break;
|
||||||
|
case DATA :
|
||||||
|
/*Datafas*/
|
||||||
|
state = State_DATA(sig, fd);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case UUNK :
|
||||||
|
/*Under utgående nedkoppling*/
|
||||||
|
state = State_UUNK(sig);
|
||||||
|
break;
|
||||||
|
case TERR :
|
||||||
|
/*Transfer error*/
|
||||||
|
state = State_TERR(sig);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Cancel transfer");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*================================================================
|
||||||
|
main()
|
||||||
|
Skapar en socket och kontrollerar så att socket'en
|
||||||
|
är redo för dataöverföring
|
||||||
|
pre :
|
||||||
|
post : Socket'en är skapad, och data kan överföras
|
||||||
|
calls: CreateUnixServerSocket, AcceptConnection, do_something
|
||||||
|
-----------------------------------------------------------------*/
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int tmp_fd1, x;
|
||||||
|
printf("FTP_APP startad...\n");
|
||||||
|
if((tmp_fd1 = CreateUnixServerSocket(S_PATH)) < 0){
|
||||||
|
fprintf(stderr, "Can't create Unix Server Signal Socket\n");
|
||||||
364
ftp_layer.c
Normal file
364
ftp_layer.c
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
/* FTP-layer av Daniel W och Anders W för datakommunikation-lab! */
|
||||||
|
|
||||||
|
#include "student.h"
|
||||||
|
#include "signal_prim.h"
|
||||||
|
|
||||||
|
#define FPATH "./ftp_socket"
|
||||||
|
#define LPATH "./link_socket"
|
||||||
|
#define AF 1 /* send AF_Abort_Ind to app with cancel() */
|
||||||
|
#define L 0 /* send L_Abort_Req to linker with cancel()*/
|
||||||
|
#define IsFTP 0x80 /* set the ID-bit to indicate FTP & !chat */
|
||||||
|
#define OPMASK 0x7f /* to mask out the 'operation'-field */
|
||||||
|
#define SIGPACKLEN 3 /* lenght of a sigpacket; primitive or PDU */
|
||||||
|
#define MAXDATALEN 200 /* max datalen to tfr between ftp and linker */
|
||||||
|
#define IDLE 0
|
||||||
|
#define UUUK 1
|
||||||
|
#define UIUK 2
|
||||||
|
#define DATA 3
|
||||||
|
#define UUNK 4
|
||||||
|
#define UINK 5
|
||||||
|
#define TERROR 6 /* the states */
|
||||||
|
#define CR 1
|
||||||
|
#define CA 2
|
||||||
|
#define DR 3
|
||||||
|
#define DA 4
|
||||||
|
#define RR 5
|
||||||
|
#define RA 6
|
||||||
|
#define DT 7 /* the PDU's */
|
||||||
|
/* #define NULL 0 */
|
||||||
|
|
||||||
|
void do_something(void);
|
||||||
|
int Polla(int,int); /* handles error from PollSocket() */
|
||||||
|
void cancel(int); /* sets 'state' to IDLE */
|
||||||
|
void WriteSigToApp(int); /* write a sig and handle error */
|
||||||
|
void WriteSigToLink(int); /* write a sig and handle error */
|
||||||
|
int WriteDataToLink(char*, int); /* cancel(AF/L) if no L_Stat from link */
|
||||||
|
void WriteDataToApp(char*,int);
|
||||||
|
int doSigPacket(int); /* uses WriteDataToLink() */
|
||||||
|
int ConnToLinker(void); /* executes cancel(AF/L) on error */
|
||||||
|
void DiscFromLinker(void); /* executes cancel(L) on error */
|
||||||
|
|
||||||
|
int lSock_fd, fSock_fd, state=IDLE, stderr=2;
|
||||||
|
|
||||||
|
main(int argc,char *argv[]) {
|
||||||
|
|
||||||
|
int temp_fd;
|
||||||
|
printf("FTP_LAYER startat\n");
|
||||||
|
if((fSock_fd=CreateUnixClientSocket(FPATH))<0) {
|
||||||
|
fprintf(stderr,"Can't create client signal socket to application!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("FTP_Layer har startat APP-socket...\n");
|
||||||
|
if((temp_fd=CreateUnixServerSocket(LPATH))<0) {
|
||||||
|
fprintf(stderr,"Can't create server signal socket to linker!\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
printf("FTP_Layer har startat LINK-socket...\n");
|
||||||
|
switch(fork()) {
|
||||||
|
case -1:
|
||||||
|
fprintf(stderr,"Fork failed in FTP-layer!\n");
|
||||||
|
exit(4);
|
||||||
|
case 0:
|
||||||
|
close(fSock_fd);
|
||||||
|
close(temp_fd);
|
||||||
|
execv("./link_layer",argv);
|
||||||
|
exit(0);
|
||||||
|
default:
|
||||||
|
if((lSock_fd=AcceptConnection(temp_fd))<0) {
|
||||||
|
fprintf(stderr,"Can't accept client signal socket from application!\n");
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
do_something();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Polla(int fd1, int fd2) {
|
||||||
|
int poll;
|
||||||
|
poll=PollSocket(fd1,fd2,NULL);
|
||||||
|
if(poll==-1) {
|
||||||
|
fprintf(stderr,"PollSocket-error in FTP-layer, quitting!\n\n");
|
||||||
|
exit(8);
|
||||||
|
}
|
||||||
|
return poll-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_something() {
|
||||||
|
int sig, poll;
|
||||||
|
char buf[MAXDATALEN+SIGPACKLEN], x;
|
||||||
|
long len;
|
||||||
|
while(1) {
|
||||||
|
poll=Polla(fSock_fd,lSock_fd);
|
||||||
|
if(poll==fSock_fd) { /* signal från applikationen */
|
||||||
|
sig=ReadSignalfromSocket(fSock_fd,SIGPACKLEN);
|
||||||
|
if(sig==AF_Abort_Req)
|
||||||
|
cancel(L);
|
||||||
|
else if(sig==-1) {
|
||||||
|
fprintf(stderr,"ReadSignal-error in FTP-layer, quitting!\n\n");
|
||||||
|
exit(15);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch(state) {
|
||||||
|
case IDLE:
|
||||||
|
if(sig==AF_Con_Req) {
|
||||||
|
if(ConnToLinker())
|
||||||
|
if(doSigPacket(CR)) state=UUUK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cancel(AF);
|
||||||
|
break;
|
||||||
|
case UIUK:
|
||||||
|
if(sig==AF_Con_Resp)
|
||||||
|
if(doSigPacket(CA)) state=DATA;
|
||||||
|
else {
|
||||||
|
cancel(AF);
|
||||||
|
cancel(L);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DATA:
|
||||||
|
if(sig==AF_Data_Req) {
|
||||||
|
PollSocket(fSock_fd,fSock_fd,NULL);
|
||||||
|
ReadDatafromSocket(fSock_fd, (char*)&len,sizeof(long));
|
||||||
|
if(len) {
|
||||||
|
PollSocket(fSock_fd,fSock_fd,NULL);
|
||||||
|
while(len>0) {
|
||||||
|
x=ReadDatafromSocket(fSock_fd,buf+3,len>MAXDATALEN?MAXDATALEN:len);
|
||||||
|
if(x>0) {
|
||||||
|
buf[0]=x+2;
|
||||||
|
buf[1]=x;
|
||||||
|
buf[2]=IsFTP | DT;
|
||||||
|
if(!WriteDataToLink(buf,x+SIGPACKLEN)) break;
|
||||||
|
len-=x;
|
||||||
|
}
|
||||||
|
else if(x==-1) {
|
||||||
|
fprintf(stderr,"Readerror in FTP-layer, quitting!\n\n");
|
||||||
|
exit(14);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(sig==AF_Disc_Req)
|
||||||
|
if(doSigPacket(DR)) state=UUNK;
|
||||||
|
else {
|
||||||
|
cancel(AF);
|
||||||
|
cancel(L);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UINK:
|
||||||
|
if(sig==AF_Disc_Resp) {
|
||||||
|
if(doSigPacket(DA)) {
|
||||||
|
state=IDLE;
|
||||||
|
DiscFromLinker();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cancel(AF);
|
||||||
|
cancel(L);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TERROR:
|
||||||
|
if(sig==AF_Rej_Resp)
|
||||||
|
if(doSigPacket(RA)) state=IDLE;
|
||||||
|
else
|
||||||
|
cancel(AF);
|
||||||
|
cancel(L);
|
||||||
|
break;
|
||||||
|
default: /* I UUUK & UUNK ska man inte få signaler från app */
|
||||||
|
cancel(AF);
|
||||||
|
cancel(L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(poll==lSock_fd) { /* signal från linkern */
|
||||||
|
sig=ReadSignalfromSocket(lSock_fd,SIGPACKLEN);
|
||||||
|
if(sig==L_Abort_Ind)
|
||||||
|
cancel(AF);
|
||||||
|
else if(sig==L_Data_Ind)
|
||||||
|
Polla(lSock_fd,lSock_fd);
|
||||||
|
else if(sig==-1) {
|
||||||
|
fprintf(stderr,"ReadSignal-error in FTP-layer, quitting!\n\n");
|
||||||
|
exit(15);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch(state) {
|
||||||
|
case IDLE:
|
||||||
|
if(sig==L_Con_Ind) {
|
||||||
|
WriteSigToLink(L_Con_Resp);
|
||||||
|
Polla(lSock_fd,lSock_fd);
|
||||||
|
if(ReadSignalfromSocket(lSock_fd,SIGPACKLEN)==L_Data_Req) {
|
||||||
|
Polla(lSock_fd,lSock_fd);
|
||||||
|
ReadDatafromSocket(lSock_fd,buf,1);
|
||||||
|
Polla(lSock_fd,lSock_fd);
|
||||||
|
ReadDatafromSocket(lSock_fd,buf,buf[0]);
|
||||||
|
if(buf[1] & IsFTP) {
|
||||||
|
if((buf[1] & OPMASK)==CR) {
|
||||||
|
WriteSigToApp(AF_Con_Ind);
|
||||||
|
state=UIUK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cancel(L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cancel(L);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cancel(AF);
|
||||||
|
cancel(L);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UUUK:
|
||||||
|
if(sig==L_Data_Ind) {
|
||||||
|
ReadDatafromSocket(lSock_fd,buf,1);
|
||||||
|
Polla(lSock_fd,lSock_fd);
|
||||||
|
ReadDatafromSocket(lSock_fd,buf,buf[0]);
|
||||||
|
if(buf[1] & IsFTP) {
|
||||||
|
if((buf[1] & OPMASK)==CA) {
|
||||||
|
WriteSigToApp(AF_Con_Conf);
|
||||||
|
state=DATA;
|
||||||
|
}
|
||||||
|
else if((buf[1] & OPMASK)==RR) {
|
||||||
|
WriteSigToApp(AF_Rej_Ind);
|
||||||
|
state=TERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cancel(AF);
|
||||||
|
break;
|
||||||
|
case DATA:
|
||||||
|
if(sig==L_Data_Ind) {
|
||||||
|
ReadDatafromSocket(lSock_fd,buf,1);
|
||||||
|
Polla(lSock_fd,lSock_fd);
|
||||||
|
ReadDatafromSocket(lSock_fd,buf,buf[0]);
|
||||||
|
if(buf[1] & IsFTP) {
|
||||||
|
if((buf[1] & OPMASK)==DT) {
|
||||||
|
len=buf[0];
|
||||||
|
WriteDataToApp((char*)&len,sizeof(long));
|
||||||
|
WriteDataToApp(buf+2,len);
|
||||||
|
}
|
||||||
|
else if((buf[1] & OPMASK)==DR) {
|
||||||
|
WriteSigToApp(AF_Disc_Ind);
|
||||||
|
state=UINK;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cancel(AF);
|
||||||
|
cancel(L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cancel(AF);
|
||||||
|
cancel(L);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UUNK:
|
||||||
|
if(sig==L_Data_Ind) {
|
||||||
|
ReadDatafromSocket(lSock_fd,buf,1);
|
||||||
|
Polla(lSock_fd,lSock_fd);
|
||||||
|
ReadDatafromSocket(lSock_fd,buf,buf[0]);
|
||||||
|
if(buf[1] & IsFTP) {
|
||||||
|
if((buf[1] & OPMASK)==DA) {
|
||||||
|
WriteSigToApp(AF_Disc_Conf);
|
||||||
|
state=IDLE;
|
||||||
|
DiscFromLinker();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cancel(AF);
|
||||||
|
cancel(L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cancel(AF);
|
||||||
|
cancel(L);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: /* i UIUK, UINK & TERROR ska man inte få sig. från linker */
|
||||||
|
cancel(AF);
|
||||||
|
cancel(L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cancel(int af_abort) {
|
||||||
|
if(af_abort)
|
||||||
|
WriteSigToApp(AF_Abort_Ind);
|
||||||
|
else
|
||||||
|
WriteSigToLink(L_Abort_Req);
|
||||||
|
state=IDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteSigToLink(int flag) {
|
||||||
|
if(WriteSignaltoSocket(lSock_fd,flag,SIGPACKLEN)==-1) {
|
||||||
|
fprintf(stderr,"Write-error to linker, quitting!\n\n");
|
||||||
|
exit(10);
|
||||||
|
} }
|
||||||
|
|
||||||
|
void WriteSigToApp(int flag) {
|
||||||
|
if(WriteSignaltoSocket(fSock_fd,flag,SIGPACKLEN)==-1) {
|
||||||
|
fprintf(stderr,"Write-error to application, quitting!\n\n");
|
||||||
|
exit(11);
|
||||||
|
} }
|
||||||
|
|
||||||
|
int WriteDataToLink(char* buf,int len) {
|
||||||
|
int x;
|
||||||
|
WriteSigToLink(L_Data_Req);
|
||||||
|
PollSocket(lSock_fd,lSock_fd,NULL);
|
||||||
|
if(ReadSignalfromSocket(lSock_fd,SIGPACKLEN)!=L_Status) {
|
||||||
|
cancel(AF);
|
||||||
|
cancel(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if((x=WriteDatatoSocket(lSock_fd,buf,len))==-1) {
|
||||||
|
fprintf(stderr,"Write-error to linker, quitting!\n\n");
|
||||||
|
exit(13);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
while(x<len) x+=WriteDatatoSocket(lSock_fd,buf+x,len-x);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteDataToApp(char* buf,int len) {
|
||||||
|
int x;
|
||||||
|
WriteSigToApp(AF_Data_Ind);
|
||||||
|
if((x=WriteDatatoSocket(fSock_fd,buf,len))==-1) {
|
||||||
|
fprintf(stderr,"Write-error to application, quitting!\n\n");
|
||||||
|
exit(13);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
while(x<len) x+=WriteDatatoSocket(lSock_fd,buf+x,len-x);
|
||||||
|
}
|
||||||
|
|
||||||
|
int doSigPacket(int flag) {
|
||||||
|
char head[3];
|
||||||
|
head[0]=2;
|
||||||
|
head[1]=0;
|
||||||
|
head[2]=IsFTP | flag;
|
||||||
|
return WriteDataToLink(head,SIGPACKLEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConnToLinker() {
|
||||||
|
WriteSigToLink(L_Con_Req);
|
||||||
|
Polla(lSock_fd,lSock_fd);
|
||||||
|
switch(ReadSignalfromSocket(lSock_fd,SIGPACKLEN)) {
|
||||||
|
case L_Con_Conf:
|
||||||
|
return 1;
|
||||||
|
case L_Abort_Ind:
|
||||||
|
cancel(AF);
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
cancel(AF);
|
||||||
|
cancel(L);
|
||||||
|
return 0;
|
||||||
|
} }
|
||||||
|
|
||||||
|
void DiscFromLinker() {
|
||||||
|
WriteSigToLink(L_Disc_Req);
|
||||||
|
Polla(lSock_fd,lSock_fd);
|
||||||
|
if(ReadSignalfromSocket(lSock_fd,SIGPACKLEN)!=L_Disc_Conf) {
|
||||||
|
cancel(AF);
|
||||||
|
cancel(L);
|
||||||
|
} }
|
||||||
29
header_ftp.h
Normal file
29
header_ftp.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*================================================================
|
||||||
|
LAB I DATAKOMMUNIKATION
|
||||||
|
FTP_APPLICATION
|
||||||
|
Stefan Sonesson
|
||||||
|
Christian Ohlsson
|
||||||
|
Karlstad 981215
|
||||||
|
-----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef ___FTP_APP___
|
||||||
|
#define ___FTP_APP___
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#define FALSE 0
|
||||||
|
#define TRUE 1
|
||||||
|
#define ENTER 13
|
||||||
|
#define BACKSPACE 8
|
||||||
|
#define PERMS 0644
|
||||||
|
#define BUFSIZE 4000
|
||||||
|
#define FNSIZE 300
|
||||||
|
#define SIGLEN 3
|
||||||
|
#define S_PATH "./ftp_socket"
|
||||||
|
#define L_PATH "./ftp_layer"
|
||||||
|
#define STDIN 0
|
||||||
|
int FSOCK_FD;
|
||||||
|
|
||||||
|
#endif
|
||||||
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)
|
||||||
52
link.h
Normal file
52
link.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#ifndef _link_h_
|
||||||
|
#define _link_h_
|
||||||
|
|
||||||
|
#define SABM 401
|
||||||
|
#define UA 403
|
||||||
|
#define I 405
|
||||||
|
#define RR 406
|
||||||
|
#define DISC 407
|
||||||
|
#define SIG_LEN 2
|
||||||
|
#define BO 2
|
||||||
|
#define SU 1
|
||||||
|
#define SP 3
|
||||||
|
#define DEFAULT 10
|
||||||
|
#define FRAME_ERROR 13
|
||||||
|
#define FRAME_IS_FULL 34
|
||||||
|
#define FRAME_NOT_READY 123
|
||||||
|
#define HEADER_LENGTH 22
|
||||||
|
#define TWO_BYTES 56
|
||||||
|
#define UPATH "./link_socket"
|
||||||
|
#define PPATH "./.phys_socket"
|
||||||
|
|
||||||
|
struct Frame;
|
||||||
|
int SystemError(void);
|
||||||
|
int GetFrameLength(Frame *frame);
|
||||||
|
int Default(void);
|
||||||
|
int DataRequest(void);
|
||||||
|
int ConnectRequest(void);
|
||||||
|
int ConnectIndication(void);
|
||||||
|
int ConnectConfirm(void);
|
||||||
|
int ConnectResponse(void);
|
||||||
|
int DisconnectRequest(void);
|
||||||
|
int DisconnectIndication(void);
|
||||||
|
int DisconnectResponse(void);
|
||||||
|
int DisconnectConfirm(void);
|
||||||
|
int AbortRequest(void);
|
||||||
|
int AbortIndication(void);
|
||||||
|
int Status(void);
|
||||||
|
int Abort(short who);
|
||||||
|
int Checksum(int data_length);
|
||||||
|
int PutDataInFrame(char *data, short data_length, Frame *frame, short control);
|
||||||
|
int ClearFrame(Frame *frame);
|
||||||
|
int FillInFrame(char *frame, char data, char *charframe);
|
||||||
|
int CheckFrame(Frame *frame);
|
||||||
|
int CheckStartHeader(char *frame);
|
||||||
|
int CheckEndHeader(char *frame);
|
||||||
|
int CheckCC(Frame *frame);
|
||||||
|
int FixFrameData(Frame *frame);
|
||||||
|
int SendFrame(Frame *frame, int socket_id);
|
||||||
|
int DataIndication(void);
|
||||||
|
void MainLoop(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
48
link_signal.h
Normal file
48
link_signal.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#ifndef ___SIGNAL_PRIM___
|
||||||
|
#define ___SIGNAL_PRIM___
|
||||||
|
|
||||||
|
#define L_CONNECT_REQUEST 101
|
||||||
|
#define L_CONNECT_INDICATION 102
|
||||||
|
#define L_CONNECT_RESPONSE 103
|
||||||
|
#define L_CONNECT_CONFIRM 104
|
||||||
|
#define L_DATA_REQUEST 105
|
||||||
|
#define L_DATA_INDICATION 106
|
||||||
|
#define L_DISCONNECT_REQUEST 107
|
||||||
|
#define L_DISCONNECT_RESPONSE 108
|
||||||
|
#define L_DISCONNECT_INDICATION 109
|
||||||
|
#define L_DISCONNECT_CONFIRM 110
|
||||||
|
#define L_ABORT_REQUEST 111
|
||||||
|
#define L_ABORT_INDICATION 112
|
||||||
|
#define L_STATUS 113
|
||||||
|
|
||||||
|
#define AF_Con_Req 201
|
||||||
|
#define AF_Con_Ind 202
|
||||||
|
#define AF_Con_Resp 203
|
||||||
|
#define AF_Con_Conf 204
|
||||||
|
#define AF_Data_Req 205
|
||||||
|
#define AF_Data_Ind 206
|
||||||
|
#define AF_Disc_Req 207
|
||||||
|
#define AF_Disc_Ind 208
|
||||||
|
#define AF_Disc_Resp 209
|
||||||
|
#define AF_Disc_Conf 210
|
||||||
|
#define AF_Rej_Req 211
|
||||||
|
#define AF_Rej_Ind 212
|
||||||
|
#define AF_Rej_Resp 213
|
||||||
|
#define AF_Rej_Conf 214
|
||||||
|
#define AF_Abort_Req 215
|
||||||
|
#define AF_Abort_Ind 216
|
||||||
|
|
||||||
|
#define AI_Con_Req 301
|
||||||
|
#define AI_Con_Ind 302
|
||||||
|
#define AI_Con_Resp 303
|
||||||
|
#define AI_Con_Conf 304
|
||||||
|
#define AI_Data_Req 305
|
||||||
|
#define AI_Data_Ind 306
|
||||||
|
#define AI_Disc_Req 307
|
||||||
|
#define AI_Disc_Ind 308
|
||||||
|
#define AI_Disc_Resp 309
|
||||||
|
#define AI_Disc_Conf 310
|
||||||
|
#define AI_Abort_Req 311
|
||||||
|
#define AI_Abort_Ind 312
|
||||||
|
|
||||||
|
#endif
|
||||||
3
physerr.log
Normal file
3
physerr.log
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Wed Dec 16 14:55:03 1998
|
||||||
|
System failure
|
||||||
|
No such file or directory
|
||||||
1886
physlayer.c
Normal file
1886
physlayer.c
Normal file
File diff suppressed because it is too large
Load Diff
96
physlayer.h
Normal file
96
physlayer.h
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* (c) Copyright 1998, University of Karlstad.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* Please report any bugs you find in this code or any improvements to:
|
||||||
|
*
|
||||||
|
* Hans Hedbom, Dept. of Computer Science,
|
||||||
|
* University of Karlstad, Sweden.
|
||||||
|
*
|
||||||
|
* Phone: +46 54 838157
|
||||||
|
* E-mail: Hans.Hedbom@hks.se
|
||||||
|
*
|
||||||
|
* ============================================================================
|
||||||
|
*
|
||||||
|
* FILE:
|
||||||
|
*
|
||||||
|
* physlayer.h [ the Data Communication I course programming project ]
|
||||||
|
*
|
||||||
|
* AUTHORS:
|
||||||
|
*
|
||||||
|
* Jonny Wiederholm
|
||||||
|
* E-mail: fr7wied@cse.hks.se or
|
||||||
|
* jonnwied@hks.se
|
||||||
|
*
|
||||||
|
* Per-Ola Gustafsson
|
||||||
|
* E-mail: fr7gust@cse.hks.se
|
||||||
|
*
|
||||||
|
* CREATION DATE:
|
||||||
|
*
|
||||||
|
* Jan, 08, 1998
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* Includes constants used in the implementation of the Physical Layer, which
|
||||||
|
* is part of the example implementation of the Data Communication I course
|
||||||
|
* programming project.
|
||||||
|
*
|
||||||
|
* MODIFICATIONS: Date Changes
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PHYSLAYER_H /* Avoid multiple copies of this file. */
|
||||||
|
#define _PHYSLAYER_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus /* Make this file possible to use in C++ code. */
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE FILES
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "systems.h"
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DEFINE CONSTANTS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Byte length. */
|
||||||
|
#define BYTE_LEN 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
Primitives (signals) not visible to the service user. The service user will
|
||||||
|
only be able to access these primitives via function calls.
|
||||||
|
*/
|
||||||
|
#define F_CONNECT_REQUEST 100
|
||||||
|
#define F_CONNECT_RESPONSE 104
|
||||||
|
#define F_DISCONNECT_REQUEST 108
|
||||||
|
#define F_DISCONNECT_RESPONSE 112
|
||||||
|
#define F_DATA_REQUEST 116
|
||||||
|
#define F_ABORT_REQUEST 188
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* END
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _PHYSLAYER_H */
|
||||||
48
signal_prim.h
Normal file
48
signal_prim.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#ifndef ___SIGNAL_PRIM___
|
||||||
|
#define ___SIGNAL_PRIM___
|
||||||
|
|
||||||
|
#define L_Con_Req 401
|
||||||
|
#define L_Con_Ind 402
|
||||||
|
#define L_Con_Resp 403
|
||||||
|
#define L_Con_Conf 404
|
||||||
|
#define L_Data_Req 405
|
||||||
|
#define L_Data_Ind 406
|
||||||
|
#define L_Disc_Req 407
|
||||||
|
#define L_Disc_Resp 408
|
||||||
|
#define L_Disc_Ind 409
|
||||||
|
#define L_Disc_Conf 410
|
||||||
|
#define L_Abort_Req 411
|
||||||
|
#define L_Abort_Ind 412
|
||||||
|
#define L_Status 413
|
||||||
|
|
||||||
|
#define AF_Con_Req 201
|
||||||
|
#define AF_Con_Ind 202
|
||||||
|
#define AF_Con_Resp 203
|
||||||
|
#define AF_Con_Conf 204
|
||||||
|
#define AF_Data_Req 205
|
||||||
|
#define AF_Data_Ind 206
|
||||||
|
#define AF_Disc_Req 207
|
||||||
|
#define AF_Disc_Ind 208
|
||||||
|
#define AF_Disc_Resp 209
|
||||||
|
#define AF_Disc_Conf 210
|
||||||
|
#define AF_Rej_Req 211
|
||||||
|
#define AF_Rej_Ind 212
|
||||||
|
#define AF_Rej_Resp 213
|
||||||
|
#define AF_Rej_Conf 214
|
||||||
|
#define AF_Abort_Req 215
|
||||||
|
#define AF_Abort_Ind 216
|
||||||
|
|
||||||
|
#define AI_Con_Req 301
|
||||||
|
#define AI_Con_Ind 302
|
||||||
|
#define AI_Con_Resp 303
|
||||||
|
#define AI_Con_Conf 304
|
||||||
|
#define AI_Data_Req 305
|
||||||
|
#define AI_Data_Ind 306
|
||||||
|
#define AI_Disc_Req 307
|
||||||
|
#define AI_Disc_Ind 308
|
||||||
|
#define AI_Disc_Resp 309
|
||||||
|
#define AI_Disc_Conf 310
|
||||||
|
#define AI_Abort_Req 311
|
||||||
|
#define AI_Abort_Ind 312
|
||||||
|
|
||||||
|
#endif
|
||||||
94
socketio.h
Normal file
94
socketio.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* (c) Copyright 1998, University of Karlstad.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* Please report any bugs you find in this code or any improvements to:
|
||||||
|
*
|
||||||
|
* Hans Hedbom, Dept. of Computer Science,
|
||||||
|
* University of Karlstad, Sweden.
|
||||||
|
*
|
||||||
|
* Phone: +46 54 838157
|
||||||
|
* E-mail: Hans.Hedbom@hks.se
|
||||||
|
*
|
||||||
|
* ============================================================================
|
||||||
|
*
|
||||||
|
* FILE:
|
||||||
|
*
|
||||||
|
* socketio.h [ the Data Communication I course programming project ]
|
||||||
|
*
|
||||||
|
* AUTHORS:
|
||||||
|
*
|
||||||
|
* Jonny Wiederholm
|
||||||
|
* E-mail: fr7wied@cse.hks.se or
|
||||||
|
* jonnwied@hks.se
|
||||||
|
*
|
||||||
|
* Per-Ola Gustafsson
|
||||||
|
* E-mail: fr7gust@cse.hks.se
|
||||||
|
*
|
||||||
|
* CREATION DATE:
|
||||||
|
*
|
||||||
|
* Jan, 05, 1998
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* Includes declarations of functions needed to handle input and output to
|
||||||
|
* sockets in the example implementation of the Data Communication I course
|
||||||
|
* programming project.
|
||||||
|
*
|
||||||
|
* MODIFICATIONS: Date Changes
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SOCKETIO_H /* Avoid multiple copies of this file. */
|
||||||
|
#define _SOCKETIO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus /* Make this file possible to use in C++ code. */
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE FILES
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "systems.h"
|
||||||
|
#include "udefs.h"
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DECLARE FUNCTIONS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* See function definitions for documentation. */
|
||||||
|
|
||||||
|
extern int WriteSignaltoSocket __P((int sockfd, u_int_ signal, \
|
||||||
|
size_t_ siglen));
|
||||||
|
extern int ReadSignalfromSocket __P((int sockfd, size_t_ siglen));
|
||||||
|
extern int WriteDatatoSocket __P((int sockfd, c_buf_ptr_ databuf, \
|
||||||
|
size_t_ datalen));
|
||||||
|
extern int ReadDatafromSocket __P((int sockfd, buf_ptr_ databuf, \
|
||||||
|
size_t_ datalen));
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* END
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _SOCKETIO_H */
|
||||||
132
sockets.h
Normal file
132
sockets.h
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* (c) Copyright 1998, University of Karlstad.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* Please report any bugs you find in this code or any improvements to:
|
||||||
|
*
|
||||||
|
* Hans Hedbom, Dept. of Computer Science,
|
||||||
|
* University of Karlstad, Sweden.
|
||||||
|
*
|
||||||
|
* Phone: +46 54 838157
|
||||||
|
* E-mail: Hans.Hedbom@hks.se
|
||||||
|
*
|
||||||
|
* ============================================================================
|
||||||
|
*
|
||||||
|
* FILE:
|
||||||
|
*
|
||||||
|
* sockets.h [ the Data Communication I course programming project ]
|
||||||
|
*
|
||||||
|
* AUTHORS:
|
||||||
|
*
|
||||||
|
* Jonny Wiederholm
|
||||||
|
* E-mail: fr7wied@cse.hks.se or
|
||||||
|
* jonnwied@hks.se
|
||||||
|
*
|
||||||
|
* Per-Ola Gustafsson
|
||||||
|
* E-mail: fr7gust@cse.hks.se
|
||||||
|
*
|
||||||
|
* CREATION DATE:
|
||||||
|
*
|
||||||
|
* Jan, 06, 1998
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* Includes constants, types and declarations of functions needed to create
|
||||||
|
* and connect sockets in the example implementation of the Data Communication
|
||||||
|
* I course programming project.
|
||||||
|
*
|
||||||
|
* MODIFICATIONS: Date Changes
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SOCKETS_H /* Avoid multiple copies of this file. */
|
||||||
|
#define _SOCKETS_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus /* Make this file possible to use in C++ code. */
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE FILES
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "systems.h"
|
||||||
|
#include "udefs.h"
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DEFINE CONSTANTS
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined (_AIX) || defined (__linux__)
|
||||||
|
|
||||||
|
/* Communication semantics. */
|
||||||
|
#define SOCK_STREAM 1 /* Stream socket. */
|
||||||
|
|
||||||
|
#elif defined (sun)
|
||||||
|
|
||||||
|
#define SOCK_STREAM 2
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Communication domains. */
|
||||||
|
#define AF_UNIX 1 /* Local to host (pipes, portals). */
|
||||||
|
#define AF_INET 2 /* Internetwork: UDP, TCP, etc. */
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DEFINE TYPES
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined (__linux__) || defined (sun)
|
||||||
|
|
||||||
|
/* Structure used by kernel to store most addresses. */
|
||||||
|
struct sockaddr {
|
||||||
|
unsigned short int sa_family; /* Address family AF_xxx. */
|
||||||
|
char sa_data[14]; /* 14 bytes of protocol address. */
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif defined (_AIX)
|
||||||
|
|
||||||
|
struct sockaddr {
|
||||||
|
unsigned char sa_len; /* Total length. */
|
||||||
|
unsigned char sa_family; /* Address family AF_xxx. */
|
||||||
|
char sa_data[14]; /* 14 bytes of protocol address. */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* defined (__linux__) || defined (sun) */
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* DECLARE FUNCTIONS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* See function definitions for documentation. */
|
||||||
|
|
||||||
|
extern int CreateSocket __P((int domain, int type, int protocol));
|
||||||
|
extern int BindSocket __P((int sockfd, struct sockaddr *name, int namelen));
|
||||||
|
extern int ConnectSocket __P((int sockfd, struct sockaddr *name, int namelen));
|
||||||
|
extern int ListenforConnection __P((int sockfd, int limit));
|
||||||
|
extern int AcceptConnection __P((int sockfd));
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* END
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _SOCKETS_H */
|
||||||
12
state.h
Normal file
12
state.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef _state_h_
|
||||||
|
#define _state_h_
|
||||||
|
|
||||||
|
#define IDLE 0
|
||||||
|
#define UUUK 1
|
||||||
|
#define DATA 2
|
||||||
|
#define UUNK 3
|
||||||
|
#define UINK 4
|
||||||
|
#define UIUK 5
|
||||||
|
#define TERR 6
|
||||||
|
|
||||||
|
#endif
|
||||||
145
student.h
Normal file
145
student.h
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* (c) Copyright 1998, University of Karlstad.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* Please report any bugs you find in this code or any improvements to:
|
||||||
|
*
|
||||||
|
* Hans Hedbom, Dept. of Computer Science,
|
||||||
|
* University of Karlstad, Sweden.
|
||||||
|
*
|
||||||
|
* Phone: +46 54 838157
|
||||||
|
* E-mail: Hans.Hedbom@hks.se
|
||||||
|
*
|
||||||
|
* ============================================================================
|
||||||
|
*
|
||||||
|
* FILE:
|
||||||
|
*
|
||||||
|
* student.h [ the Data Communication I course programming project ]
|
||||||
|
*
|
||||||
|
* AUTHORS:
|
||||||
|
*
|
||||||
|
* Jonny Wiederholm
|
||||||
|
* E-mail: fr7wied@cse.hks.se or
|
||||||
|
* jonnwied@hks.se
|
||||||
|
*
|
||||||
|
* Per-Ola Gustafsson
|
||||||
|
* E-mail: fr7gust@cse.hks.se
|
||||||
|
*
|
||||||
|
* CREATION DATE:
|
||||||
|
*
|
||||||
|
* Jan, 08, 1998
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* Includes header files, declaring the functions that are available
|
||||||
|
* and can be used in the Data Communication I course programming project.
|
||||||
|
*
|
||||||
|
* NOTE:
|
||||||
|
*
|
||||||
|
* If any system header files needs to be included in the same module as this
|
||||||
|
* file is included, make sure they are included before this file or otherwise
|
||||||
|
* it might not be possible to compile due to type redeclaration errors.
|
||||||
|
*
|
||||||
|
* MODIFICATIONS: Date Changes
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* 1998-03-16 Added the function FindAction.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _STUDENT_H /* Avoid multiple copies of this file. */
|
||||||
|
#define _STUDENT_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus /* Make this file possible to include in C++ code. */
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE FILES
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "systems.h"
|
||||||
|
#include "udefs.h"
|
||||||
|
#include "sockets.h"
|
||||||
|
#include "socketio.h"
|
||||||
|
#include "unixsockets.h"
|
||||||
|
#include "uselect.h"
|
||||||
|
#include "utimer.h"
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* sockets.h:
|
||||||
|
*
|
||||||
|
* int AcceptConnection(int sockfd)
|
||||||
|
*
|
||||||
|
* socketio.h:
|
||||||
|
*
|
||||||
|
* int WriteSignaltoSocket(int sockfd, unsigned int signal, \
|
||||||
|
* unsigned int siglen)
|
||||||
|
* int ReadSignalfromSocket(int sockfd, unsigned int siglen)
|
||||||
|
* int WriteDatatoSocket(int sockfd, char* databuf, unsigned int datalen)
|
||||||
|
* int ReadDatafromSocket(int sockfd, char* databuf, unsigned int datalen)
|
||||||
|
*
|
||||||
|
* unixsockets.h:
|
||||||
|
*
|
||||||
|
* int CreateUnixClientSocket(char *path)
|
||||||
|
* int CreateUnixServerSocket(char *path)
|
||||||
|
*
|
||||||
|
* uselect.h:
|
||||||
|
*
|
||||||
|
* struct timeval *SetPollTimeout(int seconds, int microseconds)
|
||||||
|
* int PollSocket(int sockfd1, int sockfd2, struct timeval *tv)
|
||||||
|
*
|
||||||
|
* utimer.h:
|
||||||
|
*
|
||||||
|
* void SetTimer(unsigned int seconds)
|
||||||
|
* void ResetTimer(void)
|
||||||
|
* int SetTimeoutHandler(void (*handler)(int))
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DEFINE TYPES
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Pointer to a function that takes nothing and returns an int. */
|
||||||
|
typedef int (*psf) __P((void));
|
||||||
|
|
||||||
|
/* Struct defining the relationship between a signal and a function. */
|
||||||
|
typedef struct action{
|
||||||
|
int signal;
|
||||||
|
psf function;
|
||||||
|
} action;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DECLARE FUNCTIONS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* See function definitions for documentation. */
|
||||||
|
|
||||||
|
extern psf FindAction __P((int signal, const__ action *list));
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* END
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _STUDENT_H */
|
||||||
|
|
||||||
91
systems.h
Normal file
91
systems.h
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* (c) Copyright 1998, University of Karlstad.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* Please report any bugs you find in this code or any improvements to:
|
||||||
|
*
|
||||||
|
* Hans Hedbom, Dept. of Computer Science,
|
||||||
|
* University of Karlstad, Sweden.
|
||||||
|
*
|
||||||
|
* Phone: +46 54 838157
|
||||||
|
* E-mail: Hans.Hedbom@hks.se
|
||||||
|
*
|
||||||
|
* ============================================================================
|
||||||
|
*
|
||||||
|
* FILE:
|
||||||
|
*
|
||||||
|
* systems.h [ the Data Communication I course programming project ]
|
||||||
|
*
|
||||||
|
* AUTHORS:
|
||||||
|
*
|
||||||
|
* Jonny Wiederholm
|
||||||
|
* E-mail: fr7wied@cse.hks.se or
|
||||||
|
* jonnwied@hks.se
|
||||||
|
*
|
||||||
|
* Per-Ola Gustafsson
|
||||||
|
* E-mail: fr7gust@cse.hks.se
|
||||||
|
*
|
||||||
|
* CREATION DATE:
|
||||||
|
*
|
||||||
|
* Jan, 06, 1998
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* Specifies the systems on which the example implementation of the Data
|
||||||
|
* Communication I course programming project has been verified to run
|
||||||
|
* correctly. Attempts to compile the example implementation on a system not
|
||||||
|
* specified in this file will cause an error message to be printed and the
|
||||||
|
* compilation to be aborted.
|
||||||
|
*
|
||||||
|
* Systems on which the example implementation has been verified to run
|
||||||
|
* correctly:
|
||||||
|
* Linux
|
||||||
|
* AIX
|
||||||
|
* SunOS Solaris
|
||||||
|
*
|
||||||
|
* MODIFICATIONS: Date Changes
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SYSTEMS_H /* Avoid multiple copies of this file. */
|
||||||
|
#define _SYSTEMS_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus /* Make this file possible to use in C++ code. */
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DEFINE CONSTANTS
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if ! defined (__linux__) && ! defined (_AIX) && ! defined(sun)
|
||||||
|
|
||||||
|
#error"Sorry, but this program has not been verified to run correctly on your \
|
||||||
|
system."
|
||||||
|
|
||||||
|
#endif /* ! defined (__linux__) && ! defined (_AIX) ... */
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* END
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _SYSTEMS_H */
|
||||||
236
udefs.h
Normal file
236
udefs.h
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* (c) Copyright 1998, University of Karlstad.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* Please report any bugs you find in this code or any improvements to:
|
||||||
|
*
|
||||||
|
* Hans Hedbom, Dept. of Computer Science,
|
||||||
|
* University of Karlstad, Sweden.
|
||||||
|
*
|
||||||
|
* Phone: +46 54 838157
|
||||||
|
* E-mail: Hans.Hedbom@hks.se
|
||||||
|
*
|
||||||
|
* ============================================================================
|
||||||
|
*
|
||||||
|
* FILE:
|
||||||
|
*
|
||||||
|
* udefs.h [ the Data Communication I course programming project ]
|
||||||
|
*
|
||||||
|
* AUTHORS:
|
||||||
|
*
|
||||||
|
* Jonny Wiederholm
|
||||||
|
* E-mail: fr7wied@cse.hks.se
|
||||||
|
*
|
||||||
|
* Per-Ola Gustafsson
|
||||||
|
* E-mail: fr7gust@cse.hks.se
|
||||||
|
*
|
||||||
|
* CREATION DATE:
|
||||||
|
*
|
||||||
|
* Jan, 06, 1998
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* Includes constants used in the example implementation of the Data
|
||||||
|
* Communication I course programming project.
|
||||||
|
*
|
||||||
|
* MODIFICATIONS: Date Changes
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _UDEFS_H /* Avoid multiple copies of this file. */
|
||||||
|
#define _UDEFS_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus /* Make this file possible to use in C++ code. */
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE FILES
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "systems.h"
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DEFINE CONSTANTS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Null pointer value. */
|
||||||
|
#ifndef NULL /* Avoid type redeclaration. */
|
||||||
|
#if !defined( __cplusplus) && !defined (sun)
|
||||||
|
|
||||||
|
#define NULL ((void *) 0)
|
||||||
|
|
||||||
|
#else /* !defined( __cplusplus) && !defined (sun) */
|
||||||
|
|
||||||
|
#define NULL 0 /* C++ definition of NULL. */
|
||||||
|
|
||||||
|
#endif /* ifndef __cplusplus */
|
||||||
|
#endif /* ifndef NULL */
|
||||||
|
|
||||||
|
/* Normal exit value. */
|
||||||
|
#define NORMAL_EXIT 1
|
||||||
|
|
||||||
|
/* Non normal exit value. */
|
||||||
|
#define NON_NORMAL_EXIT -1
|
||||||
|
|
||||||
|
/* End of string. */
|
||||||
|
#define EOS '\0'
|
||||||
|
|
||||||
|
/* Value returned on the occurence of a system failure. */
|
||||||
|
#ifndef SYSTEM_FAILURE /* Avoid type redeclaration. */
|
||||||
|
#define SYSTEM_FAILURE (-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Value returned on a successful operation. */
|
||||||
|
#ifndef SUCCESS /* Avoid type redeclaration. */
|
||||||
|
#define SUCCESS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Allow ANSI C keywords if ANSI C or C++. */
|
||||||
|
#if defined (__STDC__) || defined (__cplusplus)
|
||||||
|
|
||||||
|
#define const__ const
|
||||||
|
#define volatile__ volatile
|
||||||
|
/* Pointer to void is defined as pointer to char on non ANSI C systems. */
|
||||||
|
#define void_ptr_ void *
|
||||||
|
|
||||||
|
#else /* defined (__STDC__) || defined (__cplusplus) */
|
||||||
|
|
||||||
|
#define const__ /* No ANSI C keywords. */
|
||||||
|
#define volatile__
|
||||||
|
#define void_ptr_ char *
|
||||||
|
|
||||||
|
#endif /* defined (__STDC__) || defined (__cplusplus) */
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DEFINE TYPES
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
`c_buf_ptr_' is used by functions which take a pointer to a character
|
||||||
|
buffer as parameter and does not change the contents of the buffer.
|
||||||
|
*/
|
||||||
|
#ifndef C_BUF_PTR_ /* Avoid type redeclaration. */
|
||||||
|
#define C_BUF_PTR_
|
||||||
|
#if defined (__linux__)
|
||||||
|
|
||||||
|
typedef const__ char * c_buf_ptr_;
|
||||||
|
|
||||||
|
#else /* defined (__linux__) */
|
||||||
|
|
||||||
|
typedef char * c_buf_ptr_;
|
||||||
|
|
||||||
|
#endif /* defined (__linux__) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
`buf_ptr' is used by functions which take a pointer to a character
|
||||||
|
buffer and does change the value of the buffer.
|
||||||
|
*/
|
||||||
|
#ifndef BUF_PTR_ /* Avoid type redeclaration. */
|
||||||
|
#define BUF_PTR_
|
||||||
|
typedef char * buf_ptr_;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
`string_ptr_' is used by functions which take a pointer to a character
|
||||||
|
string as parameter and does not change the contents of the string.
|
||||||
|
*/
|
||||||
|
#ifndef STRING_PTR_ /* Avoid type redeclaration. */
|
||||||
|
#define STRING_PTR_
|
||||||
|
typedef c_buf_ptr_ string_ptr_;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
`byte_ptr_' is used by functions which takes a pointer to a character-buffer
|
||||||
|
which only needs to store one character, or byte.
|
||||||
|
*/
|
||||||
|
#ifndef BYTE_PTR_
|
||||||
|
#define BYTE_PTR_
|
||||||
|
typedef char * byte_ptr_;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* `size_t_' is used as a length parameter for string functions. */
|
||||||
|
#ifndef SIZE_T_ /* Avoid type redeclaration. */
|
||||||
|
#define SIZE_T_
|
||||||
|
typedef unsigned int size_t_;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
`ssize_t_' is used by functions which return a count of bytes or an error
|
||||||
|
indication.
|
||||||
|
*/
|
||||||
|
#ifndef SSIZE_T_ /* Avoid type redeclaration. */
|
||||||
|
#define SSIZE_T_
|
||||||
|
typedef signed int ssize_t_;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
`u_int_' is used by functions which take or return an unsigned int that
|
||||||
|
is not indicating a length.
|
||||||
|
*/
|
||||||
|
#ifndef U_INT_ /* Avoid type redeclaration. */
|
||||||
|
#define U_INT_
|
||||||
|
typedef unsigned int u_int_;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
`ul_int_' is used by functions which take or return an unsigned long int
|
||||||
|
that is not indicating a length.
|
||||||
|
*/
|
||||||
|
#ifndef UL_INT_ /* Avoid type redeclaration. */
|
||||||
|
#define UL_INT_
|
||||||
|
typedef unsigned long int ul_int_;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DEFINE MACROS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Allow function prototypes. */
|
||||||
|
#if defined (__STDC__) || defined (__cplusplus)
|
||||||
|
|
||||||
|
#ifndef __P /* Avoid type redeclaration. */
|
||||||
|
#define __P(args) args
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* defined (__STDC__) || defined (__cplusplus) */
|
||||||
|
|
||||||
|
#ifndef __P /* Avoid type redeclaration. */
|
||||||
|
#define __P(args) () /* No prototypes. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* defined (__STDC__) || defined (__cplusplus) */
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* END
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _UDEFS_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
90
unixsockets.h
Normal file
90
unixsockets.h
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* (c) Copyright 1998, University of Karlstad.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* Please report any bugs you find in this code or any improvements to:
|
||||||
|
*
|
||||||
|
* Hans Hedbom, Dept. of Computer Science,
|
||||||
|
* University of Karlstad, Sweden.
|
||||||
|
*
|
||||||
|
* Phone: +46 54 838157
|
||||||
|
* E-mail: Hans.Hedbom@hks.se
|
||||||
|
*
|
||||||
|
* ============================================================================
|
||||||
|
*
|
||||||
|
* FILE:
|
||||||
|
*
|
||||||
|
* unixsockets.h [ the Data Communication I course programming project ]
|
||||||
|
*
|
||||||
|
* AUTHORS:
|
||||||
|
*
|
||||||
|
* Jonny Wiederholm
|
||||||
|
* E-mail: fr7wied@cse.hks.se or
|
||||||
|
* jonnwied@hks.se
|
||||||
|
*
|
||||||
|
* Per-Ola Gustafsson
|
||||||
|
* E-mail: fr7gust@cse.hks.se
|
||||||
|
*
|
||||||
|
* CREATION DATE:
|
||||||
|
*
|
||||||
|
* Jan, 06, 1998
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* Includes declarations of functions needed to create server/client sockets in
|
||||||
|
* the AF_UNIX domain in the example implementation of the Data Communication I
|
||||||
|
* course programming project.
|
||||||
|
*
|
||||||
|
* MODIFICATIONS: Date Changes
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _UNIXSOCKETS_H /* Avoid multiple copies of this file. */
|
||||||
|
#define _UNIXSOCKETS_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus /* Make this file possible to use in C++ code. */
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE FILES
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "systems.h"
|
||||||
|
#include "udefs.h"
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DECLARE FUNCTIONS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* See function definitions for documentation. */
|
||||||
|
|
||||||
|
extern int CreateUnixClientSocket __P((string_ptr_ path));
|
||||||
|
extern int CreateUnixServerSocket __P((string_ptr_ path));
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* END
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _UNIXSOCKETS_H */
|
||||||
|
|
||||||
|
|
||||||
103
uselect.h
Normal file
103
uselect.h
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* Please report any bugs you find in this code or any improvements to:
|
||||||
|
*
|
||||||
|
* Hans Hedbom, Dept. of Computer Science,
|
||||||
|
* University of Karlstad, Sweden.
|
||||||
|
*
|
||||||
|
* Phone: +46 54 838157
|
||||||
|
* E-mail: Hans.Hedbom@hks.se
|
||||||
|
*
|
||||||
|
* ============================================================================
|
||||||
|
*
|
||||||
|
* FILE:
|
||||||
|
*
|
||||||
|
* uselect.h [ the Data Communication I course programming project ]
|
||||||
|
*
|
||||||
|
* AUTHORS:
|
||||||
|
*
|
||||||
|
* Jonny Wiederholm
|
||||||
|
* E-mail: fr7wied@cse.hks.se or
|
||||||
|
* jonnwied@hks.se
|
||||||
|
*
|
||||||
|
* Per-Ola Gustafsson
|
||||||
|
* E-mail: fr7gust@cse.hks.se
|
||||||
|
*
|
||||||
|
* CREATION DATE:
|
||||||
|
*
|
||||||
|
* Jan, 06, 1998
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* Includes types and declarations of functions needed to poll sockets in the
|
||||||
|
* example implementation of the Data Communication I course programming
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* MODIFICATIONS: Date Changes
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _USELECT_H /* Avoid multiple copies of this file. */
|
||||||
|
#define _USELECT_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus /* Make this file possible to use in C++ code. */
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE FILES
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "systems.h"
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DEFINE TYPES
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type representing part of a time peroid. */
|
||||||
|
#if defined (__linux__) || defined (_AIX)
|
||||||
|
typedef int time_p_;
|
||||||
|
#elif defined(sun)
|
||||||
|
typedef long time_p_;
|
||||||
|
#endif /* defined (__linux__) || defined (_AIX) */
|
||||||
|
|
||||||
|
/* Structure representing a timeout time period. */
|
||||||
|
struct timeout {
|
||||||
|
time_p_ tv_sec; /* Seconds. */
|
||||||
|
time_p_ tv_usec; /* Microseconds. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DECLARE FUNCTIONS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* See function definitions for documentation. */
|
||||||
|
|
||||||
|
extern struct timeout *SetPollTimeout __P((time_p_ seconds, time_p_ \
|
||||||
|
microseconds));
|
||||||
|
extern int PollSocket __P((int sockfd1, int sockfd2, struct timeout *to));
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* END
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _USELECT_H */
|
||||||
88
utimer.h
Normal file
88
utimer.h
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* (c) Copyright 1998, University of Karlstad.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* Please report any bugs you find in this code or any improvements to:
|
||||||
|
*
|
||||||
|
* Hans Hedbom, Dept. of Computer Science,
|
||||||
|
* University of Karlstad, Sweden.
|
||||||
|
*
|
||||||
|
* Phone: +46 54 838157
|
||||||
|
* E-mail: Hans.Hedbom@hks.se
|
||||||
|
*
|
||||||
|
* ============================================================================
|
||||||
|
*
|
||||||
|
* FILE:
|
||||||
|
*
|
||||||
|
* utimer.h [ the Data Communication I course programming project ]
|
||||||
|
*
|
||||||
|
* AUTHORS:
|
||||||
|
*
|
||||||
|
* Jonny Wiederholm
|
||||||
|
* E-mail: fr7wied@cse.hks.se or
|
||||||
|
* jonnwied@hks.se
|
||||||
|
*
|
||||||
|
* Per-Ola Gustafsson
|
||||||
|
* E-mail: fr7gust@cse.hks.se
|
||||||
|
*
|
||||||
|
* CREATION DATE:
|
||||||
|
*
|
||||||
|
* Jan, 06, 1998
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* Includes declarations of functions needed to simulate a timer in the example
|
||||||
|
* implementation of the Data Communication I course programming project.
|
||||||
|
*
|
||||||
|
* MODIFICATIONS: Date Changes
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _UTIMER_H /* Avoid multiple copies of this file. */
|
||||||
|
#define _UTIMER_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus /* Make this file possible to use in C++ code. */
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE FILES
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "systems.h"
|
||||||
|
#include "udefs.h"
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DECLARE FUNCTIONS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* See function definitions for documentation. */
|
||||||
|
|
||||||
|
extern void SetTimer __P((u_int_ seconds));
|
||||||
|
extern void ResetTimer __P((void));
|
||||||
|
extern int SetTimeoutHandler __P((void (*handler) __P((int))));
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* END
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _UTIMER_H */
|
||||||
Reference in New Issue
Block a user