Code Search for Developers
 
 
  

MdMatch.c from EmStar at Krugle


Show MdMatch.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 perform Tiny Diffusion's
//           matching logic
//
// Purpose: The purpose of this functionality is to encapsulate the way in
//          which attributes are matched for all of Tiny Diffusion in one
//          module.
//
////////////////////////////////////////////////////////////////////////////
//
// $Id: MdMatch.c,v 1.3 2004/03/23 12:06:35 adparker Exp $
//
////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
//
// Commad: TdMatchI.oneWayMatch( )
//
// Purpose: This command takes 2 attribute arrays (a reference and a
//          candidate) and performs one-way matching on them.  In this 
//          process, success is acheived if the candidate attributes are
//          equivalent to, or a superset of the reference attributes.
//
////////////////////////////////////////////////////////////////////////////

#include "Mdiff.h"
#include "assert.h"

result_t MdMatch_isClass(Mdiff_state_t *state,
			 int attr,
			 DiffAttr_t *p_Attr,
			 uint8_t num)
{
  result_t tReturn = FAIL;
  uint8_t i;
  assert(p_Attr != NULL);
  
  for (i = 0; i < num; ++i) {
    if ((p_Attr[i].m_uiAttr == TD_ATTR_CLASS)
	&& (p_Attr[i].m_iValue == attr)) {
      tReturn = SUCCESS;
      break;
    }
    
  }
  return tReturn;
}

