All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mobius.software.protocols.smpp.PduTranscoder Maven / Gradle / Ivy

package com.mobius.software.protocols.smpp;
import com.cloudhopper.commons.util.HexUtil;
import com.mobius.software.protocols.smpp.exceptions.NotEnoughDataInBufferException;
import com.mobius.software.protocols.smpp.exceptions.RecoverablePduException;
import com.mobius.software.protocols.smpp.exceptions.UnknownCommandIdException;
import com.mobius.software.protocols.smpp.exceptions.UnrecoverablePduException;

/*
 * Mobius Software LTD
 * Copyright 2019 - 2023, Mobius Software LTD and individual contributors
 * by the @authors tag.
 *
 * This program is free software: you can redistribute it and/or modify
 * under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see 
 */
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class PduTranscoder 
{
	public PduTranscoder() 
    {
    }

    public ByteBuf encode(Pdu pdu) throws UnrecoverablePduException, RecoverablePduException 
    {
        if (!pdu.hasCommandLengthCalculated()) 
            pdu.calculateAndSetCommandLength();
        
        ByteBuf buffer = Unpooled.buffer(pdu.getCommandLength());

        buffer.writeInt(pdu.getCommandLength());
        buffer.writeInt(pdu.getCommandId().getValue());
        
        if(pdu.getCommandStatus()!=null)
        	buffer.writeInt(pdu.getCommandStatus().getValue());
        else
        	buffer.writeInt(0);
        
        buffer.writeInt(pdu.getSequenceNumber());

        pdu.writeBody(buffer);

        pdu.writeOptionalParameters(buffer);

        if (buffer.readableBytes() != pdu.getCommandLength()) 
            throw new NotEnoughDataInBufferException("During PDU encoding the expected commandLength did not match the actual encoded (a serious error with our own encoding process)", pdu.getCommandLength(), buffer.readableBytes());
        
        return buffer;
    }
    
    public Pdu decode(ByteBuf buffer) throws UnrecoverablePduException, RecoverablePduException 
    {
        if (buffer.readableBytes() < Pdu.PDU_INT_LENGTH) 
            return null;

        int commandLength = buffer.getInt(buffer.readerIndex());

        if (commandLength < Pdu.PDU_HEADER_LENGTH) 
            throw new UnrecoverablePduException("Invalid PDU length [0x" + HexUtil.toHexString(commandLength) + "] parsed");
        
        if (buffer.readableBytes() < commandLength) 
            return null;
        
        ByteBuf buffer0 = buffer.readSlice(commandLength);
        return doDecode(commandLength, buffer0);
    }

    protected Pdu doDecode(int commandLength, ByteBuf buffer) throws UnrecoverablePduException, RecoverablePduException 
    {
        buffer.skipBytes(Pdu.PDU_INT_LENGTH);

        CommandType commandId = CommandType.fromInt(buffer.readInt());
        int commandStatus = buffer.readInt();
        int sequenceNumber = buffer.readInt();

        Pdu pdu = null;
        
        switch(commandId)
    	{
			case CMD_ID_ALERT_NOTIFICATION:
				pdu = new AlertNotification();
				break;
			case CMD_ID_BIND_RECEIVER:
				pdu = new BindReceiver();
				break;
			case CMD_ID_BIND_RECEIVER_RESP:
				pdu = new BindReceiverResp();
				break;
			case CMD_ID_BIND_TRANSCEIVER:
				pdu = new BindTransceiver();
				break;
			case CMD_ID_BIND_TRANSCEIVER_RESP:
				pdu = new BindTransceiverResp();
				break;
			case CMD_ID_BIND_TRANSMITTER:
				pdu = new BindTransmitter();
				break;
			case CMD_ID_BIND_TRANSMITTER_RESP:
				pdu = new BindTransmitterResp();
				break;
			case CMD_ID_BROADCAST_SM:				
				pdu = new PartialPdu(commandId);
				break;
			case CMD_ID_BROADCAST_SM_RESP:
				pdu = new PartialPduResp(commandId);
				break;
			case CMD_ID_CANCEL_BROADCAST_SM:
				pdu = new PartialPdu(commandId);
				break;
			case CMD_ID_CANCEL_BROADCAST_SM_RESP:
				pdu = new PartialPduResp(commandId);
				break;
			case CMD_ID_CANCEL_SM:
				pdu = new CancelSm();
				break;
			case CMD_ID_CANCEL_SM_RESP:
				pdu = new CancelSmResp();
				break;
			case CMD_ID_DATA_SM:
				pdu = new DataSm();
				break;
			case CMD_ID_DATA_SM_RESP:
				pdu = new DataSmResp();
				break;
			case CMD_ID_DELIVER_SM:
				pdu = new DeliverSm();
				break;
			case CMD_ID_DELIVER_SM_RESP:
				pdu = new DeliverSmResp();
				break;
			case CMD_ID_ENQUIRE_LINK:
				pdu = new EnquireLink();
				break;
			case CMD_ID_ENQUIRE_LINK_RESP:
				pdu = new EnquireLinkResp();
				break;
			case CMD_ID_GENERIC_NACK:
				pdu = new GenericNack();
				break;
			case CMD_ID_OUTBIND:
				pdu = new PartialPdu(commandId);
				break;
			case CMD_ID_QUERY_BROADCAST_SM:
				pdu = new PartialPdu(commandId);
				break;
			case CMD_ID_QUERY_BROADCAST_SM_RESP:
				pdu = new PartialPduResp(commandId);
				break;
			case CMD_ID_QUERY_SM:
				pdu = new QuerySm();
				break;
			case CMD_ID_QUERY_SM_RESP:
				pdu = new QuerySmResp();
				break;
			case CMD_ID_REPLACE_SM:
				pdu = new ReplaceSm();
				break;
			case CMD_ID_REPLACE_SM_RESP:
				pdu = new ReplaceSmResp();
				break;
			case CMD_ID_SUBMIT_MULTI:
				pdu = new SubmitMulti();
				break;
			case CMD_ID_SUBMIT_MULTI_RESP:
				pdu = new SubmitMultiResp();
				break;
			case CMD_ID_SUBMIT_SM:
				pdu = new SubmitSm();
				break;
			case CMD_ID_SUBMIT_SM_RESP:
				pdu = new SubmitSmResp();
				break;
			case CMD_ID_UNBIND:
				pdu = new Unbind();
				break;
			case CMD_ID_UNBIND_RESP:
				pdu = new UnbindResp();
				break;
			case CMD_ID_UNKNOWN:					
			default:
				pdu = new PartialPdu(commandId);
				break;        		
    	}

        // set pdu header values
        pdu.setCommandLength(commandLength);
        pdu.setCommandStatus(MessageStatus.fromInt(commandStatus));
        pdu.setSequenceNumber(sequenceNumber);

        // check if we need to throw an exception
        if (pdu instanceof PartialPdu) 
            throw new UnknownCommandIdException(pdu, "Unsupported or unknown PDU request commandId [0x" + HexUtil.toHexString(commandId.getValue()) + "]");
        else if (pdu instanceof PartialPduResp) 
            throw new UnknownCommandIdException(pdu, "Unsupported or unknown PDU response commandId [0x" + HexUtil.toHexString(commandId.getValue()) + "]");
        
        try 
        {
            // parse pdu body parameters (may throw exception)
            pdu.readBody(buffer);
            // parse pdu optional parameters (may throw exception)
            pdu.readOptionalParameters(buffer);
        } 
        catch (RecoverablePduException e) 
        {
            if (e.getPartialPdu() == null) 
                e.setPartialPdu(pdu);
            
            throw e;
        }

        return pdu;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy