Interface
Every module extends the following interface, which exposes a series of hooking points to tap into the data-processing pipeline.
By overriding these hooks, you can change how each I/O packet is sent to the subsequent step:
onPacketReceived
afterPacketReceived
onLoop
executeUserCommand
start
set
RFQuack Module Interface Class
#include "../RFQModule.h"
#include "../../rfquack_common.h"
#include "../../rfquack_radio.h"
extern RFQRadio *rfqRadio; // Bridge between RFQuack and radio drivers.
class MyAwesomeModule : public RFQModule, public OnPacketReceived,
public AfterPacketReceived, public OnLoop {
public:
MyAwesomeModule() : RFQModule("AwesomeModuleSlug") {}
void onInit() override {
// onInit() is called once, when module is loaded.
// here you can setup internal variables.
}
bool onPacketReceived(rfquack_Packet &pkt, rfquack_WhichRadio whichRadio) override {
// onPacketReceived() is called when a packet is captured.
// This method is called by the driver itself; you should use this method
// for tasks which should be performed as soon as a packet is received.
// If this method returns 'true' the packet is passed to the next module.
// If this method returns 'false' the packet is dropped and no further
// calls to modules will be performed.
// If every module returns 'true' then the packet gets stored in memory.
// Note: This method is called only if the module is enabled.
// It you don't plan to use this hook, you can remove this method and stop extending OnPacketReceived
return true;
}
bool afterPacketReceived(rfquack_Packet &pkt, rfquack_WhichRadio whichRadio) override {
// afterPacketReceived() is called when a packet gets popped from RFQuack's
// internal RX queue.
// Here you should perform non-time-sensitive tasks as well as packet
// modifications, retransmissions etc.
// If this method returns 'true' the packet is passed to the next module.
// If this method returns 'false' the packet is dropped and no further
// calls to modules will be performed.
// If every module returns 'true' then the packet will be sent to CLI.
// Note: This method is called only if the module is enabled.
// It you don't plan to use this hook, you can remove this method and stop extending AfterPacketReceived
return true;
}
void onLoop() override {
// onLoop(), as name suggests, is continuously called.
// Here you can perform logic which does not fit in other hooks.
// Note: This method is called only if the module is enabled.
// It you don't plan to use this hook, you can remove this method and stop extending OnLoop
return true;
}
void executeUserCommand(char *verb, char **args, uint8_t argsLen,
char *messagePayload, unsigned int messageLen) override {
// Use macros to handle incoming CLI messages:
// Set this bool from cli using: q.AwesomeModuleSlug.bool1 = True;
// Get this bool from cli using: q.AwesomeModuleSlug.bool1
CMD_MATCHES_BOOL("bool1",
"Set this bool from cli ",
boolExample)
// Same applies to CMD_MATCHES_FLOAT, CMD_MATCHES_INT, CMD_MATCHES_UINT, CMD_MATCHES_WHICHRADIO
// Call a method from cli with a Void argument:
// q.AwesomeModuleSlug.start()
// You'll have access to two variables:
// 'reply': Reply to be sent to client
// 'pkt': Deserialized argument received from client (rfquack_Void, in this case)
CMD_MATCHES_METHOD_CALL(rfquack_VoidValue, "start", "Starts something", start(reply))
// Call a method from cli with a protobuf argument, example with: "rfquack_Register"
// q.AwesomeModuleSlug.set(address=2, value=3) # A rfquack_Register will be automatically created and sent.
CMD_MATCHES_METHOD_CALL(rfquack_Register, "set", "Set something", set(pkt, reply))
}
void start(rfquack_CmdReply &reply) {
// Do something.
// Optionally with a message and a return code (0)
setReplyMessage(reply, F("optional message!"), 0);
}
void set(rfquack_Register pkt, rfquack_CmdReply &reply) {
// Use pkt.address;
// Use pkt.value;
setReplyMessage(reply, F("Done!"), 0);
}
private:
bool boolExample;
};