result_t MdMatch_oneWayMatch( Mdiff_state_t * state,
			       DiffAttr_t *p_pRefAttrs,
			       uint8_t     p_uiNumRefAttrs,
			       DiffAttr_t *p_pCandidateAttrs,
			       uint8_t     p_uiNumCandAttrs )
{
  uint8_t  uiRefIndex = 0;
  uint8_t  uiCandIndex = 0;
  uint8_t  uiSentinal = 0;
  char    *pRef = NULL;
  char    *pCand = NULL;
  result_t tReturn = SUCCESS;

  // Ensure that there is a reference array.
  if ( NULL == p_pRefAttrs )
    {
      elog( LOG_NOTICE,
           "%s [%d] - Unable to compare attributes with NULL reference array.\n",
           __FILE__,
           __LINE__ );
      tReturn = FAIL;
    }
  // Ensure the that there is a candidate array.
  else if ( NULL == p_pCandidateAttrs )
    {
      elog( LOG_NOTICE,
           "%s [%d] - Unable to compare attributes with NULL condidate array.\n",
           __FILE__,
           __LINE__ );
      tReturn = FAIL;
    }
  // If all is well...
  else
    {
      pRef = ( char * ) p_pRefAttrs;

#ifdef _DEF_TD_DEBUG
      elog( LOG_NOTICE,
           "%s [%d] - Ref Attrs:\n",
           __FILE__,
           __LINE__ );
      call TdMatchI.printAttrs( p_pRefAttrs,
				p_uiNumRefAttrs );
      elog( LOG_NOTICE,
           "%s [%d] - Cand Attrs:\n",
           __FILE__,
           __LINE__ );
      call TdMatchI.printAttrs( p_pCandidateAttrs,
				p_uiNumCandAttrs );
#endif

      // Loop over the reference array...
      for ( uiRefIndex = 0;
            uiRefIndex < p_uiNumRefAttrs;
            uiRefIndex++ )
	{
	  // Set our sentinal to indicate that we have not matched this attribute yet.
	  uiSentinal = 0;

	  if ( TD_ATTR_USER_BASE_BLOB <= ( ( DiffAttr_t * ) pRef )->m_uiAttr
	       && TD_ATTR_USER_BASE_KEY > ( ( DiffAttr_t * ) pRef )->m_uiAttr )
	    {
	      pRef += ( ( DiffBlob_t * ) pRef )->m_uiLen;
	      uiSentinal = 1;
	    }
	  // Skip Classes, round, and Noop
	  else if ( (TD_ATTR_CLASS == ((DiffAttr_t*)pRef)->m_uiAttr)
		    ||(TD_ATTR_OPP_ROUND == ((DiffAttr_t*)pRef)->m_uiAttr)
		    ||(TD_ATTR_NOOP == ((DiffAttr_t*)pRef)->m_uiAttr))
	    {
	      pRef +=  sizeof( DiffAttr_t );
	      uiSentinal = 1;
	    }
	  // Skip Round
	  else
	    {
	      pCand = ( char * ) p_pCandidateAttrs;

	      // Loop over the candidate array until our sentinal is tripped, or we have
	      // finished the array.
	      for ( uiCandIndex = 0;
		    0 == uiSentinal
		      && uiCandIndex < p_uiNumCandAttrs;
		    uiCandIndex++ )
		{
		  // Skip Blobs
		  if ( TD_ATTR_USER_BASE_BLOB <= ( ( DiffAttr_t * ) pCand )->m_uiAttr
		       && TD_ATTR_USER_BASE_KEY > ( ( DiffAttr_t * ) pCand )->m_uiAttr )
		    {
		      pCand += ( ( DiffBlob_t * ) pCand )->m_uiLen;
		    }
		  else
		    {
		      // If the reference and candidate attributes of this iteration are the same...
		      if ( ( ( DiffAttr_t * ) pRef )->m_uiAttr
			   == ( ( DiffAttr_t * ) pCand )->m_uiAttr )
			{
			  // If the operation of the candidate defines its value (IS)...
			  if ( ( ( DiffAttr_t * ) pCand )->m_uiOp == TD_IS )
			    {
			      // We switch on the operation of the reference attribute so we know how
			      // to compare these 2 attributes.
			      switch( ( ( DiffAttr_t * ) pRef )->m_uiOp )
				{
				case TD_EQ:
				  // If these are equal, we are done with this iteration of the inner loop.
				  if ( ( ( DiffAttr_t * ) pCand )->m_iValue 
				       == ( ( DiffAttr_t * ) pRef )->m_iValue )
				    {
				      // Set our sentinal so that the loop terminates and we know that
				      // we were successful.
				      uiSentinal = 1;
				    }
				  break;
				case TD_LT:
				  // If the candidate is less than the reference,
				  // we are done with this iteration of the inner loop.
				  if ( ( ( DiffAttr_t * ) pCand )->m_iValue 
				       < ( ( DiffAttr_t * ) pRef )->m_iValue )
				    {
				      // Set our sentinal so that the loop terminates and we know that
				      // we were successful.
				      uiSentinal = 1;
				    }
				  break;
				case TD_GT:
				  // If the candidate is greater than the reference,
				  // we are done with this iteration of the inner loop.
				  if ( ( ( DiffAttr_t * ) pCand )->m_iValue 
				       > ( ( DiffAttr_t * ) pRef )->m_iValue )
				    {
				      // Set our sentinal so that the loop terminates and we know that
				      // we were successful.
				      uiSentinal = 1;
				    }
				  break;
				case TD_LE:
				  // If candidate is less than or equal to the reference,
				  // we are done with this iteration of the inner loop.
				  if ( ( ( DiffAttr_t * ) pCand )->m_iValue 
				       <= ( ( DiffAttr_t * ) pRef )->m_iValue )
				    {
				      // Set our sentinal so that the loop terminates and we know that
				      // we were successful.
				      uiSentinal = 1;
				    }
				  break;
				case TD_GE:
				  // If these are equal, we are done with this iteration of the inner loop.
				  if ( ( ( DiffAttr_t * ) pCand )->m_iValue 
				       >= ( ( DiffAttr_t * ) pRef )->m_iValue )
				    {
				      // Set our sentinal so that the loop terminates and we know that
				      // we were successful.
				      uiSentinal = 1;
				    }
				  break;
				case TD_NE:
				  // If these are unequal, we are done with this iteration of the inner loop.
				  if ( ( ( DiffAttr_t * ) pCand )->m_iValue 
				       != ( ( DiffAttr_t * ) pRef )->m_iValue )
				    {
				      // Set our sentinal so that the loop terminates and we know that
				      // we were successful.
				      uiSentinal = 1;
				    }
				  break;
				case TD_ANY:
				  // Since there is any attribute at all, we are done with this
				  // iteration of the inner loop.  Set our sentinal so that the
				  // loop terminates and we know that we were successful.
				  uiSentinal = 1;
				  break;
				default:
				  elog( LOG_NOTICE,
				       "%s [%d] - Unknown matching operation: %u.\n",
				       __FILE__,
				       __LINE__,
				       ( ( DiffAttr_t * ) pCand )->m_uiOp );
				  break;
				}
			    }
			  else
			    {
			      uiSentinal = 1;
			      elog( LOG_NOTICE,
				   "%s [%d] - Got something that maybe a message type classifier (like INTEREST), or an invalid interest key: Ref Attr %u Candidate Attr %u.\n",
				   __FILE__,
				   __LINE__,
				   ( ( DiffAttr_t * ) pRef )->m_uiOp,
				   ( ( DiffAttr_t * ) pCand )->m_uiOp );
			    }
			}

		      pCand += sizeof( DiffAttr_t );
		    }
		}

	      if ( 1 != uiSentinal )
		{
#ifdef _DEF_TD_DEBUG
		  elog( LOG_NOTICE,
		       "%s [%d] - No matching candidate attribute for ref [key : op : value]: [%u : %u : %d].\n",
		       __FILE__,
		       __LINE__,
		       ( ( DiffAttr_t * ) pRef )->m_uiAttr,
		       ( ( DiffAttr_t * ) pRef )->m_uiOp,
		       ( ( DiffAttr_t * ) pRef )->m_iValue );
#endif
		  tReturn = FAIL;
		  break;
		}

	      pRef += sizeof( DiffAttr_t );
	    }
	}

      if ( 0 == uiSentinal )
	{
	  tReturn = FAIL;
	}
    }

  return tReturn;
}

