示例#1
0
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;
    }
}
示例#2
0
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;
}