From e34b3151c45e0a767d667dccc6725cdecb04c424 Mon Sep 17 00:00:00 2001 From: Vlad Badoiu <vlad_andrei.badoiu@upb.ro> Date: Sun, 19 Feb 2023 22:28:29 +0200 Subject: [PATCH] lab2: Update skeleton to match text --- lab2/README.md | 26 +++++++++++++++++++------- lab2/common.h | 10 ++++++++++ lab2/recv.c | 32 ++++++++++++++++++++++++-------- lab2/send.c | 36 ++++++++++++++++++++++++++++-------- 4 files changed, 81 insertions(+), 23 deletions(-) diff --git a/lab2/README.md b/lab2/README.md index 8644dd8..496fd77 100644 --- a/lab2/README.md +++ b/lab2/README.md @@ -1,20 +1,29 @@ -Physical layer simulator. +Physical layer simulator. We have **two separate programs**, the sender and the receiver. + +Normally, we would implement our protocol as a library, but to make things +easier, we implement part of the protocol in send.c, and the receving code in +recv.c. ``send.c`` - the code that the sender will execute ``recv.c`` - the code that the receiver on the other end of the wire will execute -``common.h`` - header where we define the `Frame` structure +``common.h`` - header where we define the `Frame` structure and the API that the physical layers exports Overview of the architecture ``` -sender receiver - | | - |______________________| - Physical (wire) + sender receiver + | | + Physical layer Physical layer + protocol protocol + |______________________| + Physical (wire) ``` -Note, if you want to use C++, simply change the extension of the `send.c` and `recv.c` to `.cpp` and update the Makefile. +## C++ + +Note, if you want to use C++, simply change the extension of the `send.c` and +`recv.c` to `.cpp` and update the Makefile to use `g++`. ## API ``` @@ -30,3 +39,6 @@ make ``` We will run the sender and receiver in parallel using ``run_experiment.sh``. +This scripts first runs the receiver binary and then runs the sender binary. +There are several parameters that can be used to modify the characteristics of +the link, but we don't need them for this lab. diff --git a/lab2/common.h b/lab2/common.h index 4d15161..9cfd562 100644 --- a/lab2/common.h +++ b/lab2/common.h @@ -1,9 +1,19 @@ +#define DLE (char)0 +#define STX (char)2 +#define ETX (char)3 + /* Atributul este folosit pentru a anunta compilatorul sa nu alinieze structura */ __attribute__((packed)) /* DELIM | DATE | DELIM */ struct Frame { char frame_delim_start[2]; /* DEL STX */ + /* TODO 2: Add source and destination */ char payload[30]; /* Datele pe care vrem sa le transmitem */ char frame_delim_end[2]; /* DEL ETX */ }; +/* Sends one character to the other end via the Physical layer */ +int send_byte(char c); +/* Receives one character from the other end, if nothing is sent by the other end, returns a random character */ +char recv_byte(); + diff --git a/lab2/recv.c b/lab2/recv.c index 95f7fa8..99dba5d 100644 --- a/lab2/recv.c +++ b/lab2/recv.c @@ -5,17 +5,34 @@ #include <fcntl.h> #include "link_emulator/lib.h" +/* Do not touch these two */ #define HOST "127.0.0.1" #define PORT 10001 #include "common.h" -#define DLE (char)0 -#define STX (char)2 -#define ETX (char)3 -/* TODO 2: write recv_frame function */ +/* Our unqiue layer 2 ID */ +static int ID = 123131; + +/* Function which our protocol implementation will provide to the upper layer. */ +int recv_frame(char *buf, int size) +{ + /* TODO 1.1: Call recv_byte() until we receive the frame start + * delimitator. This operation makes this function blocking until it + * receives a frame. */ + + /* TODO 2.1: The first two 2 * sizeof(int) bytes represent sender and receiver ID */ + + /* TODO 2.2: Check that the frame was sent to me */ + + /* TODO 1.2: Read bytes and copy them to buff until we receive the end of the frame */ + + /* If everything went well return the number of bytes received */ + return 0; +} int main(int argc,char** argv){ + /* Do not touch this */ init(HOST,PORT); @@ -52,12 +69,11 @@ int main(int argc,char** argv){ c = recv_byte(); printf("%c\n", c); + /* TODO 1.0: Allocate a buffer and call recv_frame */ - /* TODO 2: Run the receiver until you receive the frame DONE */ - - /* TODO 3: receive a frame with a structure of type Pa */ - /* TODO 4: Measure latency in a while loop for any frame that contains a timestamp we receive, print frame_size and latency */ + /* TODO 3: Measure latency in a while loop for any frame that contains + * a timestamp we receive, print frame_size and latency */ printf("[RECEIVER] Finished transmission\n"); return 0; diff --git a/lab2/send.c b/lab2/send.c index d8b1d4b..e6c35a4 100644 --- a/lab2/send.c +++ b/lab2/send.c @@ -13,13 +13,29 @@ /* Here we have the Frame structure */ #include "common.h" -#define DLE (char)0 -#define STX (char)2 -#define ETX (char)3 -/* TODO 2: implement send_frame function */ +/* Our unqiue layer 2 ID */ +static int ID = 123131; + +/* Function which our protocol implementation will provide to the upper layer. */ +int send_frame(char *buf, int size) +{ + + /* TODO 1.1: Create a new frame. */ + + /* TODO 1.2: Copy the data from buffer to our frame structure */ + + /* TODO 2.1: Set the destination and source */ + + /* TODO 1.3: We can cast the frame to a char *, and iterate through sizeof(struct Frame) bytes + calling send_bytes. */ + + /* if all went all right, return 0 */ + return 0; +} int main(int argc,char** argv){ + // Don't touch this init(HOST,PORT); /* Send Hello */ @@ -31,12 +47,16 @@ int main(int argc,char** argv){ send_byte('l'); send_byte('o'); send_byte('!'); + send_byte(DLE); + send_byte(ETX); + + /* TODO 1.0: Get some input in a buffer and call send_frame with it */ + + /* TODO 3.1: Get a timestamp of the current time copy it in the the payload */ - /* TODO 2: call send_frame function with a given string input */ + /* TODO 3.0: Upload the maximum size of the payload in Frame to 100, send the frame */ - /* TODO 3: use send_frame to send a structure of type Packet */ + /* TODO 3.0: Upload the maximum size of the payload in Frame to 300, send the frame */ - /* TODO 4: send 100 bytes, send 300 bytes, append a timestamp to these frames */ - return 0; } -- GitLab