////////////////////////////////////////////////////////////////////////////
//
// Commad: TdMatchI.getAttrIndex( )
//
// Purpose: This command attempts to locate a specific attribute in an
//          array.  The command accepts a starting index so that the entire
//          array need not be searched.
//
////////////////////////////////////////////////////////////////////////////

int16_t MdMatch_getAttrIndex( Mdiff_state_t * state,
			      uint8_t      p_uiAttr,
			      uint16_t     p_uiStartIndex,
			      DiffAttr_t  *p_pAttrArray,
			      uint8_t      p_uiNumAttrs )
{
  uint8_t      uiAttr = 0;
  int16_t      iReturn = -1;
  int16_t      iIndex = 0;
  char        *pAttr = NULL;

  // Check to make sure we have a valid array.
  if ( NULL == p_pAttrArray )
    {
      elog( LOG_NOTICE,
           "%s [%d] - Unable to search NULL array.\n",
           __FILE__,
           __LINE__ );
    }
  // If all is well.
  else
    {
      iIndex = 0;

      // Loop over the attribute array...
      for ( uiAttr = 0;
            uiAttr < p_uiNumAttrs;
            uiAttr++ )
	{
	  // We traverse the array at a byte level to account for BLOBs.
	  pAttr = &( ( ( char * ) p_pAttrArray )[ iIndex ] );

	  // If we have found the target, set our return and break out
	  // of the loop.
	  if ( p_uiAttr == ( ( DiffAttr_t * ) pAttr )->m_uiAttr )
	    {
	      iReturn = iIndex;
	      break;
	    }
	  // Otherwise, if attribute is flagged as a BLOB...
	  else if ( TD_ATTR_USER_BASE_BLOB <= ( ( DiffAttr_t * ) pAttr )->m_uiAttr
		    && TD_ATTR_USER_BASE_KEY > ( ( DiffAttr_t * ) pAttr )->m_uiAttr )
	    {
	      // We will need to jump through it (it may not be
	      // a regular sizeof( DiffAttr_t )'s length).
	      iIndex += ( ( DiffBlob_t * ) pAttr )->m_uiLen;
	    }
	  // Otherwise...
	  else
	    {
	      // We can just jump over this standard attribute.
	      iIndex += sizeof( DiffAttr_t );
	    }
	}
    }

  // Return the default index, or a value (if we found it above).
  return iReturn;
}

////////////////////////////////////////////////////////////////////////////
//
// Commad: TdMatchI.equal( )
//
// Purpose: This command performs and exact match check on 2 attribute
//          arrays.  Unlike the one-way matching, above, these 2 arrays
//          must contain all the same attribute/operation/values (although
//          they need not be in the same order).  This command also
//          skips over attributes that are of the value TD_ATTR_NOOP, so that
//          irrelevant attributes are not constrained on.
//
////////////////////////////////////////////////////////////////////////////

