Code Search for Developers
 
 
  

MdForwarder.c from EmStar at Krugle


Show MdForwarder.c syntax highlighted

////////////////////////////////////////////////////////////////////////////
//
// CENS
//
// Copyright (c) 2003 The Regents of the University of California.  All 
// rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// - Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
// - Neither the name of the University nor the names of its
//   contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Contents: This file contains the module used to forward messages in
//           Micro Diffusion.
//
// Purpose: The purpose of this module is to logically connect all of the
//          user and system logic in Micro Diffusion.
//
////////////////////////////////////////////////////////////////////////////
//
// $Id: MdForwarder.c,v 1.6 2004/04/06 08:22:27 adparker Exp $

#include "libdev/packet_dev.h"
#include "Mdiff.h"
#include "MdMatch.h"
#include "MdForwarder.h"
#include "MdOppGradient.h"

////////////////////////////////////////////////////////////////////////////
//
// Commad: StdControl.init( )
//
// Purpose: This command is used to init this component.
//
////////////////////////////////////////////////////////////////////////////

result_t MdForwarder_init( Mdiff_state_t * state )
{
  // Sequence number for outbound messages that originate on this node.
  elog(LOG_INFO," ");
  state->MdForwarder->m_uiSeq = 0;

  return SUCCESS;
}

////////////////////////////////////////////////////////////////////////////
//
// Commad: StdControl.start( )
//
// Purpose: This command is used to start this component.
//
////////////////////////////////////////////////////////////////////////////

result_t MdForwarder_start( Mdiff_state_t * state )
{
  elog(LOG_INFO," ");
  return SUCCESS;
}

////////////////////////////////////////////////////////////////////////////
//
// Commad: StdControl.stop( )
//
// Purpose: This command is used to stop this component.
//
////////////////////////////////////////////////////////////////////////////

result_t MdForwarder_stop( Mdiff_state_t * state)
{
  // Destroy devices and client contexts ???
  elog(LOG_INFO," ");
  return SUCCESS;
}

////////////////////////////////////////////////////////////////////////////
//
// Commad: TdForwarderI.recvFromFilter( )
//
// Purpose: This event is called from a filter if it has decided to pass its
//          message on to the next filter. The expected behavior of this
//          event is to cause messages to proceed up the filter stack.
//
////////////////////////////////////////////////////////////////////////////
//
// Pass ownership of p_pMsg to MdForwarder_callFilter

result_t MdForwarder_recvFromFilter( Mdiff_state_t * state, IntDiffMsg_t  *p_pMsg )
{
  result_t tReturn = SUCCESS;

  elog(LOG_INFO," ");
  // Make sure we have a message.
  if ( NULL == p_pMsg )
    {
      elog( LOG_NOTICE,
           "%s [%d] - Message is NULL.\n",
           __FILE__,
           __LINE__ );
      tReturn = FAIL;
    }
  // If all is well...
  else
    {
      p_pMsg->m_uiPriority++;
      tReturn = MdForwarder_callFilter(state, p_pMsg);
    }
  return tReturn;
}

////////////////////////////////////////////////////////////////////////////
//
// Command: TdForwarderI.sendMsg( )
//
// Purpose: This command is used to send a Tiny Diffusion message from a user
//          application to Tiny Diffusion.  This message is sent up from the
//          bottom of the priority stack.
//
////////////////////////////////////////////////////////////////////////////
//
// p_pMsg is owned by us.
// p_pMsg will be memcopied to a IntDiffMsg_t so that it's contiguous.
// p_pMsg will be freed.
//
// tMsg is malloc'ed.
// tMsg ownership is passed to MdForwarder_callFilter()

