SMPP error code 61,62

3.3k Views Asked by At

I am using the jsmpp lib for sending sms. The SMSC center returns negative response like 61,62 which are Invalid scheduled delivery time and Invalid Validty Period value. After talking with SMSC support, they require to set a default timeout for the message to be delivered, after some search on jsmpp site, didn't find it. Thanks for any suggestions ?

3

There are 3 best solutions below

0
On

According to SMPP standard it should be possible to leave both of these null, but if Validity Period is required, this can be either an absolute date or a relative one.

The format should be YYMMDDhhmmsstnnp, where

YY is a two digit year (00-99)

MM is month (01-12)

DD is day (01-31)

hh is hours (00-23)

mm is minutes (00-59)

ss is seconds (00-59)

t is tenths of second (00-59)

nn is the time difference in quarter hours between local time and UTC (00-48)

p can be one of the following :- '+' local time is ahead of UTC. '-' local time is behind UTC. 'R' This is a relative time.

So to make the validity period 1 hour using a relative time use the following: "000000010000000R"

0
On

when you submit current time as scheduled delivery time this error may occur.because it takes some time to send request. so the time you mentioned might be in past .so set the scheduled delivery time to (current time + 10 seconds )

    long TEN_SECONDS=10000;//millisecs

    Calendar date = Calendar.getInstance();
    long t= date.getTimeInMillis();
    Date scheduleDeliveryTime=new Date(t + (   TEN_SECONDS));
0
On

In my project I didn't have business requirement to schedule delivery time and set validity Period, so I set them null and it's work fine :-)

I use this class to load smpp config from properties file. Code that will using it will looks more readable and simple :-)

SMPPConfigManager is an interface for this class. It's possible to read this config not only from properties file. For example from Db and you can then implement this interface in new class.

package ru.rodin.denis.smpp;

import java.util.Properties;
import org.jsmpp.bean.*;

