-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreceiver.c
More file actions
141 lines (114 loc) · 3.64 KB
/
Copy pathreceiver.c
File metadata and controls
141 lines (114 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include "crc16.h"
#include "bitvec.h"
#include "manchester.h"
#include "netutil.h"
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#define PORT 5050 // Port number for receiver
void receiver_start()
{
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd < 0)
{
perror("socket");
exit(1);
}
int opt = 1; // Reuse address option
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if (bind(listenfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
perror("bind");
exit(1);
}
listen(listenfd, 1);
printf("[Receiver] Listening on port %d\n", PORT);
int c = accept(listenfd, NULL, NULL);
printf("[Receiver] Connected.\n");
while (1)
{
uint32_t netlen;
if (recv_all(c, &netlen, sizeof(netlen)) <= 0)
break;
size_t nbytes = ntohl(netlen);
if (nbytes == 0)
{
printf("[Receiver] End of transmission.\n");
break;
}
uint8_t *buf = malloc(nbytes); // Buffer for received frame
recv_all(c, buf, nbytes);
/* ---- UNPACK BITS ---- */
bitvec enc_bits;
unpack_bits(buf, nbytes, &enc_bits);
/* ---- MANCHESTER DECODE ---- */
bitvec dec_bits;
if (manchester_decode_bits(&enc_bits, &dec_bits) != 0)
{
printf("[Receiver] Manchester decode failure\n\n");
free(buf);
bitvec_free(&enc_bits);
continue;
}
/* ---- VERIFY FRAME HAS CRC ---- */
if (dec_bits.len < 16)
{
printf("[Receiver] Too short (corrupt)\n\n");
free(buf);
bitvec_free(&enc_bits);
bitvec_free(&dec_bits);
continue;
}
size_t payload_bits = dec_bits.len - 16;
size_t payload_bytes = (payload_bits + 7) / 8;
/* ---- EXTRACT PAYLOAD BYTES ---- */
uint8_t *payload = calloc(payload_bytes + 1, 1); // +1 for safe printing
for (size_t i = 0; i < payload_bits; ++i)
{
if (dec_bits.buf[i])
payload[i / 8] |= (1 << (7 - (i % 8)));
}
payload[payload_bytes] = '\0';
/* ---- EXTRACT RECEIVED CRC ---- */
uint16_t recv_crc = 0;
for (int i = 0; i < 16; ++i)
{
recv_crc = (recv_crc << 1) | dec_bits.buf[payload_bits + i];
}
/* ---- COMPUTE LOCAL CRC ---- */
uint16_t calc_crc = crc16_ccitt(payload, payload_bytes);
/* ---- DISPLAY RESULTS ---- */
printf("\n==============================================\n");
printf(" RECEIVED FRAME\n");
printf("==============================================\n");
printf("Payload (%zu bytes):\n", payload_bytes);
printf(" \"%s\"\n", payload);
printf("\nCRC Check:\n");
printf(" Received CRC : 0x%04X\n", recv_crc);
printf(" Calculated CRC: 0x%04X\n", calc_crc);
if (recv_crc == calc_crc)
printf(" --> CRC STATUS: PASS (Message Correct)\n");
else
printf(" --> CRC STATUS: FAIL (Message Corrupted!)\n");
printf("==============================================\n\n");
/* ---- CLEAN UP ---- */
free(payload);
free(buf);
bitvec_free(&enc_bits);
bitvec_free(&dec_bits);
}
close(c);
close(listenfd);
return;
}
int main() {
receiver_start();
return 0;
}