⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msgqueue.cpp

📁 SNMP++程序源码 for ll .8snmp++2_8.tar.Z 嵌入式linux环境下的SNMP开发代码
💻 CPP
字号:
/*===================================================================  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.      M S G Q U E U E . C P P      MSG QUEUE CLASS DECLARATION      Description:	HPUX version of Snmp class      Language:	ANSI C++      Operating System:	HP-UX 9.0      Modules Used:	- Requires use of SR's Library	- Optional, Bristol technologies WIND-U	- Optional, X-Windows Motif      Author:	Peter E Mellquist	HP RND R & D      Compiler Directives:		RTRMON_REV - compiles for router monitor use.		This turns off use of timeticks, counter and gauge SNMP++		objects.	WU_APP - compiles for use with Bristol Technologies WIND-U				 MS-Windows to UNIX porting tools.	X_MOTIF - compiles for use with X Windows motif API.      Date:	July 27, 1999=====================================================================*/char msgqueue_version[]="#(@)$Header: msgqueue.cpp,v 1.19 97/03/26 08:58:53 hmgr Exp $";// For debuggin cout's#include <iostream.h>//-----[ includes ]----------------------------------------------------//----[ snmp++ includes ]----------------------------------------------#include "msgqueue.h"		// queue for holding outstanding messages#include "msec.h"		// class for handling time in msecs#define SNMP_PORT 161 //--------[ globals ]---------------------------------------------------CSNMPMessageQueue *snmpEventList;//--------[ forwards ]--------------------------------------------------//--------[ externs ]---------------------------------------------------extern int send_snmp_request( int sock, unsigned char *send_buf,			      size_t send_len, Address &address);//----[ CSNMPMessage class ]-------------------------------------------CSNMPMessage::CSNMPMessage(unsigned long id,			   Snmp * snmp,			   int socket,			   SnmpTarget &target,			   Pdu &pdu,			   unsigned char * rawPdu,			   size_t rawPduLen,			   const Address & address,			   snmp_callback callBack,			   void * callData):  m_uniqueId(id), m_snmp(snmp), m_socket(socket), m_pdu(pdu),  m_rawPduLen(rawPduLen), m_callBack(callBack), m_callData(callData),  m_reason(0), m_received(0){  // reset pdu mvs  set_error_index(&m_pdu, 0);  set_error_status(&m_pdu, 0);  set_request_id(&m_pdu, m_uniqueId);  m_rawPdu = new unsigned char [rawPduLen];  memcpy(m_rawPdu,rawPdu, rawPduLen);  m_address = (Address *)address.clone();  m_target = target.clone();  SetSendTime();}CSNMPMessage::~CSNMPMessage() {  delete [] m_rawPdu;  delete m_address;  delete m_target;}unsigned long CSNMPMessage::GetId() {  return(m_uniqueId);}void CSNMPMessage::ResetId(const unsigned long newId) {  m_uniqueId = newId;}void CSNMPMessage::SetSendTime() {  m_sendTime.refresh();  // Kludge: When this was first designed the units were millisecs  // However, later on the units for the target class were changed  // to hundreths of secs.  Multiply the hundreths of secs by 10  // to create the millisecs which the rest of the objects use.  // 11-Dec-95 TM  m_sendTime += (m_target->get_timeout() * 10);}void CSNMPMessage::GetSendTime(msec &sendTime) {  sendTime = m_sendTime;}int CSNMPMessage::GetSocket() {  return m_socket;}int CSNMPMessage::GetPdu(int &reason, Pdu &pdu) {  pdu = m_pdu;  reason = m_reason;  return 0;}int CSNMPMessage::SetPdu(const int reason, const Pdu &pdu) {  m_received = 1;  m_pdu = pdu;  m_reason = reason;  return 0;}int CSNMPMessage::GetReceived(){  return m_received;}int CSNMPMessage::ResendMessage() {  int status;  if (m_received) {    // Don't bother to resend if we already have the response    SetSendTime();    return SNMP_CLASS_SUCCESS;  }  if (m_target->get_retry() <= 0) {    // This message has timed out    // perform callback with the error    Callback(SNMP_CLASS_TIMEOUT);    return SNMP_CLASS_TIMEOUT;  }  m_target->set_retry(m_target->get_retry() - 1);  SetSendTime();  status = send_snmp_request(m_socket, m_rawPdu, m_rawPduLen, *m_address);  if (status != 0) {    return SNMP_CLASS_TL_FAILED;  }  return SNMP_CLASS_SUCCESS;}int CSNMPMessage::Callback(const int reason) {  snmp_callback	  tmp_callBack;  if (m_callBack) {    // prevent callbacks from using this message    tmp_callBack = m_callBack;    m_callBack = NULL;    tmp_callBack(reason, m_snmp, m_pdu, *m_target, m_callData);    return 0;  }  else {    return 1;  }}//----[ CSNMPMessageQueueElt class ]--------------------------------------CSNMPMessageQueueElt::CSNMPMessageQueueElt(CSNMPMessage *message,					   CSNMPMessageQueueElt *next,					   CSNMPMessageQueueElt *previous):  m_message(message), m_next(next), m_previous(previous){    /*------------------------------------------*/    /* Finish insertion into doubly linked list */    /*------------------------------------------*/  if (m_next)    m_next->m_previous = this;  if (m_previous)    m_previous->m_next = this;}CSNMPMessageQueueElt::~CSNMPMessageQueueElt(){    /*-------------------------------------*/    /* Do deletion form doubly linked list */    /*-------------------------------------*/  if (m_next)    m_next->m_previous = m_previous;  if (m_previous)    m_previous->m_next = m_next;  if (m_message)    delete m_message;}CSNMPMessageQueueElt *CSNMPMessageQueueElt::GetNext() {  return(m_next);}CSNMPMessage *CSNMPMessageQueueElt::GetMessage() {  return(m_message);}CSNMPMessage *CSNMPMessageQueueElt::TestId(const unsigned long uniqueId){  if (m_message && (m_message->GetId() == uniqueId))    return(m_message);  else    return(NULL);}//----[ CSNMPMessageQueue class ]--------------------------------------CSNMPMessageQueue::CSNMPMessageQueue():  m_head(NULL,NULL,NULL), m_msgCount(0), m_idStack(NULL), m_stackTop(0){  PushId(0);}CSNMPMessageQueue::~CSNMPMessageQueue(){  CSNMPMessageQueueElt *leftOver;    /*--------------------------------------------------------*/    /* walk the list deleting any elements still on the queue */    /*--------------------------------------------------------*/  while (leftOver = m_head.GetNext())    delete leftOver;//  if (m_stackTop)    delete [] m_idStack;}CSNMPMessage * CSNMPMessageQueue::AddEntry(unsigned long id,					   Snmp * snmp,					   int socket,					   SnmpTarget &target,					   Pdu &pdu,					   unsigned char * rawPdu,					   size_t rawPduLen,					   const Address & address,					   snmp_callback callBack,					   void * callData) {  CSNMPMessage *newMsg = new CSNMPMessage(id, snmp, socket, target, pdu,					  rawPdu, rawPduLen, address,					  callBack, callData);    /*---------------------------------------------------------*/    /* Insert entry at head of list, done automagically by the */    /* constructor function, so don't use the return value.    */    /*---------------------------------------------------------*/  (void) new CSNMPMessageQueueElt(newMsg, m_head.GetNext(), &m_head);  m_msgCount++;#ifdef SNMPX11  SnmpX11SetTimer();#endif // SNMPX11  return(newMsg);}CSNMPMessage *CSNMPMessageQueue::GetEntry(const unsigned long uniqueId){  CSNMPMessageQueueElt *msgEltPtr = m_head.GetNext();  CSNMPMessage *returnVal = NULL;  while (msgEltPtr){    if (returnVal = msgEltPtr->TestId(uniqueId))      return(returnVal);    msgEltPtr = msgEltPtr->GetNext();  }  return (NULL);}int CSNMPMessageQueue::DeleteEntry(const unsigned long uniqueId){  CSNMPMessageQueueElt *msgEltPtr = m_head.GetNext();  CSNMPMessage *returnVal = NULL;  while (msgEltPtr){    if (returnVal = msgEltPtr->TestId(uniqueId)){      delete msgEltPtr;      m_msgCount--;#ifdef SNMPX11      SnmpX11SetTimer();#endif // SNMPX11      return SNMP_CLASS_SUCCESS;    }    msgEltPtr = msgEltPtr->GetNext();  }  return SNMP_CLASS_INVALID_REQID;}void CSNMPMessageQueue::DeleteSocketEntry(const int socket){  CSNMPMessageQueueElt *msgEltPtr = m_head.GetNext();  CSNMPMessageQueueElt *tmp_msgEltPtr;  CSNMPMessage *msg = NULL;  while (msgEltPtr){    msg = msgEltPtr->GetMessage();    if (socket == msg->GetSocket()) {      // Make a callback with an error      (void) msg->Callback(SNMP_CLASS_SESSION_DESTROYED);      tmp_msgEltPtr = msgEltPtr;      msgEltPtr = tmp_msgEltPtr->GetNext();      // delete the entry      delete tmp_msgEltPtr;    }    else      msgEltPtr = msgEltPtr->GetNext();  }}CSNMPMessage * CSNMPMessageQueue::GetNextTimeoutEntry() {  CSNMPMessageQueueElt *msgEltPtr = m_head.GetNext();  msec bestTime;  msec sendTime;  CSNMPMessage *msg;  CSNMPMessage *bestmsg = NULL;  if (msgEltPtr) {    bestmsg = msgEltPtr->GetMessage();    bestmsg->GetSendTime(bestTime);  }// This would be much simpler if the queue was an ordered list!  while (msgEltPtr){    msg = msgEltPtr->GetMessage();    msg->GetSendTime(sendTime);    if (bestTime  > sendTime) {      bestTime = sendTime;      bestmsg = msg;    }    msgEltPtr = msgEltPtr->GetNext();  }  return bestmsg;}int CSNMPMessageQueue::GetNextTimeout(msec &sendTime) {  CSNMPMessage *msg;  msg = GetNextTimeoutEntry();  if (msg == NULL) {    // nothing in the queue...    return 1;  }  else {    msg->GetSendTime(sendTime);  }  return 0;}void CSNMPMessageQueue::GetFdSets(int &maxfds, fd_set &readfds,				  fd_set &, fd_set &) {  CSNMPMessageQueueElt *msgEltPtr = m_head.GetNext();  int sock;  while (msgEltPtr){    sock = msgEltPtr->GetMessage()->GetSocket();    FD_SET(sock, &readfds);    if (maxfds < (sock+1))      maxfds = sock+1;    msgEltPtr = msgEltPtr->GetNext();  }}int CSNMPMessageQueue::GetCount() {  return m_msgCount;}void CSNMPMessageQueue::PushId(const unsigned long id) {  unsigned long *newStack;//TM: this is really dumb!  Fix it!  newStack = new unsigned long [m_stackTop+1];  for (int i=0; i< m_stackTop; i++)    newStack[i] = m_idStack[i];  newStack[m_stackTop] = id;  m_stackTop++;  delete [] m_idStack;  m_idStack = newStack;}unsigned long CSNMPMessageQueue::PeekId() {  return m_idStack[m_stackTop - 1];}unsigned long CSNMPMessageQueue::PopId() {  unsigned long temp=0;  if (m_stackTop) {    m_stackTop--;    temp = m_idStack[m_stackTop];    m_idStack[m_stackTop] = 0;  }  return temp;}// forwardextern int receive_snmp_response( int sock, Pdu &pdu);int CSNMPMessageQueue::HandleEvents(const int maxfds,				    const fd_set &readfds,				    const fd_set &,				    const fd_set &) {  CSNMPMessage *msg;  Pdu tmppdu;  unsigned long temp_req_id;  int status;  int recv_status;  fd_set snmp_readfds, snmp_writefds, snmp_errfds;  int tmp_maxfds = maxfds;  // Only read from our own fds  FD_ZERO(&snmp_readfds);  FD_ZERO(&snmp_writefds);  FD_ZERO(&snmp_errfds);  GetFdSets(tmp_maxfds, snmp_readfds, snmp_writefds, snmp_errfds);  for (int fd = 0; fd < maxfds; fd++) {    if ((FD_ISSET(fd, &snmp_readfds)) &&	(FD_ISSET(fd, &readfds))) {      set_request_id(&tmppdu, 0);      // get the response and put it into a Pdu      recv_status = receive_snmp_response(fd, tmppdu);      // find the corresponding msg in the message queue      temp_req_id = tmppdu.get_request_id();      msg = GetEntry(temp_req_id);      if (!msg) {	     // the sent message is gone!	     // probably was canceled, ignore it	     continue;      }      if (tmppdu.get_request_id()) {	     // we correctly received the pdu	     // save it back into the message	     status = msg->SetPdu(recv_status, tmppdu);	     // Do the callback	     status = msg->Callback(SNMP_CLASS_ASYNC_RESPONSE);		     if (!status) {	       // this is an asynch response and the callback is done.	       // no need to keep this message around;	       // Dequeue the message	       DeleteEntry(temp_req_id);	     }	  }    } // if socket has data  } // for all sockets  return SNMP_CLASS_SUCCESS;}int CSNMPMessageQueue::DoRetries(const msec &now) {  CSNMPMessage *msg;  msec sendTime;  int status = SNMP_CLASS_SUCCESS;  while (msg = GetNextTimeoutEntry()) {    msg->GetSendTime(sendTime);    if (sendTime <= now) {      // send out the message again      status = msg->ResendMessage();      if (status != 0) {	if (status == SNMP_CLASS_TIMEOUT) {	  // Dequeue the message	   DeleteEntry(msg->GetId());	}	else {	  // Some other send error	  // should we dequeue the message?	  // do we really want to return without processing the rest?	  return status;	}      }    }    else {      // the next timeout is still in the future...so we are done      break;    }  }  return status;}int CSNMPMessageQueue::Done() {  unsigned long id;  CSNMPMessage *msg;  if ( id = PeekId()) {    // we were looking for a req_id.  Did we find it?    msg = GetEntry(id);    if (msg) {      return(msg->GetReceived());    }    else {      // the message is not in the queue...must have timed out      return 1;    }  }  return 0;}

⌨️ 快捷键说明

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