diff options
Diffstat (limited to 'src/org/traccar/database/CommandsManager.java')
-rw-r--r-- | src/org/traccar/database/CommandsManager.java | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/src/org/traccar/database/CommandsManager.java b/src/org/traccar/database/CommandsManager.java new file mode 100644 index 000000000..9ceb995ef --- /dev/null +++ b/src/org/traccar/database/CommandsManager.java @@ -0,0 +1,149 @@ +/* + * 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.database; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; + +import org.traccar.BaseProtocol; +import org.traccar.Context; +import org.traccar.helper.Log; +import org.traccar.model.Command; +import org.traccar.model.Typed; +import org.traccar.model.Position; + +public class CommandsManager extends ExtendedObjectManager<Command> { + + private final Map<Long, Queue<Command>> deviceQueues = new ConcurrentHashMap<>(); + + public CommandsManager(DataManager dataManager) { + super(dataManager, Command.class); + } + + public boolean checkDeviceCommand(long deviceId, long commandId) { + return !getAllDeviceItems(deviceId).contains(commandId); + } + + public boolean sendCommand(Command command) throws Exception { + long deviceId = command.getDeviceId(); + if (command.getId() != 0) { + command = getById(command.getId()).clone(); + command.setDeviceId(deviceId); + } + if (command.getTextChannel()) { + Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); + String phone = Context.getIdentityManager().getById(deviceId).getPhone(); + if (lastPosition != null) { + BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); + protocol.sendTextCommand(phone, command); + } else if (command.getType().equals(Command.TYPE_CUSTOM)) { + if (Context.getSmppManager() != null) { + Context.getSmppManager().sendMessageSync(phone, command.getString(Command.KEY_DATA), true); + } else { + throw new RuntimeException("SMPP client is not enabled"); + } + } else { + throw new RuntimeException("Command " + command.getType() + " is not supported"); + } + } else { + ActiveDevice activeDevice = Context.getConnectionManager().getActiveDevice(deviceId); + if (activeDevice != null) { + activeDevice.sendCommand(command); + } else { + getDeviceQueue(deviceId).add(command); + return false; + } + } + return true; + } + + public Collection<Long> getSupportedCommands(long deviceId) { + List<Long> result = new ArrayList<>(); + Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); + for (long commandId : getAllDeviceItems(deviceId)) { + Command command = getById(commandId); + if (lastPosition != null) { + BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); + if (command.getTextChannel() && protocol.getSupportedTextCommands().contains(command.getType()) + || !command.getTextChannel() + && protocol.getSupportedDataCommands().contains(command.getType())) { + result.add(commandId); + } + } else if (command.getType().equals(Command.TYPE_CUSTOM)) { + result.add(commandId); + } + } + return result; + } + + public Collection<Typed> getCommandTypes(long deviceId, boolean textChannel) { + List<Typed> result = new ArrayList<>(); + Position lastPosition = Context.getIdentityManager().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 Typed(commandKey)); + } + } else { + result.add(new Typed(Command.TYPE_CUSTOM)); + } + return result; + } + + public Collection<Typed> getAllCommandTypes() { + List<Typed> result = new ArrayList<>(); + Field[] fields = Command.class.getDeclaredFields(); + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) { + try { + result.add(new Typed(field.get(null).toString())); + } catch (IllegalArgumentException | IllegalAccessException error) { + Log.warning(error); + } + } + } + return result; + } + + private Queue<Command> getDeviceQueue(long deviceId) { + if (!deviceQueues.containsKey(deviceId)) { + deviceQueues.put(deviceId, new ConcurrentLinkedQueue<Command>()); + } + return deviceQueues.get(deviceId); + } + + public void sendQueuedCommands(ActiveDevice activeDevice) { + Queue<Command> deviceQueue = deviceQueues.get(activeDevice.getDeviceId()); + if (deviceQueue != null) { + Command command = deviceQueue.poll(); + while (command != null) { + activeDevice.sendCommand(command); + command = deviceQueue.poll(); + } + } + } + +} |