Skip to content

Commit 6efef1f

Browse files
authored
Merge pull request #2863 from RestComm/RESTCOMM-1856
RESTCOM-1856: Allow specific inbound and outbound SMPP encoding
2 parents c15b9c6 + d1b3d90 commit 6efef1f

13 files changed

Lines changed: 159 additions & 50 deletions

File tree

restcomm/configuration/config-scripts/as7-config-scripts/restcomm/autoconfig.d/config-restcomm.sh

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,8 @@ configSMPPAccount() {
492492
peerPort="$6"
493493
sourceMap="$7"
494494
destinationMap="$8"
495+
inboundEncoding="$9"
496+
outboundEncoding="${10}"
495497

496498

497499
sed -i "s|<smpp class=\"org.restcomm.connect.sms.smpp.SmppService\" activateSmppConnection =\".*\">|<smpp class=\"org.restcomm.connect.sms.smpp.SmppService\" activateSmppConnection =\"$activate\">|g" $FILE
@@ -528,6 +530,13 @@ configSMPPAccount() {
528530
}" $FILE
529531

530532
sed -i "s|<connection activateAddressMapping=\"false\" sourceAddressMap=\"\" destinationAddressMap=\"\" tonNpiValue=\"1\">|<connection activateAddressMapping=\"false\" sourceAddressMap=\"${sourceMap}\" destinationAddressMap=\"${destinationMap}\" tonNpiValue=\"1\">|" $FILE
533+
534+
if [ ! -z "${inboundEncoding}" ]; then
535+
xmlstarlet ed -L -P -u "/restcomm/smpp/connections/connection/inboundencoding" -v $inboundEncoding $FILE
536+
fi
537+
if [ ! -z "${outboundEncoding}" ]; then
538+
xmlstarlet ed -L -P -u "/restcomm/smpp/connections/connection/outboundencoding" -v $outboundEncoding $FILE
539+
fi
531540
echo 'Configured SMPP Account Details'
532541

533542
else
@@ -560,6 +569,10 @@ configSMPPAccount() {
560569
}" $FILE
561570

562571
sed -i "s|<connection activateAddressMapping=\"false\" sourceAddressMap=\"\" destinationAddressMap=\"\" tonNpiValue=\"1\">|<connection activateAddressMapping=\"false\" sourceAddressMap=\"\" destinationAddressMap=\"\" tonNpiValue=\"1\">|" $FILE
572+
573+
xmlstarlet ed -L -P -u "/restcomm/smpp/connections/connection/inboundencoding" -v "" $FILE
574+
xmlstarlet ed -L -P -u "/restcomm/smpp/connections/connection/outboundencoding" -v "" $FILE
575+
563576
echo 'Configured SMPP Account Details'
564577
fi
565578
}
@@ -880,7 +893,7 @@ configSpeechRecognizer "$ISPEECH_KEY"
880893
configSpeechSynthesizers
881894
configTelestaxProxy "$ACTIVE_PROXY" "$TP_LOGIN" "$TP_PASSWORD" "$INSTANCE_ID" "$PROXY_IP" "$SITE_ID"
882895
configMediaServerManager "$BIND_ADDRESS" "$MS_ADDRESS" "$MEDIASERVER_EXTERNAL_ADDRESS"
883-
configSMPPAccount "$SMPP_ACTIVATE" "$SMPP_SYSTEM_ID" "$SMPP_PASSWORD" "$SMPP_SYSTEM_TYPE" "$SMPP_PEER_IP" "$SMPP_PEER_PORT" "$SMPP_SOURCE_MAP" "$SMPP_DEST_MAP"
896+
configSMPPAccount "$SMPP_ACTIVATE" "$SMPP_SYSTEM_ID" "$SMPP_PASSWORD" "$SMPP_SYSTEM_TYPE" "$SMPP_PEER_IP" "$SMPP_PEER_PORT" "$SMPP_SOURCE_MAP" "$SMPP_DEST_MAP" "$SMPP_INBOUND_ENCODING" "$SMPP_OUTBOUND_ENCODING"
884897
configRestCommURIs
885898
updateRecordingsPath
886899
configHypertextPort

