pdu_cont.cpp

来自「HP公司的SNMP++的Win32版本源码」· C++ 代码 · 共 368 行

CPP
368
字号
/*===================================================================

  Copyright (c) 1999
  Hewlett-Packard Company

  ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
  Permission to use, copy, modify, distribute and/or sell this software 
  and/or its documentation is hereby granted without fee. User agrees 
  to display the above copyright notice and this license notice in all 
  copies of the software and any documentation of the software. User 
  agrees to assume all liability for the use of the software; Hewlett-Packard 
  makes no representations about the suitability of this software for any 
  purpose. It is provided "AS-IS without warranty of any kind,either express 
  or implied. User hereby grants a royalty-free license to any and all 
  derivatives based upon this software code base. 


  
  P D U _ C O N T . C P P

  PDU CONTAINER CLASS IMPLEMENTATION

  DESIGN:
  Peter E Mellquist

  AUTHOR:
  Peter E Mellquist

  DATE:
  July 25, 1999

  DESCRIPTION:
  This module contains the implementation for the pdu
  container class.  

  LANGUAAGE:
  ANSI C++

  OPERATING SYSTEM(S):
  Win32


=====================================================================*/
char pducls_cpp_version[]="#(@)SNMP++ 2.8 $Header: pdu_cont.cpp,v 1.10 96/03/16 16:02:46 hmgr Exp $";
#include "pdu_cont.h"	 // include file for pdu class
#include "winsnmp.h"	 // winsnmp include file
#include "pdu.h"         // include pdu class definition
#include "snmperrs.h"    // include snmp error messages
#include "target.h"


//--------------[  Pdu_Container::Pdu_Container() ]--------------------
// constructor
// initialize all the slots to not pending
// clear all the statistic counters
Pdu_Container::Pdu_Container()
{
  int z;
  for (z=0;z<MAX_PDU_SLOTS;z++)
     slots[z] = NULL;	 

  // init stats
  pdus_sent = 0;
  pdus_received = 0;
  pdus_received_err = 0;
  pdus_sent_err = 0;
  timeout_count = 0;
  max_queue_size = 0;
  trap_count = 0;
  trap_sent = 0;
  decode_errors = 0;
  stray_responses = 0;
  invalid_pdu_types = 0;

  current_request_id = MAX_REQUEST_ID;
};

// destructor
Pdu_Container::~Pdu_Container()
{
   for (int z=0;z<MAX_PDU_SLOTS;z++)
	   delete slots[z];
};

//-------[ search for any dangling enteries
//	   for a given WinSNMP session
void Pdu_Container::search_and_destroy( HSNMP_SESSION hSession, Snmp *snmp)
{
  int z;
  for (z=0;z<MAX_PDU_SLOTS;z++)
  {
     if (( slots[z]!= NULL ) && ( slots[z]->hSession == hSession))
     {
		if ( slots[z]->pdu_arrived )
		{
	    SNMPDEBUG("++ SNMP++, Search and Destroy Hit\n");
        // check to see if it was an async request then
        // we need to inform the callback with the 
        // SNMP_CLASS_SESSION_DESTROYED message
        if ( slots[z]->callback != NULL)
        {
           // fire destroy message to the specified callback
           SNMPDEBUG("++ SNMP++, Destroying Snmp Object Async Notify\n");

           // we don't have the actual pdu, just the rid
           Pdu pdu;
           set_request_id( &pdu, slots[z]->RequestId); 

           CTarget v1t;

          (slots[z]->callback)( (int) SNMP_CLASS_SESSION_DESTROYED, // reason
	                       (Snmp*) snmp,	                   // snmp++ session who own the req
		               (Pdu&) pdu,		           // pdu
		               (SnmpTarget&) v1t,                  // target
		               (void*) slots[z]->callback_data);    // callback data

        }

	// free up the WinSNMP variables
	SnmpFreeEntity( slots[z]->hSourceEntity);
	SnmpFreeEntity( slots[z]->hDestEntity);
	SnmpFreeContext( slots[z]->hRecContext);
	SnmpFreeVbl( slots[z]->hRecVbl);

	}
	// free up the slot
        delete slots[z];
	slots[z] = NULL;   
     }
  };
};


//-------[ get a request id, don't save it in the pending table ]------
long int Pdu_Container::get_request_id()
{
   current_request_id--;
   if (current_request_id < MIN_REQUEST_ID)
     current_request_id = MAX_REQUEST_ID;
   return current_request_id;
};

//--------[ get a request is from the pdu container class ]---------
// this one records the rid in the pending table
long int Pdu_Container::get_request_id( HSNMP_SESSION hSession,
									    snmpcallback cb,
					                    void * cbd)
{
  int z=0;

  while (z<MAX_PDU_SLOTS)
  {
     long int my_rid;

     if ( slots[z] == NULL)
     {
       current_request_id--;
       if (current_request_id < MIN_REQUEST_ID)
	      current_request_id = MAX_REQUEST_ID;
       my_rid = current_request_id;

       slots[z] = new Pdu_Slot;
       if ( slots[z] == NULL)
          return -1;

       slots[z]->pending = TRUE;	      // this request is pending
       slots[z]->pdu_arrived = FALSE;	  // response has not arrived
       slots[z]->hSession = hSession;	  // no session handle
       slots[z]->request_id = my_rid;	  // set rid pending
       slots[z]->callback = cb;		      // remember callback ptr
       slots[z]->callback_data = cbd;	  // remember callback data
       set_max_queue( z);
       return my_rid;
     }
     z++;
  }

  return -1;  // no slots available
};


