{ "sms_id": "test_sms_123", "sender": " ", "phone": "380959999900", "text_body": "! 1000000$!", "flash": 0 }
<dependency> <groupId>com.googlecode.jsmpp</groupId> <artifactId>jsmpp</artifactId> <version>2.1.0-RELEASE</version> </dependency>
protected SMPPSession session; protected SmppServer server; private ExecutorService receiveTask; private SessionStateListener stateListener; ... // some of your code public void createSmppSession() { StopWatchHires watchHires = new StopWatchHires(); watchHires.start(); log.info("Start to create SMPPSession {}", sessionName); try { session = new SMPPSession(); session.connectAndBind(server.getHostname(), server.getPort(), new BindParameter( BindType.BIND_TRX, server.getSystemId(), server.getPassword(), server.getSystemType(), TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null)); stateListener = new SessionStateListenerImpl(); session.addSessionStateListener(stateListener); session.setMessageReceiverListener(new SmsReceiverListenerImpl()); session.setTransactionTimer(TRANSACTION_TIMER); if (Objects.isNull(receiveTask) || receiveTask.isShutdown() || receiveTask.isTerminated()) { this.receiveTask = Executors.newCachedThreadPool(); } watchHires.stop(); log.info("Open smpp session id {}, state {}, duration {} for {}", session.getSessionId(), session.getSessionState().name(), watchHires.toHiresString(), sessionName); } catch (IOException e) { watchHires.stop(); if (SmppServerConnectResponse.contains(e.getMessage())) { log.error("Exception while SMPP session creating. Reason: {}. Duration {}, {}", e.getMessage(), watchHires.toHiresString(), sessionName); close(); return; } else if (e instanceof UnknownHostException) { log.error("Exception while SMPP session creating. Unknown hostname {}, duration {}, {}", e.getMessage(), watchHires.toHiresString(), sessionName); close(); return; } else { log.error("Failed to connect SMPP session for {}, duration {}, Because {}", sessionName, watchHires.toHiresString(), e.getMessage()); } } if (!isConnected()) { reconnect(); } }
/** * This class will receive the notification from {@link SMPPSession} for the * state changes. It will schedule to re-initialize session. */ class SessionStateListenerImpl implements SessionStateListener { @Override public void onStateChange(SessionState newState, SessionState oldState, Object source) { if (!newState.isBound()) { log.warn("SmppSession changed status from {} to {}. {}", oldState, newState, sessionName); reconnect(); } } }
/*The logic on this listener should be accomplish in a short time, because the deliver_sm_resp will be processed after the logic executed.*/ class SmsReceiverListenerImpl implements MessageReceiverListener { @Override public void onAcceptDeliverSm(DeliverSm deliverSm) throws ProcessRequestException { if (Objects.isNull(deliverSm)) { log.error("Smpp server return NULL delivery answer"); return; } try { // this message is delivery receipt DeliveryReceipt delReceipt = deliverSm.getShortMessageAsDeliveryReceipt(); //delReceipt.getId() must be equals transactionId from SMPPServer String transactionId = delReceipt.getId(); StatusType statusType; String subStatus; if (MessageType.SMSC_DEL_RECEIPT.containedIn(deliverSm.getEsmClass())) { // && delReceipt.getDelivered() == 1 statusType = getDeliveryStatusType(delReceipt.getFinalStatus()); SmppErrorStatus smppErrorStatus = SmppErrorStatus.contains(delReceipt.getError()); if (smppErrorStatus != null) subStatus = smppErrorStatus.name(); else subStatus = delReceipt.getError(); } else { statusType = StatusType.SMS_UNDELIVERED; // this message is regular short message log.error("Delivery SMS event has wrong receipt. Message: {}", deliverSm.getShortMessage()); subStatus = SmppErrorStatus.INVALID_FORMAT.name(); } // some providers return phone number in deliverSm.getSourceAddr() String phoneNumber = deliverSm.getDestAddress(); saveDeliveryStatus(transactionId, statusType, subStatus, phoneNumber)); log.info("Receiving delivery receipt from {} to {}, transaction id {}, status {}, subStatus {}", deliverSm.getSourceAddr(), deliverSm.getDestAddress(), transactionId, statusType, subStatus); } catch (InvalidDeliveryReceiptException e) { log.error("Exception while SMS is sending, destination address {}, {}", deliverSm.getDestAddress(), e.getMessage(), e); } } @Override public void onAcceptAlertNotification(AlertNotification alertNotification) { log.error("Error on sending SMS message: {}", alertNotification.toString()); } @Override public DataSmResult onAcceptDataSm(DataSm dataSm, Session source) throws ProcessRequestException { log.debug("Event in SmsReceiverListenerImpl.onAcceptDataSm!"); return null; } private StatusType getDeliveryStatusType(DeliveryReceiptState state) {<cut /> if (state.equals(DeliveryReceiptState.DELIVRD)) return StatusType.SMS_DELIVERED; else if (state.equals(DeliveryReceiptState.ACCEPTD)) return StatusType.ACCEPTED; else if (state.equals(DeliveryReceiptState.DELETED)) return StatusType.DELETED; else if (state.equals(DeliveryReceiptState.EXPIRED)) return StatusType.EXPIRED; else if (state.equals(DeliveryReceiptState.REJECTD)) return StatusType.REJECTED; else if (state.equals(DeliveryReceiptState.UNKNOWN)) return StatusType.UNKNOWN; else return StatusType.SMS_UNDELIVERED; } }
public SingleSmppTransactionMessage sendSmsMessage(final SMSMessage message) { final String bodyText = message.getTextBody(); final int smsLength = bodyText.length(); OptionalParameter messagePayloadParameter; String transportId = null; String error = null; boolean isUSC2 = false; boolean isFlashSms = message.isFlash(); StopWatchHires watchHires = new StopWatchHires(); watchHires.start(); log.debug("Start to send sms id {} length {}", message.getSmsId(), smsLength); try { byte[] encoded; if ((encoded = Gsm0338.encodeInGsm0338(bodyText)) != null) { messagePayloadParameter = new OptionalParameter.OctetString( OptionalParameter.Tag.MESSAGE_PAYLOAD.code(), encoded); log.debug("Found Latin symbols in sms id {} message", message.getSmsId()); } else { isUSC2 = true; messagePayloadParameter = new OptionalParameter.OctetString( OptionalParameter.Tag.MESSAGE_PAYLOAD.code(), bodyText, "UTF-16BE"); log.debug("Found Cyrillic symbols in sms id {} message", message.getSmsId()); } GeneralDataCoding dataCoding = getDataCodingForServer(isUSC2, isFlashSms); log.debug("Selected data_coding: {}, value: {}, SMPP server type: {}", dataCoding.getAlphabet(), dataCoding.toByte(), server.getServerType()); transportId = session.submitShortMessage( "CMT", TypeOfNumber.ALPHANUMERIC, NumberingPlanIndicator.UNKNOWN, message.getSender(), TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.ISDN, message.getPhone(), ESM_CLASS, ZERO_BYTE, ONE_BYTE, null, null, rd, ZERO_BYTE, dataCoding, ZERO_BYTE, EMPTY_ARRAY, messagePayloadParameter); } catch (PDUException e) { error = e.getMessage(); // Invalid PDU parameter log.error("SMS id:{}. Invalid PDU parameter {}", message.getSmsId(), error); log.debug("Session id {}, state {}. {}", session.getSessionId(), session.getSessionState().name(), e); } catch (ResponseTimeoutException e) { error = analyseExceptionMessage(e.getMessage()); // Response timeout log.error("SMS id:{}. Response timeout: {}", message.getSmsId(), e.getMessage()); log.debug("Session id {}, state {}. {}", session.getSessionId(), session.getSessionState().name(), e); } catch (InvalidResponseException e) { error = e.getMessage(); // Invalid response log.error("SMS id:{}. Receive invalid response: {}", message.getSmsId(), error); log.debug("Session id {}, state {}. {}", session.getSessionId(), session.getSessionState().name(), e); } catch (NegativeResponseException e) { // get smpp error codes error = String.valueOf(e.getCommandStatus()); // Receiving negative response (non-zero command_status) log.error("SMS id:{}, {}. Receive negative response: {}", message.getSmsId(), message.getPhone(), e.getMessage()); log.debug("Session id {}, state {}. {}", session.getSessionId(), session.getSessionState().name(), e); } catch (IOException e) { error = analyseExceptionMessage(e.getMessage()); log.error("SMS id:{}. IO error occur {}", message.getSmsId(), e.getMessage()); log.debug("Session id {}, state {}. {}", session.getSessionId(), session.getSessionState().name(), e); } catch (Exception e) { error = e.getMessage(); log.error("SMS id:{}. Unexpected exception error occur {}", message.getSmsId(), error); log.debug("Session id {}, state {}. {}", session.getSessionId(), session.getSessionState().name(), e); } watchHires.stop(); log.info("Sms id:{} length {} sent with transaction id:{} from {} to {}, duration {}", message.getSmsId(), smsLength, transportId, message.getSender(), message.getPhone(), watchHires.toHiresString()); return new SingleSmppTransactionMessage(message, server.getId(), error, transportId); } private GeneralDataCoding getDataCodingForServer (boolean isUCS2Coding, boolean isFlashSms){ GeneralDataCoding coding; if (isFlashSms) { coding = isUCS2Coding ? UCS2_CODING : DEFAULT_CODING; } else { coding = isUCS2Coding ? UCS2_CODING_WITHOUT_CLASS : DEFAULT_CODING_WITHOUT_CLASS; } return coding; } /** * Analyze exception message for our problem with session * While schedule reconnecting session sms didn't send and didn't put to resend */ private String analyseExceptionMessage(String exMessage){ if(Objects.isNull(exMessage)) return exMessage; if (exMessage.contains("No response after waiting for")) return SmppResponseError.RECONNECT_RSPCTIMEOUT.getErrCode(); else if (exMessage.contains("Cannot submitShortMessage while")) return SmppResponseError.RECONNECT_CANNTSUBMIT.getErrCode(); else if (exMessage.contains("Failed sending submit_sm command")) return SmppResponseError.RECONNECT_FAILEDSUBMIT.getErrCode(); return exMessage; }
Source: https://habr.com/ru/post/310828/
All Articles