result_t MdForwarder_sendMsg( Mdiff_state_t * state,
			       uint16_t    p_uiLastHop,
			       DiffMsg_t  *p_pMsg )
{
  uint8_t  uiAttrs = 0;
  uint16_t ui = 0;
  result_t tReturn = SUCCESS;

  // This is the internal message that we will enqueue.
  IntDiffMsg_t * tMsg = (IntDiffMsg_t *)malloc(sizeof(IntDiffMsg_t));
  DiffAttr_t *pAttr = NULL;

  elog(LOG_INFO," ");
  // zero out tMsg;
  memset(tMsg,0,sizeof(IntDiffMsg_t));
    
  // Check to see if we have a valid message.
  if ( NULL == p_pMsg )
    {
      elog( LOG_NOTICE,
           "%s [%d] - Unable to use NULL message.\n",
           __FILE__,
           __LINE__ );
      tReturn = FAIL;
    }
  else if ( p_pMsg->m_uiDataLen > TD_MAX_MSG_LEN )
    {
      elog( LOG_NOTICE,
           "%s [%d] - Input message length was: %u (greater than %d).\n",
           __FILE__,
           __LINE__,
           p_pMsg->m_uiDataLen,
           TD_MAX_MSG_LEN );
      tReturn = FAIL;
    }
  // If all is well...
  else
    {
      uiAttrs = 0;

      // Loop over the DiffMsg_t counting attributes.
      for ( ui = 0;
            ui < p_pMsg->m_uiDataLen;
            uiAttrs++ )
	{
	  // Cast the pointer.
	  pAttr = ( DiffAttr_t * ) &( p_pMsg->m_pData[ ui ] );

	  // Check to see if this is a BLOB attribute (i.e. of a 
	  // non-standard size).
	  //
	  // If not...
	  if ( TD_ATTR_USER_BASE_BLOB > pAttr->m_uiAttr
	       || TD_ATTR_USER_BASE_KEY <= pAttr->m_uiAttr )
	    {
	      // Just advance the pointer by the length of a standard attribute.
	      ui += sizeof( DiffAttr_t );
	    }
	  // Otherwise...
	  else if (0 == pAttr->m_uiOp
		   || (p_pMsg->m_uiDataLen - ui) < pAttr->m_uiOp)
	    {
	      elog(LOG_ALERT,"Bounds error. Blob length %u is invalid with %u out of %u bytes left in message.",
		   pAttr->m_uiOp,
		   (p_pMsg->m_uiDataLen - ui),
		   p_pMsg->m_uiDataLen);
	      tReturn = FAIL;
	      break;
	    }
	  else
	    {
	      // This is a BLOB and the operator variable is overloaded to 
	      // specify the length of the BLOB.
	      ui += pAttr->m_uiOp;
	    }
	}
      if ( SUCCESS == tReturn)
	{
	  // Set the number of attributes that we found in the internal message.
	  tMsg->m_uiNumAttrs = uiAttrs;

	  // Set the last hop address:
	  tMsg->m_uiLastHop = p_uiLastHop;

	  // Copy into the payload of our internal message to be the entire DiffMsg_t.
	  memcpy( &( tMsg->m_tMsg ),
		  p_pMsg,
		  sizeof( DiffMsg_t ) );

	  // If this message originated on this node, then this is its first hop...
	  if ( ( uint16_t ) TD_LOCAL_ADDR == p_uiLastHop )
	    {
	      // We first assign it our next sequence number.
	      tMsg->m_tMsg.m_uiSeq = ++state->MdForwarder->m_uiSeq;
	      // Then we set its TTL to our default.
	      tMsg->m_tMsg.m_uiTtl = TD_MAX_TTL;
	    }

	  // Since this message is going to traverse the stack from the bottom,
	  // we will set its parameter to 0.
	  tMsg->m_uiPriority = 0;

	  // Passing ownership of tMsg
	  tReturn = MdForwarder_callFilter(state, tMsg);
	}
    }
    
  free(p_pMsg);
  return tReturn;
}

/////////////////////////////////////////////////////////
// Ownership of tMsg goes to MdFilter_recv or MdFilter_callPreGradient
// (only if it returns SUCCESS). If not, I'm still responsible for
// tMsg.

result_t MdForwarder_callFilter( Mdiff_state_t * state, IntDiffMsg_t * tMsg  )
{
  result_t tReturn = SUCCESS;
  elog(LOG_INFO," ");  
  // If the message priority is 0, then set the message priority to
  // the first filter's priority, and pass the message to it. ???
  
  if (tMsg->m_uiPriority < TD_FILTER_GRADIENT) {
    // call function that returns first PD client with priorty >= priority.
    if (SUCCESS != MdForwarder_callPreGradient(state, tMsg)) {
      tMsg->m_uiPriority = TD_FILTER_GRADIENT;
      MdOppGradient_recv(state, tMsg);
    }
  }
  else if (tMsg->m_uiPriority == TD_FILTER_GRADIENT) {
    // pass to gradient
    MdOppGradient_recv(state, tMsg);
  }
  else {
    if (SUCCESS != MdForwarder_callPostGradient(state, tMsg)) {
      free(tMsg);
    }
  }
    
  return tReturn;
}


void MdForwarder_filterReceive(pd_context_t * pd_ref, pd_client_t * pdc,
			       IntDiffMsg_t * tMsg)
{
  MdMsg_t * msg = (MdMsg_t*)malloc(sizeof(MdMsg_t)+sizeof(IntDiffMsg_t));
  elog(LOG_INFO," ");  
  memset(msg,0,sizeof(MdMsg_t)+sizeof(IntDiffMsg_t));
  msg->type = MdRecv;
  msg->length = sizeof(IntDiffMsg_t);
  memcpy(msg->data,tMsg,sizeof(IntDiffMsg_t));
  pd_client_receive(pd_ref, pdc, msg, sizeof(MdMsg_t)+sizeof(IntDiffMsg_t), NULL);
  free(msg);
}

result_t MdForwarder_callPreGradient(Mdiff_state_t * state, IntDiffMsg_t * tMsg)
{
  result_t tReturn = FAIL;
  pd_client_t * pdc = pd_client_top(state->filter_pd_ref);
  uint8_t client_priority = 0;
  pd_client_t * best_pdc = NULL;
  uint8_t best_priority = 0;
  elog(LOG_INFO," ");
  for ( ; pdc != NULL; pdc = pd_client_next(pdc) ) {
    if ( pd_client_data(pdc) == NULL) continue;
    client_priority = *((uint8_t *)pd_client_data(pdc));
    if (client_priority >= TD_FILTER_GRADIENT) continue;
    if (client_priority <  tMsg->m_uiPriority) continue;
    if ( (NULL == best_pdc)
	 || ( client_priority < best_priority ) ) {
      best_pdc = pdc;
      best_priority = client_priority;
      tReturn = SUCCESS;
    }
  }
  if (tReturn == SUCCESS) {
    tMsg->m_uiPriority = best_priority;
    MdForwarder_filterReceive(state->filter_pd_ref, best_pdc, tMsg);
    free(tMsg);
  }
  return tReturn;
}

result_t MdForwarder_callPostGradient(Mdiff_state_t * state, IntDiffMsg_t * tMsg)
{
  result_t tReturn = FAIL;
  pd_client_t * pdc = pd_client_top(state->filter_pd_ref);
  uint8_t client_priority = 0;
  pd_client_t * best_pdc = NULL;
  uint8_t best_priority = 0;
  elog(LOG_INFO," ");
  for ( ; pdc != NULL; pdc = pd_client_next(pdc) ) {
    if ( pd_client_data(pdc) == NULL) continue;
    client_priority = *((uint8_t *)pd_client_data(pdc));
    if (client_priority <= TD_FILTER_GRADIENT) continue;
    if (client_priority <  tMsg->m_uiPriority) continue;
    if ( (NULL == best_pdc)
	 || ( client_priority < best_priority ) ) {
      best_pdc = pdc;
      best_priority = client_priority;
      tReturn = SUCCESS;
    }
  }
  if (tReturn == SUCCESS) {
    tMsg->m_uiPriority = best_priority;
    MdForwarder_filterReceive(state->filter_pd_ref, best_pdc, tMsg);
    free(tMsg);
  }
  return tReturn;
}





See more files for this project here

EmStar

EmStar is a software system for developing and deploying wireless sensor networks involving Linux-based platforms. As the wireless sensor network community has attempted to deploy more complex designs---large-scale, long-lived systems that need self-organization and adaptivity---a number of difficult software design issues have arisen. Advances in software design have not kept pace with the capabilities of hardware. This is because designing for an adaptive, efficient, and useful sensor network has turned out to be surprisingly complex and difficult. EmStar is a Linux-based software framework, whose goal is to dramatically reduce this complexity, enabling work to be shared and reused, and simplifying and speeding the design of new sensor network applications.

Project homepage: http://cvs.cens.ucla.edu/emstar/
Programming language(s): C,Shell Script
License: other

  old/
    MDForwarder.c
    MDForwarder_i.h
    MDOppGradient.c
    MDOppGradient.h
    MD_i.h
    microdiff.c
    microdiff.h
  DiffTypes.h
  MdForwarder.c
  MdForwarder.h
  MdMatch.c
  MdMatch.h
  MdOppGradient.c
  MdOppGradient.h
  Mdiff.h
  Mdiff.txt
  Mdiff_main.c