boolean RF22Mesh::recvfromAck(uint8_t* buf, uint8_t* len, uint8_t* source, uint8_t* dest, uint8_t* id, uint8_t* flags) { uint8_t tmpMessageLen = sizeof(_tmpMessage); uint8_t _source; uint8_t _dest; uint8_t _id; uint8_t _flags; uint8_t frags = 0; uint8_t offset = 0; uint8_t total_len = 0; uint8_t seq_no = 0; uint8_t x = 0, y = 0; uint8_t loop_once = 1; uint8_t have_message = 0; #ifndef CLIENT lcd.begin( 20, 4 ); lcd.clear(); #endif while( frags > 0 || loop_once == 1 ) { loop_once = 0; if (RF22Router::recvfromAck(_tmpMessage, &tmpMessageLen, &_source, &_dest, &_id, &_flags)) { MeshMessageHeader* p = (MeshMessageHeader*)&_tmpMessage; if ( tmpMessageLen >= 1 && p->msgType == RF22_MESH_MESSAGE_TYPE_APPLICATION) { have_message = 1; MeshApplicationMessage* a = (MeshApplicationMessage*)p; // Handle application layer messages, presumably for our caller if (source) *source = _source; if (dest) *dest = _dest; if (id) *id = _id; if (flags) *flags = _flags; uint8_t msgLen = tmpMessageLen - sizeof(MeshMessageHeader); if (*len > msgLen) *len = msgLen; frags = a->header.frag; #ifdef CLIENT Serial.print( F( "RF22Mesh::recvfromAck frags: " ) ); Serial.println( frags ); #endif seq_no = a->header.seqno; if( frags > 0 || (frags == 0 && a->header.seqno > 0 ) ) { offset = a->header.seqno * RF22_MESH_MAX_MESSAGE_LEN; } #ifdef CLIENT for( int i = 0; i < *len; i++ ) { Serial.print( a->data[i] ); Serial.print( F( ", " ) ); } Serial.println( F( "" ) ); #endif memcpy( buf + offset, a->data, *len ); #ifndef CLIENT lcd.setCursor( x, y ); lcd.print( *len ); if( ( x + 8 ) > 20 ) { y++; x = 0; } else { x += 4; } #endif } else if ( _dest == RF22_BROADCAST_ADDRESS && tmpMessageLen > 1 && p->msgType == RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST) { MeshRouteDiscoveryMessage* d = (MeshRouteDiscoveryMessage*)p; // Handle Route discovery requests // Message is an array of node addresses the route request has already passed through // If it originally came from us, ignore it if (_source == _thisAddress) return false; uint8_t numRoutes = tmpMessageLen - sizeof(MeshMessageHeader) - 2; uint8_t i; // Are we already mentioned? for (i = 0; i < numRoutes; i++) if (d->route[i] == _thisAddress) return false; // Already been through us. Discard // Hasnt been past us yet, record routes back to the earlier nodes addRouteTo(_source, headerFrom()); // The originator for (i = 0; i < numRoutes; i++) addRouteTo(d->route[i], headerFrom()); if (isPhysicalAddress(&d->dest, d->destlen)) { // This route discovery is for us. Unicast the whole route back to the originator // as a RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE // We are certain to have a route there, becuase we just got it d->header.msgType = RF22_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE; RF22Router::sendtoWait((uint8_t*)d, tmpMessageLen, _source); } else if (i < _max_hops) { // Its for someone else, rebroadcast it, after adding ourselves to the list d->route[numRoutes] = _thisAddress; tmpMessageLen++; // Have to impersonate the source // REVISIT: if this fails what can we do? RF22Router::sendtoWait(_tmpMessage, tmpMessageLen, RF22_BROADCAST_ADDRESS, _source); } } } else if( frags == 0 ) { return false; } else { #ifdef CLIENT Serial.print( F( "corner case: frags: " ) ); Serial.print( frags ); Serial.print( F( "loop_once: " ) ); Serial.println( loop_once ); #endif } } if( have_message == 1 ) { *len = *len + ( seq_no * RF22_MESH_MAX_MESSAGE_LEN ); #ifdef CLIENT Serial.print( F( "if have_message: frags: " ) ); Serial.print( frags ); Serial.print( F( "loop_once: " ) ); Serial.println( loop_once ); #endif #ifndef CLIENT lcd.setCursor( x, y ); lcd.print( "t" ); lcd.print( *len ); #endif return true; } else { return false; } }
bool RHMesh::recvfromAck(uint8_t* buf, uint8_t* len, uint8_t* source, uint8_t* dest, uint8_t* id, uint8_t* flags) { uint8_t tmpMessageLen = sizeof(_tmpMessage); uint8_t _source; uint8_t _dest; uint8_t _id; uint8_t _flags; if (RHRouter::recvfromAck(_tmpMessage, &tmpMessageLen, &_source, &_dest, &_id, &_flags)) { MeshMessageHeader* p = (MeshMessageHeader*)&_tmpMessage; if ( tmpMessageLen >= 1 && p->msgType == RH_MESH_MESSAGE_TYPE_APPLICATION) { MeshApplicationMessage* a = (MeshApplicationMessage*)p; // Handle application layer messages, presumably for our caller if (source) *source = _source; if (dest) *dest = _dest; if (id) *id = _id; if (flags) *flags = _flags; uint8_t msgLen = tmpMessageLen - sizeof(MeshMessageHeader); if (*len > msgLen) *len = msgLen; memcpy(buf, a->data, *len); return true; } else if ( _dest == RH_BROADCAST_ADDRESS && tmpMessageLen > 1 && p->msgType == RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_REQUEST) { MeshRouteDiscoveryMessage* d = (MeshRouteDiscoveryMessage*)p; // Handle Route discovery requests // Message is an array of node addresses the route request has already passed through // If it originally came from us, ignore it if (_source == _thisAddress) return false; uint8_t numRoutes = tmpMessageLen - sizeof(MeshMessageHeader) - 2; uint8_t i; // Are we already mentioned? for (i = 0; i < numRoutes; i++) if (d->route[i] == _thisAddress) return false; // Already been through us. Discard // Hasnt been past us yet, record routes back to the earlier nodes addRouteTo(_source, headerFrom()); // The originator for (i = 0; i < numRoutes; i++) addRouteTo(d->route[i], headerFrom()); if (isPhysicalAddress(&d->dest, d->destlen)) { // This route discovery is for us. Unicast the whole route back to the originator // as a RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE // We are certain to have a route there, becuase we just got it d->header.msgType = RH_MESH_MESSAGE_TYPE_ROUTE_DISCOVERY_RESPONSE; RHRouter::sendtoWait((uint8_t*)d, tmpMessageLen, _source); } else if (i < _max_hops) { // Its for someone else, rebroadcast it, after adding ourselves to the list d->route[numRoutes] = _thisAddress; tmpMessageLen++; // Have to impersonate the source // REVISIT: if this fails what can we do? RHRouter::sendtoWait(_tmpMessage, tmpMessageLen, RH_BROADCAST_ADDRESS, _source); } } } return false; }