Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

Commit 854bb0c

Browse files
authored
Merge pull request #189 from ed7coyne/modular-protocols
Add concept of multiple protocols to SerialTransciever.
2 parents b36352d + 6b4c5ba commit 854bb0c

28 files changed

+318
-95
lines changed

Diff for: examples/FirebaseSerialHost_ESP8266/FirebaseSerialHost_ESP8266.ino

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ void setup() {
5555
delay(5000);
5656
}
5757

58+
transceiver.RegisterProtocol(new DatabaseProtocol());
5859
transceiver.begin(&data_serial);
5960
}
6061

Diff for: examples/FirebaseSerialTerminal_ESP8266/FirebaseSerialTerminal_ESP8266.ino

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ void setup() {
5555
Serial.print("connected: ");
5656
Serial.println(WiFi.localIP());
5757

58+
transceiver.RegisterProtocol(new DatabaseProtocol());
5859
transceiver.begin(&Serial);
5960
}
6061

Diff for: examples/FirebaseSerialTerminal_ESP8266/begin.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
BEGIN $YOUR_HOST $YOUR_SECRET
1+
BEGIN_DB $YOUR_HOST $YOUR_SECRET
22

Diff for: src/SerialTransceiver.h

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#include <string>
22

33
#include "modem/SerialTransceiver.h"
4+
#include "modem/db/DatabaseProtocol.h"
5+
46
// Bring them into the base namespace for easier use in arduino ide.
57
using firebase::modem::SerialTransceiver;
8+
using firebase::modem::DatabaseProtocol;

Diff for: src/modem/SerialProtocol.h

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#ifndef MODEM_SERIAL_PROTOCOL_H
2+
#define MODEM_SERIAL_PROTOCOL_H
3+
4+
#include <WString.h>
5+
#include <vector>
6+
7+
namespace firebase {
8+
namespace modem {
9+
10+
class InputStream;
11+
class OutputStream;
12+
13+
/*
14+
* Define generic baseclass for all serial protocols that wish to share
15+
* the common commandspace.
16+
*/
17+
class SerialProtocol {
18+
public:
19+
virtual ~SerialProtocol() = default;
20+
21+
/*
22+
* Returns all commands this protocol supports, commands are single words.
23+
* Returned vector MUST be sorted.
24+
*/
25+
virtual const std::vector<String>& commands() const = 0;
26+
27+
/*
28+
* Execute command, takes over the serial line until execution is done.
29+
*/
30+
virtual void Execute(const String& command, InputStream* in, OutputStream* out) = 0;
31+
32+
};
33+
34+
} // modem
35+
} // firebase
36+
37+
#endif // MODEM_SERIAL_PROTOCOL_H

Diff for: src/modem/SerialTransceiver.cpp

+14-31
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
#include "SerialTransceiver.h"
22

