struct event {
 float evtime; /\* event time \*/
 int evtype; /\* event type code \*/
 int eventity; /\* entity where event occurs \*/
 struct pkt \*pktptr; /\* ptr to packet (if any) assoc w/ this event \*/
 struct event \*prev;
 struct event \*next;
};
struct event \*evlist = NULL; /\* the event list \*/
void insertevent(struct event \*);
/\* possible events: \*/
#define TIMER\_INTERRUPT 0
#define FROM\_LAYER5 1
#define FROM\_LAYER3 2

#define OFF 0
#define ON 1
#define A 0
#define B 1
int TRACE = -1; /\* for my debugging \*/
int nsim = 0; /\* number of messages from 5 to 4 so far \*/
int nsimmax = 0; /\* number of msgs to generate, then stop \*/
float time = 0.000;
float lossprob; /\* probability that a packet is dropped \*/
float corruptprob; /\* probability that one bit is packet is flipped \*/
float lambda; /\* arrival rate of messages from layer 5 \*/
int ntolayer3; /\* number sent into layer 3 \*/
int nlost; /\* number lost in media \*/
int ncorrupt; /\* number corrupted by media\*/

char pattern[40]; /\*channel pattern string\*/
int npttns = 0;
int cp = -1; /\*current pattern\*/
char pttnchars[3] = {'o', '-', 'x'};
enum pttns {
 OK = 0, CORRUPT, LOST
};
int main(void) {
 struct event \*eventptr;
 struct msg msg2give;
 struct pkt pkt2give;

 int i, j;
 init();
 A\_init();
 B\_init();

 while (1) {
 eventptr = evlist; /\* get next event to simulate \*/
 if (eventptr == NULL)
 goto terminate;

 evlist = evlist->next; /\* remove this event from event list \*/
 if (evlist != NULL)
 evlist->prev = NULL;

 if (TRACE >= 2) {
 printf("\nEVENT time: %f,", eventptr->evtime);
 printf(" type: %d", eventptr->evtype);
 if (eventptr->evtype == 0)
 printf(", timerinterrupt ");
 else if (eventptr->evtype == 1)
 printf(", fromlayer5 ");
 else
 printf(", fromlayer3 ");
 printf(" entity: %d\n", eventptr->eventity);
 }
 time = eventptr->evtime; /\* update time to next event time \*/

 if (eventptr->evtype == FROM\_LAYER5) {
 generate\_next\_arrival(); /\* set up future arrival \*/

 /\* fill in msg to give with string of same letter \*/
 j = nsim % 26;
 for (i = 0; i < 20; i++)
 msg2give.data[i] = 97 + j;

 if (TRACE > 2) {
 printf(" MAINLOOP: data given to student: ");
 for (i = 0; i < 20; i++)
 printf("%c", msg2give.data[i]);
 printf("\n");
 }
 if (eventptr->eventity == A)
 A\_output(msg2give);
 else {}

 } else if (eventptr->evtype == FROM\_LAYER3) {
 pkt2give.seqnum = eventptr->pktptr->seqnum;
 pkt2give.acknum = eventptr->pktptr->acknum;
 pkt2give.checksum = eventptr->pktptr->checksum;
 for (i = 0; i < 20; i++)
 pkt2give.payload[i] = eventptr->pktptr->payload[i];

 if (eventptr->eventity == A) /\* deliver packet by calling \*/
 A\_input(pkt2give); /\* appropriate entity \*/
 else
 B\_input(pkt2give);

 free(eventptr->pktptr); /\* free the memory for packet \*/
 } else if (eventptr->evtype == TIMER\_INTERRUPT) {
 if (eventptr->eventity == A)
 A\_timerinterrupt();
 else {}
 } else {
 printf("INTERNAL PANIC: unknown event type \n");
 }
 free(eventptr);
 }

 terminate:
 printf("Simulator terminated.\n", nsim);
 print\_info();
}
void init() /\* initialize the simulator \*/
{
 
 float jimsrand();
 printf("Enter the number of messages to simulate: \n");
 scanf("%d", &nsimmax);
 printf("Enter time between messages from sender's layer5 [ > 0.0]:\n");
 scanf("%f", λ);
 printf("Enter channel pattern string\n");
 scanf("%s", pattern);
 npttns = strlen(pattern);
 printf("Enter sender's window size\n");
 scanf("%d", &WINDOWSIZE);

 winbuf = (struct pkt \*) malloc(sizeof(struct pkt) \* WINDOWSIZE);

 ntolayer3 = 0;
 nlost = 0;
 ncorrupt = 0;

 time = 0.0; /\* initialize time to 0.0 \*/
 generate\_next\_arrival(); /\* initialize event list \*/

 printf("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n");
 printf(" Packet Transmission Log \n");
 printf("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n");
}
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* EVENT HANDLINE ROUTINES \*\*\*\*\*\*\*/
/\* The next set of routines handle the event list \*/
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/

