📄 snmpinformrequest.java
字号:
SnmpInformHandler savedCallback = callback; callback = null; informSession.waitForResponse(this, time); callback = savedCallback; } else { // This is being done from a different thread. So notifyClient will do the notification. // synchronized (this) { SnmpInformHandler savedCallback = callback ; try { callback = null ; this.wait(time) ; } catch (InterruptedException e) { } callback = savedCallback ; } } return (! inProgress()); // true if request completed. } /** * Cancels the active inform request and removes itself from the polling list. */ final public void cancelRequest() { errorStatus = snmpReqAborted; stopRequest(); deleteRequest(); notifyClient(); } /** * Notifies the registered client about the completion of an operation. */ final public synchronized void notifyClient() { this.notifyAll(); } /** * Finalizer of the <CODE>SnmpInformRequest</CODE> objects. * This method is called by the garbage collector on an object * when garbage collection determines that there are no more references to the object. * <P>Sets all the references to this SNMP inform request object to <CODE>null</CODE>. */ public void finalize() { callback = null; varBindList = null; internalVarBind = null; adaptor = null; informSession = null; requestPdu = null; responsePdu = null; } /** * Returns the <CODE>String</CODE> representation of an error code. * @param errcode The error code as an integer. * @return The error code as a <CODE>String</CODE>. */ public static String snmpErrorToString(int errcode) { switch (errcode) { case snmpRspNoError : return "noError" ; case snmpRspTooBig : return "tooBig" ; case snmpRspNoSuchName : return "noSuchName" ; case snmpRspBadValue : return "badValue" ; case snmpRspReadOnly : return "readOnly" ; case snmpRspGenErr : return "genErr" ; case snmpRspNoAccess : return "noAccess" ; case snmpRspWrongType : return "wrongType" ; case snmpRspWrongLength : return "wrongLength" ; case snmpRspWrongEncoding : return "wrongEncoding" ; case snmpRspWrongValue : return "wrongValue" ; case snmpRspNoCreation : return "noCreation" ; case snmpRspInconsistentValue : return "inconsistentValue" ; case snmpRspResourceUnavailable : return "resourceUnavailable" ; case snmpRspCommitFailed : return "commitFailed" ; case snmpRspUndoFailed : return "undoFailed" ; case snmpRspAuthorizationError : return "authorizationError" ; case snmpRspNotWritable : return "notWritable" ; case snmpRspInconsistentName : return "inconsistentName" ; case snmpReqTimeout : return "reqTimeout" ; case snmpReqAborted : return "reqAborted" ; case snmpRspDecodingError : return "rspDecodingError" ; case snmpReqEncodingError : return "reqEncodingError" ; case snmpReqPacketOverflow : return "reqPacketOverflow" ; case snmpRspEndOfTable : return "rspEndOfTable" ; case snmpReqRefireAfterVbFix : return "reqRefireAfterVbFix" ; case snmpReqHandleTooBig : return "reqHandleTooBig" ; case snmpReqTooBigImpossible : return "reqTooBigImpossible" ; case snmpReqInternalError : return "reqInternalError" ; case snmpReqSocketIOError : return "reqSocketIOError" ; case snmpReqUnknownError : return "reqUnknownError" ; case snmpWrongSnmpVersion : return "wrongSnmpVersion" ; case snmpUnknownPrincipal: return "snmpUnknownPrincipal"; case snmpAuthNotSupported: return "snmpAuthNotSupported"; case snmpPrivNotSupported: return "snmpPrivNotSupported"; case snmpBadSecurityLevel: return "snmpBadSecurityLevel"; case snmpUsmBadEngineId: return "snmpUsmBadEngineId"; case snmpUsmInvalidTimeliness: return "snmpUsmInvalidTimeliness"; } return "Unknown Error = " + errcode; } // PRIVATE AND PACKAGE METHODS //---------------------------- /** * For SNMP Runtime internal use only. * Starts an inform request in asynchronous mode. The callback interface * is used to notify the user upon request completion. * @param vblst The list of <CODE>SnmpVarBind</CODE> to be used. * @exception SnmpStatusException This inform request is already in progress. */ synchronized void start(SnmpVarBindList vblst) throws SnmpStatusException { if (inProgress()) throw new SnmpStatusException("Inform request already in progress."); setVarBindList(vblst); initializeAndFire(); } private synchronized void initializeAndFire() { requestPdu = null; responsePdu = null; reason = null; startRequest(System.currentTimeMillis()); setErrorStatusAndIndex(0, 0); } /** * This method submits the inform request for polling and marks the request * active. It does nothing if the request is already active. * The poll will be scheduled to happen immediately. * @param starttime The start time for polling. */ private synchronized void startRequest(long starttime) { nextPollTime = starttime; prevPollTime = 0; schedulePoll(); } /** * This method creates a new request ID. The ID is submitted to the poll server for scheduling. */ private void schedulePoll() { numTries = 0; initNewRequest(); setRequestStatus(stWaitingToSend); informSession.getSnmpQManager().addRequest(this); } /** * This method determines whether the inform request is to be retried. This is used if the * peer did not respond to a previous request. If the request exceeds * the maxTries limit, a timeout is signaled. */ void action() { if (inProgress() == false) return; while (true) { try { if (numTries == 0) { invokeOnReady(); } else if (numTries < getMaxTries()) { invokeOnRetry(); } else { invokeOnTimeout(); } return ; } catch (OutOfMemoryError omerr) { // Consider it as a try ! // numTries++; if (isDebugOn()) { debug("action", "Inform request hit out of memory situation..."); } Thread.currentThread().yield(); } } } final private void invokeOnReady() { if (requestPdu == null) { requestPdu = constructPduPacket(); } if (requestPdu != null) { if (sendPdu() == false) queueResponse(); } } final private void invokeOnRetry() { invokeOnReady(); } final private void invokeOnTimeout() { errorStatus = snmpReqTimeout; queueResponse(); } final private void queueResponse() { informSession.addResponse(this); } /** * Constructs an inform request PDU. */ synchronized SnmpPdu constructPduPacket() { SnmpPduPacket reqpdu = null; Exception excep = null; try { reqpdu = new SnmpPduRequest(); reqpdu.port = port; reqpdu.type = pduInformRequestPdu; reqpdu.version = snmpVersionTwo; reqpdu.community = communityString.getBytes("8859_1"); reqpdu.requestId = getRequestId(); reqpdu.varBindList = internalVarBind; if (isTraceOn()) { trace("constructPduPacket", "Packet built"); } } catch (Exception e) { excep = e; errorStatus = snmpReqUnknownError; reason = e.getMessage(); } if (excep != null) { if (isDebugOn()) { debug("constructPduPacket", excep); } reqpdu = null; queueResponse(); } return reqpdu; } boolean sendPdu() { try { responsePdu = null; SnmpPduFactory pduFactory = adaptor.getPduFactory(); SnmpMessage msg = (SnmpMessage)pduFactory.encodeSnmpPdu((SnmpPduPacket)requestPdu, adaptor.getBufferSize().intValue()); if (msg == null) { if (isDebugOn()) { debug("sendPdu", "pdu factory returned a null value"); } throw new SnmpStatusException(snmpReqUnknownError); // This exception will caught hereafter and reported as an snmpReqUnknownError // FIXME: may be it's not the best behaviour ? } int maxPktSize = adaptor.getBufferSize().intValue(); byte[] encoding = new byte[maxPktSize]; int encodingLength = msg.encodeMessage(encoding); if (isTraceOn()) { trace("sendPdu", "Dump : \n" + msg.printMessage()); } sendPduPacket(encoding, encodingLength); return true; } catch (SnmpTooBigException ar) { if (isDebugOn()) { debug("sendPdu", ar); } setErrorStatusAndIndex(snmpReqPacketOverflow, ar.getVarBindCount()); requestPdu = null; reason = ar.getMessage(); if (isDebugOn()) { debug("sendPdu", "Packet Overflow while building inform request"); } } catch (java.io.IOException ioe) { setErrorStatusAndIndex(snmpReqSocketIOError, 0); reason = ioe.getMessage(); } catch (Exception e) { if (isDebugOn()) { debug("sendPdu", e); } setErrorStatusAndIndex(snmpReqUnknownError, 0); reason = e.getMessage(); } return false; } /** * Sends the prepared PDU packet to the manager and updates the data structure * to expect a response. It acquires a lock on the socket to prevent a case * where a response arrives before this thread could insert the * request into the wait queue. * @exception IOException Signals that an I/O exception of some sort has occurred. */ final void sendPduPacket(byte[] buffer, int length) throws java.io.IOException { if (isTraceOn()) { trace("sendPduPacket", "Send to peer. Peer/Port : " + address.getHostName() + "/" + port + ". Length = " + length + "\nDump : \n" + SnmpMessage.dumpHexBuffer(buffer,0, length)); } SnmpSocket theSocket = informSession.getSocket(); synchronized (theSocket) { theSocket.sendPacket(buffer, length, address, port); setRequestSentTime(System.currentTimeMillis()); } } /** * For SNMP Runtime internal use only. */ final void processResponse() { if (isTraceOn()) { trace("processResponse", "errstatus = " + errorStatus); } if (inProgress() == false) { // check if this request is still alive. responsePdu = null; return; // the request may have cancelled. } if (errorStatus >= snmpReqInternalError) { handleInternalError("Internal Error..."); return; } try { parsePduPacket(responsePdu); //responsePdu = null; // At this point the errorIndex is rationalized to start with 0. switch (errorStatus) { case snmpRspNoError : handleSuccess(); return; case snmpReqTimeout : handleTimeout(); return; case snmpReqInternalError : handleInternalError("Unknown internal error. deal with it later!"); return; case snmpReqHandleTooBig : setErrorStatusAndIndex(snmpRspTooBig, 0); handleError("Cannot handle too-big situation..."); return; case snmpReqRefireAfterVbFix : // Refire request after fixing varbindlist. initializeAndFire(); return; default : handleError("Error status set in packet...!!"); return; } } catch (Exception e) { if (isDebugOn()) { debug("processResponse", e); } reason = e.getMessage(); } handleInternalError(reason); } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -