Skip to content
Snippets Groups Projects
Commit 6491f22e authored by Teodor Adrian Miron's avatar Teodor Adrian Miron
Browse files

lab2 and 3 finished

parent 1d1b0cee
No related branches found
No related tags found
No related merge requests found
File added
......@@ -6,8 +6,8 @@
/* DELIM | DATE | DELIM */
struct __attribute__((packed)) Frame {
char frame_delim_start[2]; /* DLE STX */
/* TODO 2: Add source and destination */
int source;
int dest;
char payload[30]; /* Datele pe care vrem sa le transmitem */
char frame_delim_end[2]; /* DLE ETX */
};
......@@ -16,68 +16,83 @@
#define PORT 10001
#include "common.h"
#define BUFFER_SIZE 32
/* Our unique layer 2 ID */
static int ID = 123131;
int recv_bytes(char *buffer, int length) {
int i = 0;
while (i < length) {
char c = recv_byte();
if (c == DLE) {
char next = recv_byte();
if (next == DLE) {
buffer[i++] = DLE;
} else {
return -1;
}
} else {
buffer[i++] = c;
}
}
return i;
}
/* 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 */
char frame;
char frame2;
fprintf(stderr, "1\n");
frame = recv_byte();
fprintf(stderr, "2\n");
frame2 = recv_byte();
fprintf(stderr, "3\n");
while( ((frame != DLE) && (frame2 != STX)) || (frame == DLE && frame2 != STX)
|| (frame != DLE && frame2 == STX)) {
frame = frame2;
frame2 = recv_byte();
}
/* If everything went well return the number of bytes received */
return 0;
int source;
int dest;
(void) source;
recv_bytes((char *)&source, sizeof(int));
recv_bytes((char *)&dest, sizeof(int));
if (dest != ID) {
fprintf(stderr, "skipping\n");
return -1;
}
int i;
for (i = 0; i < size; i++) {
char byte = recv_byte();
if (byte == DLE) {
char next = recv_byte();
if (next == ETX) {
buf[i] = '\0';
break;
} else if (next == DLE) {
buf[i] = DLE;
} else {
return -1;
}
} else {
buf[i] = byte;
}
}
return i;
}
int main(int argc,char** argv){
/* Don't modify this */
init(HOST,PORT);
// TODO remove these recives, whih are hardcoded to receive a "Hello"
// message, and replace them with code that can receive any message.
char c;
/* Wait for the start of a frame */
char c1,c2;
c1 = recv_byte();
c2 = recv_byte();
/* Cat timp nu am primit DLE STX citim bytes */
while((c1 != DLE) && (c2 != STX)) {
c1 = c2;
c2 = recv_byte();
}
printf("%d ## %d\n",c1, c2);
c = recv_byte();
printf("%c\n", c);
c = recv_byte();
printf("%c\n", c);
c = recv_byte();
printf("%c\n", c);
c = recv_byte();
printf("%c\n", c);
c = recv_byte();
printf("%c\n", c);
c = recv_byte();
printf("%c\n", c);
/* TODO 1.0: Allocate a buffer and call recv_frame */
char buffer[BUFFER_SIZE];
recv_frame(buffer, BUFFER_SIZE);
printf("%s\n", buffer);
/* TODO 3: Measure latency in a while loop for any frame that contains
* a timestamp we receive, print frame_size and latency */
......
......@@ -22,21 +22,38 @@
/* Our unqiue layer 2 ID */
static int ID = 123131;
#define BUFFER_SIZE 32
/* 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. */
struct Frame *new_frame = (struct Frame *)malloc(sizeof(struct Frame));
new_frame->frame_delim_start[0] = DLE;
new_frame->frame_delim_start[1] = STX;
/* 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 */
if (size > sizeof(new_frame->payload)) {
fprintf(stderr, "buffer size exceeds payload size\n");
free(new_frame);
return -1;
}
memcpy(new_frame->payload, buf, size);
new_frame->frame_delim_end[0] = DLE;
new_frame->frame_delim_end[1] = ETX;
new_frame->source = ID;
new_frame->dest = ID;
char *frame = (char *)new_frame;
int size_of_frame = sizeof(struct Frame);
for (int i = 0; i < size_of_frame; i++) {
if (frame[i] == DLE) {
send_byte(DLE);
}
send_byte(frame[i]);
}
free(new_frame);
return 0;
}
......@@ -44,22 +61,10 @@ int main(int argc,char** argv){
// Don't touch this
init(HOST,PORT);
// TODO remove these sends, whih are hardcoded to send a "Hello"
// message, and replace them with code that can send any message.
/* Send Hello */
send_byte(DLE);
send_byte(STX);
send_byte('H');
send_byte('e');
send_byte('l');
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 */
char buffer[BUFFER_SIZE];
fgets(buffer, BUFFER_SIZE, stdin);
int length = strlen(buffer);
send_frame(buffer, length - 1);
/* TODO 3.1: Get a timestamp of the current time copy it in the the payload */
/* TODO 3.0: Update the maximum size of the payload in Frame to 100 (in common.h), send the frame */
......
#include "common.h"
#include <arpa/inet.h>
uint8_t simple_csum(uint8_t *buf, size_t len) {
/* TODO 1.1: Implement the simple checksum algorithm */
uint8_t sum = 0;
for (int i = 0; i < len; i++) {
for (size_t i = 0; i < len; i++) {
sum += buf[i];
}
return sum;
}
uint32_t crc32(uint8_t *buf, size_t len)
{
/* TODO 2.1: Implement the CRC 32 algorithm */
uint32_t crc = ~0;
const uint32_t POLY = 0xEDB88320;
/* Iterate through each byte of buff */
/* Iterate through each bit */
/* If the bit is 1, compute the new reminder */
/* By convention, we negate the crc */
return 0;
for (size_t i = 0; i < len; i++) {
crc = crc ^ buf[i];
for (size_t j = 0; j < 8; j++) {
if (crc & 1) {
crc = (crc >> 1) ^ POLY;
} else {
crc = (crc >> 1);
}
}
}
crc = ~crc;
return crc;
}
......@@ -7,6 +7,7 @@
#include "common.h"
#include "link_emulator/lib.h"
#include "include/utils.h"
#include <inttypes.h>
/**
* You can change these to communicate with another colleague.
......@@ -27,21 +28,41 @@ int main(int argc,char** argv) {
/* Receive the frame from the link */
int len = link_recv(&t, sizeof(struct l3_msg));
DIE(len < 0, "Receive message");
/* We have to convert it to host order */
uint32_t temp = t.hdr.sum;
uint32_t recv_sum = ntohl(t.hdr.sum);
t.hdr.sum = 0;
int sum_ok = (simple_csum((void *) &t, sizeof(struct l3_msg)) == recv_sum);
//int sum_ok = (simple_csum((void *) &t, sizeof(struct l3_msg)) == recv_sum);
/* TODO 2: Change to crc32 */
t.hdr.sum = 0;
int ok_sum = (crc32((uint8_t *) &t, sizeof(struct l3_msg)) == recv_sum);
/* Since we are sending messages with a payload of 1500 - sizeof(header), most of the times the bytes from
* 30 - 1500 will be corrupted and thus when we are printing or string message "Hello world" we see no probems.
* This will be visible when we will be sending a file */
printf("[RECV] len=%d; sum(%s)=0x%04hx; payload=\"%s\";\n", t.hdr.len, sum_ok ? "GOOD" : "BAD", recv_sum, t.payload);
printf("[RECV] len=%d; sum(%s)=0x%04x; payload=\"%s\";\n", t.hdr.len, ok_sum ? "GOOD" : "BAD", recv_sum, t.payload);
/* TODO 3.1: In a loop, recv a frame and check if the CRC is good */
while (true) {
link_recv(&t, sizeof(struct l3_msg));
uint32_t recieved_sum = ntohl(t.hdr.sum);
t.hdr.sum = 0;
int sum_good = (crc32((uint8_t *) &t, sizeof(struct l3_msg)) == recieved_sum);
if (!sum_good) {
struct l3_msg nack_msg;
memset(&nack_msg, 0, sizeof(struct l3_msg));
strcpy(nack_msg.payload, "NACK");
nack_msg.hdr.len = strlen(nack_msg.payload);
nack_msg.hdr.sum = htonl(crc32((uint8_t *)&nack_msg, sizeof(struct l3_msg)));
link_send(&nack_msg, sizeof(struct l3_msg));
} else {
printf("[RECV] len=%d; sum(%s)=0x%04hx; payload=\"%s\";\n", t.hdr.len, sum_good ? "GOOD" : "BAD", recieved_sum, t.payload);
FILE *file = fopen("recv.data", "a");
DIE(file == NULL, "Failed to open recv.data");
fwrite(t.payload, 1, t.hdr.len, file);
fclose(file);
}
}
/* TODO 3.2: If the crc is bad, send a NACK frame */
/* TODO 3.2: Otherwise, write the frame payload to a file recv.data */
......
......@@ -30,17 +30,40 @@ int main(int argc,char** argv) {
t.hdr.sum = 0;
/* Since sum is on 32 bits, we have to convert it to network order */
t.hdr.sum = htonl(simple_csum((void *) &t, sizeof(struct l3_msg)));
//t.hdr.sum = htonl(simple_csum((void *) &t, sizeof(struct l3_msg)));
uint32_t temp = crc32((uint8_t *) &t, sizeof(struct l3_msg));
printf("[SEND] len=%d; sum=0x%04x; payload=\"%s\";\n", t.hdr.len, temp, t.payload);
/* TODO 2.0: Call crc32 function */
t.hdr.sum = htonl(temp);
/* Send the message */
link_send(&t, sizeof(struct l3_msg));
/* TODO 3.1: Receive the confirmation */
/* TODO 3.2: If we received a NACK, retransmit the previous frame */
struct l3_msg recv;
link_recv(&recv, sizeof(struct l3_msg));
while (strcmp(recv.payload, "NACK") == 0) {
link_send(&t, sizeof(struct l3_msg));
link_recv(&recv, sizeof(struct l3_msg));
}
FILE *f;
f = fopen("input.txt", "rb");
size_t bytes_read;
while ((bytes_read = fread(t.payload, 1, 1500, f)) > 0) {
t.hdr.len = bytes_read;
t.hdr.sum = 0;
t.hdr.sum = htonl(crc32((uint8_t *) &t, sizeof(struct l3_msg)));
link_send(&t, sizeof(struct l3_msg));
link_recv(&recv, sizeof(struct l3_msg));
while (strcmp(recv.payload, "NACK") == 0) {
link_send(&t, sizeof(struct l3_msg));
link_recv(&recv, sizeof(struct l3_msg));
}
}
fclose(f);
/* TODO 3.3: Update this to read the content of a file and send it as
* chunks of that file given a MTU of 1500 bytes */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment