Search in sources :

Example 1 with PDU

use of org.smpp.pdu.PDU in project opensmpp by OpenSmpp.

the class ReceiverBase method tryReceivePDUWithTimeout.

/**
 * For specified time tries to receive a PDU from given connection by
 * calling method <code>tryReceivePDU</code>.
 * The method <code>tryReceivePDU</code> must be implemented in the derived
 * class.
 * <p>
 * The timeout can be either value > 0, then it means for
 * how many milliseconds will be repeatedly tried to receive a PDU.
 * If the timeout is = 0 then there is only one attempt to receive a PDU.
 * If the timeout is equal to Data.RECEIVE_BLOCKING, then the this method
 * tries receive a PDU until it is received.
 *
 * @param connection  the connection from which the PDU should be received
 * @param expectedPDU the command id and sequence id of the received PDU
 *                    should be equal to those of expectedPDU
 * @param timeout     the timeout indication
 * @return the received PDU if any or null if none received
 *
 * @exception IOException exception during communication
 * @exception PDUException incorrect format of PDU
 * @exception TimeoutException rest of data not received for too long time
 * @exception UnknownCommandIdException PDU with unknown id was received
 * @see #tryReceivePDU(Connection,PDU)
 * @see PDU#equals(Object)
 */
protected final PDU tryReceivePDUWithTimeout(Connection connection, PDU expectedPDU, long timeout) throws UnknownCommandIdException, TimeoutException, PDUException, IOException {
    debug.write(DRXTX, "receivePDU: Going to receive response.");
    long startTime = Data.getCurrentTime();
    PDU pdu = null;
    if (timeout == 0) {
        // with no timeout try just once
        pdu = tryReceivePDU(connection, expectedPDU);
    } else {
        // with timeout keep trying until get some or timeout expires
        while ((pdu == null) && canContinueReceiving(startTime, timeout)) {
            pdu = tryReceivePDU(connection, expectedPDU);
        }
    }
    if (pdu != null) {
        debug.write(DRXTX, "Got pdu " + pdu.debugString());
    }
    return pdu;
}
Also used : PDU(org.smpp.pdu.PDU)

Example 2 with PDU

use of org.smpp.pdu.PDU in project opensmpp by OpenSmpp.

the class Receiver method receiveAsync.

/**
 * This method receives a PDU from connection and stores it into
 * <code>pduQueue</code>. It's called from the <code>ReceiverBase</code>'s
 * p<code>process</code> method which is called in loop from
 * <code>ProcessingThread</code>'s <code>run</code> method.
 * <p>
 * If an exception occurs during receiving, depending on type
 * of the exception this method either just reports the exception to
 * debug & event objects or stops processing to indicate
 * that it isn't able to process the exception. The function
 * <code>setTermException</code> is then called with the caught exception.
 *
 * @see ReceiverBase#run()
 */
protected void receiveAsync() {
    PDU pdu = null;
    try {
        debug.write(DRXTXD2, "Receiver.receiveAsync() going to receive pdu.");
        pdu = receivePDUFromConnection(connection, unprocessed);
    // we must catch every exception as this is thread running
    // on the background and we don't want the thread to be terminated
    } catch (InvalidPDUException e) {
        // thrown when enough data were received but further parsing
        // required more than indicated by CommandLength, i.e. pdu is
        // corrupted or further parsing didn't find terminating zero
        // of a c-string i.e. pdu is corrupted
        // must send generic nack anyway
        event.write(e, "Receiver.receiveAsync(): received PDU is invalid.");
        PDU expdu = e.getPDU();
        int seqNr = expdu == null ? 0 : expdu.getSequenceNumber();
        if (automaticNack) {
            sendGenericNack(Data.ESME_RINVMSGLEN, seqNr);
        } else {
            pdu = new GenericNack(Data.ESME_RINVMSGLEN, seqNr);
        }
    } catch (UnknownCommandIdException e) {
        // if received unknown pdu, we must send generic nack
        event.write(e, "Receiver.receiveAsync(): Unknown command id.");
        if (automaticNack) {
            sendGenericNack(Data.ESME_RINVCMDID, e.getSequenceNumber());
        } else {
            pdu = new GenericNack(Data.ESME_RINVCMDID, e.getSequenceNumber());
        }
    } catch (TimeoutException e) {
        // too long had unprocessed data
        debug.write(DRXTX, "Receiver.receiveAsync() too long had an uncomplete message.");
    } catch (PDUException e) {
        // something wrong with the PDU
        event.write(e, "Receiver.receiveAsync()");
        PDU expdu = e.getPDU();
        int seqNr = expdu == null ? 0 : expdu.getSequenceNumber();
        if (automaticNack) {
            sendGenericNack(e.getErrorCode(), seqNr);
        } else {
            pdu = new GenericNack(e.getErrorCode(), seqNr);
        }
    } catch (Exception e) {
        // don't know what happen, let's end the show
        event.write(e, "Receiver.receiveAsync()");
        stopProcessing(e);
    }
    if (pdu != null) {
        debug.write(DRXTX, "Receiver.receiveAsync(): PDU received, processing " + pdu.debugString());
        if (asynchronous) {
            process(pdu);
        } else {
            enqueue(pdu);
        }
    }
}
Also used : PDU(org.smpp.pdu.PDU) InvalidPDUException(org.smpp.pdu.InvalidPDUException) GenericNack(org.smpp.pdu.GenericNack) UnknownCommandIdException(org.smpp.pdu.UnknownCommandIdException) PDUException(org.smpp.pdu.PDUException) InvalidPDUException(org.smpp.pdu.InvalidPDUException) PDUException(org.smpp.pdu.PDUException) UnknownCommandIdException(org.smpp.pdu.UnknownCommandIdException) IOException(java.io.IOException) InvalidPDUException(org.smpp.pdu.InvalidPDUException)

Example 3 with PDU

use of org.smpp.pdu.PDU in project opensmpp by OpenSmpp.

the class Receiver method setServerPDUEventListener.

/**
 * Sets the event listener for asynchronous <code>Receiver</code>.
 * In case there are unprocessed PDUs in the queue,
 * they are removed from the queue and passed to the newly set listener.
 */
public synchronized void setServerPDUEventListener(ServerPDUEventListener pduListener) {
    this.pduListener = pduListener;
    this.asynchronous = pduListener != null;
    if (asynchronous) {
        // let's remove all pdu's from the queue as since now all
        // processing should be asynchronous -- it's not wise to
        // expect that the programmer will try AFTER setting the listener
        // to call receive() which when in sync mode removes the pdus from
        // the queue
        PDU pdu;
        int queueSize;
        synchronized (pduQueue) {
            queueSize = pduQueue.size();
            for (int i = 0; i < queueSize; i++) {
                pdu = (PDU) pduQueue.dequeue();
                process(pdu);
            }
        }
    }
}
Also used : PDU(org.smpp.pdu.PDU)

Example 4 with PDU

use of org.smpp.pdu.PDU in project opensmpp by OpenSmpp.

the class Receiver method tryReceivePDU.

/**
 * This method tries to receive one PDU from the connection.
 * It is called in cycle from <code>tryReceivePDUWithTimeout</code> until
 * timeout expires. <code>tryReceivePDUWithTimeout</code> is called
 * either from <code>receiveAsync</code> as asynchronous receive on
 * background or from <code>receive</code> as synchronous receive.
 * It either gets pdu from the queue or tries to receive it from connection
 * using <code>receivePDUFromConnection</code> depending on
 * the value of the <code>receiver</code> flag. The method
 * checks if the actualy received PUD is equal to <code>expectedPDU</code>.
 *
 * @exception IOException exception during communication
 * @exception PDUException incorrect format of PDU
 * @exception TimeoutException rest of PDU not received for too long time
 * @exception UnknownCommandIdException PDU with unknown id was received
 * @see ReceiverBase#tryReceivePDUWithTimeout(Connection,PDU,long)
 * @see #receiveAsync()
 * @see ReceiverBase#run()
 */
protected PDU tryReceivePDU(Connection connection, PDU expectedPDU) throws UnknownCommandIdException, TimeoutException, PDUException, IOException {
    PDU pdu = null;
    if (receiver) {
        debug.write(DRXTXD2, "Is receiver/transciever => trying to get from queue.");
        synchronized (pduQueue) {
            if (expectedPDU == null) {
                // i.e. any pdu is acceptable
                if (!pduQueue.isEmpty()) {
                    pdu = (PDU) pduQueue.dequeue();
                }
            } else {
                pdu = (PDU) pduQueue.dequeue(expectedPDU);
            }
            if (pdu == null) {
                try {
                    pduQueue.wait(getQueueWaitTimeout());
                } catch (InterruptedException e) {
                    // we don't care
                    debug.write(DRXTX, "tryReceivePDU got interrupt waiting for queue");
                }
            }
        }
    } else {
        debug.write(DRXTX, "Is transmitter only => trying to receive from connection.");
        pdu = receivePDUFromConnection(connection, unprocessed);
        if (pdu != null) {
            if ((expectedPDU == null) || !pdu.equals(expectedPDU)) {
                debug.write(DRXTX, "This is not the pdu we expect, processing" + pdu.debugString());
                enqueue(pdu);
                pdu = null;
            }
        }
    }
    return pdu;
}
Also used : PDU(org.smpp.pdu.PDU)

Example 5 with PDU

use of org.smpp.pdu.PDU in project opensmpp by OpenSmpp.

