WIP on GPIO example
This commit is contained in:
+26
-1
@@ -1,5 +1,6 @@
|
||||
#include "MeshPlugin.h"
|
||||
#include "NodeDB.h"
|
||||
#include "MeshService.h"
|
||||
#include <assert.h>
|
||||
|
||||
std::vector<MeshPlugin *> *MeshPlugin::plugins;
|
||||
@@ -31,7 +32,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp)
|
||||
|
||||
// Possibly send replies (unless we are handling a locally generated message)
|
||||
if (mp.decoded.want_response && mp.from != nodeDB.getNodeNum())
|
||||
pi.sendResponse(mp.from);
|
||||
pi.sendResponse(mp);
|
||||
|
||||
DEBUG_MSG("Plugin %s handled=%d\n", pi.name, handled);
|
||||
if (handled)
|
||||
@@ -41,4 +42,28 @@ void MeshPlugin::callPlugins(const MeshPacket &mp)
|
||||
DEBUG_MSG("Plugin %s not interested\n", pi.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Messages can be received that have the want_response bit set. If set, this callback will be invoked
|
||||
* so that subclasses can (optionally) send a response back to the original sender. Implementing this method
|
||||
* is optional
|
||||
*/
|
||||
void MeshPlugin::sendResponse(const MeshPacket &req) {
|
||||
auto r = allocReply();
|
||||
if(r) {
|
||||
DEBUG_MSG("Sending response\n");
|
||||
setReplyTo(r, req);
|
||||
service.sendToMesh(r);
|
||||
}
|
||||
else {
|
||||
DEBUG_MSG("WARNING: Client requested response but this plugin did not provide\n");
|
||||
}
|
||||
}
|
||||
|
||||
/** set the destination and packet parameters of packet p intended as a reply to a particular "to" packet
|
||||
* This ensures that if the request packet was sent reliably, the reply is sent that way as well.
|
||||
*/
|
||||
void setReplyTo(MeshPacket *p, const MeshPacket &to) {
|
||||
p->to = to.from;
|
||||
p->want_ack = to.want_ack;
|
||||
}
|
||||
+15
-4
@@ -49,8 +49,19 @@ class MeshPlugin
|
||||
virtual bool handleReceived(const MeshPacket &mp) { return false; }
|
||||
|
||||
/** Messages can be received that have the want_response bit set. If set, this callback will be invoked
|
||||
* so that subclasses can (optionally) send a response back to the original sender. Implementing this method
|
||||
* is optional
|
||||
* so that subclasses can (optionally) send a response back to the original sender. */
|
||||
virtual MeshPacket *allocReply() { return NULL; }
|
||||
|
||||
private:
|
||||
|
||||
/** Messages can be received that have the want_response bit set. If set, this callback will be invoked
|
||||
* so that subclasses can (optionally) send a response back to the original sender. This method calls allocReply()
|
||||
* to generate the reply message, and if !NULL that message will be delivered to whoever sent req
|
||||
*/
|
||||
virtual void sendResponse(NodeNum to) {}
|
||||
};
|
||||
void sendResponse(const MeshPacket &req);
|
||||
};
|
||||
|
||||
/** set the destination and packet parameters of packet p intended as a reply to a particular "to" packet
|
||||
* This ensures that if the request packet was sent reliably, the reply is sent that way as well.
|
||||
*/
|
||||
void setReplyTo(MeshPacket *p, const MeshPacket &to);
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
#include "SinglePortPlugin.h"
|
||||
#include "Router.h"
|
||||
|
||||
/**
|
||||
* A base class for mesh plugins that assume that they are sending/receiving one particular protobuf based
|
||||
@@ -34,12 +33,10 @@ template <class T> class ProtobufPlugin : private SinglePortPlugin
|
||||
* You can then send this packet (after customizing any of the payload fields you might need) with
|
||||
* service.sendToMesh()
|
||||
*/
|
||||
MeshPacket *allocForSending(const T &payload)
|
||||
MeshPacket *allocDataProtobuf(const T &payload)
|
||||
{
|
||||
// Update our local node info with our position (even if we don't decide to update anyone else)
|
||||
MeshPacket *p = router->allocForSending();
|
||||
p->decoded.which_payload = SubPacket_data_tag;
|
||||
p->decoded.data.portnum = ourPortNum;
|
||||
MeshPacket *p = allocDataPacket();
|
||||
|
||||
p->decoded.data.payload.size =
|
||||
pb_encode_to_bytes(p->decoded.data.payload.bytes, sizeof(p->decoded.data.payload.bytes), fields, &payload);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "MeshPlugin.h"
|
||||
#include "Router.h"
|
||||
|
||||
/**
|
||||
* Most plugins are only interested in sending/receving one particular portnum. This baseclass simplifies that common
|
||||
@@ -21,4 +22,19 @@ class SinglePortPlugin : public MeshPlugin
|
||||
* @return true if you want to receive the specified portnum
|
||||
*/
|
||||
virtual bool wantPortnum(PortNum p) { return p == ourPortNum; }
|
||||
|
||||
/**
|
||||
* Return a mesh packet which has been preinited as a data packet with a particular port number.
|
||||
* You can then send this packet (after customizing any of the payload fields you might need) with
|
||||
* service.sendToMesh()
|
||||
*/
|
||||
MeshPacket *allocDataPacket()
|
||||
{
|
||||
// Update our local node info with our position (even if we don't decide to update anyone else)
|
||||
MeshPacket *p = router->allocForSending();
|
||||
p->decoded.which_payload = SubPacket_data_tag;
|
||||
p->decoded.data.portnum = ourPortNum;
|
||||
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -14,32 +14,32 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
typedef enum _HardwareMessage_MessageType {
|
||||
HardwareMessage_MessageType_UNSET = 0,
|
||||
HardwareMessage_MessageType_WRITE_GPIOS = 1,
|
||||
HardwareMessage_MessageType_WATCH_GPIOS = 2,
|
||||
HardwareMessage_MessageType_GPIOS_CHANGED = 3,
|
||||
HardwareMessage_MessageType_READ_GPIOS = 4,
|
||||
HardwareMessage_MessageType_READ_GPIOS_REPLY = 5
|
||||
} HardwareMessage_MessageType;
|
||||
typedef enum _HardwareMessage_Type {
|
||||
HardwareMessage_Type_UNSET = 0,
|
||||
HardwareMessage_Type_WRITE_GPIOS = 1,
|
||||
HardwareMessage_Type_WATCH_GPIOS = 2,
|
||||
HardwareMessage_Type_GPIOS_CHANGED = 3,
|
||||
HardwareMessage_Type_READ_GPIOS = 4,
|
||||
HardwareMessage_Type_READ_GPIOS_REPLY = 5
|
||||
} HardwareMessage_Type;
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _HardwareMessage {
|
||||
HardwareMessage_MessageType typ;
|
||||
HardwareMessage_Type typ;
|
||||
uint64_t gpio_mask;
|
||||
uint64_t gpio_value;
|
||||
} HardwareMessage;
|
||||
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _HardwareMessage_MessageType_MIN HardwareMessage_MessageType_UNSET
|
||||
#define _HardwareMessage_MessageType_MAX HardwareMessage_MessageType_READ_GPIOS_REPLY
|
||||
#define _HardwareMessage_MessageType_ARRAYSIZE ((HardwareMessage_MessageType)(HardwareMessage_MessageType_READ_GPIOS_REPLY+1))
|
||||
#define _HardwareMessage_Type_MIN HardwareMessage_Type_UNSET
|
||||
#define _HardwareMessage_Type_MAX HardwareMessage_Type_READ_GPIOS_REPLY
|
||||
#define _HardwareMessage_Type_ARRAYSIZE ((HardwareMessage_Type)(HardwareMessage_Type_READ_GPIOS_REPLY+1))
|
||||
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define HardwareMessage_init_default {_HardwareMessage_MessageType_MIN, 0, 0}
|
||||
#define HardwareMessage_init_zero {_HardwareMessage_MessageType_MIN, 0, 0}
|
||||
#define HardwareMessage_init_default {_HardwareMessage_Type_MIN, 0, 0}
|
||||
#define HardwareMessage_init_zero {_HardwareMessage_Type_MIN, 0, 0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define HardwareMessage_typ_tag 1
|
||||
|
||||
Reference in New Issue
Block a user