void generate\_next\_arrival() {
 double x, log(), ceil();
 struct event \*evptr;
 //char \*malloc();

 if (nsim >= nsimmax) return;

 if (TRACE > 2)
 printf(" GENERATE NEXT ARRIVAL: creating new arrival\n");

 x = lambda;

 evptr = (struct event \*) malloc(sizeof(struct event));
 evptr->evtime = time + x;
 evptr->evtype = FROM\_LAYER5;
 if (BIDIRECTIONAL)
 evptr->eventity = B;
 else
 evptr->eventity = A;
 insertevent(evptr);
 nsim++;
}
void insertevent(p)
 struct event \*p;
{
 struct event \*q, \*qold;

 if (TRACE > 2) {
 printf(" INSERTEVENT: time is %lf\n", time);
 printf(" INSERTEVENT: future time will be %lf\n", p->evtime);
 }
 q = evlist; /\* q points to front of list in which p struct inserted \*/
 if (q == NULL) { /\* list is empty \*/
 evlist = p;
 p->next = NULL;
 p->prev = NULL;
 } else {
 for (qold = q; q != NULL && p->evtime >= q->evtime; q = q->next)
 qold = q;
 if (q == NULL) { /\* end of list \*/
 qold->next = p;
 p->prev = qold;
 p->next = NULL;
 } else if (q == evlist) { /\* front of list \*/
 p->next = evlist;
 p->prev = NULL;
 p->next->prev = p;
 evlist = p;
 } else { /\* middle of list \*/
 p->next = q;
 p->prev = q->prev;
 q->prev->next = p;
 q->prev = p;
 }
 }
}

void printevlist() {
 struct event \*q;

 printf("--------------\nEvent List Follows:\n");
 for (q = evlist; q != NULL; q = q->next) {
 printf("Event time: %f, type: %d entity: %d\n", q->evtime, q->evtype, q->eventity);
 }
 printf("--------------\n");
}
this is the part 4
구조체 이벤트 {
 float evtime; /\* 이벤트 시간 \*/
 int evtype; /\* 이벤트 유형 코드 \*/
 int eventity; /\* 이벤트가 발생한 엔티티 \*/
 struct pkt \*pktptr; /\* 이 이벤트와 연관된 (있는 경우) 패킷에 대한 ptr \*/
 struct event \*prev;
 구조체 이벤트 \*다음;
};
struct event \*evlist = NULL; /\* 이벤트 리스트 \*/
void insertevent(구조체 이벤트 \*);
/\* 가능한 이벤트: \*/
#define TIMER\_INTERRUPT 0
#define FROM\_LAYER5 1
#define FROM\_LAYER3 2

#define OFF 0
#define ON 1
#define A 0
#define B 1
int TRACE = -1; /\* 내 디버깅용 \*/
int nsim = 0; /\* 지금까지 5에서 4까지의 메시지 수 \*/
int nsimmax = 0; /\* 생성할 메시지 수, 이후 중지 \*/
float time = 0.000;
float lossprob; /\* 패킷이 삭제될 확률 \*/
float corruptprob; /\* 한 비트가 패킷이 뒤집힐 확률 \*/
float lambda; /\* 레이어 5에서 메시지의 도착률 \*/
int ntolayer3; /\* 레이어 3으로 전송된 번호 \*/
int nlost; /\* 미디어에서 손실된 번호 \*/
int ncorrupt; /\* 미디어에 의해 손상된 번호 \*/