restcomm/configuration/config-scripts/as7-config-scripts/restcomm/restcomm.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ SMPP_PEER_IP='' #use IP or DNS name of peer SMPP server
5555
SMPP_PEER_PORT=''
5656
SMPP_SOURCE_MAP=''
5757
SMPP_DEST_MAP=''
58+
SMPP_INBOUND_ENCODING=''
59+
SMPP_OUTBOUND_ENCODING=''
5860

5961
# DID Provision provider variable declarations
6062
PROVISION_PROVIDER='' # values: VI (VoipInnovation), BW (Bandwidth), NX (Nexmo), VB (Voxbone)

restcomm/restcomm.application/src/main/webapp/WEB-INF/conf/restcomm.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,10 @@
672672
If no response received for 3 consecutive requests, connection will be killed
673673
and attempted to connect again -->
674674
<enquirelinkdelay>30000</enquirelinkdelay>
675+
<!-- when no values are set, default value from code is MODIFIED-UTF8 inbound, GSM7 for outbound-->
676+
<inboundencoding/>
677+
<outboundencoding/>
678+
675679
</connection>
676680
</connections>
677681
</smpp>

restcomm/restcomm.docs/sources-asciidoc/src/main/asciidoc/configuration/Restcomm- Automatic Configuration Options.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ SMPP_PEER_IP='' #use IP or DNS name of peer SMPP server
7575
SMPP_PEER_PORT=''
7676
SMPP_SOURCE_MAP=''
7777
SMPP_DEST_MAP=''
78+
SMPP_INBOUND_ENCODING=''
79+
SMPP_OUTBOUND_ENCODING=''
7880
----
7981

8082
* Section *#Restcomm DID provider integration*.

restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/client/Downloader.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import akka.actor.ActorRef;
2323
import akka.event.Logging;
2424
import akka.event.LoggingAdapter;
25+
26+
import org.apache.commons.io.IOUtils;
2527
import org.apache.http.Header;
2628
import org.apache.http.HttpEntity;
2729
import org.apache.http.HttpHeaders;
@@ -39,7 +41,6 @@
3941
import org.restcomm.connect.commons.common.http.CustomHttpClientBuilder;
4042
import org.restcomm.connect.commons.configuration.RestcommConfiguration;
4143
import org.restcomm.connect.commons.faulttolerance.RestcommUntypedActor;
42-
import org.restcomm.connect.commons.util.StringUtils;
4344
import org.xml.sax.InputSource;
4445

