Skip to content

Commit deaf832

Browse files
committed
Introduced module SerialProtocols, Moved current protocol to DatabaseProtocol, added unit test to SerialTransciever around delegation.
1 parent a072cb3 commit deaf832

22 files changed

+299
-92
lines changed

src/modem/SerialProtocol.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#ifndef MODEM_SERIAL_PROTOCOL_H
2+
#define MODEM_SERIAL_PROTOCOL_H
3+
4+
#include <string>
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+
*/
24+
virtual const std::vector<std::string>& commands() const = 0;
25+
26+
/*
27+
* Execute command, takes over the serial line until execution is done.
28+
*/
29+
virtual void Execute(const std::string& command, InputStream* in, OutputStream* out) = 0;
30+
31+
};
32+
33+
} // modem
34+
} // firebase
35+
36+
#endif // MODEM_SERIAL_PROTOCOL_H

src/modem/SerialTransceiver.cpp

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,18 @@ namespace firebase {
44
namespace modem {
55

66
void SerialTransceiver::begin(Stream* serial) {
7-
std::unique_ptr<Firebase> fbase;
8-
97
in_.reset(new ArduinoInputStream(serial));
108
out_.reset(new ArduinoOutputStream(serial));
119
}
1210

11+
void SerialTransceiver::RegisterProtocol(std::unique_ptr<SerialProtocol> protocol) {
12+
for (const std::string& command : protocol->commands()) {
13+
command_to_protocol_.insert({command, protocol.get()});
14+
}
15+
16+
protocols_.push_back(std::move(protocol));
17+
}
18+
1319
void SerialTransceiver::loop() {
1420
String command_name = in_->readStringUntil(' ');
1521

@@ -18,44 +24,15 @@ void SerialTransceiver::loop() {
1824
return;
1925
}
2026

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-
}
26-
return;
27-
} else if (!fbase_) {
28-
in_->drain();
29-
out_->println("-FAIL Must call BEGIN before anything else.");
30-
return;
31-
}
32-
33-
std::unique_ptr<Command> command = CreateCommand(command_name, fbase_.get());
34-
if (!command) {
27+
auto itr = command_to_protocol_.find(command_name);
28+
if (itr == command_to_protocol_.end()) {
3529
in_->drain();
3630
out_->println(String("-FAIL Invalid command '") + command_name + "'." );
3731
return;
3832
}
39-
40-
command->execute(command_name, in_.get(), out_.get());
33+
itr->second->Execute(command_name, in_.get(), out_.get());
4134
}
4235

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-
}
5936

6037
} // modem
6138
} // firebase

src/modem/SerialTransceiver.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,31 @@
22
#define MODEM_SERIAL_TRANSCIEVER_H
33

44
#include <memory>
5+
#include <unordered_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_;
29+
std::unordered_map<std::string, SerialProtocol*> command_to_protocol_;
2330
};
2431

2532
} // modem

src/modem/command.h

Lines changed: 31 additions & 0 deletions
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

src/modem/db/DatabaseProtocol.cpp

Lines changed: 61 additions & 0 deletions
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<std::string> commands {
7+
"BEGIN_DB",
8+
"GET",
9+
"SET",
10+
"PUSH",
11+
"REMOVE",
12+
"BEGIN_STREAM"
13+
}
14+
}
15+
16+
const std::vector<std::string>& DatabaseProtocol::commands() const {
17+
return commands;
18+
}
19+
20+
void DatabaseProtocol::Execute(const std::string& command, InputStream* in,
21+
OutputStream* out) {
22+
if (command_name == "BEGIN_DB") {
23+
BeginCommand command;
24+
if (command.execute(command_name, in_.get(), out_.get())) {
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 Invalid command '") + command_name + "'." );
38+
return;
39+
}
40+
41+
command->execute(command_name, in_.get(), out_.get());
42+
}
43+
44+
std::unique_ptr<Command> SerialTransceiver::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

src/modem/db/DatabaseProtocol.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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+
7+
namespace firebase {
8+
namespace modem {
9+
10+
class DatabaseProtocol : public SerialProtocol {
11+
public:
12+
const std::vector<std::string>& commands() const override;
13+
void Execute(const std::string& command, InputStream* in, OutputStream* out) override;
14+
private:
15+
std::unique_ptr<Command> CreateCommand(const String& text, Firebase* fbase);
16+
};
17+
18+
19+
} // modem
20+
} // firebase
21+
22+
23+
#endif // MODEM_DB_DATABASE_PROTOCOL_H

src/modem/begin-command.cpp renamed to src/modem/db/begin-command.cpp

Lines changed: 1 addition & 1 deletion
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 {

src/modem/commands.h renamed to src/modem/db/commands.h

Lines changed: 4 additions & 20 deletions
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

src/modem/get-command.cpp renamed to src/modem/db/get-command.cpp

Lines changed: 1 addition & 1 deletion
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 {

src/modem/push-command.cpp renamed to src/modem/db/push-command.cpp

Lines changed: 1 addition & 1 deletion
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 {

0 commit comments

Comments
 (0)