/**
*
* @author Denis Rodin
*/
public class SMPPFileConfig implements SMPPConfigManager {

private String host;
private int port;
private String systemId;
private String password;
private String systemType;
private TypeOfNumber sourceAddrTon;
private TypeOfNumber destAddrTon;
private NumberingPlanIndicator sourceAddrNpi;
private NumberingPlanIndicator destAddrNpi;
private String addressRange;
private int connectTimeout;
private long reconnectInterval;
private String sourceAddr;
private String destinationAddr;
private SMSCDeliveryReceipt deliveryReceipt;
private RegisteredDelivery registeredDelivery;
private BindType bindType;
private ESMClass esmClass;
private byte protocolId;
private byte priorityFlag;
private String scheduleDeliveryTime;
private String validityPeriod;
private byte replaceIfPresentFlag;
private GeneralDataCoding generalDataCoding;
private boolean generalDataCoding_compressed = true;
private boolean generalDataCoding_containMessageClass = true;
private MessageClass generalDataCoding_messageClass = MessageClass.CLASS1;
private Alphabet generalDataCoding_alphabet = Alphabet.ALPHA_DEFAULT;
private byte smDefaultMsgId;
private long transactionTimer;
private int enquireLinkTimer;

public SMPPFileConfig(Properties prop) {
    this.host = prop.getProperty("smpp.host");
    this.port = Integer.parseInt(prop.getProperty("smpp.port"));
    this.systemId = prop.getProperty("smpp.systemId");
    this.password = prop.getProperty("smpp.password");
    this.systemType = prop.getProperty("smpp.systemType");
    this.sourceAddrTon = getTypeOfNumber(SMPPConfigManager.AddrTon.SOURCE, prop);
    this.destAddrTon = getTypeOfNumber(SMPPConfigManager.AddrTon.DEST, prop);
    this.sourceAddrNpi = getNumberingPlanIndicator(SMPPConfigManager.AddrNpi.SOURCE, prop);
    this.destAddrNpi = getNumberingPlanIndicator(SMPPConfigManager.AddrNpi.DEST, prop);
    this.addressRange = prop.getProperty("smpp.addressRange");
    this.connectTimeout = Integer.parseInt(prop.getProperty("smpp.connect.timeout"));
    this.reconnectInterval = Long.parseLong(prop.getProperty("smpp.reconnect.interval"));
    this.sourceAddr = prop.getProperty("smpp.sourceAddr");
    this.destinationAddr = null;
    this.deliveryReceipt = getSMSCDeliveryReceipt(prop.getProperty("smpp.SMSC.delivery.receipt"));
    this.registeredDelivery = new RegisteredDelivery(deliveryReceipt);
    this.bindType = getBindTypeFromProp(prop.getProperty("smpp.bindType"));
    this.esmClass = createESMClass(prop.getProperty("smpp.ESMClass.MessageMode"), prop.getProperty("smpp.ESMClass.MessageType"), prop.getProperty("smpp.ESMClass.GSMSpecificFeature"));
    this.protocolId = new Byte(prop.getProperty("smpp.protocolId"));
    this.priorityFlag = new Byte(prop.getProperty("smpp.priorityFlag"));
    this.scheduleDeliveryTime = prop.getProperty("smpp.scheduleDeliveryTime");
    this.validityPeriod = prop.getProperty("smpp.validityPeriod");
    this.replaceIfPresentFlag = new Byte(prop.getProperty("smpp.replaceIfPresentFlag"));
    this.generalDataCoding = new GeneralDataCoding(generalDataCoding_compressed, generalDataCoding_containMessageClass, generalDataCoding_messageClass, generalDataCoding_alphabet);
    this.smDefaultMsgId = new Byte(prop.getProperty("smpp.smDefaultMsgId"));
    this.transactionTimer = Long.parseLong(prop.getProperty("smpp.transactionTimer"));
    this.enquireLinkTimer = Integer.parseInt(prop.getProperty("smpp.enquireLinkTimer"));
}

@Override
public String toString() {
    return "SMPPFileConfig{" + "host=" + host + ", port=" + port + ", systemId=" + systemId + ", password=" + password + ", systemType=" + systemType + ", sourceAddrTon=" + sourceAddrTon + ", destAddrTon=" + destAddrTon + ", sourceAddrNpi=" + sourceAddrNpi + ", destAddrNpi=" + destAddrNpi + ", addressRange=" + addressRange + ", connectTimeout=" + connectTimeout + ", reconnectInterval=" + reconnectInterval + ", sourceAddr=" + sourceAddr + ", destinationAddr=" + destinationAddr + ", deliveryReceipt=" + deliveryReceipt + ", registeredDelivery=" + registeredDelivery + ", bindType=" + bindType + ", esmClass=" + esmClass + ", protocolId=" + protocolId + ", priorityFlag=" + priorityFlag + ", scheduleDeliveryTime=" + scheduleDeliveryTime + ", validityPeriod=" + validityPeriod + ", replaceIfPresentFlag=" + replaceIfPresentFlag + ", generalDataCoding=" + generalDataCoding + ", generalDataCoding_compressed=" + generalDataCoding_compressed + ", generalDataCoding_containMessageClass=" + generalDataCoding_containMessageClass + ", generalDataCoding_messageClass=" + generalDataCoding_messageClass + ", generalDataCoding_alphabet=" + generalDataCoding_alphabet + ", smDefaultMsgId=" + smDefaultMsgId + '}';
}

@Override
public String getAddressRange() {
    return addressRange;
}

@Override
public int getConnectTimeout() {
    return connectTimeout;
}

@Override
public SMSCDeliveryReceipt getDeliveryReceipt() {
    return deliveryReceipt;
}

@Override
public RegisteredDelivery getRegisteredDelivery() {
    return registeredDelivery;
}

@Override
public NumberingPlanIndicator getDestAddrNpi() {
    return destAddrNpi;
}

@Override
public TypeOfNumber getDestAddrTon() {
    return destAddrTon;
}

@Override
public void setDestinationAddr(String destinationAddr) {
    this.destinationAddr = destinationAddr;
}

@Override
public String getDestinationAddr() {
    return destinationAddr;
}

@Override
public String getHost() {
    return host;
}

@Override
public String getPassword() {
    return password;
}

@Override
public int getPort() {
    return port;
}

@Override
public long getReconnectInterval() {
    return reconnectInterval;
}

@Override
public String getSourceAddr() {
    return sourceAddr;
}

@Override
public NumberingPlanIndicator getSourceAddrNpi() {
    return sourceAddrNpi;
}

@Override
public TypeOfNumber getSourceAddrTon() {
    return sourceAddrTon;
}

@Override
public String getSystemId() {
    return systemId;
}

@Override
public String getSystemType() {
    return systemType;
}

@Override
public BindType getBindType() {
    return bindType;
}

@Override
public ESMClass getESMClass() {
    return esmClass;
}

@Override
public void setESMClass(ESMClass esmClass) {
    this.esmClass = esmClass;
}

@Override
public byte getProtocolId() {
    return protocolId;
}

@Override
public byte getPriorityFlag() {
    return priorityFlag;
}

@Override
public String getScheduleDeliveryTime() {
    return scheduleDeliveryTime;
}

@Override
public String getValidityPeriod() {
    return validityPeriod;
}

@Override
public byte getReplaceIfPresentFlag() {
    return replaceIfPresentFlag;
}

@Override
public GeneralDataCoding getGeneralDataCoding() {
    return generalDataCoding;
}

@Override
public byte getsmDefaultMsgId(){
    return smDefaultMsgId;
}

@Override
public long getTransactionTimer()
{
    return transactionTimer;
}

@Override
public int getEnquireLinkTimer()
{
    return enquireLinkTimer;
}

private ESMClass createESMClass(String messageMode, String messageType, String GSMSpecificFeature) {
    return new ESMClass(getESMClassMessageMode(messageMode), getESMMessageType(messageType), getESMGSMSpecificFeature(GSMSpecificFeature));
}

private MessageMode getESMClassMessageMode(String type) {
    if (type.equals("DEFAULT")) {
        return MessageMode.DEFAULT;
    } else if (type.equals("DATAGRAM")) {
        return MessageMode.DATAGRAM;
    } else if (type.equals("STORE_AND_FORWARD")) {
        return MessageMode.STORE_AND_FORWARD;
    } else if (type.equals("TRANSACTION")) {
        return MessageMode.TRANSACTION;
    } else {
        return null;
    }
}

private MessageType getESMMessageType(String type) {
    if (type.equals("DEFAULT")) {
        return MessageType.DEFAULT;
    } else if (type.equals("CONV_ABORT")) {
        return MessageType.CONV_ABORT;
    } else if (type.equals("ESME_DEL_ACK")) {
        return MessageType.ESME_DEL_ACK;
    } else if (type.equals("ESME_MAN_ACK")) {
        return MessageType.ESME_MAN_ACK;
    } else if (type.equals("INTER_DEL_NOTIF")) {
        return MessageType.INTER_DEL_NOTIF;
    } else if (type.equals("SME_DEL_ACK")) {
        return MessageType.SME_DEL_ACK;
    } else if (type.equals("SME_MAN_ACK")) {
        return MessageType.SME_MAN_ACK;
    } else if (type.equals("SMSC_DEL_RECEIPT")) {
        return MessageType.SMSC_DEL_RECEIPT;
    } else {
        return null;
    }

}

private GSMSpecificFeature getESMGSMSpecificFeature(String type) {
    if (type.equals("DEFAULT")) {
        return GSMSpecificFeature.DEFAULT;
    } else if (type.equals("REPLYPATH")) {
        return GSMSpecificFeature.REPLYPATH;
    } else if (type.equals("UDHI")) {
        return GSMSpecificFeature.UDHI;
    } else if (type.equals("UDHI_REPLYPATH")) {
        return GSMSpecificFeature.UDHI_REPLYPATH;
    } else {
        return null;
    }
}

private BindType getBindTypeFromProp(String type) {
    //String type = prop.getProperty("smpp.bindType");
    if (type.equals("BIND_RX")) {
        return BindType.BIND_RX;
    } else if (type.equals("BIND_TX")) {
        return BindType.BIND_TX;
    } else if (type.equals("BIND_TRX")) {
        return BindType.BIND_TRX;
    } else {
        return null;
    }
}

private TypeOfNumber getTypeOfNumber(SMPPConfigManager.AddrTon ton, Properties prop) {
    String type;
    if (ton == SMPPConfigManager.AddrTon.SOURCE) {
        type = prop.getProperty("smpp.sourceAddrTon");
    } else {
        type = prop.getProperty("smpp.destAddrTon");
    }

    if (type.equals("ABBREVIATED")) {
        return TypeOfNumber.ABBREVIATED;
    } else if (type.equals("ALPHANUMERIC")) {
        return TypeOfNumber.ALPHANUMERIC;
    } else if (type.equals("INTERNATIONAL")) {
        return TypeOfNumber.INTERNATIONAL;
    } else if (type.equals("NATIONAL")) {
        return TypeOfNumber.NATIONAL;
    } else if (type.equals("NETWORK_SPECIFIC")) {
        return TypeOfNumber.NETWORK_SPECIFIC;
    } else if (type.equals("SUBSCRIBER_NUMBER")) {
        return TypeOfNumber.SUBSCRIBER_NUMBER;
    } else if (type.equals("UNKNOWN")) {
        return TypeOfNumber.UNKNOWN;
    } else {
        return null;
    }
}

private SMSCDeliveryReceipt getSMSCDeliveryReceipt(String type) {
    //String type = prop.getProperty("smpp.SMSC.delivery.receipt");

    if (type.equals("DEFAULT")) {
        return SMSCDeliveryReceipt.DEFAULT;
    } else if (type.equals("SUCCESS")) {
        return SMSCDeliveryReceipt.SUCCESS;
    } else if (type.equals("SUCCESS_FAILURE")) {
        return SMSCDeliveryReceipt.SUCCESS_FAILURE;
    } else {
        return null;
    }
}

private NumberingPlanIndicator getNumberingPlanIndicator(SMPPConfigManager.AddrNpi npi, Properties prop) {

    String type;
    if (npi == SMPPConfigManager.AddrNpi.SOURCE) {
        type = prop.getProperty("smpp.sourceAddrNpi");
    } else {
        type = prop.getProperty("smpp.destAddrNpi");
    }

    if (type.equals("DATA")) {
        return NumberingPlanIndicator.DATA;
    } else if (type.equals("ERMES")) {
        return NumberingPlanIndicator.ERMES;
    } else if (type.equals("INTERNET")) {
        return NumberingPlanIndicator.INTERNET;
    } else if (type.equals("ISDN")) {
        return NumberingPlanIndicator.ISDN;
    } else if (type.equals("LAND_MOBILE")) {
        return NumberingPlanIndicator.LAND_MOBILE;
    } else if (type.equals("NATIONAL")) {
        return NumberingPlanIndicator.NATIONAL;
    } else if (type.equals("PRIVATE")) {
        return NumberingPlanIndicator.PRIVATE;
    } else if (type.equals("TELEX")) {
        return NumberingPlanIndicator.TELEX;
    } else if (type.equals("WAP")) {
        return NumberingPlanIndicator.WAP;
    } else if (type.equals("UNKNOWN")) {
        return NumberingPlanIndicator.UNKNOWN;
    } else {
        return null;
    }
}
}