V148

Fork of RadioHead-148 by David Rimer

Committer:
ilkaykozak
Date:
Wed Oct 25 05:14:09 2017 +0000
Revision:
1:b7641da2b203
Parent:
0:ab4e012489ef
V148

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davidr99 0:ab4e012489ef 1 // RHMesh.h
davidr99 0:ab4e012489ef 2 //
davidr99 0:ab4e012489ef 3 // Author: Mike McCauley (mikem@airspayce.com)
davidr99 0:ab4e012489ef 4 // Copyright (C) 2011 Mike McCauley
davidr99 0:ab4e012489ef 5 // $Id: RHMesh.h,v 1.15 2015/08/13 02:45:47 mikem Exp $
davidr99 0:ab4e012489ef 6
davidr99 0:ab4e012489ef 7 #ifndef RHMesh_h
davidr99 0:ab4e012489ef 8 #define RHMesh_h
davidr99 0:ab4e012489ef 9
davidr99 0:ab4e012489ef 10 #include <RHRouter.h>
davidr99 0:ab4e012489ef 11
davidr99 0:ab4e012489ef 12 // Types of RHMesh message, used to set msgType in the RHMeshHeader
davidr99 0:ab4e012489ef 13 #define RH_MESH_MESSAGE_TYPE_APPLICATION 0
davidr99 0:ab4e012489ef 14 #define RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST 1
davidr99 0:ab4e012489ef 15 #define RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE 2
davidr99 0:ab4e012489ef 16 #define RH_MESH_MESSAGE_TYPE_ROUTE_FAILURE 3
davidr99 0:ab4e012489ef 17
davidr99 0:ab4e012489ef 18 // Timeout for address resolution in milliecs
davidr99 0:ab4e012489ef 19 #define RH_MESH_ARP_TIMEOUT 4000
davidr99 0:ab4e012489ef 20
davidr99 0:ab4e012489ef 21 /////////////////////////////////////////////////////////////////////
davidr99 0:ab4e012489ef 22 /// \class RHMesh RHMesh.h <RHMesh.h>
davidr99 0:ab4e012489ef 23 /// \brief RHRouter subclass for sending addressed, optionally acknowledged datagrams
davidr99 0:ab4e012489ef 24 /// multi-hop routed across a network, with automatic route discovery
davidr99 0:ab4e012489ef 25 ///
davidr99 0:ab4e012489ef 26 /// Manager class that extends RHRouter to add automatic route discovery within a mesh of adjacent nodes,
davidr99 0:ab4e012489ef 27 /// and route signalling.
davidr99 0:ab4e012489ef 28 ///
davidr99 0:ab4e012489ef 29 /// Unlike RHRouter, RHMesh can be used in networks where the network topology is fluid, or unknown,
davidr99 0:ab4e012489ef 30 /// or if nodes can mode around or go in or out of service. When a node wants to send a
davidr99 0:ab4e012489ef 31 /// message to another node, it will automatically discover a route to the destination node and use it.
davidr99 0:ab4e012489ef 32 /// If the route becomes unavailable, a new route will be discovered.
davidr99 0:ab4e012489ef 33 ///
davidr99 0:ab4e012489ef 34 /// \par Route Discovery
davidr99 0:ab4e012489ef 35 ///
davidr99 0:ab4e012489ef 36 /// When a RHMesh mesh node is initialised, it doe not know any routes to any other nodes
davidr99 0:ab4e012489ef 37 /// (see RHRouter for details on route and the routing table).
davidr99 0:ab4e012489ef 38 /// When you attempt to send a message with sendtoWait, will first check to see if there is a route to the
davidr99 0:ab4e012489ef 39 /// destinastion node in the routing tabl;e. If not, it wil initialite 'Route Discovery'.
davidr99 0:ab4e012489ef 40 /// When a node needs to discover a route to another node, it broadcasts MeshRouteDiscoveryMessage
davidr99 0:ab4e012489ef 41 /// with a message type of RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST.
davidr99 0:ab4e012489ef 42 /// Any node that receives such a request checks to see if it is a request for a route to itself
davidr99 0:ab4e012489ef 43 /// (in which case it makes a unicast reply to the originating node with a
davidr99 0:ab4e012489ef 44 /// MeshRouteDiscoveryMessage
davidr99 0:ab4e012489ef 45 /// with a message type of RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE)
davidr99 0:ab4e012489ef 46 /// otherwise it rebroadcasts the request, after adding itself to the list of nodes visited so
davidr99 0:ab4e012489ef 47 /// far by the request.
davidr99 0:ab4e012489ef 48 ///
davidr99 0:ab4e012489ef 49 /// If a node receives a RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST that already has itself
davidr99 0:ab4e012489ef 50 /// listed in the visited nodes, it knows it has already seen and rebroadcast this request,
davidr99 0:ab4e012489ef 51 /// and threfore ignores it. This prevents broadcast storms.
davidr99 0:ab4e012489ef 52 /// When a node receives a RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST it can use the list of
davidr99 0:ab4e012489ef 53 /// nodes aready visited to deduce routes back towards the originating (requesting node).
davidr99 0:ab4e012489ef 54 /// This also means that when the destination node of the request is reached, it (and all
davidr99 0:ab4e012489ef 55 /// the previous nodes the request visited) will have a route back to the originating node.
davidr99 0:ab4e012489ef 56 /// This means the unicast RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE
davidr99 0:ab4e012489ef 57 /// reply will be routed successfully back to the original route requester.
davidr99 0:ab4e012489ef 58 ///
davidr99 0:ab4e012489ef 59 /// The RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE sent back by the destination node contains
davidr99 0:ab4e012489ef 60 /// the full list of nodes that were visited on the way to the destination.
davidr99 0:ab4e012489ef 61 /// Therefore, intermediate nodes that route the reply back towards the originating node can use the
davidr99 0:ab4e012489ef 62 /// node list in the reply to deduce routes to all the nodes between it and the destination node.
davidr99 0:ab4e012489ef 63 ///
davidr99 0:ab4e012489ef 64 /// Therefore, RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST and
davidr99 0:ab4e012489ef 65 /// RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE together ensure the original requester and all
davidr99 0:ab4e012489ef 66 /// the intermediate nodes know how to route to the source and destination nodes and every node along the path.
davidr99 0:ab4e012489ef 67 ///
davidr99 0:ab4e012489ef 68 /// Note that there is a race condition here that can effect routing on multipath routes. For example,
davidr99 0:ab4e012489ef 69 /// if the route to the destination can traverse several paths, last reply from the destination
davidr99 0:ab4e012489ef 70 /// will be the one used.
davidr99 0:ab4e012489ef 71 ///
davidr99 0:ab4e012489ef 72 /// \par Route Failure
davidr99 0:ab4e012489ef 73 ///
davidr99 0:ab4e012489ef 74 /// RHRouter (and therefore RHMesh) use reliable hop-to-hop delivery of messages using
davidr99 0:ab4e012489ef 75 /// hop-to-hop acknowledgements, but not end-to-end acknowledgements. When sendtoWait() returns,
davidr99 0:ab4e012489ef 76 /// you know that the message has been delivered to the next hop, but not if it is (or even if it can be)
davidr99 0:ab4e012489ef 77 /// delivered to the destination node. If during the course of hop-to-hop routing of a message,
davidr99 0:ab4e012489ef 78 /// one of the intermediate RHMesh nodes finds it cannot deliver to the next hop
davidr99 0:ab4e012489ef 79 /// (say due to a lost route or no acknwledgement from the next hop), it replies to the
davidr99 0:ab4e012489ef 80 /// originator with a unicast MeshRouteFailureMessage RH_MESH_MESSAGE_TYPE_ROUTE_FAILURE message.
davidr99 0:ab4e012489ef 81 /// Intermediate nodes (on the way beack to the originator)
davidr99 0:ab4e012489ef 82 /// and the originating node use this message to delete the route to the destination
davidr99 0:ab4e012489ef 83 /// node of the original message. This means that if a route to a destination becomes unusable
davidr99 0:ab4e012489ef 84 /// (either because an intermediate node is off the air, or has moved out of range) a new route
davidr99 0:ab4e012489ef 85 /// will be established the next time a message is to be sent.
davidr99 0:ab4e012489ef 86 ///
davidr99 0:ab4e012489ef 87 /// \par Message Format
davidr99 0:ab4e012489ef 88 ///
davidr99 0:ab4e012489ef 89 /// RHMesh uses a number of message formats layered on top of RHRouter:
davidr99 0:ab4e012489ef 90 /// - MeshApplicationMessage (message type RH_MESH_MESSAGE_TYPE_APPLICATION).
davidr99 0:ab4e012489ef 91 /// Carries an application layer message for the caller of RHMesh
davidr99 0:ab4e012489ef 92 /// - MeshRouteDiscoveryMessage (message types RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST
davidr99 0:ab4e012489ef 93 /// and RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE). Carries Route Discovery messages
davidr99 0:ab4e012489ef 94 /// (broadcast) and replies (unicast).
davidr99 0:ab4e012489ef 95 /// - MeshRouteFailureMessage (message type RH_MESH_MESSAGE_TYPE_ROUTE_FAILURE) Informs nodes of
davidr99 0:ab4e012489ef 96 /// route failures.
davidr99 0:ab4e012489ef 97 ///
davidr99 0:ab4e012489ef 98 /// Part of the Arduino RH library for operating with HopeRF RH compatible transceivers
davidr99 0:ab4e012489ef 99 /// (see http://www.hoperf.com)
davidr99 0:ab4e012489ef 100 ///
davidr99 0:ab4e012489ef 101 /// \par Memory
davidr99 0:ab4e012489ef 102 ///
davidr99 0:ab4e012489ef 103 /// RHMesh programs require significant amount of SRAM, often approaching 2kbytes,
davidr99 0:ab4e012489ef 104 /// which is beyond or at the limits of some Arduinos and other processors. Programs
davidr99 0:ab4e012489ef 105 /// with additional software besides basic RHMesh programs may well require even more. If you have insufficient
davidr99 0:ab4e012489ef 106 /// SRAM for your program, it may result in failure to run, or wierd crashes and other hard to trace behaviour.
davidr99 0:ab4e012489ef 107 /// In this event you should consider a processor with more SRAM, such as the MotienoMEGA with 16k
davidr99 0:ab4e012489ef 108 /// (https://lowpowerlab.com/shop/moteinomega) or others.
davidr99 0:ab4e012489ef 109 ///
davidr99 0:ab4e012489ef 110 /// \par Performance
davidr99 0:ab4e012489ef 111 /// This class (in the interests of simple implemtenation and low memory use) does not have
davidr99 0:ab4e012489ef 112 /// message queueing. This means that only one message at a time can be handled. Message transmission
davidr99 0:ab4e012489ef 113 /// failures can have a severe impact on network performance.
davidr99 0:ab4e012489ef 114 /// If you need high performance mesh networking under all conditions consider XBee or similar.
davidr99 0:ab4e012489ef 115 class RHMesh : public RHRouter
davidr99 0:ab4e012489ef 116 {
davidr99 0:ab4e012489ef 117 public:
davidr99 0:ab4e012489ef 118
davidr99 0:ab4e012489ef 119 /// The maximum length permitted for the application payload data in a RHMesh message
davidr99 0:ab4e012489ef 120 #define RH_MESH_MAX_MESSAGE_LEN (RH_ROUTER_MAX_MESSAGE_LEN - sizeof(RHMesh::MeshMessageHeader))
davidr99 0:ab4e012489ef 121
davidr99 0:ab4e012489ef 122 /// Structure of the basic RHMesh header.
davidr99 0:ab4e012489ef 123 typedef struct
davidr99 0:ab4e012489ef 124 {
davidr99 0:ab4e012489ef 125 uint8_t msgType; ///< Type of RHMesh message, one of RH_MESH_MESSAGE_TYPE_*
davidr99 0:ab4e012489ef 126 } MeshMessageHeader;
davidr99 0:ab4e012489ef 127
davidr99 0:ab4e012489ef 128 /// Signals an application layer message for the caller of RHMesh
davidr99 0:ab4e012489ef 129 typedef struct
davidr99 0:ab4e012489ef 130 {
davidr99 0:ab4e012489ef 131 MeshMessageHeader header; ///< msgType = RH_MESH_MESSAGE_TYPE_APPLICATION
davidr99 0:ab4e012489ef 132 uint8_t data[RH_MESH_MAX_MESSAGE_LEN]; ///< Application layer payload data
davidr99 0:ab4e012489ef 133 } MeshApplicationMessage;
davidr99 0:ab4e012489ef 134
davidr99 0:ab4e012489ef 135 /// Signals a route discovery request or reply (At present only supports physical dest addresses of length 1 octet)
davidr99 0:ab4e012489ef 136 typedef struct
davidr99 0:ab4e012489ef 137 {
davidr99 0:ab4e012489ef 138 MeshMessageHeader header; ///< msgType = RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_*
davidr99 0:ab4e012489ef 139 uint8_t destlen; ///< Reserved. Must be 1.g
davidr99 0:ab4e012489ef 140 uint8_t dest; ///< The address of the destination node whose route is being sought
davidr99 0:ab4e012489ef 141 uint8_t route[RH_MESH_MAX_MESSAGE_LEN - 1]; ///< List of node addresses visited so far. Length is implcit
davidr99 0:ab4e012489ef 142 } MeshRouteDiscoveryMessage;
davidr99 0:ab4e012489ef 143
davidr99 0:ab4e012489ef 144 /// Signals a route failure
davidr99 0:ab4e012489ef 145 typedef struct
davidr99 0:ab4e012489ef 146 {
davidr99 0:ab4e012489ef 147 MeshMessageHeader header; ///< msgType = RH_MESH_MESSAGE_TYPE_ROUTE_FAILURE
davidr99 0:ab4e012489ef 148 uint8_t dest; ///< The address of the destination towards which the route failed
davidr99 0:ab4e012489ef 149 } MeshRouteFailureMessage;
davidr99 0:ab4e012489ef 150
davidr99 0:ab4e012489ef 151 /// Constructor.
davidr99 0:ab4e012489ef 152 /// \param[in] driver The RadioHead driver to use to transport messages.
davidr99 0:ab4e012489ef 153 /// \param[in] thisAddress The address to assign to this node. Defaults to 0
davidr99 0:ab4e012489ef 154 RHMesh(RHGenericDriver& driver, uint8_t thisAddress = 0);
davidr99 0:ab4e012489ef 155
davidr99 0:ab4e012489ef 156 /// Sends a message to the destination node. Initialises the RHRouter message header
davidr99 0:ab4e012489ef 157 /// (the SOURCE address is set to the address of this node, HOPS to 0) and calls
davidr99 0:ab4e012489ef 158 /// route() which looks up in the routing table the next hop to deliver to.
davidr99 0:ab4e012489ef 159 /// If no route is known, initiates route discovery and waits for a reply.
davidr99 0:ab4e012489ef 160 /// Then sends the message to the next hop
davidr99 0:ab4e012489ef 161 /// Then waits for an acknowledgement from the next hop
davidr99 0:ab4e012489ef 162 /// (but not from the destination node (if that is different).
davidr99 0:ab4e012489ef 163 /// \param [in] buf The application message data
davidr99 0:ab4e012489ef 164 /// \param [in] len Number of octets in the application message data. 0 is permitted
davidr99 0:ab4e012489ef 165 /// \param [in] dest The destination node address. If the address is RH_BROADCAST_ADDRESS (255)
davidr99 0:ab4e012489ef 166 /// the message will be broadcast to all the nearby nodes, but not routed or relayed.
davidr99 0:ab4e012489ef 167 /// \param [in] flags Optional flags for use by subclasses or application layer,
davidr99 0:ab4e012489ef 168 /// delivered end-to-end to the dest address. The receiver can recover the flags with recvFromAck().
davidr99 0:ab4e012489ef 169 /// \return The result code:
davidr99 0:ab4e012489ef 170 /// - RH_ROUTER_ERROR_NONE Message was routed and delivered to the next hop
davidr99 0:ab4e012489ef 171 /// (not necessarily to the final dest address)
davidr99 0:ab4e012489ef 172 /// - RH_ROUTER_ERROR_NO_ROUTE There was no route for dest in the local routing table
davidr99 0:ab4e012489ef 173 /// - RH_ROUTER_ERROR_UNABLE_TO_DELIVER Not able to deliver to the next hop
davidr99 0:ab4e012489ef 174 /// (usually because it dod not acknowledge due to being off the air or out of range
davidr99 0:ab4e012489ef 175 uint8_t sendtoWait(uint8_t* buf, uint8_t len, uint8_t dest, uint8_t flags = 0);
davidr99 0:ab4e012489ef 176
davidr99 0:ab4e012489ef 177 /// Starts the receiver if it is not running already, processes and possibly routes any received messages
davidr99 0:ab4e012489ef 178 /// addressed to other nodes
davidr99 0:ab4e012489ef 179 /// and delivers any messages addressed to this node.
davidr99 0:ab4e012489ef 180 /// If there is a valid application layer message available for this node (or RH_BROADCAST_ADDRESS),
davidr99 0:ab4e012489ef 181 /// send an acknowledgement to the last hop
davidr99 0:ab4e012489ef 182 /// address (blocking until this is complete), then copy the application message payload data
davidr99 0:ab4e012489ef 183 /// to buf and return true
davidr99 0:ab4e012489ef 184 /// else return false.
davidr99 0:ab4e012489ef 185 /// If a message is copied, *len is set to the length..
davidr99 0:ab4e012489ef 186 /// If from is not NULL, the originator SOURCE address is placed in *source.
davidr99 0:ab4e012489ef 187 /// If to is not NULL, the DEST address is placed in *dest. This might be this nodes address or
davidr99 0:ab4e012489ef 188 /// RH_BROADCAST_ADDRESS.
davidr99 0:ab4e012489ef 189 /// This is the preferred function for getting messages addressed to this node.
davidr99 0:ab4e012489ef 190 /// If the message is not a broadcast, acknowledge to the sender before returning.
davidr99 0:ab4e012489ef 191 /// \param[in] buf Location to copy the received message
davidr99 0:ab4e012489ef 192 /// \param[in,out] len Available space in buf. Set to the actual number of octets copied.
davidr99 0:ab4e012489ef 193 /// \param[in] source If present and not NULL, the referenced uint8_t will be set to the SOURCE address
davidr99 0:ab4e012489ef 194 /// \param[in] dest If present and not NULL, the referenced uint8_t will be set to the DEST address
davidr99 0:ab4e012489ef 195 /// \param[in] id If present and not NULL, the referenced uint8_t will be set to the ID
davidr99 0:ab4e012489ef 196 /// \param[in] flags If present and not NULL, the referenced uint8_t will be set to the FLAGS
davidr99 0:ab4e012489ef 197 /// (not just those addressed to this node).
davidr99 0:ab4e012489ef 198 /// \return true if a valid message was received for this node and copied to buf
davidr99 0:ab4e012489ef 199 bool recvfromAck(uint8_t* buf, uint8_t* len, uint8_t* source = NULL, uint8_t* dest = NULL, uint8_t* id = NULL, uint8_t* flags = NULL);
davidr99 0:ab4e012489ef 200
davidr99 0:ab4e012489ef 201 /// Starts the receiver if it is not running already.
davidr99 0:ab4e012489ef 202 /// Similar to recvfromAck(), this will block until either a valid application layer
davidr99 0:ab4e012489ef 203 /// message available for this node
davidr99 0:ab4e012489ef 204 /// or the timeout expires.
davidr99 0:ab4e012489ef 205 /// \param[in] buf Location to copy the received message
davidr99 0:ab4e012489ef 206 /// \param[in,out] len Available space in buf. Set to the actual number of octets copied.
davidr99 0:ab4e012489ef 207 /// \param[in] timeout Maximum time to wait in milliseconds
davidr99 0:ab4e012489ef 208 /// \param[in] source If present and not NULL, the referenced uint8_t will be set to the SOURCE address
davidr99 0:ab4e012489ef 209 /// \param[in] dest If present and not NULL, the referenced uint8_t will be set to the DEST address
davidr99 0:ab4e012489ef 210 /// \param[in] id If present and not NULL, the referenced uint8_t will be set to the ID
davidr99 0:ab4e012489ef 211 /// \param[in] flags If present and not NULL, the referenced uint8_t will be set to the FLAGS
davidr99 0:ab4e012489ef 212 /// (not just those addressed to this node).
davidr99 0:ab4e012489ef 213 /// \return true if a valid message was copied to buf
davidr99 0:ab4e012489ef 214 bool recvfromAckTimeout(uint8_t* buf, uint8_t* len, uint16_t timeout, uint8_t* source = NULL, uint8_t* dest = NULL, uint8_t* id = NULL, uint8_t* flags = NULL);
davidr99 0:ab4e012489ef 215
davidr99 0:ab4e012489ef 216 protected:
davidr99 0:ab4e012489ef 217
davidr99 0:ab4e012489ef 218 /// Internal function that inspects messages being received and adjusts the routing table if necessary.
davidr99 0:ab4e012489ef 219 /// Called by recvfromAck() immediately after it gets the message from RHReliableDatagram
davidr99 0:ab4e012489ef 220 /// \param [in] message Pointer to the RHRouter message that was received.
davidr99 0:ab4e012489ef 221 /// \param [in] messageLen Length of message in octets
davidr99 0:ab4e012489ef 222 virtual void peekAtMessage(RoutedMessage* message, uint8_t messageLen);
davidr99 0:ab4e012489ef 223
davidr99 0:ab4e012489ef 224 /// Internal function that inspects messages being received and adjusts the routing table if necessary.
davidr99 0:ab4e012489ef 225 /// This is virtual, which lets subclasses override or intercept the route() function.
davidr99 0:ab4e012489ef 226 /// Called by sendtoWait after the message header has been filled in.
davidr99 0:ab4e012489ef 227 /// \param [in] message Pointer to the RHRouter message to be sent.
davidr99 0:ab4e012489ef 228 /// \param [in] messageLen Length of message in octets
davidr99 0:ab4e012489ef 229 virtual uint8_t route(RoutedMessage* message, uint8_t messageLen);
davidr99 0:ab4e012489ef 230
davidr99 0:ab4e012489ef 231 /// Try to resolve a route for the given address. Blocks while discovering the route
davidr99 0:ab4e012489ef 232 /// which may take up to 4000 msec.
davidr99 0:ab4e012489ef 233 /// Virtual so subclasses can override.
davidr99 0:ab4e012489ef 234 /// \param [in] address The physical address to resolve
davidr99 0:ab4e012489ef 235 /// \return true if the address was resolved and added to the local routing table
davidr99 0:ab4e012489ef 236 virtual bool doArp(uint8_t address);
davidr99 0:ab4e012489ef 237
davidr99 0:ab4e012489ef 238 /// Tests if the given address of length addresslen is indentical to the
davidr99 0:ab4e012489ef 239 /// physical address of this node.
davidr99 0:ab4e012489ef 240 /// RHMesh always implements physical addresses as the 1 octet address of the node
davidr99 0:ab4e012489ef 241 /// given by _thisAddress
davidr99 0:ab4e012489ef 242 /// Called by recvfromAck() to test whether a RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST
davidr99 0:ab4e012489ef 243 /// is for this node.
davidr99 0:ab4e012489ef 244 /// Subclasses may want to override to implement more complicated or longer physical addresses
davidr99 0:ab4e012489ef 245 /// \param [in] address Address of the pyysical addres being tested
davidr99 0:ab4e012489ef 246 /// \param [in] addresslen Lengthof the address in bytes
davidr99 0:ab4e012489ef 247 /// \return true if the physical address of this node is identical to address
davidr99 0:ab4e012489ef 248 virtual bool isPhysicalAddress(uint8_t* address, uint8_t addresslen);
davidr99 0:ab4e012489ef 249
davidr99 0:ab4e012489ef 250 private:
davidr99 0:ab4e012489ef 251 /// Temporary message buffer
davidr99 0:ab4e012489ef 252 static uint8_t _tmpMessage[RH_ROUTER_MAX_MESSAGE_LEN];
davidr99 0:ab4e012489ef 253
davidr99 0:ab4e012489ef 254 };
davidr99 0:ab4e012489ef 255
davidr99 0:ab4e012489ef 256 /// @example rf22_mesh_client.pde
davidr99 0:ab4e012489ef 257 /// @example rf22_mesh_server1.pde
davidr99 0:ab4e012489ef 258 /// @example rf22_mesh_server2.pde
davidr99 0:ab4e012489ef 259 /// @example rf22_mesh_server3.pde
davidr99 0:ab4e012489ef 260
davidr99 0:ab4e012489ef 261 #endif
davidr99 0:ab4e012489ef 262