4546
import javax.xml.parsers.DocumentBuilder;
@@ -86,6 +87,7 @@ public HttpResponseDescriptor fetch (final HttpRequestDescriptor descriptor) thr
8687
try {
8788
do {
8889
request = request(temp);
90+
//FIXME:should we externalize RVD encoding default?
8991
request.setHeader("http.protocol.content-charset", "UTF-8");
9092
if (descriptor.getTimeout() > 0){
9193
HttpContext httpContext = new BasicHttpContext();
@@ -161,6 +163,7 @@ private HttpResponseDescriptor validateXML (final HttpResponseDescriptor descrip
161163
// parse an XML document into a DOM tree
162164
String xml = descriptor.getContentAsString().trim().replaceAll("&([^;]+(?!(?:\\w|;)))", "&amp;$1");
163165
DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
166+
//FIXME:should we externalize RVD encoding default?
164167
parser.parse(new InputSource(new ByteArrayInputStream(xml.getBytes("utf-8"))));
165168
return descriptor;
166169
} catch (final Exception e) {
@@ -218,6 +221,7 @@ public HttpUriRequest request (final HttpRequestDescriptor descriptor) throws Il
218221
} else if ("POST".equalsIgnoreCase(method)) {
219222
final List<NameValuePair> parameters = descriptor.getParameters();
220223
final HttpPost post = new HttpPost(uri);
224+
//FIXME:should we externalize RVD encoding default?
221225
post.setEntity(new UrlEncodedFormEntity(parameters, "UTF-8"));
222226
return post;
223227
} else {
@@ -237,14 +241,17 @@ private HttpResponseDescriptor response (final HttpRequest request, final HttpRe
237241
InputStream stream = entity.getContent();
238242
try {
239243
final Header contentEncoding = entity.getContentEncoding();
240-
if (contentEncoding != null) {
241-
builder.setContentEncoding(contentEncoding.getValue());
244+
//FIXME:should we externalize RVD encoding default?
245+
String encodingValue = "UTF-8";
246+
if (contentEncoding != null && !contentEncoding.getValue().isEmpty()) {
247+
encodingValue = contentEncoding.getValue();
248+
builder.setContentEncoding(encodingValue);
242249
}
243250
final Header contentType = entity.getContentType();
244251
if (contentType != null) {
245252
builder.setContentType(contentType.getValue());
246253
}
247-
builder.setContent(StringUtils.toString(stream));
254+
builder.setContent(IOUtils.toString(stream, encodingValue));
248255
builder.setContentLength(entity.getContentLength());
249256
builder.setIsChunked(entity.isChunked());
250257
} finally {

restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/client/HttpRequestDescriptor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public HttpRequestDescriptor(final URI uri, final String method,
5656
}
5757
final String query = uri.getQuery();
5858
if (query != null) {
59+
//FIXME:should we externalize RVD encoding default?
5960
final List<NameValuePair> other = URLEncodedUtils.parse(uri, "UTF-8");
6061
parameters.addAll(other);
6162
}
@@ -104,6 +105,7 @@ public List<NameValuePair> getParameters() {
104105
}
105106

106107
public String getParametersAsString() {
108+
//FIXME:should we externalize RVD encoding default?
107109
return URLEncodedUtils.format(parameters, "UTF-8");
108110
}
109111

restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/smpp/Smpp.java

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package org.restcomm.connect.sms.smpp;
22

3+
import org.apache.log4j.Logger;
4+
5+
import com.cloudhopper.commons.charset.Charset;
6+
import com.cloudhopper.commons.charset.CharsetUtil;
37
import com.cloudhopper.smpp.SmppBindType;
48
import com.cloudhopper.smpp.impl.DefaultSmppSession;
59
import com.cloudhopper.smpp.type.Address;
@@ -11,6 +15,10 @@
1115
*/
1216
public class Smpp {
1317

18+
private static final Logger logger = Logger.getLogger(Smpp.class);
19+
20+
private static final String DEFAULT_SMPP_INBOUND_ENCODING = "MODIFIED-UTF8";
21+
private static final String DEFAULT_SMPP_OUTBOUND_ENCODING = "GSM7";
1422
private String name;
1523
private String systemId;
1624
private String peerIp;
@@ -37,6 +45,9 @@ public class Smpp {
3745

3846
private long enquireLinkDelay;
3947

48+
private Charset inboundCharacterEncoding;
49+
private Charset outboundCharacterEncoding;
50+
4051
// not used as of today, but later we can allow users to stop each SMPP
4152
private boolean started = true;
4253

@@ -45,7 +56,7 @@ public class Smpp {
4556
public Smpp(String name, String systemId, String peerIp, int peerPort, SmppBindType smppBindType, String password,
4657
String systemType, byte interfaceVersion, Address address, long connectTimeout, int windowSize,
4758
long windowWaitTimeout, long requestExpiryTimeout, long windowMonitorInterval, boolean countersEnabled,
48-
boolean logBytes, long enquireLinkDelay) {
59+
boolean logBytes, long enquireLinkDelay, String inboundCharacterEncoding, String outboundCharacterEncoding) {
4960
super();
5061
this.name = name;
5162
this.systemId = systemId;
@@ -64,6 +75,22 @@ public Smpp(String name, String systemId, String peerIp, int peerPort, SmppBindT
6475
this.countersEnabled = countersEnabled;
6576
this.logBytes = logBytes;
6677
this.enquireLinkDelay = enquireLinkDelay;
78+
try {
79+
this.inboundCharacterEncoding = CharsetUtil.map(inboundCharacterEncoding);
80+
} catch (Exception e) {
81+
this.inboundCharacterEncoding = CharsetUtil.map(DEFAULT_SMPP_INBOUND_ENCODING);
82+
if(logger.isInfoEnabled()) {
83+
logger.info("Charset " + inboundCharacterEncoding + " does not exist. Inbound encoding is set to default " + DEFAULT_SMPP_INBOUND_ENCODING + "\n" + e.getMessage());
84+
}
85+
}
86+
try {
87+
this.outboundCharacterEncoding = CharsetUtil.map(outboundCharacterEncoding);
88+
} catch (Exception e) {
89+
this.outboundCharacterEncoding = CharsetUtil.map(DEFAULT_SMPP_OUTBOUND_ENCODING);
90+
if(logger.isInfoEnabled()) {
91+
logger.info("Charset " + outboundCharacterEncoding+ " does not exist. Outbound encoding is set to default " + DEFAULT_SMPP_OUTBOUND_ENCODING + "\n" + e.getMessage());
92+
}
93+
}
6794
}
6895

6996
public String getName() {
@@ -202,6 +229,13 @@ public void setEnquireLinkDelay(long enquireLinkDelay) {
202229
this.enquireLinkDelay = enquireLinkDelay;
203230
}
204231

232+
public Charset getInboundDefaultEncoding() {
233+
return inboundCharacterEncoding;
234+
}
235+
public Charset getOutboundDefaultEncoding() {
236+
return outboundCharacterEncoding;
237+
}
238+
205239
public boolean isStarted() {
206240
return started;
207241
}
@@ -228,7 +262,10 @@ public String toString() {
228262
+ ", interfaceVersion=" + interfaceVersion + ", address=" + address + ", connectTimeout=" + connectTimeout
229263
+ ", windowSize=" + windowSize + ", windowWaitTimeout=" + windowWaitTimeout + ", requestExpiryTimeout="
230264
+ requestExpiryTimeout + ", windowMonitorInterval=" + windowMonitorInterval + ", countersEnabled="
231-
+ countersEnabled + ", logBytes=" + logBytes + ", enquireLinkDelay=" + enquireLinkDelay + "]";
265+
+ countersEnabled + ", logBytes=" + logBytes + ", enquireLinkDelay=" + enquireLinkDelay
266+
+ ", inboundCharacterEncoding=" + inboundCharacterEncoding.toString()
267+
+ ", outboundCharacterEncoding=" + outboundCharacterEncoding.toString()
268+
+ "]";
232269
}
233270

234271
@Override
@@ -255,5 +292,4 @@ public boolean equals(Object obj) {
255292
return false;
256293
return true;
257294
}
258-
259295
}

restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/smpp/SmppClientOpsThread.java

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.cloudhopper.commons.charset.CharsetUtil;
2626
import com.cloudhopper.commons.charset.Charset;
2727
import com.cloudhopper.smpp.PduAsyncResponse;
28+
import com.cloudhopper.smpp.SmppConstants;
2829
import com.cloudhopper.smpp.SmppSession;
2930
import com.cloudhopper.smpp.SmppSessionConfiguration;
3031
import com.cloudhopper.smpp.SmppSessionHandler;
@@ -59,6 +60,10 @@ public class SmppClientOpsThread implements Runnable {
5960
private Object waitObject = new Object();
6061
private final DefaultSmppClient clientBootstrap;
6162
private static SmppSession getSmppSession;
63+
//FIXME: like getSmppSession, this is bad design
64+
//this assumes singular SMPP connection all the time,so it works
65+
private static Charset outboundEncoding;
66+
private static Charset inboundEncoding;
6267
protected volatile boolean started = true;
6368
private static int sipPort;
6469

@@ -294,6 +299,8 @@ protected class ClientSmppSessionHandler implements SmppSessionHandler {
294299
public ClientSmppSessionHandler(Smpp esme) {
295300
super();
296301
this.esme = esme;
302+
inboundEncoding = esme.getInboundDefaultEncoding();
303+
outboundEncoding = esme.getOutboundDefaultEncoding();
297304
}
298305

299306
@Override
@@ -352,18 +359,20 @@ public PduResponse firePduRequestReceived(PduRequest pduRequest) {
352359

353360
DeliverSm deliverSm = (DeliverSm) pduRequest;
354361
try {
355-
String decodedPduMessage = CharsetUtil.CHARSET_MODIFIED_UTF8.decode(deliverSm.getShortMessage());
362+
byte dcs = deliverSm.getDataCoding();
356363
String destSmppAddress = deliverSm.getDestAddress().getAddress();
357364
String sourceSmppAddress = deliverSm.getSourceAddress().getAddress();
358-
Charset charset;
359-
if (DataCoding.DATA_CODING_UCS2 == deliverSm.getDataCoding()) {
360-
charset = CharsetUtil.CHARSET_UCS_2;
361-
} else {
362-
charset = CharsetUtil.CHARSET_GSM;
365+
366+
//this default esme encoding only applies to DCS==0
367+
Charset encoding = esme.getInboundDefaultEncoding();
368+
if(dcs == SmppConstants.DATA_CODING_UCS2) {
369+
encoding = CharsetUtil.CHARSET_UCS_2;
363370
}
371+
372+
String decodedPduMessage = CharsetUtil.decode(deliverSm.getShortMessage(), encoding);
364373
//send received SMPP PDU message to restcomm
365374
try {
366-
sendSmppMessageToRestcomm(decodedPduMessage, destSmppAddress, sourceSmppAddress, charset);
375+
sendSmppMessageToRestcomm(decodedPduMessage, destSmppAddress, sourceSmppAddress, encoding);
367376
} catch (IOException | ServletException e) {
368377
logger.error("Exception while trying to dispatch incoming SMPP message to Restcomm: " + e);
369378
}
@@ -429,4 +438,12 @@ public void sendSmppMessageToRestcomm(String smppMessage, String smppTo, String
429438
SmppInboundMessageEntity smppInboundMessage = new SmppInboundMessageEntity(to, from, inboundMessage, charset);
430439
smppMessageHandler.tell(smppInboundMessage, null);
431440
}
441+
442+
public static Charset getInboundDefaultEncoding() {
443+
return inboundEncoding;
444+
}
445+
446+
public static Charset getOutboundDefaultEncoding() {
447+
return outboundEncoding;
448+
}
432449
}

restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/smpp/SmppMessageHandler.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import org.restcomm.smpp.parameter.TlvSet;
6767

6868
import com.cloudhopper.commons.charset.CharsetUtil;
69+
import com.cloudhopper.smpp.SmppConstants;
6970
import com.cloudhopper.smpp.pdu.SubmitSm;
7071
import com.cloudhopper.smpp.tlv.Tlv;
7172
import com.cloudhopper.smpp.type.Address;
@@ -357,11 +358,11 @@ public void outbound(SmppOutboundMessageEntity request) throws SmppInvalidArgume
357358
submit0.setSourceAddress(new Address((byte) smppTonNpiValue, (byte) smppTonNpiValue, request.getSmppFrom()));
358359
submit0.setDestAddress(new Address((byte) smppTonNpiValue, (byte) smppTonNpiValue, request.getSmppTo()));
359360
if (CharsetUtil.CHARSET_UCS_2 == request.getSmppEncoding()) {
360-
submit0.setDataCoding(DataCoding.DATA_CODING_UCS2);
361+
submit0.setDataCoding(SmppConstants.DATA_CODING_UCS2);
361362
textBytes = CharsetUtil.encode(request.getSmppContent(), CharsetUtil.CHARSET_UCS_2);
362363
} else {
363-
submit0.setDataCoding(DataCoding.DATA_CODING_GSM7);
364-
textBytes = CharsetUtil.encode(request.getSmppContent(), request.getSmppEncoding());
364+
submit0.setDataCoding(SmppConstants.DATA_CODING_DEFAULT);
365+
textBytes = CharsetUtil.encode(request.getSmppContent(), SmppClientOpsThread.getOutboundDefaultEncoding());
365366
}
366367

367368
//TODO reverted from https://telestax.atlassian.net/browse/RESTCOMM-1595 as it caused SMS loop at SMSC

restcomm/restcomm.sms/src/main/java/org/restcomm/connect/sms/smpp/SmppService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,12 @@ private void initializeSmppConnections() {
159159
boolean countersEnabled = smppConfiguration.getBoolean("connections.connection(" + count + ").countersenabled");
160160

161161
long enquireLinkDelay = smppConfiguration.getLong("connections.connection(" + count + ").enquirelinkdelay");
162+
String inboundCharacterEncoding = smppConfiguration.getString("connections.connection(" + count + ").inboundencoding");
163+
String outboundCharacterEncoding = smppConfiguration.getString("connections.connection(" + count + ").outboundencoding");
162164

163165
Smpp smpp = new Smpp(name, systemId, peerIp, peerPort, bindtype, password, systemType, interfaceVersion, address,
164166
connectTimeout, windowSize, windowWaitTimeout, requestExpiryTimeout, windowMonitorInterval,
165-
countersEnabled, logBytes, enquireLinkDelay);
167+
countersEnabled, logBytes, enquireLinkDelay, inboundCharacterEncoding, outboundCharacterEncoding);
166168

167169
this.smppList.add(smpp);
168170

0 commit comments

Comments
 (0)