mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-07-28 09:53:45 +02:00
Broadcast changes (1) UNTESTED
This commit is contained in:
@@ -16,16 +16,100 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "CommandDistributor.h"
|
||||
#include "SerialManager.h"
|
||||
#include "WiThrottle.h"
|
||||
#include "DIAG.h"
|
||||
#include "defines.h"
|
||||
#include "DCCWaveform.h"
|
||||
|
||||
DCCEXParser * CommandDistributor::parser=0;
|
||||
const byte NO_CLIENT=255;
|
||||
|
||||
void CommandDistributor::parse(byte clientId,byte * buffer, RingStream * streamer) {
|
||||
if (buffer[0] == '<') {
|
||||
if (!parser) parser = new DCCEXParser();
|
||||
parser->parse(streamer, buffer, streamer);
|
||||
}
|
||||
else WiThrottle::getThrottle(clientId)->parse(streamer, buffer);
|
||||
RingStream * CommandDistributor::ring=0;
|
||||
byte CommandDistributor::ringClient=NO_CLIENT;
|
||||
CommandDistributor::clientType CommandDistributor::clients[8]={
|
||||
NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE};
|
||||
RingStream * CommandDistributor::broadcastBufferWriter=new RingStream(100);
|
||||
|
||||
void CommandDistributor::parse(byte clientId,byte * buffer, RingStream * stream) {
|
||||
ring=stream;
|
||||
ringClient=stream->peekTargetMark();
|
||||
if (buffer[0] == '<') {
|
||||
clients[clientId]=COMMAND_TYPE;
|
||||
DCCEXParser::parse(stream, buffer, ring);
|
||||
}
|
||||
else {
|
||||
clients[clientId]=WITHROTTLE_TYPE;
|
||||
WiThrottle::getThrottle(clientId)->parse(ring, buffer);
|
||||
}
|
||||
ringClient=NO_CLIENT;
|
||||
}
|
||||
|
||||
void CommandDistributor::forget(byte clientId) {
|
||||
clients[clientId]=NONE_TYPE;
|
||||
}
|
||||
|
||||
|
||||
void CommandDistributor::broadcast() {
|
||||
broadcastBufferWriter->write((byte)'\0');
|
||||
|
||||
/* Boadcast to Serials */
|
||||
SerialManager::broadcast(broadcastBufferWriter);
|
||||
|
||||
#if defined(WIFI_ON) | defined(ETHERNET_ON)
|
||||
// If we are broadcasting from a wifi/eth process we need to complete its output
|
||||
// before merging broadcasts in the ring, then reinstate it in case
|
||||
// the process continues to output to its client.
|
||||
if (ringClient!=NO_CLIENT) ring->commit();
|
||||
|
||||
/* loop through ring clients */
|
||||
for (byte clientId=0; clientId<sizeof(clients); clientId++) {
|
||||
if (clients[clientId]==NONE_TYPE) continue;
|
||||
ring->mark(clientId);
|
||||
|
||||
if (clients[clientId]==COMMAND_TYPE) broadcastBufferWriter->printBuffer(ring);
|
||||
else if (clients[clientId]==WITHROTTLE_TYPE) {
|
||||
// TODO... withrottle broadcasts?
|
||||
}
|
||||
|
||||
ring->commit();
|
||||
}
|
||||
if (ringClient!=NO_CLIENT) ring->mark(ringClient);
|
||||
|
||||
#endif
|
||||
broadcastBufferWriter->flush();
|
||||
}
|
||||
|
||||
void CommandDistributor::broadcastSensor(int16_t id, bool on ) {
|
||||
StringFormatter::send(broadcastBufferWriter,F("<%c %d>\n"), on?'Q':'q', id);
|
||||
broadcast();
|
||||
}
|
||||
|
||||
void CommandDistributor::broadcastTurnout(int16_t id, bool isClosed ) {
|
||||
// For DCC++ classic compatibility, state reported to JMRI is 1 for thrown and 0 for closed;
|
||||
StringFormatter::send(broadcastBufferWriter,F("<H %d %d>\n"),id, !isClosed);
|
||||
broadcast();
|
||||
}
|
||||
|
||||
void CommandDistributor::broadcastLoco(int16_t cab, int16_t slot, byte speed, uint32_t functions) {
|
||||
StringFormatter::send(broadcastBufferWriter,F("<l %d %d %d %x>\n"), cab,slot,speed,functions);
|
||||
broadcast();
|
||||
}
|
||||
|
||||
void CommandDistributor::broadcastPower() {
|
||||
const FSH * reason;
|
||||
bool main=DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON;
|
||||
bool prog=DCCWaveform::progTrack.getPowerMode()==POWERMODE::ON;
|
||||
bool join=DCCWaveform::progTrackSyncMain;
|
||||
if (main && prog && join) reason=F("p1 JOIN");
|
||||
else if (main && prog) reason=F("p1");
|
||||
else if (main) reason=F("p1 MAIN");
|
||||
else if (prog) reason=F("p1 PROG");
|
||||
StringFormatter::send(broadcastBufferWriter,F("<%S>\n"),reason);
|
||||
LCD(2,reason);
|
||||
broadcast();
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user