V148
Fork of RadioHead-148 by
RHMesh.h@0:ab4e012489ef, 2015-10-15 (annotated)
- Committer:
- davidr99
- Date:
- Thu Oct 15 01:27:00 2015 +0000
- Revision:
- 0:ab4e012489ef
Messy start, but a port for RadioHead.; Currently the SPI modulus are the only ones that work.
Who changed what in which revision?
User | Revision | Line number | New 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 |