Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of RF22 by
RF22Mesh.h
00001 // RF22Mesh.h 00002 // 00003 // Author: Mike McCauley (mikem@open.com.au) 00004 // Copyright (C) 2011 Mike McCauley 00005 // $Id: RF22Mesh.h,v 1.4 2012/05/30 01:51:25 mikem Exp $ 00006 // ported to mbed by Karl Zweimueller 00007 00008 #ifndef RF22Mesh_h 00009 #define RF22Mesh_h 00010 00011 #include <RF22Router.h> 00012 00013 // Types of RF22Mesh message, used to set msgType in the RF22MeshHeader 00014 #define RF22_MESH_MESSAGE_TYPE_APPLICATION 0 00015 #define RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST 1 00016 #define RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE 2 00017 #define RF22_MESH_MESSAGE_TYPE_ROUTE_FAILURE 3 00018 00019 ///////////////////////////////////////////////////////////////////// 00020 /// \class RF22Mesh RF22Mesh.h <RF22Mesh.h> 00021 /// \brief RF22 subclass for sending addressed, optionally acknowledged datagrams 00022 /// multi-hop routed across a network, with automatic route discovery 00023 /// 00024 /// Extends RF22Router to add automatic route discovery within a mesh of adjacent nodes, 00025 /// and route signalling. 00026 /// 00027 /// Unlike RF22Router, RF22Mesh can be used in networks where the network topology is fluid, or unknown, 00028 /// or if nodes can mode around or go in or out of service. When a node wants to send a 00029 /// message to another node, it will automcatically discover a route to the destaintion node and use it. 00030 /// If the route becomes unavailable, a new route will be discovered. 00031 /// 00032 /// \par Route Discovery 00033 /// 00034 /// When a RF22Mesh mesh node is initialised, it doe not know any routes to any other nodes 00035 /// (see RF22Router for details on route and the routing table). 00036 /// When you attempt to send a message with sendtoWait, will first check to see if there is a route to the 00037 /// destinastion node in the routing tabl;e. If not, it wil initialite 'Route Discovery'. 00038 /// When a node needs to discover a route to another node, it broadcasts MeshRouteDiscoveryMessage 00039 /// with a message type of RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST. 00040 /// Any node that receives such a request checks to see if it is a request for a route to itself 00041 /// (in which case it makes a unicast reply to the originating node with a 00042 /// MeshRouteDiscoveryMessage 00043 /// with a message type of RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE) 00044 /// otherwise it rebroadcasts the request, after adding itself to the list of nodes visited so 00045 /// far by the request. 00046 /// 00047 /// If a node receives a RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST that already has itself 00048 /// listed in the visited nodes, it knows it has already seen and rebroadcast this request, 00049 /// and threfore ignores it. This prevents broadcast storms. 00050 /// When a node receives a RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST it can use the list of 00051 /// nodes aready visited to deduce routes back towards the originating (requesting node). 00052 /// This also means that when the destination node of the request is reached, it (and all 00053 /// the previous nodes the request visited) will have a route back to the originating node. 00054 /// This means the unicast RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE 00055 /// reply will be routed successfully back to the original route requester. 00056 /// 00057 /// The RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE sent back by the destination node contains 00058 /// the full list of nodes that were visited on the way to the destination. 00059 /// Therefore, intermediate nodes that route the reply back towards the originating node can use the 00060 /// node list in the reply to deduce routes to all the nodes between it and the destination node. 00061 /// 00062 /// Therefore, RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST and 00063 /// RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE together ensure the original requester and all 00064 /// the intermediate nodes know how to route to the source and destination nodes and every node along the path. 00065 /// 00066 /// Note that there is a race condition here that can effect routing on multipath routes. For example, 00067 /// if the route to the destination can traverse several paths, last reply from the destination 00068 /// will be the one used. 00069 /// 00070 /// \par Route Failure 00071 /// 00072 /// RF22Router (and therefore RF22Mesh) use reliable hop-to-hop delivery of messages using 00073 /// hop-to-hop acknowledgements, but not end-to-end acknowledgements. When sendtoWait() returns, 00074 /// you know that the message has been delivered to the next hop, but not if it is (or even if it can be) 00075 /// delivered to the destination node. If during the course of hop-to-hop routing of a message, 00076 /// one of the intermediate RF22Mesh nodes finds it cannot deliver to the next hop 00077 /// (say due to a lost route or no acknwledgement from the next hop), it replies to the 00078 /// originator with a unicast MeshRouteFailureMessage RF22_MESH_MESSAGE_TYPE_ROUTE_FAILURE message. 00079 /// Intermediate nodes (on the way beack to the originator) 00080 /// and the originating node use this message to delete the route to the destination 00081 /// node of the original message. This means that if a route to a destination becomes unusable 00082 /// (either because an intermediate node is off the air, or has moved out of range) a new route 00083 /// will be established the next time a message is to be sent. 00084 /// 00085 /// \par Message Format 00086 /// 00087 /// RF22Mesh uses a number of message formats layered on top of RF22Router: 00088 /// - MeshApplicationMessage (message type RF22_MESH_MESSAGE_TYPE_APPLICATION). 00089 /// Carries an application layer message for the caller of RF22Mesh 00090 /// - MeshRouteDiscoveryMessage (message types RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST 00091 /// and RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE). Carries Route Discovery messages 00092 /// (broadcast) and replies (unicast). 00093 /// - MeshRouteFailureMessage (message type RF22_MESH_MESSAGE_TYPE_ROUTE_FAILURE) Informs nodes of 00094 /// route failures. 00095 /// 00096 /// Part of the Arduino RF22 library for operating with HopeRF RF22 compatible transceivers 00097 /// (see http://www.hoperf.com) 00098 class RF22Mesh : public RF22Router 00099 { 00100 public: 00101 00102 /// The maximum length permitted for the application payload data in a RF22Mesh message 00103 #define RF22_MESH_MAX_MESSAGE_LEN (RF22_ROUTER_MAX_MESSAGE_LEN - sizeof(RF22Mesh::MeshMessageHeader)) 00104 00105 /// Structure of the basic RF22Mesh header. 00106 typedef struct 00107 { 00108 uint8_t msgType; ///< Type of RF22Mesh message, one of RF22_MESH_MESSAGE_TYPE_* 00109 } MeshMessageHeader; 00110 00111 /// Signals an application layer message for the caller of RF22Mesh 00112 typedef struct 00113 { 00114 MeshMessageHeader header; ///< msgType = RF22_MESH_MESSAGE_TYPE_APPLICATION 00115 uint8_t data[RF22_MESH_MAX_MESSAGE_LEN]; ///< Applicaiotn layer payload data 00116 } MeshApplicationMessage; 00117 00118 /// Signals a route discovery request or reply 00119 /// At present only supports physical dest addresses of length 1 octet 00120 typedef struct 00121 { 00122 MeshMessageHeader header; ///< msgType = RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_* 00123 uint8_t destlen; ///< Reserved. Must be 1.g 00124 uint8_t dest; ///< The address of the destination node whose route is being sought 00125 uint8_t route[RF22_MESH_MAX_MESSAGE_LEN - 1]; ///< List of node addresses visited so far. Length is implcit 00126 } MeshRouteDiscoveryMessage; 00127 00128 /// Signals a route failure 00129 typedef struct 00130 { 00131 MeshMessageHeader header; ///< msgType = RF22_MESH_MESSAGE_TYPE_ROUTE_FAILURE 00132 uint8_t dest; ///< The address of the destination towards which the route failed 00133 } MeshRouteFailureMessage; 00134 00135 /// Constructor. 00136 /// \param[in] thisAddress The address to assign to this node. Defaults to 0 00137 /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the RF22 before 00138 /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega) 00139 /// \param[in] interrupt The interrupt number to use. Default is interrupt 0 (Arduino input pin 2) 00140 RF22Mesh(uint8_t thisAddress , PinName slaveSelectPin , PinName mosi, PinName miso, PinName sclk, PinName interrupt ); 00141 00142 /// Sends a message to the destination node. Initialises the RF22Router message header 00143 /// (the SOURCE address is set to the address of this node, HOPS to 0) and calls 00144 /// route() which looks up in the routing table the next hop to deliver to. 00145 /// If no route is known, initiates route discovery and waits for a reply. 00146 /// Then sends the message to the next hop 00147 /// Then waits for an acknowledgement from the next hop 00148 /// (but not from the destination node (if that is different). 00149 /// \param [in] buf The application message data 00150 /// \param [in] len Number of octets in the application message data. 0 is permitted 00151 /// \param [in] dest The destination node address 00152 /// \return The result code: 00153 /// - RF22_ROUTER_ERROR_NONE Message was routed and deliverd to the next hop 00154 /// (not necessarily to the final dest address) 00155 /// - RF22_ROUTER_ERROR_NO_ROUTE There was no route for dest in the local routing table 00156 /// - RF22_ROUTER_ERROR_UNABLE_TO_DELIVER Noyt able to deliver to the next hop 00157 /// (usually because it dod not acknowledge due to being off the air or out of range 00158 uint8_t sendtoWait(uint8_t* buf, uint8_t len, uint8_t dest); 00159 00160 /// Starts the receiver if it is not running already. 00161 /// If there is a valid application layer message available for this node (or RF22_BROADCAST_ADDRESS), 00162 /// send an acknowledgement to the last hop 00163 /// address (blocking until this is complete), then copy the application message payload data 00164 /// to buf and return true 00165 /// else return false. 00166 /// If a message is copied, *len is set to the length.. 00167 /// If from is not NULL, the originator SOURCE address is placed in *source. 00168 /// If to is not NULL, the DEST address is placed in *dest. This might be this nodes address or 00169 /// RF22_BROADCAST_ADDRESS. 00170 /// This is the preferred function for getting messages addressed to this node. 00171 /// If the message is not a broadcast, acknowledge to the sender before returning. 00172 /// \param[in] buf Location to copy the received message 00173 /// \param[in,out] len Available space in buf. Set to the actual number of octets copied. 00174 /// \param[in] source If present and not NULL, the referenced uint8_t will be set to the SOURCE address 00175 /// \param[in] dest If present and not NULL, the referenced uint8_t will be set to the DEST address 00176 /// \param[in] id If present and not NULL, the referenced uint8_t will be set to the ID 00177 /// \param[in] flags If present and not NULL, the referenced uint8_t will be set to the FLAGS 00178 /// (not just those addressed to this node). 00179 /// \return true if a valid message was recvived for this node and copied to buf 00180 boolean recvfromAck(uint8_t* buf, uint8_t* len, uint8_t* source = NULL, uint8_t* dest = NULL, uint8_t* id = NULL, uint8_t* flags = NULL); 00181 00182 /// Starts the receiver if it is not running already. 00183 /// Similar to recvfromAck(), this will block until either a valid application layer 00184 /// message available for this node 00185 /// or the timeout expires. 00186 /// \param[in] buf Location to copy the received message 00187 /// \param[in,out] len Available space in buf. Set to the actual number of octets copied. 00188 /// \param[in] timeout Maximum time to wait in milliseconds 00189 /// \param[in] source If present and not NULL, the referenced uint8_t will be set to the SOURCE address 00190 /// \param[in] dest If present and not NULL, the referenced uint8_t will be set to the DEST address 00191 /// \param[in] id If present and not NULL, the referenced uint8_t will be set to the ID 00192 /// \param[in] flags If present and not NULL, the referenced uint8_t will be set to the FLAGS 00193 /// (not just those addressed to this node). 00194 /// \return true if a valid message was copied to buf 00195 boolean 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); 00196 00197 protected: 00198 00199 /// Internal function that inspects messages being received and adjusts the routing table if necessary. 00200 /// Called by recvfromAck() immediately after it gets the message from RF22ReliableDatagram 00201 /// \param [in] message Pointer to the RF22Router message that was received. 00202 /// \param [in] messageLen Length of message in octets 00203 virtual void peekAtMessage(RoutedMessage* message, uint8_t messageLen); 00204 00205 /// Internal function that inspects messages being received and adjusts the routing table if necessary. 00206 /// This is virtual, which lets subclasses override or intercept the route() function. 00207 /// Called by sendtoWait after the message header has been filled in. 00208 /// \param [in] message Pointer to the RF22Router message to be sent. 00209 /// \param [in] messageLen Length of message in octets 00210 virtual uint8_t route(RoutedMessage* message, uint8_t messageLen); 00211 00212 /// Try to resolve a route for the given address. Blocks while discovering the route 00213 /// which may take up to 4000 msec. 00214 /// Virtual so subclasses can override. 00215 /// \param [in] address The physical addres to resolve 00216 /// \return true if the address was resolved and added to the local routing table 00217 virtual boolean doArp(uint8_t address); 00218 00219 /// Tests if the given address of length addresslen is indentical to the 00220 /// physical addres of this node. 00221 /// RF22Mesh always ikmplements p[hysical addresses as the 1 octet address of the node 00222 /// given by _thisAddress 00223 /// Called by recvfromAck() to test whether a RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST 00224 /// is for this node. 00225 /// Subclasses may want to override to implemnt mode complicated or longer physical addresses 00226 /// \param [in] address Address of the pyysical addres being tested 00227 /// \param [in] addresslen Lengthof the address in bytes 00228 /// \return true if the physical address of this node is identical to address 00229 virtual boolean isPhysicalAddress(uint8_t* address, uint8_t addresslen); 00230 00231 private: 00232 /// Temporary mesage buffer 00233 static uint8_t _tmpMessage[RF22_ROUTER_MAX_MESSAGE_LEN]; 00234 00235 }; 00236 00237 #endif
Generated on Wed Jul 13 2022 22:24:22 by