//------------[ Pdu_Container::clear_request_id(long int rid) ]----------
// clear the slot to make it available again
void Pdu_Container::clear_request_id( const long int rid)
{
   int w=0;

   while ( w < MAX_PDU_SLOTS)
   {
     if ((slots[w] != NULL) && ( slots[w]->request_id == rid))	
     {
        delete slots[w];
        slots[w] = NULL;
	    return;
     }
     w++;
   }
};


//----------[ Pdu_Container::check_if_arrived( long int rid) ]----------
// check if a pending pdu has arrived
int Pdu_Container::check_if_arrived( const long int rid)
{
  int w=0;

  // look through all the slots for a rid match
  // and an arrival
  while(w<MAX_PDU_SLOTS)
  {
     if (( slots[w] != NULL) &&( slots[w]->request_id == rid)&&(slots[w]->pdu_arrived))
       return TRUE;
     w++;
  }

  return FALSE;
};

//------[ Pdu_Container::check_if_pending( long int rid) ]-----------
// determine if a pdu slot is pending
// received pdus are only placed into a slot
// if it is pending
int Pdu_Container::check_if_pending( const long int rid, snmpcallback *cb)
{
  int w=0;

  // look for a rid match and a pending request
  // if found, return the callback ptr
  while ( w<MAX_PDU_SLOTS)
  {
     if (( slots[w] != NULL) &&(slots[w]->request_id ==rid)&&(slots[w]->pending))
     {
	*cb = slots[w]->callback;
	return TRUE;   // don't pull the data out, just report it there
     }
     w++;
  }

  *cb = 0;
  return FALSE;
};


//---------[ Pdu_Container::set_slot ]----------------------------------
// set a slot with an arrived pdu
void Pdu_Container::set_slot( long int rid,	 // slot to set as arrived
		 HSNMP_SESSION hSession,	 // WinSnmp Session handle
		 HSNMP_ENTITY  hSourceEntity,	 // Source Entity
		 HSNMP_ENTITY  hDestEntity,	 // Destination Entity
		 HSNMP_CONTEXT hRecContext,	 // Receive Context
		 smiINT	       PduType,		 // Type of pdu
		 smiINT	       RequestId,	 // Request ID
		 smiINT	       ErrorStatus,	 // Error Status
		 smiINT	       ErrorIndex,	 // Error Index
		 HSNMP_VBL     hRecVbl)		 // Received Variable Binding List
{
    int w=0;
    int z=-1;
    SNMPDEBUG("++ SNMP++, in Set Slot \n");
    // find the slot
    while (w<MAX_PDU_SLOTS)
    {
       if (( slots[w] != NULL) &&( slots[w]->request_id == rid))
	 z = w;
       w++;
    }
    if ((z<0)||(z>=MAX_PDU_SLOTS)) return;


    slots[z]->pdu_arrived = TRUE;	      // mark as arrived

    // fill in the params
    slots[z]->hSession = hSession;
    slots[z]->hSourceEntity = hSourceEntity;
    slots[z]->hDestEntity = hDestEntity;
    slots[z]->hRecContext = hRecContext;
    slots[z]->PduType = PduType;
    slots[z]->RequestId = RequestId;
    slots[z]->ErrorStatus = ErrorStatus;
    slots[z]->ErrorIndex = ErrorIndex;
    slots[z]->hRecVbl = hRecVbl;

    SNMPDEBUG("++ SNMP++, Out Set Slot \n");
};


//------------[ Pdu_Container::get_slot ]------------------------------
// get the data from a slot
//
void Pdu_Container::get_slot( long int rid, // for this rid
	    HSNMP_ENTITY  *hSrcRecvEnt,
	    HSNMP_ENTITY  *hDstRecvEnt,
	    HSNMP_CONTEXT *hRecvContext,
	    smiINT *lnRecvPduType,
	    smiINT *lnRecvRequestId,
	    smiINT *lnErrorStatus,
	    smiINT *lnErrorIndex,
	    snmpcallback *cb,
	    void * *cbd,
	    HSNMP_VBL *hRecvVbl)
{
    int w=0;
    int z=-1;

    // find the slot
    while (w<MAX_PDU_SLOTS)
    {
       if ((slots[w] != NULL) &&( slots[w]->request_id == rid))
	 z = w;
       w++;
    }
    if ((z<0)||(z>=MAX_PDU_SLOTS))
       return;


     // fill in the return variables
     *hSrcRecvEnt = slots[z]->hSourceEntity;
     *hDstRecvEnt = slots[z]->hDestEntity;
     *hRecvContext = slots[z]->hRecContext;
     *lnRecvPduType = slots[z]->PduType;
     *lnRecvRequestId = slots[z]->RequestId;
     *lnErrorStatus = slots[z]->ErrorStatus;
     *lnErrorIndex = slots[z]->ErrorIndex;
     *hRecvVbl = slots[z]->hRecVbl;
     *cb = slots[z]->callback;
     *cbd = slots[z]->callback_data;

     // clear the slot
     delete slots[z];
     slots[z] = NULL;

};


// return the callback information for
// a given request id
int Pdu_Container::get_cb_info( long int rid,
				 snmpcallback *cb,
				 void * *cbd)
{
    int w=0;
    int z=-1;

    // find the slot
    while (w<MAX_PDU_SLOTS)
    {
       if (( slots[w] != NULL ) &&( slots[w]->request_id == rid)&&( slots[w]->callback !=0))
	 z = w;
       w++;
    }
    if ((z<0)||(z>=MAX_PDU_SLOTS))
    {
       *cb=0;
       *cbd=0;
       return FALSE;
    }


     // fill in the return variables
     *cb = slots[z]->callback;
     *cbd = slots[z]->callback_data;

     delete slots[z];
     slots[z] = NULL;

     return TRUE;
};

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?