char pattern[40]; /\*채널 패턴 문자열\*/
int npttns = 0;
int cp = -1; /\*현재 패턴\*/
char pttnchars[3] = {'o', '-', 'x'};
열거형 pttns {
 ok = 0, 손상, 손실
};
int main(void) {
 구조체 event \*eventptr;
 구조체 msg msg2give;
 구조체 PKT PKT2GIVE;

 int i, j;
 init();
 A\_init();
 B\_init();

 while (1) {
 eventptr = evlist; /\* 시뮬레이션할 다음 이벤트를 가져옵니다 \*/
 if (eventptr == NULL)
 종료합니다;

 evlist = evlist->next; /\* 이벤트 목록에서 이 이벤트를 제거 \*/
 if (evlist != NULL)
 evlist->prev = NULL;

 if (TRACE >= 2) {
 printf("\nEVENT 시간: %f,", eventptr->evtime);
 printf(" type: %d", eventptr->evtype);
 if (eventptr->evtype == 0)
 printf(", timerinterrupt ");
 else if (eventptr->evtype == 1)
 printf(", fromlayer5 ");
 else
 printf(", fromlayer3 ");
 printf(" 엔티티: %d\n", eventptr->eventity);
 }
 time = eventptr->evtime; /\* 다음 이벤트 시간으로 업데이트 시간 \*/

 if (eventptr->evtype == FROM\_LAYER5) {
 GENERATE\_NEXT\_ARRIVAL(); /\* 향후 도착 설정 \*/

 /\* 같은 문자의 문자열로 전달할 메시지 입력 \*/
 j = NSIM % 26;
 for (i = 0; i < 20; i++)
 msg2give.data[i] = 97 + j;

 if (TRACE > 2) {
 printf(" MAINLOOP: 학생에게 제공된 데이터: ");
 for (i = 0; i < 20; i++)
 printf("%c", msg2give.data[i]);
 printf("\n");
 }
 if (eventptr->eventity == A)
 A\_output(msg2give);
 else {}

 } else if (eventptr->evtype == FROM\_LAYER3) {}
 pkt2give.seqnum = eventptr->pktptr->seqnum;
 pkt2give.acknum = eventptr->pktptr->acknum;
 pkt2give.checksum = eventptr->pktptr->checksum;
 for (i = 0; i < 20; i++)
 pkt2give.payload[i] = eventptr->pktptr->payload[i];

 if (eventptr->eventity == A) /\* \*/를 호출하여 패킷을 전달합니다.
 A\_input(pkt2give); /\* 적절한 엔티티 \*/
 else
 B\_input(pkt2give);

 free(eventptr->pktptr); /\* 패킷을 위한 메모리 해제 \*/
 } else if (eventptr->evtype == TIMER\_INTERRUPT) {
 if (eventptr->eventity == A)
 A\_timerinterrupt();
 else {}
 } else {
 printf("INTERNAL PANIC: 알 수 없는 이벤트 유형 \n");
 }
 free(eventptr);
 }

 종료합니다:
 printf("시뮬레이터가 종료되었습니다.\n", nsim);
 print\_info();
}
void init() /\* 시뮬레이터 초기화 \*/
{
 
 float jimsrand();
 printf("시뮬레이션할 메시지 개수 입력: \n");
 scanf("%d", &nsimmax);
 printf("발신자 레이어5 [ > 0.0]에서 메시지 사이의 시간 입력:\n");
 scanf("%f", λ);
 printf("채널 패턴 문자열 입력\n");
 scanf("%s", pattern);
 npttns = strlen(패턴);
 printf("발신자의 창 크기 입력\n");
 scanf("%d", &WINDOWSIZE);

 winbuf = (구조체 pkt \*) malloc(sizeof(구조체 pkt) \* WINDOWSIZE);

 ntolayer3 = 0;
 nlost = 0;
 ncorrupt = 0;

 time = 0.0; /\* 시간을 0.0으로 초기화 \*/
 generate\_next\_arrival(); /\* 이벤트 리스트 초기화 \*/

 printf("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n");
 printf(" 패킷 전송 로그 \n");
 printf("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n");
}
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* 이벤트 핸드라인 루틴 \*\*\*\*\*\*\*\*\*\*/
/\* 다음 루틴 세트는 이벤트 목록을 처리합니다 \*/.
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/

void generate\_next\_arrival() {
 double x, log(), ceil();
 struct event \*evptr;
 //char \*malloc();

 if (nsim >= nsimmax) return;

 if (TRACE > 2)
 printf(" 다음 도착 생성: 새 도착 생성\n");

 x = 람다;

 evptr = (구조체 이벤트 \*) malloc(sizeof(구조체 이벤트));
 evptr->evtime = 시간 + x;
 evptr->evtype = FROM\_LAYER5;
 if (BIDIRECTIONAL)
 evptr->eventity = B;
 else
 evptr->eventity = A;
 INSERTEENT(EVPTR);
 nsim++;
}
void insertevent(p)
 구조체 이벤트 \*p;
{
 구조체 event \*q, \*qold;

 if (TRACE > 2) {
 printf(" INSERTEVENT: 시간은 %lf\입니다.