From 5a964d4adf67d2f49b58f0b14d4388d7aa2353d2 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 2 Mar 2017 12:16:17 +0500 Subject: Implement sms commands --- src/org/traccar/smpp/ClientSmppSessionHandler.java | 6 +-- src/org/traccar/smpp/SmppClient.java | 47 +++++++++++++++------- 2 files changed, 36 insertions(+), 17 deletions(-) (limited to 'src/org/traccar/smpp') diff --git a/src/org/traccar/smpp/ClientSmppSessionHandler.java b/src/org/traccar/smpp/ClientSmppSessionHandler.java index 721243f9f..abfd6120c 100644 --- a/src/org/traccar/smpp/ClientSmppSessionHandler.java +++ b/src/org/traccar/smpp/ClientSmppSessionHandler.java @@ -44,14 +44,14 @@ public class ClientSmppSessionHandler extends DefaultSmppSessionHandler { try { if (request instanceof DeliverSm) { if (request.getOptionalParameters() != null) { - Log.debug("Message Delivered: " + Log.debug("SMS Message Delivered: " + request.getOptionalParameter(SmppConstants.TAG_RECEIPTED_MSG_ID).getValueAsString() + ", State: " + request.getOptionalParameter(SmppConstants.TAG_MSG_STATE).getValueAsByte()); } else { - Log.debug("Message Received: " + Log.debug("SMS Message Received: " + CharsetUtil.decode(((DeliverSm) request).getShortMessage(), - smppClient.mapDataCodingToCharset(((DeliverSm) request).getDataCoding())) + smppClient.mapDataCodingToCharset(((DeliverSm) request).getDataCoding())).trim() + ", Source Address: " + ((DeliverSm) request).getSourceAddress().getAddress()); } diff --git a/src/org/traccar/smpp/SmppClient.java b/src/org/traccar/smpp/SmppClient.java index 3680d20e2..bef2abbf6 100644 --- a/src/org/traccar/smpp/SmppClient.java +++ b/src/org/traccar/smpp/SmppClient.java @@ -60,8 +60,10 @@ public class SmppClient { private String sourceAddress; private int submitTimeout; - private String charsetName; - private byte dataCoding; + private String notificationsCharsetName; + private byte notificationsDataCoding; + private String commandsCharsetName; + private byte commandsDataCoding; private byte sourceTon; private byte sourceNpi; @@ -84,8 +86,15 @@ public class SmppClient { sourceAddress = Context.getConfig().getString("sms.smpp.sourceAddress", ""); submitTimeout = Context.getConfig().getInteger("sms.smpp.submitTimeout", 10000); - charsetName = Context.getConfig().getString("sms.smpp.charsetName", CharsetUtil.NAME_UCS_2); - dataCoding = (byte) Context.getConfig().getInteger("sms.smpp.dataCoding", SmppConstants.DATA_CODING_UCS2); + notificationsCharsetName = Context.getConfig().getString("sms.smpp.notificationsCharset", + CharsetUtil.NAME_UCS_2); + notificationsDataCoding = (byte) Context.getConfig().getInteger("sms.smpp.notificationsDataCoding", + SmppConstants.DATA_CODING_UCS2); + commandsCharsetName = Context.getConfig().getString("sms.smpp.commandsCharset", + CharsetUtil.NAME_GSM); + commandsDataCoding = (byte) Context.getConfig().getInteger("sms.smpp.commandsDataCoding", + SmppConstants.DATA_CODING_DEFAULT); + sourceTon = (byte) Context.getConfig().getInteger("sms.smpp.sourceTon", SmppConstants.TON_ALPHANUMERIC); sourceNpi = (byte) Context.getConfig().getInteger("sms.smpp.sourceNpi", SmppConstants.NPI_UNKNOWN); @@ -184,31 +193,41 @@ public class SmppClient { } } - public synchronized void sendMessageSync(String destAddress, String message) throws RecoverablePduException, - UnrecoverablePduException, SmppTimeoutException, SmppChannelException, InterruptedException { + public synchronized void sendMessageSync(String destAddress, String message, boolean command) + throws RecoverablePduException, UnrecoverablePduException, SmppTimeoutException, SmppChannelException, + InterruptedException, IllegalStateException { if (getSession() != null && getSession().isBound()) { - byte[] textBytes = CharsetUtil.encode(message, charsetName); - SubmitSm submit = new SubmitSm(); + byte[] textBytes; + if (command) { + textBytes = CharsetUtil.encode(message, commandsCharsetName); + submit.setDataCoding(commandsDataCoding); + } else { + textBytes = CharsetUtil.encode(message, notificationsCharsetName); + submit.setDataCoding(notificationsDataCoding); + } + submit.setShortMessage(textBytes); submit.setSourceAddress(new Address(sourceTon, sourceNpi, sourceAddress)); submit.setDestAddress(new Address(destTon, destNpi, destAddress)); - submit.setDataCoding(dataCoding); - submit.setShortMessage(textBytes); SubmitSmResp submitResponce = getSession().submit(submit, submitTimeout); - Log.debug("SMS submited, msg_id: " + submitResponce.getMessageId()); + if (submitResponce.getCommandStatus() == SmppConstants.STATUS_OK) { + Log.debug("SMS submited, msg_id: " + submitResponce.getMessageId()); + } else { + throw new IllegalStateException(submitResponce.getResultMessage()); + } } else { throw new SmppChannelException("Smpp session is not connected"); } } - public void sendMessageAsync(final String destAddress, final String message) { + public void sendMessageAsync(final String destAddress, final String message, final boolean command) { executorService.execute(new Runnable() { @Override public void run() { try { - sendMessageSync(destAddress, message); + sendMessageSync(destAddress, message, command); } catch (InterruptedException | RecoverablePduException | UnrecoverablePduException - | SmppTimeoutException | SmppChannelException error) { + | SmppTimeoutException | SmppChannelException | IllegalStateException error) { Log.warning(error); } } -- cgit v1.2.3 From 6ff73337236f126839e8ce936ba9d201e8a501c7 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 2 Mar 2017 17:05:25 +0500 Subject: Remove BaseProtocolSmsEncoder class Add fallback to SMS if device is not online Use more variables and ternary operators --- src/org/traccar/BaseProtocol.java | 6 ++-- src/org/traccar/BaseProtocolSmsEncoder.java | 30 ------------------ src/org/traccar/api/resource/CommandResource.java | 8 +---- src/org/traccar/database/DeviceManager.java | 37 +++++++++++----------- .../traccar/protocol/GranitProtocolSmsEncoder.java | 6 ++-- .../traccar/protocol/WondexProtocolEncoder.java | 11 ++----- src/org/traccar/smpp/SmppClient.java | 9 ++---- 7 files changed, 31 insertions(+), 76 deletions(-) delete mode 100644 src/org/traccar/BaseProtocolSmsEncoder.java (limited to 'src/org/traccar/smpp') diff --git a/src/org/traccar/BaseProtocol.java b/src/org/traccar/BaseProtocol.java index e9a8a9713..9a03fbff4 100644 --- a/src/org/traccar/BaseProtocol.java +++ b/src/org/traccar/BaseProtocol.java @@ -37,7 +37,7 @@ public abstract class BaseProtocol implements Protocol { private final Set supportedCommands = new HashSet<>(); private final Set supportedSmsCommands = new HashSet<>(); - private BaseProtocolSmsEncoder smsEncoder = null; + private StringProtocolEncoder smsEncoder = null; public BaseProtocol(String name) { this.name = name; @@ -86,7 +86,7 @@ public abstract class BaseProtocol implements Protocol { } } - public void setSmsEncoder(BaseProtocolSmsEncoder smsEncoder) { + public void setSmsEncoder(StringProtocolEncoder smsEncoder) { this.smsEncoder = smsEncoder; } @@ -97,7 +97,7 @@ public abstract class BaseProtocol implements Protocol { if (command.getType().equals(Command.TYPE_CUSTOM)) { Context.getSmppManager().sendMessageSync(phone, command.getString(Command.KEY_DATA), true); } else if (supportedSmsCommands.contains(command.getType()) && smsEncoder != null) { - Context.getSmppManager().sendMessageSync(phone, smsEncoder.encodeSmsCommand(command), true); + Context.getSmppManager().sendMessageSync(phone, (String) smsEncoder.encodeCommand(command), true); } else { throw new RuntimeException( "Command " + command.getType() + " is not supported in protocol " + getName()); diff --git a/src/org/traccar/BaseProtocolSmsEncoder.java b/src/org/traccar/BaseProtocolSmsEncoder.java deleted file mode 100644 index b5694794c..000000000 --- a/src/org/traccar/BaseProtocolSmsEncoder.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2017 Anton Tananaev (anton@traccar.org) - * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar; - -import org.traccar.model.Command; - -public abstract class BaseProtocolSmsEncoder extends StringProtocolEncoder { - - protected abstract String encodeSmsCommand(Command command); - - @Override - protected Object encodeCommand(Command command) { - return null; - } - -} diff --git a/src/org/traccar/api/resource/CommandResource.java b/src/org/traccar/api/resource/CommandResource.java index e5468b5f5..9ed92d3d5 100644 --- a/src/org/traccar/api/resource/CommandResource.java +++ b/src/org/traccar/api/resource/CommandResource.java @@ -19,11 +19,6 @@ import org.traccar.Context; import org.traccar.api.BaseResource; import org.traccar.model.Command; -import com.cloudhopper.smpp.type.RecoverablePduException; -import com.cloudhopper.smpp.type.SmppChannelException; -import com.cloudhopper.smpp.type.SmppTimeoutException; -import com.cloudhopper.smpp.type.UnrecoverablePduException; - import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -37,8 +32,7 @@ import javax.ws.rs.core.Response; public class CommandResource extends BaseResource { @POST - public Response add(Command entity) throws RecoverablePduException, UnrecoverablePduException, - SmppTimeoutException, SmppChannelException, InterruptedException { + public Response add(Command entity) throws Exception { Context.getPermissionsManager().checkReadonly(getUserId()); Context.getPermissionsManager().checkDevice(getUserId(), entity.getDeviceId()); Context.getDeviceManager().sendCommand(entity); diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index f60109770..8b28bec9d 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -26,6 +26,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; +import org.traccar.BaseProtocol; import org.traccar.Config; import org.traccar.Context; import org.traccar.helper.Log; @@ -37,11 +38,6 @@ import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.Server; -import com.cloudhopper.smpp.type.RecoverablePduException; -import com.cloudhopper.smpp.type.SmppChannelException; -import com.cloudhopper.smpp.type.SmppTimeoutException; -import com.cloudhopper.smpp.type.UnrecoverablePduException; - public class DeviceManager implements IdentityManager { public static final long DEFAULT_REFRESH_DELAY = 300; @@ -60,11 +56,14 @@ public class DeviceManager implements IdentityManager { private final Map positions = new ConcurrentHashMap<>(); + private boolean fallbackToSms; + public DeviceManager(DataManager dataManager) { this.dataManager = dataManager; this.config = Context.getConfig(); dataRefreshDelay = config.getLong("database.refreshDelay", DEFAULT_REFRESH_DELAY) * 1000; lookupGroupsAttribute = config.getBoolean("deviceManager.lookupGroupsAttribute"); + fallbackToSms = config.getBoolean("command.fallbackToSms"); if (dataManager != null) { try { updateGroupCache(true); @@ -428,25 +427,30 @@ public class DeviceManager implements IdentityManager { } } - public void sendCommand(Command command) throws RecoverablePduException, UnrecoverablePduException, - SmppTimeoutException, SmppChannelException, InterruptedException { + public void sendCommand(Command command) throws Exception { + long deviceId = command.getDeviceId(); if (command.getSms()) { - Position lastPosition = getLastPosition(command.getDeviceId()); + Position lastPosition = getLastPosition(deviceId); if (lastPosition != null) { - Context.getServerManager().getProtocol(lastPosition.getProtocol()) - .sendSmsCommand(devicesById.get(command.getDeviceId()).getPhone(), command); + BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); + protocol.sendSmsCommand(devicesById.get(deviceId).getPhone(), command); } else if (command.getType().equals(Command.TYPE_CUSTOM)) { - Context.getSmppManager().sendMessageSync(devicesById.get(command.getDeviceId()).getPhone(), + Context.getSmppManager().sendMessageSync(devicesById.get(deviceId).getPhone(), command.getString(Command.KEY_DATA), true); } else { throw new RuntimeException("Command " + command.getType() + " is not supported"); } } else { - ActiveDevice activeDevice = Context.getConnectionManager().getActiveDevice(command.getDeviceId()); + ActiveDevice activeDevice = Context.getConnectionManager().getActiveDevice(deviceId); if (activeDevice != null) { activeDevice.sendCommand(command); } else { - throw new RuntimeException("Device is not online"); + if (fallbackToSms) { + command.setSms(true); + sendCommand(command); + } else { + throw new RuntimeException("Device is not online"); + } } } } @@ -455,12 +459,9 @@ public class DeviceManager implements IdentityManager { List result = new ArrayList<>(); Position lastPosition = Context.getDeviceManager().getLastPosition(deviceId); if (lastPosition != null) { + BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); Collection commands; - if (sms) { - commands = Context.getServerManager().getProtocol(lastPosition.getProtocol()).getSupportedSmsCommands(); - } else { - commands = Context.getServerManager().getProtocol(lastPosition.getProtocol()).getSupportedCommands(); - } + commands = sms ? protocol.getSupportedSmsCommands() : protocol.getSupportedCommands(); for (String commandKey : commands) { result.add(new CommandType(commandKey)); } diff --git a/src/org/traccar/protocol/GranitProtocolSmsEncoder.java b/src/org/traccar/protocol/GranitProtocolSmsEncoder.java index 05954d550..668e5d4d3 100644 --- a/src/org/traccar/protocol/GranitProtocolSmsEncoder.java +++ b/src/org/traccar/protocol/GranitProtocolSmsEncoder.java @@ -16,14 +16,14 @@ */ package org.traccar.protocol; -import org.traccar.BaseProtocolSmsEncoder; +import org.traccar.StringProtocolEncoder; import org.traccar.helper.Log; import org.traccar.model.Command; -public class GranitProtocolSmsEncoder extends BaseProtocolSmsEncoder { +public class GranitProtocolSmsEncoder extends StringProtocolEncoder { @Override - protected String encodeSmsCommand(Command command) { + protected String encodeCommand(Command command) { switch (command.getType()) { case Command.TYPE_REBOOT_DEVICE: return "BB+RESET"; diff --git a/src/org/traccar/protocol/WondexProtocolEncoder.java b/src/org/traccar/protocol/WondexProtocolEncoder.java index ddb5c1475..8f9887b10 100644 --- a/src/org/traccar/protocol/WondexProtocolEncoder.java +++ b/src/org/traccar/protocol/WondexProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2016 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,11 +15,11 @@ */ package org.traccar.protocol; -import org.traccar.BaseProtocolSmsEncoder; +import org.traccar.StringProtocolEncoder; import org.traccar.helper.Log; import org.traccar.model.Command; -public class WondexProtocolEncoder extends BaseProtocolSmsEncoder { +public class WondexProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { @@ -40,9 +40,4 @@ public class WondexProtocolEncoder extends BaseProtocolSmsEncoder { return null; } - @Override - protected String encodeSmsCommand(Command command) { - return (String) encodeCommand(command); - } - } diff --git a/src/org/traccar/smpp/SmppClient.java b/src/org/traccar/smpp/SmppClient.java index bef2abbf6..7f004645d 100644 --- a/src/org/traccar/smpp/SmppClient.java +++ b/src/org/traccar/smpp/SmppClient.java @@ -199,13 +199,8 @@ public class SmppClient { if (getSession() != null && getSession().isBound()) { SubmitSm submit = new SubmitSm(); byte[] textBytes; - if (command) { - textBytes = CharsetUtil.encode(message, commandsCharsetName); - submit.setDataCoding(commandsDataCoding); - } else { - textBytes = CharsetUtil.encode(message, notificationsCharsetName); - submit.setDataCoding(notificationsDataCoding); - } + textBytes = CharsetUtil.encode(message, command ? commandsCharsetName : notificationsCharsetName); + submit.setDataCoding(command ? commandsDataCoding : notificationsDataCoding); submit.setShortMessage(textBytes); submit.setSourceAddress(new Address(sourceTon, sourceNpi, sourceAddress)); submit.setDestAddress(new Address(destTon, destNpi, destAddress)); -- cgit v1.2.3 From f882c2e248fdf1eb87f3ccc339e943c74a6c8dff Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Sat, 4 Mar 2017 11:03:12 +0500 Subject: - Fixed log messages - Combine exceptions in Protocol --- src/org/traccar/BaseProtocol.java | 2 +- src/org/traccar/Protocol.java | 8 +------- src/org/traccar/smpp/ClientSmppSessionHandler.java | 2 +- src/org/traccar/smpp/SmppClient.java | 10 +++++----- 4 files changed, 8 insertions(+), 14 deletions(-) (limited to 'src/org/traccar/smpp') diff --git a/src/org/traccar/BaseProtocol.java b/src/org/traccar/BaseProtocol.java index 9a03fbff4..790a1484c 100644 --- a/src/org/traccar/BaseProtocol.java +++ b/src/org/traccar/BaseProtocol.java @@ -103,7 +103,7 @@ public abstract class BaseProtocol implements Protocol { "Command " + command.getType() + " is not supported in protocol " + getName()); } } else { - throw new RuntimeException("Smpp client is not enabled"); + throw new RuntimeException("SMPP client is not enabled"); } } diff --git a/src/org/traccar/Protocol.java b/src/org/traccar/Protocol.java index 5f510b10b..f6a4fbebb 100644 --- a/src/org/traccar/Protocol.java +++ b/src/org/traccar/Protocol.java @@ -3,11 +3,6 @@ package org.traccar; import org.traccar.database.ActiveDevice; import org.traccar.model.Command; -import com.cloudhopper.smpp.type.RecoverablePduException; -import com.cloudhopper.smpp.type.SmppChannelException; -import com.cloudhopper.smpp.type.SmppTimeoutException; -import com.cloudhopper.smpp.type.UnrecoverablePduException; - import java.util.Collection; import java.util.List; @@ -23,7 +18,6 @@ public interface Protocol { Collection getSupportedSmsCommands(); - void sendSmsCommand(String phone, Command command) throws RecoverablePduException, UnrecoverablePduException, - SmppTimeoutException, SmppChannelException, InterruptedException; + void sendSmsCommand(String phone, Command command) throws Exception; } diff --git a/src/org/traccar/smpp/ClientSmppSessionHandler.java b/src/org/traccar/smpp/ClientSmppSessionHandler.java index abfd6120c..2a538a40f 100644 --- a/src/org/traccar/smpp/ClientSmppSessionHandler.java +++ b/src/org/traccar/smpp/ClientSmppSessionHandler.java @@ -68,7 +68,7 @@ public class ClientSmppSessionHandler extends DefaultSmppSessionHandler { @Override public void fireChannelUnexpectedlyClosed() { - Log.warning("Smpp session channel unexpectedly closed"); + Log.warning("SMPP session channel unexpectedly closed"); smppClient.scheduleReconnect(); } } diff --git a/src/org/traccar/smpp/SmppClient.java b/src/org/traccar/smpp/SmppClient.java index 7f004645d..006f86e53 100644 --- a/src/org/traccar/smpp/SmppClient.java +++ b/src/org/traccar/smpp/SmppClient.java @@ -149,10 +149,10 @@ public class SmppClient { smppSession = clientBootstrap.bind(sessionConfig, sessionHandler); stopReconnectionkTask(); runEnquireLinkTask(); - Log.info("Smpp session connected"); + Log.info("SMPP session connected"); } catch (SmppTimeoutException | SmppChannelException | UnrecoverablePduException | InterruptedException error) { - Log.warning("Unable to connect to smpp server: ", error); + Log.warning("Unable to connect to SMPP server: ", error); } } @@ -187,7 +187,7 @@ public class SmppClient { private void destroySession() { if (smppSession != null) { - Log.debug("Cleaning up smpp session... "); + Log.debug("Cleaning up SMPP session... "); smppSession.destroy(); smppSession = null; } @@ -206,12 +206,12 @@ public class SmppClient { submit.setDestAddress(new Address(destTon, destNpi, destAddress)); SubmitSmResp submitResponce = getSession().submit(submit, submitTimeout); if (submitResponce.getCommandStatus() == SmppConstants.STATUS_OK) { - Log.debug("SMS submited, msg_id: " + submitResponce.getMessageId()); + Log.debug("SMS submitted, message id: " + submitResponce.getMessageId()); } else { throw new IllegalStateException(submitResponce.getResultMessage()); } } else { - throw new SmppChannelException("Smpp session is not connected"); + throw new SmppChannelException("SMPP session is not connected"); } } -- cgit v1.2.3