Skip to content

Commit caddb8e

Browse files
authored
Merge pull request #537 from LeeLeahy2/slow-read
Add Slow_Read application to test flow control
2 parents 54ac6f4 + af616d8 commit caddb8e

File tree

3 files changed

+259
-0
lines changed

3 files changed

+259
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,5 @@ Icon
5555
*.a
5656

5757
# Executables
58+
Firmware/Tools/Slow_Read
5859
Firmware/Tools/VcServerTest

Firmware/Tools/Slow_Read.c

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
#include "settings.h"
2+
3+
#define INPUT_BUFFER_SIZE 2048
4+
#define OUTPUT_BUFFER_SIZE 32
5+
#define POLL_TIMEOUT_USEC 100000
6+
#define STDIN 0
7+
#define STDOUT 1
8+
#define STDERR 2
9+
10+
uint8_t inputBuffer[INPUT_BUFFER_SIZE];
11+
uint8_t outputBuffer[OUTPUT_BUFFER_SIZE];
12+
uint32_t timeoutCount;
13+
suseconds_t timer;
14+
15+
void dumpBuffer(uint8_t * data, int length)
16+
{
17+
char byte;
18+
int bytes;
19+
uint8_t * dataEnd;
20+
uint8_t * dataStart;
21+
const int displayWidth = 16;
22+
int index;
23+
24+
dataStart = data;
25+
dataEnd = &data[length];
26+
while (data < dataEnd)
27+
{
28+
// Display the offset
29+
printf(" 0x%02x: ", (unsigned int)(data - dataStart));
30+
31+
// Determine the number of bytes to display
32+
bytes = dataEnd - data;
33+
if (bytes > displayWidth)
34+
bytes = displayWidth;
35+
36+
// Display the data bytes in hex
37+
for (index = 0; index < bytes; index++)
38+
printf(" %02x", *data++);
39+
40+
// Space over to the ASCII display
41+
for (; index < displayWidth; index++)
42+
printf(" ");
43+
printf(" ");
44+
45+
// Display the ASCII bytes
46+
data -= bytes;
47+
for (index = 0; index < bytes; index++) {
48+
byte = *data++;
49+
printf("%c", ((byte < ' ') || (byte >= 0x7f)) ? '.' : byte);
50+
}
51+
printf("\n");
52+
}
53+
}
54+
55+
int stdinToRadio()
56+
{
57+
int bytesRead;
58+
int bytesSent;
59+
int bytesToSend;
60+
int bytesWritten;
61+
int length;
62+
int maxfds;
63+
int status;
64+
struct timeval timeout;
65+
static int index;
66+
67+
status = 0;
68+
do
69+
{
70+
//Read the console input data into the local buffer.
71+
bytesRead = read(STDIN, inputBuffer, sizeof(inputBuffer) - 3);
72+
if (bytesRead < 0)
73+
{
74+
perror("ERROR: Read from stdin failed!");
75+
status = bytesRead;
76+
break;
77+
}
78+
79+
//Terminate the line
80+
inputBuffer[bytesRead++] = '\r';
81+
inputBuffer[bytesRead++] = '\n';
82+
inputBuffer[bytesRead] = 0;
83+
84+
//Send this data over the VC
85+
bytesSent = 0;
86+
while (bytesSent < bytesRead)
87+
{
88+
//Send the data
89+
bytesWritten = write(radio, &inputBuffer[bytesSent], bytesRead - bytesSent);
90+
if (bytesWritten < 0)
91+
{
92+
perror("ERROR: Write to radio failed!");
93+
status = bytesWritten;
94+
break;
95+
}
96+
97+
//Account for the bytes written
98+
bytesSent += bytesWritten;
99+
}
100+
} while (0);
101+
return status;
102+
}
103+
104+
int radioToHost()
105+
{
106+
int bytesRead;
107+
int bytesSent;
108+
int bytesToSend;
109+
int bytesWritten;
110+
int status;
111+
112+
status = 0;
113+
do
114+
{
115+
//Read the virtual circuit header into the local buffer.
116+
bytesRead = read(radio, outputBuffer, sizeof(outputBuffer) - 1);
117+
if (bytesRead == 0)
118+
break;
119+
if (bytesRead < 0)
120+
{
121+
perror("ERROR: Read from radio failed!");
122+
status = bytesRead;
123+
break;
124+
}
125+
126+
//Write this data to stdout
127+
bytesSent = 0;
128+
status = 0;
129+
while (bytesSent < bytesRead)
130+
{
131+
bytesWritten = write(STDOUT, &outputBuffer[bytesSent], bytesRead - bytesSent);
132+
if (bytesWritten < 0)
133+
{
134+
perror("ERROR: Write to stdout!");
135+
status = bytesWritten;
136+
break;
137+
}
138+
139+
//Account for the bytes written
140+
bytesSent += bytesWritten;
141+
}
142+
} while(0);
143+
return status;
144+
}
145+
146+
int main(int argc, char **argv)
147+
{
148+
fd_set currentfds;
149+
suseconds_t delta_usec;
150+
int maxfds;
151+
int numfds;
152+
bool reset;
153+
int status;
154+
char * terminal;
155+
struct timeval timeout;
156+
157+
maxfds = STDIN;
158+
status = 0;
159+
do
160+
{
161+
//Display the help text if necessary
162+
if (argc != 2)
163+
{
164+
printf("%s terminal\n", argv[0]);
165+
printf("\n");
166+
printf("terminal - Name or path to the terminal device for the radio\n");
167+
status = -1;
168+
break;
169+
}
170+
171+
//Get the path to the terminal
172+
terminal = argv[1];
173+
174+
//Open the terminal
175+
status = openLoRaSerial(terminal);
176+
if (status)
177+
break;
178+
179+
FD_ZERO(&readfds);
180+
FD_SET(STDIN, &readfds);
181+
if (maxfds < radio)
182+
maxfds = radio;
183+
FD_SET(radio, &readfds);
184+
185+
while (1)
186+
{
187+
//Set the timeout
188+
timeout.tv_sec = 0;
189+
timeout.tv_usec = POLL_TIMEOUT_USEC;
190+
191+
//Wait for receive data or timeout
192+
memcpy((void *)&currentfds, (void *)&readfds, sizeof(readfds));
193+
numfds = select(maxfds + 1, &currentfds, NULL, NULL, &timeout);
194+
if (numfds < 0)
195+
{
196+
perror("ERROR: select call failed!");
197+
status = errno;
198+
break;
199+
}
200+
201+
//----------------------------------------
202+
// Terminal --> Radio
203+
//----------------------------------------
204+
205+
//Determine if console input is available
206+
if (FD_ISSET(STDIN, &currentfds))
207+
{
208+
//Send the console input to the radio
209+
status = stdinToRadio();
210+
if (status)
211+
break;
212+
}
213+
214+
//----------------------------------------
215+
// Detect radio data and start delay
216+
//----------------------------------------
217+
218+
if ((!timer) && FD_ISSET(radio, &currentfds))
219+
{
220+
//Start the timer to read the data
221+
gettimeofday(&timeout, NULL);
222+
timer = timeout.tv_usec;
223+
if (!timer)
224+
timer = 1;
225+
}
226+
227+
//----------------------------------------
228+
// Radio --> Terminal, after delay
229+
//----------------------------------------
230+
231+
//Check for time to receive more data
232+
gettimeofday(&timeout, NULL);
233+
delta_usec = (1000000 + timeout.tv_usec - timer) % 1000000;
234+
if (timer && (delta_usec >= POLL_TIMEOUT_USEC))
235+
{
236+
status = radioToHost();
237+
if (status)
238+
break;
239+
timer = 0;
240+
}
241+
242+
//----------------------------------------
243+
// Delay for a while
244+
//----------------------------------------
245+
246+
if (numfds == 0)
247+
timeoutCount++;
248+
}
249+
} while (0);
250+
251+
//Done with the radio
252+
close(radio);
253+
return status;
254+
}

Firmware/Tools/makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
# Source files
99
##########
1010

11+
EXECUTABLES += Slow_Read
1112
EXECUTABLES += VcServerTest
1213

1314
INCLUDES = settings.h ../LoRaSerial_Firmware/Virtual_Circuit_Protocol.h
@@ -50,6 +51,9 @@ $(COMMON_LIB): $(LIB_OBJS)
5051
# Build the executables
5152
##########
5253

54+
Slow_Read: Slow_Read.c $(COMMON_LIB)
55+
$(CC) -o $@ $^
56+
5357
VcServerTest: VcServerTest.c $(COMMON_LIB)
5458
$(CC) -o $@ $^
5559

0 commit comments

Comments
 (0)