the class ReceiverBase method tryGetUnprocessedPDU.

/**
 * Tries to create a PDU from the buffer provided.
 * Returns the PDU if successfull or null if not or an exception
 * if the PDU is incorrect.
 */
private final PDU tryGetUnprocessedPDU(Unprocessed unprocessed) throws UnknownCommandIdException, PDUException {
    debug.write(DRXTX, "trying to create pdu from unprocessed buffer");
    PDU pdu = null;
    ByteBuffer unprocBuffer = unprocessed.getUnprocessed();
    try {
        pdu = PDU.createPDU(unprocBuffer);
        unprocessed.check();
        // Reset counter after successful createPDU (as per bug #2138444):
        messageIncompleteRetryCount = 0;
    } catch (HeaderIncompleteException e) {
        // the header wasn't received completly, we will try to
        // receive the rest next time
        debug.write(DRXTXD, "incomplete message header, will wait for the rest.");
        // as it's incomplete - wait for new data
        unprocessed.setHasUnprocessed(false);
        unprocessed.setExpected(Data.PDU_HEADER_SIZE);
    } catch (MessageIncompleteException e) {
        // busy servers and PDUs split across TCP packets.
        if (messageIncompleteRetryCount > 5) {
            messageIncompleteRetryCount = 0;
            event.write("Giving up on incomplete messages - probably garbage in unprocessed buffer. Flushing unprocessed buffer.");
            unprocessed.reset();
        }
        // the message wasn't received completly, less bytes than command
        // length has been received, will try to receive the rest next time
        debug.write(DRXTXD, "incomplete message, will wait for the rest.");
        // as it's incomplete - wait for new data
        unprocessed.setHasUnprocessed(false);
        unprocessed.setExpected(Data.PDU_HEADER_SIZE);
        messageIncompleteRetryCount++;
    } catch (UnknownCommandIdException e) {
        // message with invalid id was received, should send generic_nack
        debug.write(DRXTX, "unknown pdu, might remove from unprocessed buffer. CommandId=" + e.getCommandId());
        if (e.getCommandLength() <= unprocBuffer.length()) {
            // have already enough to remove
            try {
                unprocBuffer.removeBytes(e.getCommandLength());
            } catch (NotEnoughDataInByteBufferException e1) {
                // can't happen, we've checked it above
                throw new Error("Not enough data in buffer even if previously checked that there was enough.");
            }
            unprocessed.check();
            // caller will decide what to do
            throw e;
        }
        // discarded via an UnknownCommandIdException again).
        throw e;
    } catch (PDUException e) {
        // paolo@bulksms.com: safer to catch all other PDU exceptions and force
        // force a check() here - some exception in parsing should not be allowed
        // to leave ghost data in the Unprocessed buffer (even though this is now
        // less likely after improvements to PDU.createPDU()):
        unprocessed.check();
        throw e;
    }
    /* paolo@bulksms.com: concerned that this is too broad, and will
		   stop useful exceptions from being passed back up the call stack,
			so disabling for now:
		} catch (Exception e) {
			debug.write(DRXTX, "Exception catched: " + e.toString());
			StringWriter stringWriter = new StringWriter();
			PrintWriter printWriter = new PrintWriter(stringWriter);
			e.printStackTrace(printWriter);
			debug.write(DRXTX, stringWriter.toString());
		}
		*/
    if (pdu != null) {
        debug.write(DRXTX, "received complete pdu" + pdu.debugString());
        debug.write(DRXTX, "there is " + unprocBuffer.length() + " bytes left in unprocessed buffer");
    }
    // unprocessed.check();
    return pdu;
}
Also used : PDU(org.smpp.pdu.PDU) MessageIncompleteException(org.smpp.pdu.MessageIncompleteException) NotEnoughDataInByteBufferException(org.smpp.util.NotEnoughDataInByteBufferException) UnknownCommandIdException(org.smpp.pdu.UnknownCommandIdException) PDUException(org.smpp.pdu.PDUException) HeaderIncompleteException(org.smpp.pdu.HeaderIncompleteException) ByteBuffer(org.smpp.util.ByteBuffer)

Aggregations

PDU (org.smpp.pdu.PDU)6 UnknownCommandIdException (org.smpp.pdu.UnknownCommandIdException)3 PDUException (org.smpp.pdu.PDUException)2 ByteBuffer (org.smpp.util.ByteBuffer)2 IOException (java.io.IOException)1 GenericNack (org.smpp.pdu.GenericNack)1 HeaderIncompleteException (org.smpp.pdu.HeaderIncompleteException)1 InvalidPDUException (org.smpp.pdu.InvalidPDUException)1 MessageIncompleteException (org.smpp.pdu.MessageIncompleteException)1 NotEnoughDataInByteBufferException (org.smpp.util.NotEnoughDataInByteBufferException)1