result_t MdMatch_equal( Mdiff_state_t * state,
			DiffAttr_t   *p_pAttrArray1,
			uint8_t       p_uiNumAttrs1,
			uint8_t       p_uiNumNoOps1,
			DiffAttr_t   *p_pAttrArray2,
			uint8_t       p_uiNumAttrs2,
			uint8_t       p_uiNumNoOps2 )
{
  uint8_t   ui1 = 0;
  uint8_t   ui2 = 0;
  result_t  tReturn = SUCCESS;

  // Make sure there is a valid array.
  if ( NULL == p_pAttrArray1 )
    {
      elog( LOG_NOTICE,
	    "%s [%d] - Unable to use NULL array1 for comparison.\n",
	    __FILE__,
	    __LINE__ );
      tReturn = FAIL;
    }
  // Make sure there is a valid array.
  else if ( NULL == p_pAttrArray2 )
    {
      elog( LOG_NOTICE,
	    "%s [%d] - Unable to use NULL array2 for comparison.\n",
	    __FILE__,
	    __LINE__ );
      tReturn = FAIL;
    }
  // Check to see if the attribute counts match (without including the
  // number of noops).  This is a sanity check before we begin looping
  // over the arrays.
  else if ( ( p_uiNumAttrs1 - p_uiNumNoOps1 )
	    != ( p_uiNumAttrs2 - p_uiNumNoOps2 ) )
    {
#ifdef _DEF_TD_DEBUG
      elog( LOG_NOTICE,
	    "%s [%d] - Array 1 and array 2 are different lengths and cannot be equal (%u != %u ).\n",
	    __FILE__,
	    __LINE__,
	    p_uiNumAttrs1 - p_uiNumNoOps1,
	    p_uiNumAttrs2 - p_uiNumNoOps2 );
#endif
      tReturn = FAIL;
    }
  // If all is well...
  else
    {
      // Loop over the first array...
      for ( ui1 = 0;
            SUCCESS == tReturn
	      && ui1 < p_uiNumAttrs1;
            ui1++ )
	{
	  // Set our default mode as failure.
	  tReturn = FAIL;

	  // If we encounter a BLOB we will fail.  Tiny Diffusion doesn't currently
	  // support the comparison of BLOBs.
	  if ( TD_ATTR_USER_BASE_BLOB <= p_pAttrArray1[ ui1 ].m_uiAttr
	       && TD_ATTR_USER_BASE_KEY > p_pAttrArray1[ ui1 ].m_uiAttr )
	    {
	      elog( LOG_NOTICE,
		    "%s [%d] - BLOB found in array1.  Attr is %u.\n",
		    __FILE__,
		    __LINE__,
		    p_pAttrArray1[ ui1 ].m_uiAttr );
	    }
	  // If we encounter a no-op, then we consider this iteration as a success
	  // (since no-ops are irrelevant, we just continue on).
	  else if ( TD_ATTR_NOOP == p_pAttrArray1[ ui1 ].m_uiAttr )
	    {
	      tReturn = SUCCESS;
	    }
	  // Otherwise, if we have a valid attribute in our outter loop...
	  else
	    {
	      // Loop over the second attribute array.
	      for ( ui2 = 0;
		    ui2 < p_uiNumAttrs2;
		    ui2++ )
		{
		  // If we encounter a BLOB here, we will break out of this, inner
		  // loops and fail the outter one.  This is because tiny diffusion does
		  // not currently support the comparison of BLOBs.
		  if ( TD_ATTR_USER_BASE_BLOB <= p_pAttrArray2[ ui2 ].m_uiAttr
		       && TD_ATTR_USER_BASE_KEY > p_pAttrArray2[ ui2 ].m_uiAttr )
		    {
		      elog( LOG_NOTICE,
			    "%s [%d] - BLOB found in array2.  Attr is %u.\n",
			    __FILE__,
			    __LINE__,
			    p_pAttrArray2[ ui2 ].m_uiAttr );

		      // Breaking here will leave our sentenel in the FAIL mode and we
		      // will then exit the outter loop and fail the command.
		      break;
		    }
		  // If this attribute is valid, we check to see if it completely matches
		  // the outter array's attribute.
		  else if ( p_pAttrArray1[ ui1 ].m_uiAttr == p_pAttrArray2[ ui2 ].m_uiAttr
			    && p_pAttrArray1[ ui1 ].m_uiOp == p_pAttrArray2[ ui2 ].m_uiOp
			    && p_pAttrArray1[ ui1 ].m_iValue == p_pAttrArray2[ ui2 ].m_iValue )
		    {
		      // If we found a match, then all is well on this iteration.
		      tReturn = SUCCESS;
		      break;
		    }
		}
	    }
	}
    }

  return tReturn;
}

////////////////////////////////////////////////////////////////////////////
//
// Commad: TdMatchI.printAttrs( )
//
// Purpose: This command prints the attributes in the input array.
//
////////////////////////////////////////////////////////////////////////////

void MdMatch_printAttrs( Mdiff_state_t * state,
			 DiffAttr_t   *p_pAttrs,
			 uint8_t       p_uiLen )
{
  uint8_t ui = 0;
    
  // If we have valid input.
  if ( NULL != p_pAttrs )
    {
      // Loop...
      for ( ui = 0;
	    ui < p_uiLen;
	    ui++ )
	{
	  // Stop processing on BLOBs.
	  if ( TD_ATTR_USER_BASE_BLOB <= p_pAttrs[ ui ].m_uiAttr
	       && TD_ATTR_USER_BASE_KEY > p_pAttrs[ ui ].m_uiAttr )
	    {
	      break;
	    }
	  // If this is a valid attr, print it.
	  else
	    {
	      elog( LOG_NOTICE,
		    "[%u - %u - %d]\n",
		    p_pAttrs[ ui ].m_uiAttr,
		    p_pAttrs[ ui ].m_uiOp,
		    p_pAttrs[ ui ].m_iValue );
	    }
	}
    }
}





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