-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSwitch.cpp
152 lines (110 loc) · 3.36 KB
/
Switch.cpp
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
#include <map>
#include <stdio.h>
#include <stdlib.h>
#include <thread>
#include <algorithm>
#include "EthernetFrame.h"
#include "MACAddress.h"
#include "gpioFileSystem.h"
#include "circular_queue.h"
#define MAXPORTS 10
#define pinIn 418
#define pinOut 394
#define BUFFER_SIZE 10000
int connectedPorts[MAXPORTS] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0};
long long int addressTable[MAXPORTS]; //addressTable[port] = mac addr
CircularQueue in_buffers[MAXPORTS];
CircularQueue out_buffers[MAXPORTS];
std::thread threads[MAXPORTS];
// template <size_t rows, size_t cols>
// void readFile(bool (&buf)[rows][cols], int len){
// for (int i = 0; i < len; i++){
// buf[i] = readPin();
// }
// }
void *readInputSignals(void * arg){
//read 64 bits - preamble + SFD (TODO)
//put in process buffer
//For now, to test logic I will just use a big array with random values and some ethernet frames instead of reading input signals
}
void *writeOutputSignals(void * arg){
//write bits to correct port/pin
}
// TODO: fix args
void *processData(int in_port){
//detect start of frame with FSM
char prev = -1;
char curr = -1;
int count = 0;
while(count < 64){
prev = curr;
curr = in_buffers[in_port].popFront();
// detect last "1" which is a consecutive 1
if(count == 63 && curr == 1 && prev == 1){
count += 1;
}else{
continue;
}
if ((curr == 1 && prev == 0) || (curr == 0 && prev == 1)){
count += 1;
}else if(curr == 1){
count = 1;
}else{
count = 0;
}
}
// read source and destination addresses (6 octets each)
long long int source_addr = 0;
for (size_t i = 0; i < (6*8); i++){
source_addr += (bool) in_buffers[in_port].popFront();
source_addr <<= 1;
}
addressTable[in_port] = source_addr;
long long int dest_addr = 0;
for (size_t i = 0; i < (6*8); i++){
dest_addr += (bool) in_buffers[in_port].popFront();
dest_addr <<= 1;
}
//search address table
long long int* item = std::find(std::begin(addressTable), std::end(addressTable), source_addr);
if(item == std::end(addressTable)){
// address not found, broadcast to all ports
broadcastData();
}else{
int index = std::distance(addressTable, item);
sendData(addressTable[index]);
}
//compare data and find correct output port
//put in output buffer
}
void setup(){
// fill all values in addressTable to 0
for (int i = 0; i < MAXPORTS; i++){
addressTable[i] = 0;
}
//pin setup
exportPin(pinIn);
setDirectionOut(pinIn);
exportPin(pinOut);
setDirectionIn(pinOut);
}
int main (int argc, char *argv[]){
// address : port #
//std::map<long long int, int> addressTable;
setup();
for (size_t i = 0; i < MAXPORTS; i++){
in_buffers[i] = CircularQueue(BUFFER_SIZE);
}
// todo: set thread affinity to separate cores for input and output
// todo: multiple i/o for multiple signals
for (size_t i = 0; i < MAXPORTS; i++){
if(connectedPorts[i]){
threads[i] = std::thread(processData, i);
}
}
for (size_t i = 0; i < MAXPORTS; i++){
if(connectedPorts[i]){
threads[i].join();
}
}
}