-
Notifications
You must be signed in to change notification settings - Fork 2
/
new_protocol.cu
171 lines (145 loc) · 5.51 KB
/
new_protocol.cu
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/**
* @file new_protocol.cu
* @brief New Ethernet protocol
* @author John Melton, G0ORX/N6LYT
*/
/* Copyright (C)
* 2015 - John Melton, G0ORX/N6LYT
*
* Based on code by Steven Passe AD0ES and Vasiliy Gokoyev K3IT
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include <errno.h>
#include <pthread.h>
#include <sched.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <netpacket/packet.h>
#include <net/if_packet.h>
#include <cufft.h>
#include <helper_cuda.h>
#include "common.cuh"
#include "new_protocol.cuh"
#define STATE_IDLE 0
#define STATE_RUNNING 1
static int state;
#define BASE_PORT 1024
static int new_socket;
static unsigned char mac_address[6];
static long base_sequence=0L;
#define MAX_BUFFER_LEN 1444
#define DISCOVERY_BUFFER_LEN 60
void *new_read_thread(void *arg) {
struct sockaddr_in read_addr;
uint8_t read_buffer[MAX_BUFFER_LEN];
socklen_t read_length;
struct ifreq ifr;
int rc;
int on=1;
new_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (new_socket < 0) {
perror("new_read_thread: create socket failed for new_socket\n");
exit(EXIT_FAILURE);
}
rc = setsockopt(new_socket, SOL_SOCKET, SO_REUSEADDR, (const void*)&on, sizeof(on));
if (rc != 0) {
fprintf(stderr, "new_read_thread: cannot set SO_REUSEADDR: rc=%d\n", rc);
exit(EXIT_FAILURE);
}
read_addr.sin_family = AF_INET;
read_addr.sin_port = htons(BASE_PORT);
read_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(new_socket, (struct sockaddr*) &read_addr, sizeof(read_addr)) < 0) {
perror("new_read_thread: bind socket failed for new_socket\n");
exit(EXIT_FAILURE);
}
rc = setsockopt(new_socket, SOL_SOCKET, SO_BROADCAST, (const void*)&on, sizeof(on));
if (rc != 0) {
fprintf(stderr, "new_read_thread: cannot set SO_BROADCAST: rc=%d\n", rc);
exit(EXIT_FAILURE);
}
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name, interface, IFNAMSIZ-1);
ioctl(new_socket, SIOCGIFADDR, &ifr);
unsigned char* u = (unsigned char*)&ifr.ifr_addr.sa_data;
for (int k = 0; k < 6; k++) {
mac_address[k] = u[k];
}
while(1) {
if ((rc=recvfrom(new_socket, read_buffer, sizeof(read_buffer), 0,
(struct sockaddr*)&read_addr, &read_length)) < 0) {
fprintf(stderr, "new_read_thread: error recvfrom %d", rc);
exit(EXIT_FAILURE);
}
short port=htons(read_addr.sin_port);
unsigned long sequence;
uint8_t command;
if(port==BASE_PORT) {
sequence=(read_buffer[0]<<24)+(read_buffer[1]<<16)+(read_buffer[2]<<8)+read_buffer[3];
command=read_buffer[4];
switch(command) {
case 0: // general packet
break;
case 2: // discovery
// check length==DISCOVERY_BUFFER_LEN?
// send reply
uint8_t discovery_reply[DISCOVERY_BUFFER_LEN];
memset(discovery_reply,0x00,sizeof(discovery_reply));
discovery_reply[0]=(base_sequence>>24)&0xFF;
discovery_reply[1]=(base_sequence>>16)&0xFF;
discovery_reply[2]=(base_sequence>>8)&0xFF;
discovery_reply[3]=base_sequence&0xFF;
discovery_reply[4]=state+2; // 2=idle 3=active
discovery_reply[5]=mac_address[0];
discovery_reply[6]=mac_address[1];
discovery_reply[7]=mac_address[2];
discovery_reply[8]=mac_address[3];
discovery_reply[9]=mac_address[4];
discovery_reply[10]=mac_address[5];
discovery_reply[11]=6; // hermes lite
discovery_reply[12]=100; // version 1.00
discovery_reply[20]=8; // receivers
discovery_reply[21]=1; // phase word
if ((rc=sendto(new_socket, discovery_reply, 60, 0,
(struct sockaddr*)&read_addr, sizeof(read_addr))) < 0) {
fprintf(stderr, "new_read_thread: Error sendtoa discovery_reply: %d",rc);
exit(EXIT_FAILURE);
}
break;
case 3: // set IP address
// ignore
break;
case 4: // erase
// ignore
break;
case 5: // program
// ignore
break;
default:
fprintf(stderr, "new_read_thread: unknown command on port 1024: %d\n", command);
break;
}
}
}
}