Commit 2855a15f authored by Andreas Schmidt's avatar Andreas Schmidt

Create basic source packet header.

parent 4654393e
......@@ -6,9 +6,11 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
add_subdirectory(prrt)
add_library(PRRT prrt/socket.c)
add_library(PRRT prrt/socket.c prrt/block.c prrt/block.h prrt/packet.c prrt/packet.h)
add_executable(sender sender.c)
add_executable(receiver receiver.c)
add_executable(tester tester.c)
target_link_libraries(sender LINK_PUBLIC PRRT)
target_link_libraries(receiver LINK_PUBLIC PRRT)
\ No newline at end of file
target_link_libraries(receiver LINK_PUBLIC PRRT)
target_link_libraries(tester LINK_PUBLIC PRRT)
\ No newline at end of file
//
// Created by root on 05.11.15.
//
#ifndef PRRT_DEFINES_H
#define PRRT_DEFINES_H
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define PRRT_MAX_RECEIVER_COUNT 255
#define PRRT_PACKET_GENERAL_HEADER_SIZE 4
#define PRRT_PACKET_SOURCE_HEADER_SIZE 12
#define MAX_PAYLOAD_LENGTH 65528 // maximum UDP packet length (2^16 - 8)
#endif //PRRT_DEFINES_H
#include "block.h"
#ifndef PRRT_BLOCK_H
#define PRRT_BLOCK_H
#endif //PRRT_BLOCK_H
//
// Created by andreas on 06.11.15.
//
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <string.h>
#include <tgmath.h>
#include "packet.h"
#include "../defines.h"
uint8_t packet_type(prrt_packet *packet_ptr) {
return (uint8_t) ((packet_ptr->type_priority >> 4) & 0x0F);
}
uint8_t packet_priority(prrt_packet *packet_ptr) {
return (uint8_t) (packet_ptr->type_priority & 0x0F);
}
uint16_t packet_size(prrt_packet *packet_ptr) {
return (uint16_t) (packet_ptr->payload_len + PRRT_PACKET_GENERAL_HEADER_SIZE); // 4 = 4bit type + 4bit priority + 8 bit index + 16bit seqno
}
int create_packet_source(prrt_packet *packet_ptr, uint8_t priority, const void * data_ptr, unsigned long data_len) {
packet_ptr->type_priority = PACKET_TYPE_SOURCE << 4;
packet_ptr->type_priority |= priority & 0x0F;
prrt_packet_source_payload * payload = malloc(sizeof(prrt_packet_source_payload));
struct timeval tv;
gettimeofday(&tv,NULL);
unsigned long time_in_micros = (unsigned long) (1000000 * tv.tv_sec + tv.tv_usec);
payload->timestamp = (uint32_t) time_in_micros;
// TODO: payload->rtt = CURRENT ESTIMATE
// TODO: payload->packet_timeout = NOW + maximum delay
// TODO: payload->decoding_timeout
// TODO: payload->feedback_timer
packet_ptr->payload = (void*) payload;
memcpy(payload + sizeof(prrt_packet_source_payload), data_ptr, data_len);
packet_ptr->payload_len = (uint32_t) (data_len + sizeof(prrt_packet_source_payload));
return 0;
}
int encode_packet_source(void *buf, uint16_t buf_size, prrt_packet *packet) {
prrt_packet_source_payload * payload = packet->payload;
if(buf_size < packet->payload_len + PRRT_PACKET_GENERAL_HEADER_SIZE) {
return -1;
}
memcpy(buf, packet, PRRT_PACKET_GENERAL_HEADER_SIZE);
buf += PRRT_PACKET_GENERAL_HEADER_SIZE;
memcpy(buf, payload, PRRT_PACKET_SOURCE_HEADER_SIZE);
buf += PRRT_PACKET_SOURCE_HEADER_SIZE;
memcpy(buf, payload + PRRT_PACKET_SOURCE_HEADER_SIZE, packet->payload_len - PRRT_PACKET_SOURCE_HEADER_SIZE);
return 0;
}
#ifndef PRRT_FRAME_H
#define PRRT_FRAME_H
#include <stdint.h>
#define PACKET_TYPE_SOURCE 0
#define PACKET_TYPE_REPETITION 1
#define PACKET_TYPE_PARITY 2
#define PACKET_TYPE_FEEDBACK 3
typedef struct {
uint8_t type_priority;
uint8_t index;
uint16_t seqno;
void* payload;
uint32_t payload_len;
} prrt_packet;
typedef struct {
uint32_t timestamp;
uint16_t rtt;
uint16_t packet_timeout;
uint16_t decoding_timeout;
uint16_t feedback_timer;
} prrt_packet_source_payload;
uint8_t packet_type(prrt_packet *packet_ptr);
uint8_t packet_priority(prrt_packet *packet_ptr);
uint16_t packet_size(prrt_packet *packet_ptr);
int create_packet_source(prrt_packet *packet_ptr, uint8_t priority, const void * data_ptr, unsigned long data_len);
int encode_packet_source(void* buf_ptr, uint16_t buf_size, prrt_packet *packet_ptr);
int create_packet_repetition(prrt_packet packet, uint8_t priority);
int create_packet_parity(prrt_packet packet, uint8_t priority);
int create_packet_feedback(prrt_packet packet, uint8_t priority);
#endif //PRRT_FRAME_H
......@@ -3,11 +3,14 @@
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include "../defines.h"
#include "socket.h"
#include "packet.h"
int prrt_create_socket(prrt_socket *sock, uint16_t port) {
int prrt_create_socket(prrt_socket *sock_ptr, uint16_t port) {
// Create Data Socket
if((sock->fd_data = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
if((sock_ptr->fd_data = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("cannot create socket");
return -1;
}
......@@ -19,13 +22,13 @@ int prrt_create_socket(prrt_socket *sock, uint16_t port) {
address.sin_addr.s_addr = htonl(INADDR_ANY);
address.sin_port = htons(port);
if(bind(sock->fd_data, (struct sockaddr *) &address, sizeof(address)) < 0) {
if(bind(sock_ptr->fd_data, (struct sockaddr *) &address, sizeof(address)) < 0) {
perror("cannot bind socket");
return -1;
}
// Create Feedback Socket
if((sock->fd_feedback = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
if((sock_ptr->fd_feedback = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("cannot create socket");
return -1;
}
......@@ -36,7 +39,7 @@ int prrt_create_socket(prrt_socket *sock, uint16_t port) {
address.sin_addr.s_addr = htonl(INADDR_ANY);
address.sin_port = htons((uint16_t) (port + 1)); // TODO: fail if port is 65535
if(bind(sock->fd_feedback, (struct sockaddr *) &address, sizeof(address)) < 0) {
if(bind(sock_ptr->fd_feedback, (struct sockaddr *) &address, sizeof(address)) < 0) {
perror("cannot bind socket");
return -1;
}
......@@ -44,41 +47,57 @@ int prrt_create_socket(prrt_socket *sock, uint16_t port) {
return 0;
}
int prrt_connect(prrt_socket *sock, char *host, size_t host_len, uint16_t port) {
int prrt_connect(prrt_socket *sock_ptr, char *host, uint16_t port) {
prrt_receiver recv = { host , port};
if(sock_ptr->receiver_len < PRRT_MAX_RECEIVER_COUNT) {
sock_ptr->receivers[sock_ptr->receiver_len] =recv;
sock_ptr->receiver_len++;
} else {
return -1;
}
return 0;
}
int prrt_send(prrt_socket *sock, const void *data, size_t data_len) {
// TODO: should iterate over receivers
int prrt_send(prrt_socket *sock_ptr, const void *data, size_t data_len) {
int i;
for(i = 0; i < sock_ptr->receiver_len; i++) {
prrt_receiver recv = sock_ptr->receivers[i];
struct hostent *hp;
char *host = "localhost"; // TODO make receiver flexible
struct hostent *hp;
struct sockaddr_in targetaddr;
memset((char*) &targetaddr, 0, sizeof(targetaddr));
targetaddr.sin_family = AF_INET;
targetaddr.sin_port = htons(5000); // TODO: make port flexible
struct sockaddr_in targetaddr;
memset((char*) &targetaddr, 0, sizeof(targetaddr));
targetaddr.sin_family = AF_INET;
targetaddr.sin_port = htons(recv.port);
hp = gethostbyname(host);
memcpy((void *)&targetaddr.sin_addr, hp->h_addr_list[0], hp->h_length);
hp = gethostbyname(recv.host_name);
memcpy((void *)&targetaddr.sin_addr, hp->h_addr_list[0], (size_t) hp->h_length);
if((sendto(sock->fd_data, data, data_len, 0, (struct sockaddr *) &targetaddr, sizeof(targetaddr)) < 0)) {
perror("sendto failed");
return -1;
// TODO: create source packet
prrt_packet * packet = malloc(sizeof(prrt_packet));
create_packet_source(packet, 0, data, data_len);
if((sendto(sock_ptr->fd_data, data, data_len, 0, (struct sockaddr *) &targetaddr, sizeof(targetaddr)) < 0)) {
perror("sendto failed");
return -1;
}
}
return 0;
}
ssize_t prrt_recv(prrt_socket *sock, void *bufin, size_t length) {
ssize_t prrt_recv(prrt_socket *sock_ptr, void *bufin, size_t length) {
// RECEIVE DATA
ssize_t n;
struct sockaddr_in remote;
socklen_t addrlen = sizeof(remote);
n = recvfrom(sock->fd_data, bufin, length, 0, (struct sockaddr *) &remote, &addrlen);
n = recvfrom(sock_ptr->fd_data, bufin, length, 0, (struct sockaddr *) &remote, &addrlen);
uint16_t remote_port = ntohs(remote.sin_port);
char *remote_host = inet_ntoa(remote.sin_addr);
printf("got a datagram from %s port %d\n", remote_host, remote_port);
......@@ -95,7 +114,7 @@ ssize_t prrt_recv(prrt_socket *sock, void *bufin, size_t length) {
hp = gethostbyname(remote_host);
memcpy((void *)&targetaddr.sin_addr, hp->h_addr_list[0], hp->h_length);
if((sendto(sock->fd_data, bufin, n, 0, (struct sockaddr *) &targetaddr, sizeof(targetaddr)) < 0)) {
if((sendto(sock_ptr->fd_data, bufin, n, 0, (struct sockaddr *) &targetaddr, sizeof(targetaddr)) < 0)) {
perror("sendto failed");
return -1;
}
......@@ -103,19 +122,21 @@ ssize_t prrt_recv(prrt_socket *sock, void *bufin, size_t length) {
return n;
}
int prrt_close_socket(prrt_socket *sock) {
close(sock->fd_data);
close(sock->fd_feedback);
int prrt_close_socket(prrt_socket *sock_ptr) {
// TODO: clean up all receivers
close(sock_ptr->fd_data);
close(sock_ptr->fd_feedback);
return 0;
}
ssize_t prrt_recv_feedback(prrt_socket *sock, void *bufin, size_t length) {
ssize_t prrt_recv_feedback(prrt_socket *sock_ptr, void *bufin, size_t length) {
printf("RECEIVING FB");
ssize_t n;
struct sockaddr_in remote;
socklen_t addrlen = sizeof(remote);
n = recvfrom(sock->fd_feedback, bufin, length, 0, (struct sockaddr *) &remote, &addrlen);
n = recvfrom(sock_ptr->fd_feedback, bufin, length, 0, (struct sockaddr *) &remote, &addrlen);
uint16_t remote_port = ntohs(remote.sin_port);
char *remote_host = inet_ntoa(remote.sin_addr);
printf("got feedback from %s port %d\n", remote_host, remote_port);
......
......@@ -4,17 +4,30 @@
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include "../defines.h"
typedef struct {
char* host_name;
uint16_t port;
} prrt_receiver;
typedef struct {
int fd_data;
int fd_feedback;
prrt_receiver receivers[PRRT_MAX_RECEIVER_COUNT];
int receiver_len;
uint16_t seqno_source;
uint16_t seqno_repetition;
uint16_t seqno_parity;
uint16_t seqno_feedback;
} prrt_socket;
int prrt_create_socket(prrt_socket *sock, uint16_t port);
int prrt_close_socket(prrt_socket *sock);
int prrt_connect(prrt_socket *string, char *i, size_t i1, uint16_t i2);
int prrt_send(prrt_socket *sock, const void *data, size_t data_len);
ssize_t prrt_recv(prrt_socket *sock, void *bufin, size_t length);
ssize_t prrt_recv_feedback(prrt_socket *sock, void *bufin, size_t length);
int prrt_create_socket(prrt_socket *sock_ptr, uint16_t port);
int prrt_close_socket(prrt_socket *sock_ptr);
int prrt_connect(prrt_socket *sock_ptr, char *host, uint16_t port);
int prrt_send(prrt_socket *sock_ptr, const void *data, size_t data_len);
ssize_t prrt_recv(prrt_socket *sock_ptr, void *bufin, size_t length);
ssize_t prrt_recv_feedback(prrt_socket *sock_ptr, void *bufin, size_t length);
#endif // PRRT_SOCKET_H
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "prrt/socket.h"
#define MAXBUF 1024*1024
int main() {
int main(int argc, char* const argv[]) {
if(argc != 2) {
printf("Too few arguments.\n");
return -1;
}
uint16_t port = (uint16_t) atoi(argv[1]);
prrt_socket sock;
ssize_t n;
char bufin[MAXBUF];
printf("PRRT - RECEIVER\n");
if(prrt_create_socket(&sock, 5000) < 0) {
if(prrt_create_socket(&sock, port) < 0) {
perror("could not create socket");
return 0;
}
......
......@@ -5,12 +5,15 @@
#define MAXBUF 1024 * 1024
int main() {
int main(int argc, char* const argv) {
if(argc != 1) {
printf("Too few arguments.\n");
}
uint16_t local_port = 6000;
prrt_socket sock = {};
printf("PRRT - SENDER\n");
if(prrt_create_socket(&sock, local_port) < 0) {
perror("socket failed");
return 0;
......@@ -18,8 +21,13 @@ int main() {
char *remote_host = "localhost";
uint16_t remote_port = 5000;
prrt_connect(&sock, remote_host, strlen(remote_host), remote_port);
prrt_connect(&sock, remote_host, remote_port);
char *remote_host2 = "localhost";
uint16_t remote_port2 = 5003;
prrt_connect(&sock, remote_host2, remote_port2);
printf("SENDING\n");
char *message = "this is a message";
prrt_send(&sock, message, strlen(message));
......@@ -27,6 +35,8 @@ int main() {
ssize_t t = prrt_recv_feedback(&sock, bufin, MAXBUF);
printf("FEEDBACK: %d\n", (int) t);
t = prrt_recv_feedback(&sock, bufin, MAXBUF);
printf("FEEDBACK: %d\n", (int) t);
prrt_close_socket(&sock);
return 0;
......
//
// Created by andreas on 06.11.15.
//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "prrt/packet.h"
#include "defines.h"
int main() {
int i;
char *message = "this is a message";
prrt_packet * packet = malloc(sizeof(prrt_packet));
create_packet_source(packet, 0, message, strlen(message));
printf("+------+------+----------+------------------+\n");
printf("| %4u | %4u | %8u | %16u |\n", packet_type(packet), packet_priority(packet), packet->index, packet->seqno);
printf("+------------------------+------------------+\n");
prrt_packet_source_payload * payload = packet->payload;
printf("| %32u |\n", payload->timestamp);
printf("+---------------------+---------------------+\n");
printf("| %16u | %16u |\n", payload->rtt, payload->packet_timeout);
printf("+---------------------+---------------------+\n");
uint8_t buf[MAX_PAYLOAD_LENGTH];
uint32_t length = packet_size(packet);
if(encode_packet_source(buf, MAX_PAYLOAD_LENGTH, packet) < 0) {
perror("BUF too small.");
return -1;
}
for(i = 0; i < length; i++) {
if(i % 4 == 0) {
printf("|");
}
printf("%2x", buf[i]);
}
printf("\n");
return 0;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment