diff options
Diffstat (limited to 'src/org')
42 files changed, 591 insertions, 84 deletions
diff --git a/src/org/traccar/BaseProtocol.java b/src/org/traccar/BaseProtocol.java index 59331d7cc..90b9f21f2 100644 --- a/src/org/traccar/BaseProtocol.java +++ b/src/org/traccar/BaseProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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. @@ -29,7 +29,10 @@ import java.util.Set; public abstract class BaseProtocol implements Protocol { private final String name; - private final Set<String> supportedCommands = new HashSet<>(); + private final Set<String> supportedDataCommands = new HashSet<>(); + private final Set<String> supportedTextCommands = new HashSet<>(); + + private StringProtocolEncoder textCommandEncoder = null; public BaseProtocol(String name) { this.name = name; @@ -40,20 +43,36 @@ public abstract class BaseProtocol implements Protocol { return name; } + public void setSupportedDataCommands(String... commands) { + supportedDataCommands.addAll(Arrays.asList(commands)); + } + + public void setSupportedTextCommands(String... commands) { + supportedTextCommands.addAll(Arrays.asList(commands)); + } + public void setSupportedCommands(String... commands) { - supportedCommands.addAll(Arrays.asList(commands)); + supportedDataCommands.addAll(Arrays.asList(commands)); + supportedTextCommands.addAll(Arrays.asList(commands)); + } + + @Override + public Collection<String> getSupportedDataCommands() { + Set<String> commands = new HashSet<>(supportedDataCommands); + commands.add(Command.TYPE_CUSTOM); + return commands; } @Override - public Collection<String> getSupportedCommands() { - Set<String> commands = new HashSet<>(supportedCommands); + public Collection<String> getSupportedTextCommands() { + Set<String> commands = new HashSet<>(supportedTextCommands); commands.add(Command.TYPE_CUSTOM); return commands; } @Override - public void sendCommand(ActiveDevice activeDevice, Command command) { - if (supportedCommands.contains(command.getType())) { + public void sendDataCommand(ActiveDevice activeDevice, Command command) { + if (supportedDataCommands.contains(command.getType())) { activeDevice.write(command); } else if (command.getType().equals(Command.TYPE_CUSTOM)) { String data = command.getString(Command.KEY_DATA); @@ -67,4 +86,25 @@ public abstract class BaseProtocol implements Protocol { } } + public void setTextCommandEncoder(StringProtocolEncoder textCommandEncoder) { + this.textCommandEncoder = textCommandEncoder; + } + + @Override + public void sendTextCommand(String destAddress, Command command) throws Exception { + if (Context.getSmppManager() != null) { + if (command.getType().equals(Command.TYPE_CUSTOM)) { + Context.getSmppManager().sendMessageSync(destAddress, command.getString(Command.KEY_DATA), true); + } else if (supportedTextCommands.contains(command.getType()) && textCommandEncoder != null) { + Context.getSmppManager().sendMessageSync(destAddress, + (String) textCommandEncoder.encodeCommand(command), true); + } else { + throw new RuntimeException( + "Command " + command.getType() + " is not supported in protocol " + getName()); + } + } else { + throw new RuntimeException("SMPP client is not enabled"); + } + } + } diff --git a/src/org/traccar/Protocol.java b/src/org/traccar/Protocol.java index c99fd8ecb..87ac05298 100644 --- a/src/org/traccar/Protocol.java +++ b/src/org/traccar/Protocol.java @@ -10,10 +10,14 @@ public interface Protocol { String getName(); - Collection<String> getSupportedCommands(); + Collection<String> getSupportedDataCommands(); - void sendCommand(ActiveDevice activeDevice, Command command); + void sendDataCommand(ActiveDevice activeDevice, Command command); void initTrackerServers(List<TrackerServer> serverList); + Collection<String> getSupportedTextCommands(); + + void sendTextCommand(String destAddress, Command command) throws Exception; + } diff --git a/src/org/traccar/ServerManager.java b/src/org/traccar/ServerManager.java index 953428b8f..9b1e2650d 100644 --- a/src/org/traccar/ServerManager.java +++ b/src/org/traccar/ServerManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2017 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. @@ -23,12 +23,15 @@ import java.nio.charset.StandardCharsets; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class ServerManager { private final List<TrackerServer> serverList = new LinkedList<>(); + private final Map<String, BaseProtocol> protocolList = new ConcurrentHashMap<>(); public ServerManager() throws Exception { @@ -64,10 +67,15 @@ public class ServerManager { if (BaseProtocol.class.isAssignableFrom(protocolClass)) { BaseProtocol baseProtocol = (BaseProtocol) protocolClass.newInstance(); initProtocolServer(baseProtocol); + protocolList.put(baseProtocol.getName(), baseProtocol); } } } + public BaseProtocol getProtocol(String name) { + return protocolList.get(name); + } + public void start() { for (TrackerServer server: serverList) { server.start(); diff --git a/src/org/traccar/api/resource/CommandResource.java b/src/org/traccar/api/resource/CommandResource.java index 41b263bf9..9ed92d3d5 100644 --- a/src/org/traccar/api/resource/CommandResource.java +++ b/src/org/traccar/api/resource/CommandResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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. @@ -32,10 +32,10 @@ import javax.ws.rs.core.Response; public class CommandResource extends BaseResource { @POST - public Response add(Command entity) { + public Response add(Command entity) throws Exception { Context.getPermissionsManager().checkReadonly(getUserId()); Context.getPermissionsManager().checkDevice(getUserId(), entity.getDeviceId()); - Context.getConnectionManager().getActiveDevice(entity.getDeviceId()).sendCommand(entity); + Context.getDeviceManager().sendCommand(entity); return Response.ok(entity).build(); } diff --git a/src/org/traccar/api/resource/CommandTypeResource.java b/src/org/traccar/api/resource/CommandTypeResource.java index ce27f5241..d5d220547 100644 --- a/src/org/traccar/api/resource/CommandTypeResource.java +++ b/src/org/traccar/api/resource/CommandTypeResource.java @@ -1,5 +1,6 @@ /* * Copyright 2016 Gabor Somogyi (gabor.g.somogyi@gmail.com) + * 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. @@ -25,7 +26,6 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; -import java.sql.SQLException; import java.util.Collection; @Path("commandtypes") @@ -34,9 +34,10 @@ import java.util.Collection; public class CommandTypeResource extends BaseResource { @GET - public Collection<CommandType> get(@QueryParam("deviceId") long deviceId) throws SQLException { + public Collection<CommandType> get(@QueryParam("deviceId") long deviceId, + @QueryParam("textChannel") boolean textChannel) { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - return Context.getConnectionManager().getActiveDevice(deviceId).getCommandTypes(); + return Context.getDeviceManager().getCommandTypes(deviceId, textChannel); } } diff --git a/src/org/traccar/database/ActiveDevice.java b/src/org/traccar/database/ActiveDevice.java index 6109bc517..f491111e1 100644 --- a/src/org/traccar/database/ActiveDevice.java +++ b/src/org/traccar/database/ActiveDevice.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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. @@ -18,12 +18,8 @@ package org.traccar.database; import org.jboss.netty.channel.Channel; import org.traccar.Protocol; import org.traccar.model.Command; -import org.traccar.model.CommandType; import java.net.SocketAddress; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; public class ActiveDevice { @@ -47,18 +43,8 @@ public class ActiveDevice { return deviceId; } - public Collection<CommandType> getCommandTypes() { - List<CommandType> result = new ArrayList<>(); - - for (String commandKey : protocol.getSupportedCommands()) { - result.add(new CommandType(commandKey)); - } - - return result; - } - public void sendCommand(Command command) { - protocol.sendCommand(this, command); + protocol.sendDataCommand(this, command); } public void write(Object message) { diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index 8e75903db..f5fde9e1f 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -26,9 +26,12 @@ 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; +import org.traccar.model.Command; +import org.traccar.model.CommandType; import org.traccar.model.Device; import org.traccar.model.DeviceTotalDistance; import org.traccar.model.Group; @@ -53,11 +56,14 @@ public class DeviceManager implements IdentityManager { private final Map<Long, Position> positions = new ConcurrentHashMap<>(); + private boolean fallbackToText; + 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"); + fallbackToText = config.getBoolean("command.fallbackToSms"); if (dataManager != null) { try { updateGroupCache(true); @@ -420,4 +426,48 @@ public class DeviceManager implements IdentityManager { throw new IllegalArgumentException(); } } + + public void sendCommand(Command command) throws Exception { + long deviceId = command.getDeviceId(); + if (command.getTextChannel()) { + Position lastPosition = getLastPosition(deviceId); + if (lastPosition != null) { + BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); + protocol.sendTextCommand(devicesById.get(deviceId).getPhone(), command); + } else if (command.getType().equals(Command.TYPE_CUSTOM)) { + 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(deviceId); + if (activeDevice != null) { + activeDevice.sendCommand(command); + } else { + if (fallbackToText) { + command.setTextChannel(true); + sendCommand(command); + } else { + throw new RuntimeException("Device is not online"); + } + } + } + } + + public Collection<CommandType> getCommandTypes(long deviceId, boolean textChannel) { + List<CommandType> result = new ArrayList<>(); + Position lastPosition = Context.getDeviceManager().getLastPosition(deviceId); + if (lastPosition != null) { + BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); + Collection<String> commands; + commands = textChannel ? protocol.getSupportedTextCommands() : protocol.getSupportedDataCommands(); + for (String commandKey : commands) { + result.add(new CommandType(commandKey)); + } + } else { + result.add(new CommandType(Command.TYPE_CUSTOM)); + } + return result; + } } diff --git a/src/org/traccar/model/Command.java b/src/org/traccar/model/Command.java index 84f5d95ce..016862214 100644 --- a/src/org/traccar/model/Command.java +++ b/src/org/traccar/model/Command.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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. @@ -66,4 +66,14 @@ public class Command extends Message { public static final String KEY_INDEX = "index"; public static final String KEY_PHONE = "phone"; + private boolean textChannel; + + public boolean getTextChannel() { + return textChannel; + } + + public void setTextChannel(boolean textChannel) { + this.textChannel = textChannel; + } + } diff --git a/src/org/traccar/notification/NotificationSms.java b/src/org/traccar/notification/NotificationSms.java index cb5dd563a..7b265e3ce 100644 --- a/src/org/traccar/notification/NotificationSms.java +++ b/src/org/traccar/notification/NotificationSms.java @@ -35,7 +35,7 @@ public final class NotificationSms { User user = Context.getPermissionsManager().getUser(userId); if (Context.getSmppManager() != null && user.getPhone() != null) { Context.getSmppManager().sendMessageAsync(user.getPhone(), - NotificationFormatter.formatSmsMessage(userId, event, position)); + NotificationFormatter.formatSmsMessage(userId, event, position), false); } } @@ -44,7 +44,7 @@ public final class NotificationSms { User user = Context.getPermissionsManager().getUser(userId); if (Context.getSmppManager() != null && user.getPhone() != null) { Context.getSmppManager().sendMessageSync(user.getPhone(), - NotificationFormatter.formatSmsMessage(userId, event, position)); + NotificationFormatter.formatSmsMessage(userId, event, position), false); } } } diff --git a/src/org/traccar/protocol/CarcellProtocol.java b/src/org/traccar/protocol/CarcellProtocol.java index e53a10eb5..c9fedad65 100644 --- a/src/org/traccar/protocol/CarcellProtocol.java +++ b/src/org/traccar/protocol/CarcellProtocol.java @@ -30,7 +30,7 @@ public class CarcellProtocol extends BaseProtocol { public CarcellProtocol() { super("carcell"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); } diff --git a/src/org/traccar/protocol/CellocatorProtocol.java b/src/org/traccar/protocol/CellocatorProtocol.java index 7c8510204..4a20bc977 100644 --- a/src/org/traccar/protocol/CellocatorProtocol.java +++ b/src/org/traccar/protocol/CellocatorProtocol.java @@ -29,7 +29,7 @@ public class CellocatorProtocol extends BaseProtocol { public CellocatorProtocol() { super("cellocator"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_OUTPUT_CONTROL); } diff --git a/src/org/traccar/protocol/CityeasyProtocol.java b/src/org/traccar/protocol/CityeasyProtocol.java index c5ad05fcd..7e5ca0ba0 100644 --- a/src/org/traccar/protocol/CityeasyProtocol.java +++ b/src/org/traccar/protocol/CityeasyProtocol.java @@ -28,7 +28,7 @@ public class CityeasyProtocol extends BaseProtocol { public CityeasyProtocol() { super("cityeasy"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, Command.TYPE_POSITION_STOP, diff --git a/src/org/traccar/protocol/DmtProtocol.java b/src/org/traccar/protocol/DmtProtocol.java new file mode 100644 index 000000000..18bb1524a --- /dev/null +++ b/src/org/traccar/protocol/DmtProtocol.java @@ -0,0 +1,46 @@ +/* + * Copyright 2017 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. + * 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.protocol; + +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import org.traccar.BaseProtocol; +import org.traccar.TrackerServer; + +import java.nio.ByteOrder; +import java.util.List; + +public class DmtProtocol extends BaseProtocol { + + public DmtProtocol() { + super("dmt"); + } + + @Override + public void initTrackerServers(List<TrackerServer> serverList) { + TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 3, 2)); + pipeline.addLast("objectDecoder", new DmtProtocolDecoder(DmtProtocol.this)); + } + }; + server.setEndianness(ByteOrder.LITTLE_ENDIAN); + serverList.add(server); + } + +} diff --git a/src/org/traccar/protocol/DmtProtocolDecoder.java b/src/org/traccar/protocol/DmtProtocolDecoder.java new file mode 100644 index 000000000..4c641f397 --- /dev/null +++ b/src/org/traccar/protocol/DmtProtocolDecoder.java @@ -0,0 +1,147 @@ +/* + * Copyright 2017 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. + * 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.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +public class DmtProtocolDecoder extends BaseProtocolDecoder { + + public DmtProtocolDecoder(DmtProtocol protocol) { + super(protocol); + } + + public static final int MSG_HELLO = 0x00; + public static final int MSG_HELLO_RESPONSE = 0x01; + public static final int MSG_DATA_RECORD = 0x04; + public static final int MSG_COMMIT = 0x05; + public static final int MSG_COMMIT_RESPONSE = 0x06; + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ChannelBuffer buf = (ChannelBuffer) msg; + + buf.skipBytes(2); // header + + int type = buf.readUnsignedByte(); + + buf.readUnsignedShort(); // length + + if (type == MSG_HELLO) { + + buf.readUnsignedInt(); // device serial number + + DeviceSession deviceSession = getDeviceSession( + channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.US_ASCII)); + + if (channel != null) { + ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); + response.writeByte(0x02); response.writeByte(0x55); // header + response.writeByte(MSG_HELLO_RESPONSE); + response.writeShort(4 + 4); + response.writeInt((int) (System.currentTimeMillis() / 1000)); + response.writeInt(deviceSession != null ? 0 : 1); // flags + channel.write(response); + } + + } else if (type == MSG_COMMIT) { + + if (channel != null) { + ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); + response.writeByte(0x02); response.writeByte(0x55); // header + response.writeByte(MSG_COMMIT_RESPONSE); + response.writeShort(1); + response.writeByte(1); // flags (success) + channel.write(response); + } + + } else if (type == MSG_DATA_RECORD) { + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + List<Position> positions = new LinkedList<>(); + + while (buf.readable()) { + + int recordEnd = buf.readerIndex() + buf.readUnsignedShort(); + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_INDEX, buf.readUnsignedInt()); + + position.setDeviceTime(new Date(1356998400000L + buf.readUnsignedInt() * 1000)); // since 1 Jan 2013 + + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); + + while (buf.readerIndex() < recordEnd) { + + int fieldId = buf.readUnsignedByte(); + int fieldLength = buf.readUnsignedByte(); + int fieldEnd = buf.readerIndex() + (fieldLength == 255 ? buf.readUnsignedShort() : fieldLength); + + if (fieldId == 0) { + + position.setFixTime(new Date(1356998400000L + buf.readUnsignedInt() * 1000)); + position.setLatitude(buf.readInt() * 0.0000001); + position.setLongitude(buf.readInt() * 0.0000001); + position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedShort())); + + buf.readUnsignedByte(); // speed accuracy + + position.setCourse(buf.readUnsignedByte() * 2); + + position.set(Position.KEY_PDOP, buf.readUnsignedByte() * 0.1); + + position.setAccuracy(buf.readUnsignedByte()); + position.setValid(buf.readUnsignedByte() != 0); + + } + + buf.readerIndex(fieldEnd); + + } + + positions.add(position); + + } + + return positions; + + } + + return null; + } + +} diff --git a/src/org/traccar/protocol/EelinkProtocol.java b/src/org/traccar/protocol/EelinkProtocol.java index 5900f0059..5499094d9 100644 --- a/src/org/traccar/protocol/EelinkProtocol.java +++ b/src/org/traccar/protocol/EelinkProtocol.java @@ -28,7 +28,7 @@ public class EelinkProtocol extends BaseProtocol { public EelinkProtocol() { super("eelink"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, diff --git a/src/org/traccar/protocol/Gl200Protocol.java b/src/org/traccar/protocol/Gl200Protocol.java index b6f01c773..b3743042c 100644 --- a/src/org/traccar/protocol/Gl200Protocol.java +++ b/src/org/traccar/protocol/Gl200Protocol.java @@ -31,7 +31,7 @@ public class Gl200Protocol extends BaseProtocol { public Gl200Protocol() { super("gl200"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, diff --git a/src/org/traccar/protocol/Gps103Protocol.java b/src/org/traccar/protocol/Gps103Protocol.java index a4d563bfc..a5bd32261 100644 --- a/src/org/traccar/protocol/Gps103Protocol.java +++ b/src/org/traccar/protocol/Gps103Protocol.java @@ -31,7 +31,7 @@ public class Gps103Protocol extends BaseProtocol { public Gps103Protocol() { super("gps103"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, diff --git a/src/org/traccar/protocol/GranitProtocol.java b/src/org/traccar/protocol/GranitProtocol.java index a5d5458f0..32e8e00b0 100644 --- a/src/org/traccar/protocol/GranitProtocol.java +++ b/src/org/traccar/protocol/GranitProtocol.java @@ -1,5 +1,6 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 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. @@ -28,10 +29,14 @@ public class GranitProtocol extends BaseProtocol { public GranitProtocol() { super("granit"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_IDENTIFICATION, Command.TYPE_REBOOT_DEVICE, Command.TYPE_POSITION_SINGLE); + setTextCommandEncoder(new GranitProtocolSmsEncoder()); + setSupportedTextCommands( + Command.TYPE_REBOOT_DEVICE, + Command.TYPE_POSITION_PERIODIC); } @Override diff --git a/src/org/traccar/protocol/GranitProtocolSmsEncoder.java b/src/org/traccar/protocol/GranitProtocolSmsEncoder.java new file mode 100644 index 000000000..668e5d4d3 --- /dev/null +++ b/src/org/traccar/protocol/GranitProtocolSmsEncoder.java @@ -0,0 +1,38 @@ +/* + * 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.protocol; + +import org.traccar.StringProtocolEncoder; +import org.traccar.helper.Log; +import org.traccar.model.Command; + +public class GranitProtocolSmsEncoder extends StringProtocolEncoder { + + @Override + protected String encodeCommand(Command command) { + switch (command.getType()) { + case Command.TYPE_REBOOT_DEVICE: + return "BB+RESET"; + case Command.TYPE_POSITION_PERIODIC: + return formatCommand(command, "BB+BBMD={%s}", Command.KEY_FREQUENCY); + default: + Log.warning(new UnsupportedOperationException(command.getType())); + return null; + } + } + +} diff --git a/src/org/traccar/protocol/Gt06Protocol.java b/src/org/traccar/protocol/Gt06Protocol.java index e96679799..aa8f1f0c0 100644 --- a/src/org/traccar/protocol/Gt06Protocol.java +++ b/src/org/traccar/protocol/Gt06Protocol.java @@ -27,7 +27,7 @@ public class Gt06Protocol extends BaseProtocol { public Gt06Protocol() { super("gt06"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); } diff --git a/src/org/traccar/protocol/H02Protocol.java b/src/org/traccar/protocol/H02Protocol.java index 498f63c0e..df64402f8 100644 --- a/src/org/traccar/protocol/H02Protocol.java +++ b/src/org/traccar/protocol/H02Protocol.java @@ -29,7 +29,7 @@ public class H02Protocol extends BaseProtocol { public H02Protocol() { super("h02"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_ALARM_ARM, Command.TYPE_ALARM_DISARM, Command.TYPE_ENGINE_STOP, diff --git a/src/org/traccar/protocol/HuabaoProtocol.java b/src/org/traccar/protocol/HuabaoProtocol.java index d5e68e091..c74cb58c7 100644 --- a/src/org/traccar/protocol/HuabaoProtocol.java +++ b/src/org/traccar/protocol/HuabaoProtocol.java @@ -27,7 +27,7 @@ public class HuabaoProtocol extends BaseProtocol { public HuabaoProtocol() { super("huabao"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); } diff --git a/src/org/traccar/protocol/Jt600Protocol.java b/src/org/traccar/protocol/Jt600Protocol.java index 132770511..8c71ca4f6 100644 --- a/src/org/traccar/protocol/Jt600Protocol.java +++ b/src/org/traccar/protocol/Jt600Protocol.java @@ -28,7 +28,7 @@ public class Jt600Protocol extends BaseProtocol { public Jt600Protocol() { super("jt600"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_ENGINE_RESUME, Command.TYPE_ENGINE_STOP, Command.TYPE_SET_TIMEZONE, diff --git a/src/org/traccar/protocol/KhdProtocol.java b/src/org/traccar/protocol/KhdProtocol.java index bf0d2855d..167727191 100644 --- a/src/org/traccar/protocol/KhdProtocol.java +++ b/src/org/traccar/protocol/KhdProtocol.java @@ -28,7 +28,7 @@ public class KhdProtocol extends BaseProtocol { public KhdProtocol() { super("khd"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); } diff --git a/src/org/traccar/protocol/MeiligaoProtocol.java b/src/org/traccar/protocol/MeiligaoProtocol.java index 23af19ef1..dbdd2619a 100644 --- a/src/org/traccar/protocol/MeiligaoProtocol.java +++ b/src/org/traccar/protocol/MeiligaoProtocol.java @@ -28,7 +28,7 @@ public class MeiligaoProtocol extends BaseProtocol { public MeiligaoProtocol() { super("meiligao"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, Command.TYPE_ENGINE_STOP, diff --git a/src/org/traccar/protocol/MeitrackProtocol.java b/src/org/traccar/protocol/MeitrackProtocol.java index 918729f97..e89825da5 100644 --- a/src/org/traccar/protocol/MeitrackProtocol.java +++ b/src/org/traccar/protocol/MeitrackProtocol.java @@ -30,7 +30,7 @@ public class MeitrackProtocol extends BaseProtocol { public MeitrackProtocol() { super("meitrack"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, diff --git a/src/org/traccar/protocol/MiniFinderProtocol.java b/src/org/traccar/protocol/MiniFinderProtocol.java index 3bbdc1beb..c36acb238 100644 --- a/src/org/traccar/protocol/MiniFinderProtocol.java +++ b/src/org/traccar/protocol/MiniFinderProtocol.java @@ -30,7 +30,7 @@ public class MiniFinderProtocol extends BaseProtocol { public MiniFinderProtocol() { super("minifinder"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_SET_TIMEZONE, Command.TYPE_VOICE_MONITORING, Command.TYPE_ALARM_SPEED, diff --git a/src/org/traccar/protocol/NoranProtocol.java b/src/org/traccar/protocol/NoranProtocol.java index bf10eb127..7d3dc4852 100644 --- a/src/org/traccar/protocol/NoranProtocol.java +++ b/src/org/traccar/protocol/NoranProtocol.java @@ -28,7 +28,7 @@ public class NoranProtocol extends BaseProtocol { public NoranProtocol() { super("noran"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, Command.TYPE_POSITION_STOP, diff --git a/src/org/traccar/protocol/Pt502Protocol.java b/src/org/traccar/protocol/Pt502Protocol.java index a15938dc3..ad97a777e 100644 --- a/src/org/traccar/protocol/Pt502Protocol.java +++ b/src/org/traccar/protocol/Pt502Protocol.java @@ -30,7 +30,7 @@ public class Pt502Protocol extends BaseProtocol { public Pt502Protocol() { super("pt502"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_SET_TIMEZONE, Command.TYPE_ALARM_SPEED, Command.TYPE_OUTPUT_CONTROL, diff --git a/src/org/traccar/protocol/RuptelaProtocol.java b/src/org/traccar/protocol/RuptelaProtocol.java index 54cdcc267..4be07307d 100644 --- a/src/org/traccar/protocol/RuptelaProtocol.java +++ b/src/org/traccar/protocol/RuptelaProtocol.java @@ -28,7 +28,7 @@ public class RuptelaProtocol extends BaseProtocol { public RuptelaProtocol() { super("ruptela"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_CUSTOM); } diff --git a/src/org/traccar/protocol/StarLinkProtocol.java b/src/org/traccar/protocol/StarLinkProtocol.java new file mode 100644 index 000000000..e71d94fd0 --- /dev/null +++ b/src/org/traccar/protocol/StarLinkProtocol.java @@ -0,0 +1,47 @@ +/* + * Copyright 2017 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. + * 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.protocol; + +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder; +import org.jboss.netty.handler.codec.string.StringDecoder; +import org.jboss.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.TrackerServer; + +import java.util.List; + +public class StarLinkProtocol extends BaseProtocol { + + public StarLinkProtocol() { + super("starlink"); + } + + @Override + public void initTrackerServers(List<TrackerServer> serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); + pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new StarLinkProtocolDecoder(StarLinkProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/org/traccar/protocol/StarLinkProtocolDecoder.java new file mode 100644 index 000000000..46d8ee9cc --- /dev/null +++ b/src/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -0,0 +1,110 @@ +/* + * Copyright 2017 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. + * 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.protocol; + +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.DateBuilder; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.model.CellTower; +import org.traccar.model.Network; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class StarLinkProtocolDecoder extends BaseProtocolDecoder { + + public StarLinkProtocolDecoder(StarLinkProtocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .expression(".") // protocol head + .text("SLU") // message head + .number("(x{6}|d{15}),") // id + .number("(d+),") // type + .number("(d+),") // index + .number("(dd)(dd)(dd)") // event date + .number("(dd)(dd)(dd),") // event time + .number("(d+),") // event + .number("(dd)(dd)(dd)") // fix date + .number("(dd)(dd)(dd),") // fix time + .number("([-+])(dd)(dd.d+),") // latitude + .number("([-+])(ddd)(dd.d+),") // longitude + .number("(d+.d+),") // speed + .number("(d+),") // course + .number("(d+),") // odometer + .number("(d+),") // lac + .number("(d+),") // cid + .number("(d+.d+),") // power + .number("(d+.d+)") // battery + .any() + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_TYPE, parser.nextInt()); + position.set(Position.KEY_INDEX, parser.nextInt()); + + DateBuilder dateBuilder = new DateBuilder() + .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setDeviceTime(dateBuilder.getDate()); + + position.set(Position.KEY_EVENT, parser.nextInt()); + + dateBuilder = new DateBuilder() + .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setFixTime(dateBuilder.getDate()); + + position.setValid(true); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); + + position.setSpeed(parser.nextDouble()); + position.setCourse(parser.nextInt()); + + position.set(Position.KEY_ODOMETER, parser.nextInt()); + + position.setNetwork(new Network(CellTower.fromLacCid(parser.nextInt(), parser.nextInt()))); + + position.set(Position.KEY_POWER, parser.nextDouble()); + position.set(Position.KEY_BATTERY, parser.nextDouble()); + + return position; + } + +} diff --git a/src/org/traccar/protocol/SuntechProtocol.java b/src/org/traccar/protocol/SuntechProtocol.java index 410dc8af7..871c3becd 100644 --- a/src/org/traccar/protocol/SuntechProtocol.java +++ b/src/org/traccar/protocol/SuntechProtocol.java @@ -30,7 +30,7 @@ public class SuntechProtocol extends BaseProtocol { public SuntechProtocol() { super("suntech"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_OUTPUT_CONTROL, Command.TYPE_REBOOT_DEVICE, Command.TYPE_POSITION_SINGLE, diff --git a/src/org/traccar/protocol/T800xProtocol.java b/src/org/traccar/protocol/T800xProtocol.java index 70341d0dc..830ff4de6 100644 --- a/src/org/traccar/protocol/T800xProtocol.java +++ b/src/org/traccar/protocol/T800xProtocol.java @@ -28,7 +28,7 @@ public class T800xProtocol extends BaseProtocol { public T800xProtocol() { super("t800x"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_CUSTOM); } diff --git a/src/org/traccar/protocol/TeltonikaProtocol.java b/src/org/traccar/protocol/TeltonikaProtocol.java index f0ed61886..524e6d5b5 100644 --- a/src/org/traccar/protocol/TeltonikaProtocol.java +++ b/src/org/traccar/protocol/TeltonikaProtocol.java @@ -28,7 +28,7 @@ public class TeltonikaProtocol extends BaseProtocol { public TeltonikaProtocol() { super("teltonika"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_CUSTOM); } diff --git a/src/org/traccar/protocol/TotemProtocol.java b/src/org/traccar/protocol/TotemProtocol.java index 860fff894..1c5cf5b02 100644 --- a/src/org/traccar/protocol/TotemProtocol.java +++ b/src/org/traccar/protocol/TotemProtocol.java @@ -29,7 +29,7 @@ public class TotemProtocol extends BaseProtocol { public TotemProtocol() { super("totem"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_ENGINE_RESUME, Command.TYPE_ENGINE_STOP ); diff --git a/src/org/traccar/protocol/WatchProtocol.java b/src/org/traccar/protocol/WatchProtocol.java index abce3d16a..f664691c3 100644 --- a/src/org/traccar/protocol/WatchProtocol.java +++ b/src/org/traccar/protocol/WatchProtocol.java @@ -30,7 +30,7 @@ public class WatchProtocol extends BaseProtocol { public WatchProtocol() { super("watch"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, Command.TYPE_SOS_NUMBER, diff --git a/src/org/traccar/protocol/WialonProtocol.java b/src/org/traccar/protocol/WialonProtocol.java index 04e18cd85..02da154e2 100644 --- a/src/org/traccar/protocol/WialonProtocol.java +++ b/src/org/traccar/protocol/WialonProtocol.java @@ -32,7 +32,7 @@ public class WialonProtocol extends BaseProtocol { public WialonProtocol() { super("wialon"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_REBOOT_DEVICE, Command.TYPE_SEND_USSD, Command.TYPE_IDENTIFICATION, diff --git a/src/org/traccar/protocol/WondexProtocol.java b/src/org/traccar/protocol/WondexProtocol.java index 0cc21d2b4..e7e13c63a 100644 --- a/src/org/traccar/protocol/WondexProtocol.java +++ b/src/org/traccar/protocol/WondexProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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. @@ -29,6 +29,7 @@ public class WondexProtocol extends BaseProtocol { public WondexProtocol() { super("wondex"); + setTextCommandEncoder(new WondexProtocolEncoder()); setSupportedCommands( Command.TYPE_REBOOT_DEVICE, Command.TYPE_POSITION_SINGLE, diff --git a/src/org/traccar/protocol/XexunProtocol.java b/src/org/traccar/protocol/XexunProtocol.java index a52d9ff45..b90cbfaaf 100644 --- a/src/org/traccar/protocol/XexunProtocol.java +++ b/src/org/traccar/protocol/XexunProtocol.java @@ -31,7 +31,7 @@ public class XexunProtocol extends BaseProtocol { public XexunProtocol() { super("xexun"); - setSupportedCommands( + setSupportedDataCommands( Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); } diff --git a/src/org/traccar/smpp/ClientSmppSessionHandler.java b/src/org/traccar/smpp/ClientSmppSessionHandler.java index 721243f9f..2a538a40f 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()); } @@ -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 0bec60fd2..317d6debf 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); @@ -140,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); } } @@ -180,37 +189,42 @@ 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; } } - 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; + 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)); - 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 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"); } } - 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); } } |