3+
#include <algorithm>
4+
35
namespace firebase {
46
namespace modem {
57

68
void SerialTransceiver::begin(Stream* serial) {
7-
std::unique_ptr<Firebase> fbase;
8-
99
in_.reset(new ArduinoInputStream(serial));
1010
out_.reset(new ArduinoOutputStream(serial));
1111
}
1212

13+
void SerialTransceiver::RegisterProtocol(std::unique_ptr<SerialProtocol> protocol) {
14+
protocols_.push_back(std::move(protocol));
15+
}
16+
1317
void SerialTransceiver::loop() {
1418
String command_name = in_->readStringUntil(' ');
1519

@@ -18,44 +22,23 @@ void SerialTransceiver::loop() {
1822
return;
1923
}
2024

21-
if (command_name == "BEGIN") {
22-
BeginCommand command;
23-
if (command.execute(command_name, in_.get(), out_.get())) {
24-
fbase_ = std::move(command.firebase());
25+
bool command_found = false;
26+
for (auto& protocol : protocols_) {
27+
const std::vector<String>& commands = protocol->commands();
28+
if (std::binary_search(commands.begin(), commands.end(), command_name)) {
29+
protocol->Execute(command_name, in_.get(), out_.get());
30+
command_found = true;
31+
break;
2532
}
26-
return;
27-
} else if (!fbase_) {
28-
in_->drain();
29-
out_->println("-FAIL Must call BEGIN before anything else.");
30-
return;
3133
}
3234

33-
std::unique_ptr<Command> command = CreateCommand(command_name, fbase_.get());
34-
if (!command) {
35+
if (!command_found) {
3536
in_->drain();
3637
out_->println(String("-FAIL Invalid command '") + command_name + "'." );
3738
return;
3839
}
39-
40-
command->execute(command_name, in_.get(), out_.get());
4140
}
4241

43-
std::unique_ptr<Command> SerialTransceiver::CreateCommand(const String& text,
44-
Firebase* fbase) {
45-
std::unique_ptr<Command> command;
46-
if (text == "GET") {
47-
command.reset(new GetCommand(fbase));
48-
} else if (text == "SET") {
49-
command.reset(new SetCommand(fbase));
50-
} else if (text == "PUSH") {
51-
command.reset(new PushCommand(fbase));
52-
} else if (text == "REMOVE") {
53-
command.reset(new RemoveCommand(fbase));
54-
} else if (text == "BEGIN_STREAM") {
55-
command.reset(new StreamCommand(fbase));
56-
}
57-
return command;
58-
}
5942

6043
} // modem
6144
} // firebase

Diff for: src/modem/SerialTransceiver.h

+11-5
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,30 @@
22
#define MODEM_SERIAL_TRANSCIEVER_H
33

44
#include <memory>
5+
#include <map>
56

6-
#include "Firebase.h"
7-
#include "modem/commands.h"
7+
#include "modem/SerialProtocol.h"
8+
#include "modem/input-stream.h"
9+
#include "modem/output-stream.h"
810

911
namespace firebase {
1012
namespace modem {
1113

1214
class SerialTransceiver {
1315
public:
16+
void RegisterProtocol(std::unique_ptr<SerialProtocol> protocol);
17+
// Also takes ownership as above but more arduino friendly.
18+
void RegisterProtocol(SerialProtocol* protocol) {
19+
RegisterProtocol(std::unique_ptr<SerialProtocol>(protocol));
20+
}
21+
1422
void begin(Stream* serial);
1523
void loop();
1624

1725
private:
18-
std::unique_ptr<Command> CreateCommand(const String& name, Firebase* fbase);
19-
20-
std::unique_ptr<Firebase> fbase_;
2126
std::unique_ptr<ArduinoInputStream> in_;
2227
std::unique_ptr<ArduinoOutputStream> out_;
28+
std::vector<std::unique_ptr<SerialProtocol>> protocols_;
2329
};
2430

2531
} // modem

Diff for: src/modem/command.h

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#ifndef MODEM_COMMAND_H
2+
#define MODEM_COMMAND_H
3+
4+
#include "Firebase.h"
5+
#include "modem/output-stream.h"
6+
#include "modem/input-stream.h"
7+
8+
namespace firebase {
9+
namespace modem {
10+
11+
class Command {
12+
public:
13+
Command(Firebase* fbase) : fbase_(fbase) {}
14+
15+
// Execute command, reading any additional data needed from stream.
16+
// Return false if execution failed.
17+
virtual bool execute(const String& command,
18+
InputStream* in, OutputStream* out) = 0;
19+
protected:
20+
Firebase& fbase() {
21+
return *fbase_;
22+
}
23+
24+
private:
25+
Firebase* fbase_;
26+
};
27+
28+
} // modem
29+
} // firebase
30+
31+
#endif //MODEM_COMMAND_H

Diff for: src/modem/db/DatabaseProtocol.cpp

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include "modem/db/DatabaseProtocol.h"
2+
3+
namespace firebase {
4+
namespace modem {
5+
namespace {
6+
const std::vector<String> kCommands {
7+
"BEGIN_DB",
8+
"GET",
9+
"SET",
10+
"PUSH",
11+
"REMOVE",
12+
"BEGIN_STREAM"
13+
};
14+
}
15+
16+
const std::vector<String>& DatabaseProtocol::commands() const {
17+
return kCommands;
18+
}
19+
20+
void DatabaseProtocol::Execute(const String& command_name, InputStream* in,
21+
OutputStream* out) {
22+
if (command_name == "BEGIN_DB") {
23+
BeginCommand command;
24+
if (command.execute(command_name, in, out)) {
25+
fbase_ = std::move(command.firebase());
26+
}
27+
return;
28+
} else if (!fbase_) {
29+
in->drain();
30+
out->println("-FAIL Must call BEGIN_DB before anything else.");
31+
return;
32+
}
33+
34+
std::unique_ptr<Command> command = CreateCommand(command_name, fbase_.get());
35+
if (!command) {
36+
in->drain();
37+
out->println(String("-FAIL unhandled command '") + command_name + "'." );
38+
return;
39+
}
40+
41+
command->execute(command_name, in, out);
42+
}
43+
44+
std::unique_ptr<Command> DatabaseProtocol::CreateCommand(const String& text,
45+
Firebase* fbase) {
46+
std::unique_ptr<Command> command;
47+
if (text == "GET") {
48+
command.reset(new GetCommand(fbase));
49+
} else if (text == "SET") {
50+
command.reset(new SetCommand(fbase));
51+
} else if (text == "PUSH") {
52+
command.reset(new PushCommand(fbase));
53+
} else if (text == "REMOVE") {
54+
command.reset(new RemoveCommand(fbase));
55+
} else if (text == "BEGIN_STREAM") {
56+
command.reset(new StreamCommand(fbase));
57+
}
58+
return command;
59+
}
60+
} // modem
61+
} // firebase

Diff for: src/modem/db/DatabaseProtocol.h

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef MDOEM_DB_DATABASE_PROTOCOL_H
2+
#define MODEM_DB_DATABASE_PROTOCOL_H
3+
4+
#include "modem/SerialProtocol.h"
5+
#include "modem/db/commands.h"
6+
#include "Firebase.h"
7+
8+
namespace firebase {
9+
namespace modem {
10+
11+
class DatabaseProtocol : public SerialProtocol {
12+
public:
13+
const std::vector<String>& commands() const override;
14+
void Execute(const String& command, InputStream* in, OutputStream* out) override;
15+
private:
16+
std::unique_ptr<Command> CreateCommand(const String& text, Firebase* fbase);
17+
18+
std::unique_ptr<Firebase> fbase_;
19+
};
20+
21+
22+
} // modem
23+
} // firebase
24+
25+
26+
#endif // MODEM_DB_DATABASE_PROTOCOL_H

Diff for: src/modem/begin-command.cpp renamed to src/modem/db/begin-command.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "modem/commands.h"
1+
#include "modem/db/commands.h"
22

33
namespace firebase {
44
namespace modem {
@@ -9,7 +9,7 @@ bool BeginCommand::execute(const String& command,
99
return false;
1010
}
1111

12-
if (command != "BEGIN") {
12+
if (command != "BEGIN_DB") {
1313
return false;
1414
}
1515

Diff for: src/modem/commands.h renamed to src/modem/db/commands.h

+4-20
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,14 @@
1-
#ifndef MODEM_COMMAND_H
2-
#define MODEM_COMMAND_H
1+
#ifndef MODEM_DB_COMMANDS_H
2+
#define MODEM_DB_COMMANDS_H
33

44
#include "Firebase.h"
5+
#include "modem/command.h"
56
#include "modem/output-stream.h"
67
#include "modem/input-stream.h"
78

89
namespace firebase {
910
namespace modem {
1011

11-
class Command {
12-
public:
13-
Command(Firebase* fbase) : fbase_(fbase) {}
14-
15-
// Execute command, reading any additional data needed from stream.
16-
// Return false if execution failed.
17-
virtual bool execute(const String& command,
18-
InputStream* in, OutputStream* out) = 0;
19-
protected:
20-
Firebase& fbase() {
21-
return *fbase_;
22-
}
23-
24-
private:
25-
Firebase* fbase_;
26-
};
27-
2812
class GetCommand : public Command {
2913
public:
3014
GetCommand(Firebase* fbase) : Command(fbase) {}
@@ -76,4 +60,4 @@ class StreamCommand : public Command {
7660
} // modem
7761
} // firebase
7862

79-
#endif //MODEM_COMMAND_H
63+
#endif //MODEM_DB_COMMANDS_H

Diff for: src/modem/get-command.cpp renamed to src/modem/db/get-command.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "modem/commands.h"
1+
#include "modem/db/commands.h"
22

33
namespace firebase {
44
namespace modem {

Diff for: src/modem/push-command.cpp renamed to src/modem/db/push-command.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "modem/commands.h"
1+
#include "modem/db/commands.h"
22
#include "modem/json_util.h"
33

44
namespace firebase {

Diff for: src/modem/remove-command.cpp renamed to src/modem/db/remove-command.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "modem/commands.h"
1+
#include "modem/db/commands.h"
22

33
namespace firebase {
44
namespace modem {

Diff for: src/modem/set-command.cpp renamed to src/modem/db/set-command.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "modem/commands.h"
1+
#include "modem/db/commands.h"
22
#include "modem/json_util.h"
33

44
namespace firebase {

Diff for: src/modem/stream-command.cpp renamed to src/modem/db/stream-command.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "modem/commands.h"
1+
#include "modem/db/commands.h"
22

33
namespace firebase {
44
namespace modem {

0 commit comments

Comments
 (0)