@@ -79,9 +79,27 @@ const char *const tcpServerStateName[] = {
79
79
" TCP_SERVER_STATE_WAIT_FOR_NETWORK" ,
80
80
" TCP_SERVER_STATE_RUNNING" ,
81
81
};
82
-
83
82
const int tcpServerStateNameEntries = sizeof (tcpServerStateName) / sizeof (tcpServerStateName[0 ]);
84
83
84
+ // Define the TCP server client states
85
+ enum tcpServerClientStates
86
+ {
87
+ TCP_SERVER_CLIENT_OFF = 0 ,
88
+ TCP_SERVER_CLIENT_WAIT_REQUEST,
89
+ TCP_SERVER_CLIENT_GET_REQUEST,
90
+ TCP_SERVER_CLIENT_SENDING_DATA,
91
+ // Insert new states here
92
+ TCP_SERVER_CLIENT_MAX // Last entry in the state list
93
+ };
94
+
95
+ const char *const tcpServerClientStateName[] = {
96
+ " TCP_SERVER_CLIENT_OFF" ,
97
+ " TCP_SERVER_CLIENT_WAIT_REQUEST" ,
98
+ " TCP_SERVER_CLIENT_GET_REQUEST" ,
99
+ " TCP_SERVER_CLIENT_SENDING_DATA" ,
100
+ };
101
+ const int tcpServerClientStateNameEntries = sizeof (tcpServerClientStateName) / sizeof (tcpServerClientStateName[0 ]);
102
+
85
103
const RtkMode_t baseCasterMode = RTK_MODE_BASE_FIXED;
86
104
const RtkMode_t tcpServerMode = RTK_MODE_ROVER
87
105
| RTK_MODE_BASE_SURVEY_IN;
@@ -105,6 +123,7 @@ static uint32_t tcpServerClientTimer[TCP_SERVER_MAX_CLIENTS];
105
123
static volatile uint8_t tcpServerClientWriteError;
106
124
static NetworkClient *tcpServerClient[TCP_SERVER_MAX_CLIENTS];
107
125
static IPAddress tcpServerClientIpAddress[TCP_SERVER_MAX_CLIENTS];
126
+ static uint8_t tcpServerClientState[TCP_SERVER_MAX_CLIENTS];
108
127
static volatile RING_BUFFER_OFFSET tcpServerClientTails[TCP_SERVER_MAX_CLIENTS];
109
128
110
129
// ----------------------------------------
@@ -350,83 +369,119 @@ void tcpServerClientUpdate(uint8_t index)
350
369
systemPrintf (" %s client %d connected to %s\r\n " ,
351
370
tcpServerName, index,
352
371
tcpServerClientIpAddress[index].toString ().c_str ());
372
+
373
+ // Process the client state
374
+ switch (tcpServerClientState[index])
375
+ {
376
+ // Wait until the request is received from the NTRIP client
377
+ case TCP_SERVER_CLIENT_WAIT_REQUEST:
378
+ if (tcpServerClient[index]->available ())
379
+ {
380
+ // Indicate that data was received
381
+ tcpServerClientDataSent = tcpServerClientDataSent | (1 << index);
382
+ tcpServerClientTimer[index] = millis ();
383
+ tcpServerClientState[index] = TCP_SERVER_CLIENT_GET_REQUEST;
384
+ }
385
+ break ;
386
+
387
+ // Process the request from the NTRIP client
388
+ case TCP_SERVER_CLIENT_GET_REQUEST:
389
+ // Read response from client
390
+ spot = 0 ;
391
+ while (tcpServerClient[index]->available ())
392
+ {
393
+ response[spot++] = tcpServerClient[index]->read ();
394
+ if (spot == sizeof (response))
395
+ spot = 0 ; // Wrap
396
+ }
397
+ response[spot] = ' \0 ' ; // Terminate string
398
+
399
+ // Handle the mount point table request
400
+ if (strnstr (response, " GET / " , sizeof (response)) != NULL ) // No mount point in header
401
+ {
402
+ if (settings.debugTcpServer )
403
+ systemPrintln (" Mount point table requested." );
404
+
405
+ // Respond with a single mountpoint
406
+ const char fakeSourceTable[] =
407
+ " SOURCETABLE 200 OK\r\n Server: SparkPNT Caster/1.0\r\n Content-Type: "
408
+ " text/plain\r\n Content-Length: 96\r\n\r\n STR;SparkBase;none;RTCM "
409
+ " 3.0;none;none;none;none;none;none;none;none;none;none;none;B;N;none;none" ;
410
+
411
+ tcpServerClient[index]->write (fakeSourceTable, strlen (fakeSourceTable));
412
+
413
+ // Disconnect from client
414
+ tcpServerStopClient (index);
415
+ }
416
+
417
+ // Check for unknown request
418
+ else if (strnstr (response, " GET /" , sizeof (response)) == NULL )
419
+ {
420
+ // Unknown response
421
+ if (settings.debugTcpServer )
422
+ systemPrintf (" Unknown response: %s\r\n " , response);
423
+
424
+ // Disconnect from client
425
+ tcpServerStopClient (index);
426
+ }
427
+
428
+ // Handle the mount point request, ignore the mount point and start sending data
429
+ else
430
+ {
431
+ // NTRIP Client is sending us their mount point. Begin sending RTCM.
432
+ if (settings.debugTcpServer )
433
+ systemPrintln (" NTRIP Client connected - Sending ICY 200 OK" );
434
+
435
+ // Successfully connected to the mount point
436
+ char confirmConnection[] = " ICY 200 OK\r\n " ;
437
+ tcpServerClient[index]->write (confirmConnection, strlen (confirmConnection));
438
+
439
+ // Start sending RTCM
440
+ tcpServerClientState[index] = TCP_SERVER_CLIENT_SENDING_DATA;
441
+ }
442
+ break ;
443
+
444
+ case TCP_SERVER_CLIENT_SENDING_DATA:
445
+ break ;
446
+ }
353
447
break ;
354
448
}
355
449
356
450
// Determine if the client data structure is not in use
357
451
while ((tcpServerClientConnected & (1 << index)) == 0 )
358
452
{
453
+ // Data structure not in use
359
454
if (tcpServerClient[index] == nullptr )
360
455
tcpServerClient[index] = new NetworkClient;
361
456
362
- // Data structure not in use
363
457
// Check for another TCP server client
364
458
*tcpServerClient[index] = tcpServer->accept ();
365
459
366
460
// Exit if no TCP server client found
367
- if (*tcpServerClient[index])
368
- {
369
- // TCP server client found
370
- // Start processing the new TCP server client connection
371
- tcpServerClientIpAddress[index] = tcpServerClient[index]->remoteIP ();
372
- if ((settings.debugTcpServer || PERIODIC_DISPLAY (PD_TCP_SERVER_DATA)) && (!inMainMenu))
373
- systemPrintf (" %s client %d connected to %s\r\n " ,
374
- tcpServerName, index,
375
- tcpServerClientIpAddress[index].toString ().c_str ());
376
-
377
- // If we are acting as an NTRIP Caster, intercept the initial communication from the client
378
- // and respond accordingly
379
- if (tcpServerInCasterMode)
380
- {
381
- // Read response from client
382
- spot = 0 ;
383
- while (tcpServerClient[index]->available ())
384
- {
385
- response[spot++] = tcpServerClient[index]->read ();
386
- if (spot == sizeof (response))
387
- spot = 0 ; // Wrap
388
- }
389
- response[spot] = ' \0 ' ; // Terminate string
390
-
391
- if (strnstr (response, " GET / " , sizeof (response)) != NULL ) // No mount point in header
392
- {
393
- if (settings.debugTcpServer )
394
- systemPrintln (" Mount point table requested." );
395
-
396
- // Respond with a single mountpoint
397
- const char fakeSourceTable[] =
398
- " SOURCETABLE 200 OK\r\n Server: SparkPNT Caster/1.0\r\n Content-Type: "
399
- " text/plain\r\n Content-Length: 96\r\n\r\n STR;SparkBase;none;RTCM "
400
- " 3.0;none;none;none;none;none;none;none;none;none;none;none;B;N;none;none" ;
401
-
402
- tcpServerClient[index]->write (fakeSourceTable, strlen (fakeSourceTable));
461
+ if (!*tcpServerClient[index])
462
+ break ;
403
463
404
- tcpServerStopClient (index); // Disconnect from client
405
- }
406
- else if ( strnstr (response, " GET / " , sizeof (response)) != NULL ) // Mount point in header
407
- {
408
- // NTRIP Client is sending us their mount point. Begin sending RTCM.
409
- if (settings. debugTcpServer )
410
- systemPrintln ( " NTRIP Client connected - Sending ICY 200 OK " );
464
+ // TCP server client found
465
+ // Start processing the new TCP server client connection
466
+ tcpServerClientIpAddress[index] = tcpServerClient[index]-> remoteIP ();
467
+ if ((settings. debugTcpServer || PERIODIC_DISPLAY (PD_TCP_SERVER_DATA)) && (!inMainMenu))
468
+ systemPrintf ( " %s client %d connected to %s \r\n " ,
469
+ tcpServerName, index,
470
+ tcpServerClientIpAddress[index]. toString (). c_str () );
411
471
412
- char confirmConnection[] = " ICY 200 OK\r\n " ;
413
- tcpServerClient[index]->write (confirmConnection, strlen (confirmConnection));
414
- }
415
- else
416
- {
417
- // Unknown response
418
- if (settings.debugTcpServer )
419
- systemPrintf (" Unknown response: %s\r\n " , response);
420
- }
421
- } // tcpServerInCasterMode
472
+ // Mark this client as connected
473
+ tcpServerClientConnected = tcpServerClientConnected | (1 << index);
422
474
423
- // Start the data timer
424
- tcpServerClientTimer[index] = millis ();
475
+ // Start the data timer
476
+ tcpServerClientTimer[index] = millis ();
477
+ tcpServerClientDataSent = tcpServerClientDataSent | (1 << index);
425
478
479
+ // Set the client state
480
+ if (tcpServerInCasterMode)
481
+ tcpServerClientState[index] = TCP_SERVER_CLIENT_WAIT_REQUEST;
482
+ else
426
483
// Make client online after any NTRIP injections so ring buffer can start outputting data to it
427
- tcpServerClientConnected = tcpServerClientConnected | (1 << index);
428
- tcpServerClientDataSent = tcpServerClientDataSent | (1 << index);
429
- }
484
+ tcpServerClientState[index] = TCP_SERVER_CLIENT_SENDING_DATA;
430
485
break ;
431
486
}
432
487
}
@@ -647,6 +702,8 @@ void tcpServerUpdate()
647
702
if (tcpServerStart ())
648
703
{
649
704
networkUserAdd (NETCONSUMER_TCP_SERVER, __FILE__, __LINE__);
705
+ for (index = 0 ; index < TCP_SERVER_MAX_CLIENTS; index++)
706
+ tcpServerClientState[index] = TCP_SERVER_CLIENT_OFF;
650
707
tcpServerSetState (TCP_SERVER_STATE_RUNNING);
651
708
}
652
709
}
@@ -707,8 +764,12 @@ void tcpServerValidateTables()
707
764
sizeof (tcpServerClientConnected) * 8 );
708
765
reportFatalError (line);
709
766
}
767
+
768
+ // Verify the state name tables
710
769
if (tcpServerStateNameEntries != TCP_SERVER_STATE_MAX)
711
770
reportFatalError (" Fix tcpServerStateNameEntries to match tcpServerStates" );
771
+ if (tcpServerClientStateNameEntries != TCP_SERVER_CLIENT_MAX)
772
+ reportFatalError (" Fix tcpServerClientStateNameEntries to match tcpServerClientStates" );
712
773
}
713
774
714
775
// ----------------------------------------
0 commit comments