aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2018-06-09 15:51:11 +1200
committerAnton Tananaev <anton.tananaev@gmail.com>2018-06-09 15:51:11 +1200
commit5cf987a9e9cab3e9ec3d2a8acc335a85f2637df0 (patch)
treee290b09c50900b4700ac244827c337ff0fc3450c /src
parentc40928cd674144fa5ed3dc7306c33b16823b2fad (diff)
downloadtraccar-server-5cf987a9e9cab3e9ec3d2a8acc335a85f2637df0.tar.gz
traccar-server-5cf987a9e9cab3e9ec3d2a8acc335a85f2637df0.tar.bz2
traccar-server-5cf987a9e9cab3e9ec3d2a8acc335a85f2637df0.zip
Fix various issues
Diffstat (limited to 'src')
-rw-r--r--src/org/traccar/ServerManager.java11
-rw-r--r--src/org/traccar/TrackerServer.java6
-rw-r--r--src/org/traccar/helper/BufferUtil.java8
-rw-r--r--src/org/traccar/protocol/At2000ProtocolDecoder.java63
-rw-r--r--src/org/traccar/protocol/BlackKiteProtocol.java2
-rw-r--r--src/org/traccar/protocol/EelinkProtocolEncoder.java2
-rw-r--r--src/org/traccar/protocol/GalileoProtocolEncoder.java2
-rw-r--r--src/org/traccar/protocol/Gps056ProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/HuabaoProtocolEncoder.java2
-rw-r--r--src/org/traccar/protocol/MeiligaoProtocolDecoder.java13
-rw-r--r--src/org/traccar/protocol/NavisProtocolDecoder.java8
-rw-r--r--src/org/traccar/protocol/NoranProtocolDecoder.java4
-rw-r--r--src/org/traccar/protocol/NoranProtocolEncoder.java4
-rw-r--r--src/org/traccar/protocol/SigfoxProtocolDecoder.java25
-rw-r--r--src/org/traccar/protocol/TlvProtocolDecoder.java4
-rw-r--r--src/org/traccar/protocol/TytanProtocolDecoder.java3
16 files changed, 82 insertions, 77 deletions
diff --git a/src/org/traccar/ServerManager.java b/src/org/traccar/ServerManager.java
index 9cd5aed79..a8da6d57e 100644
--- a/src/org/traccar/ServerManager.java
+++ b/src/org/traccar/ServerManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 2018 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,7 +15,6 @@
*/
package org.traccar;
-import io.netty.channel.ChannelException;
import org.traccar.helper.Log;
import java.io.File;
@@ -80,14 +79,12 @@ public class ServerManager {
return protocolList.get(name);
}
- public void start() {
+ public void start() throws Exception {
for (TrackerServer server: serverList) {
try {
server.start();
- } catch (ChannelException e) {
- if (e.getCause() instanceof BindException) {
- Log.warning("One of the protocols is disabled due to port conflict"); // TODO test this
- }
+ } catch (BindException e) {
+ Log.warning("One of the protocols is disabled due to port conflict");
}
}
}
diff --git a/src/org/traccar/TrackerServer.java b/src/org/traccar/TrackerServer.java
index c3d36b04c..490106367 100644
--- a/src/org/traccar/TrackerServer.java
+++ b/src/org/traccar/TrackerServer.java
@@ -25,6 +25,7 @@ import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.concurrent.GlobalEventExecutor;
+import java.io.IOException;
import java.net.InetSocketAddress;
public abstract class TrackerServer {
@@ -94,7 +95,7 @@ public abstract class TrackerServer {
return channelGroup;
}
- public void start() {
+ public void start() throws Exception {
InetSocketAddress endpoint;
if (address == null) {
endpoint = new InetSocketAddress(port);
@@ -102,8 +103,7 @@ public abstract class TrackerServer {
endpoint = new InetSocketAddress(address, port);
}
- Channel channel = bootstrap.bind(endpoint).channel();
-
+ Channel channel = bootstrap.bind(endpoint).sync().channel();
if (channel != null) {
getChannelGroup().add(channel);
}
diff --git a/src/org/traccar/helper/BufferUtil.java b/src/org/traccar/helper/BufferUtil.java
index 81a081182..5606dba8a 100644
--- a/src/org/traccar/helper/BufferUtil.java
+++ b/src/org/traccar/helper/BufferUtil.java
@@ -28,8 +28,12 @@ public final class BufferUtil {
}
public static int indexOf(String needle, ByteBuf haystack) {
- return ByteBufUtil.indexOf(
- Unpooled.wrappedBuffer(needle.getBytes(StandardCharsets.US_ASCII)), haystack);
+ ByteBuf needleBuffer = Unpooled.wrappedBuffer(needle.getBytes(StandardCharsets.US_ASCII));
+ try {
+ return ByteBufUtil.indexOf(needleBuffer, haystack);
+ } finally {
+ needleBuffer.release();
+ }
}
public static int indexOf(String needle, ByteBuf haystack, int startIndex, int endIndex) {
diff --git a/src/org/traccar/protocol/At2000ProtocolDecoder.java b/src/org/traccar/protocol/At2000ProtocolDecoder.java
index 4c2967158..4457854e3 100644
--- a/src/org/traccar/protocol/At2000ProtocolDecoder.java
+++ b/src/org/traccar/protocol/At2000ProtocolDecoder.java
@@ -106,51 +106,54 @@ public class At2000ProtocolDecoder extends BaseProtocolDecoder {
return null; // empty message
}
+ List<Position> positions = new LinkedList<>();
+
byte[] data = new byte[buf.capacity() - BLOCK_LENGTH];
buf.readBytes(data);
buf = Unpooled.wrappedBuffer(cipher.update(data));
+ try {
+ while (buf.readableBytes() >= 63) {
- List<Position> positions = new LinkedList<>();
-
- while (buf.readableBytes() >= 63) {
-
- Position position = new Position(getProtocolName());
- position.setDeviceId(deviceSession.getDeviceId());
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
- buf.readUnsignedShortLE(); // index
- buf.readUnsignedShortLE(); // reserved
+ buf.readUnsignedShortLE(); // index
+ buf.readUnsignedShortLE(); // reserved
- position.setValid(true);
+ position.setValid(true);
- position.setTime(new Date(buf.readLongLE() * 1000));
+ position.setTime(new Date(buf.readLongLE() * 1000));
- position.setLatitude(buf.readFloatLE());
- position.setLongitude(buf.readFloatLE());
- position.setAltitude(buf.readFloatLE());
- position.setSpeed(UnitsConverter.knotsFromKph(buf.readFloatLE()));
- position.setCourse(buf.readFloatLE());
+ position.setLatitude(buf.readFloatLE());
+ position.setLongitude(buf.readFloatLE());
+ position.setAltitude(buf.readFloatLE());
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readFloatLE()));
+ position.setCourse(buf.readFloatLE());
- buf.readUnsignedIntLE(); // geozone event
- buf.readUnsignedIntLE(); // io events
- buf.readUnsignedIntLE(); // geozone value
- buf.readUnsignedIntLE(); // io values
- buf.readUnsignedShortLE(); // operator
+ buf.readUnsignedIntLE(); // geozone event
+ buf.readUnsignedIntLE(); // io events
+ buf.readUnsignedIntLE(); // geozone value
+ buf.readUnsignedIntLE(); // io values
+ buf.readUnsignedShortLE(); // operator
- position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE());
- position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE());
+ position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE());
+ position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE());
- position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.001);
+ position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.001);
- buf.readUnsignedShortLE(); // cid
- position.set(Position.KEY_RSSI, buf.readUnsignedByte());
- buf.readUnsignedByte(); // current profile
+ buf.readUnsignedShortLE(); // cid
+ position.set(Position.KEY_RSSI, buf.readUnsignedByte());
+ buf.readUnsignedByte(); // current profile
- position.set(Position.KEY_BATTERY, buf.readUnsignedByte());
- position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedByte());
- position.set(Position.KEY_SATELLITES, buf.readUnsignedByte());
+ position.set(Position.KEY_BATTERY, buf.readUnsignedByte());
+ position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedByte());
+ position.set(Position.KEY_SATELLITES, buf.readUnsignedByte());
- positions.add(position);
+ positions.add(position);
+ }
+ } finally {
+ buf.release();
}
return positions;
diff --git a/src/org/traccar/protocol/BlackKiteProtocol.java b/src/org/traccar/protocol/BlackKiteProtocol.java
index 3e0b918f8..423562907 100644
--- a/src/org/traccar/protocol/BlackKiteProtocol.java
+++ b/src/org/traccar/protocol/BlackKiteProtocol.java
@@ -33,7 +33,7 @@ public class BlackKiteProtocol extends BaseProtocol {
serverList.add(new TrackerServer(false, getName()) {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
- // pipeline.addLast("frameDecoder", new GalileoFrameDecoder()); TODO uncomment
+ pipeline.addLast("frameDecoder", new GalileoFrameDecoder());
pipeline.addLast("objectDecoder", new BlackKiteProtocolDecoder(BlackKiteProtocol.this));
}
});
diff --git a/src/org/traccar/protocol/EelinkProtocolEncoder.java b/src/org/traccar/protocol/EelinkProtocolEncoder.java
index 33dca54f2..64236ca4a 100644
--- a/src/org/traccar/protocol/EelinkProtocolEncoder.java
+++ b/src/org/traccar/protocol/EelinkProtocolEncoder.java
@@ -47,7 +47,7 @@ public class EelinkProtocolEncoder extends BaseProtocolEncoder {
ByteBuf buf = Unpooled.buffer();
if (connectionless) {
- buf.writeBytes(Unpooled.wrappedBuffer(DataConverter.parseHex('0' + uniqueId)));
+ buf.writeBytes(DataConverter.parseHex('0' + uniqueId));
}
buf.writeByte(0x67);
diff --git a/src/org/traccar/protocol/GalileoProtocolEncoder.java b/src/org/traccar/protocol/GalileoProtocolEncoder.java
index 47fbc3f9c..12463dc7d 100644
--- a/src/org/traccar/protocol/GalileoProtocolEncoder.java
+++ b/src/org/traccar/protocol/GalileoProtocolEncoder.java
@@ -31,7 +31,7 @@ public class GalileoProtocolEncoder extends BaseProtocolEncoder {
ByteBuf buf = Unpooled.buffer(256);
buf.writeByte(0x01);
- buf.writeShortLE(uniqueId.length() + text.length() + 11); // TODO
+ buf.writeShortLE(uniqueId.length() + text.length() + 11);
buf.writeByte(0x03); // imei tag
buf.writeBytes(uniqueId.getBytes(StandardCharsets.US_ASCII));
diff --git a/src/org/traccar/protocol/Gps056ProtocolDecoder.java b/src/org/traccar/protocol/Gps056ProtocolDecoder.java
index bfe9fc68e..00010b542 100644
--- a/src/org/traccar/protocol/Gps056ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Gps056ProtocolDecoder.java
@@ -90,7 +90,7 @@ public class Gps056ProtocolDecoder extends BaseProtocolDecoder {
if (type.startsWith("LOGN")) {
sendResponse(channel, "LGSA" + type.substring(4), imei,
- Unpooled.copiedBuffer("1", StandardCharsets.US_ASCII));
+ Unpooled.copiedBuffer("1", StandardCharsets.US_ASCII)); // TODO ref count
} else if (type.startsWith("GPSL")) {
diff --git a/src/org/traccar/protocol/HuabaoProtocolEncoder.java b/src/org/traccar/protocol/HuabaoProtocolEncoder.java
index b8db1f21a..a622fdb9a 100644
--- a/src/org/traccar/protocol/HuabaoProtocolEncoder.java
+++ b/src/org/traccar/protocol/HuabaoProtocolEncoder.java
@@ -31,7 +31,7 @@ public class HuabaoProtocolEncoder extends BaseProtocolEncoder {
protected Object encodeCommand(Command command) {
ByteBuf id = Unpooled.wrappedBuffer(
- DataConverter.parseHex(getUniqueId(command.getDeviceId())));
+ DataConverter.parseHex(getUniqueId(command.getDeviceId()))); // TODO ref count
ByteBuf data = Unpooled.buffer();
byte[] time = DataConverter.parseHex(new SimpleDateFormat("yyMMddHHmmss").format(new Date()));
diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
index 6813ffcfe..752168233 100644
--- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
+++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
@@ -189,7 +189,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
if (channel != null) {
ByteBuf buf = Unpooled.buffer(
- 2 + 2 + id.readableBytes() + 2 + msg.readableBytes() + 2 + 2);
+ 2 + 2 + id.readableBytes() + 2 + msg.readableBytes() + 2 + 2); // TODO ref count
buf.writeByte('@');
buf.writeByte('@');
@@ -400,29 +400,28 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
buf.readShort(); // length
ByteBuf id = buf.readSlice(7);
int command = buf.readUnsignedShort();
- ByteBuf response;
if (command == MSG_LOGIN) {
- response = Unpooled.wrappedBuffer(new byte[]{0x01});
+ ByteBuf response = Unpooled.wrappedBuffer(new byte[]{0x01});
sendResponse(channel, remoteAddress, id, MSG_LOGIN_RESPONSE, response);
return null;
} else if (command == MSG_HEARTBEAT) {
- response = Unpooled.wrappedBuffer(new byte[]{0x01});
+ ByteBuf response = Unpooled.wrappedBuffer(new byte[]{0x01});
sendResponse(channel, remoteAddress, id, MSG_HEARTBEAT, response);
return null;
} else if (command == MSG_SERVER) {
- response = Unpooled.copiedBuffer(getServer(channel), StandardCharsets.US_ASCII);
+ ByteBuf response = Unpooled.copiedBuffer(getServer(channel), StandardCharsets.US_ASCII);
sendResponse(channel, remoteAddress, id, MSG_SERVER, response);
return null;
} else if (command == MSG_UPLOAD_PHOTO) {
byte imageIndex = buf.readByte();
photos.put(imageIndex, Unpooled.buffer());
- response = Unpooled.copiedBuffer(new byte[]{imageIndex});
+ ByteBuf response = Unpooled.copiedBuffer(new byte[]{imageIndex});
sendResponse(channel, remoteAddress, id, MSG_UPLOAD_PHOTO_RESPONSE, response);
return null;
} else if (command == MSG_UPLOAD_COMPLETE) {
byte imageIndex = buf.readByte();
- response = Unpooled.copiedBuffer(new byte[]{imageIndex, 0, 0});
+ ByteBuf response = Unpooled.copiedBuffer(new byte[]{imageIndex, 0, 0});
sendResponse(channel, remoteAddress, id, MSG_RETRANSMISSION, response);
return null;
}
diff --git a/src/org/traccar/protocol/NavisProtocolDecoder.java b/src/org/traccar/protocol/NavisProtocolDecoder.java
index 37001c35b..dac8f7ba3 100644
--- a/src/org/traccar/protocol/NavisProtocolDecoder.java
+++ b/src/org/traccar/protocol/NavisProtocolDecoder.java
@@ -183,7 +183,7 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
ParseResult result = parsePosition(deviceSession, buf);
ByteBuf response = Unpooled.buffer(8);
- response.writeBytes(Unpooled.copiedBuffer("*<T", StandardCharsets.US_ASCII));
+ response.writeCharSequence("*<T", StandardCharsets.US_ASCII);
response.writeIntLE((int) result.getId());
sendReply(channel, response);
@@ -206,7 +206,7 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
}
ByteBuf response = Unpooled.buffer(8);
- response.writeBytes(Unpooled.copiedBuffer("*<A", StandardCharsets.US_ASCII));
+ response.writeCharSequence("*<A", StandardCharsets.US_ASCII);
response.writeByte(count);
sendReply(channel, response);
@@ -235,7 +235,7 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
private void sendReply(Channel channel, ByteBuf data) {
ByteBuf header = Unpooled.buffer(16);
- header.writeBytes(Unpooled.copiedBuffer(prefix, StandardCharsets.US_ASCII));
+ header.writeCharSequence(prefix, StandardCharsets.US_ASCII);
header.writeIntLE((int) deviceUniqueId);
header.writeIntLE((int) serverId);
header.writeShortLE(data.readableBytes());
@@ -243,7 +243,7 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
header.writeByte(checksum(header));
if (channel != null) {
- channel.writeAndFlush(new NetworkMessage(Unpooled.copiedBuffer(header, data), channel.remoteAddress()));
+ channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(header, data), channel.remoteAddress()));
}
}
diff --git a/src/org/traccar/protocol/NoranProtocolDecoder.java b/src/org/traccar/protocol/NoranProtocolDecoder.java
index 2c5da4a78..65bd64384 100644
--- a/src/org/traccar/protocol/NoranProtocolDecoder.java
+++ b/src/org/traccar/protocol/NoranProtocolDecoder.java
@@ -59,12 +59,12 @@ public class NoranProtocolDecoder extends BaseProtocolDecoder {
if (type == MSG_SHAKE_HAND && channel != null) {
ByteBuf response = Unpooled.buffer(13);
- response.writeBytes(Unpooled.copiedBuffer("\r\n*KW", StandardCharsets.US_ASCII));
+ response.writeCharSequence("\r\n*KW", StandardCharsets.US_ASCII);
response.writeByte(0);
response.writeShortLE(response.capacity());
response.writeShortLE(MSG_SHAKE_HAND_RESPONSE);
response.writeByte(1); // status
- response.writeBytes(Unpooled.copiedBuffer("\r\n", StandardCharsets.US_ASCII));
+ response.writeCharSequence("\r\n", StandardCharsets.US_ASCII);
channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
diff --git a/src/org/traccar/protocol/NoranProtocolEncoder.java b/src/org/traccar/protocol/NoranProtocolEncoder.java
index cb25cc94b..53b0c54ba 100644
--- a/src/org/traccar/protocol/NoranProtocolEncoder.java
+++ b/src/org/traccar/protocol/NoranProtocolEncoder.java
@@ -29,7 +29,7 @@ public class NoranProtocolEncoder extends BaseProtocolEncoder {
ByteBuf buf = Unpooled.buffer(12 + 56);
- buf.writeBytes(Unpooled.copiedBuffer("\r\n*KW", StandardCharsets.US_ASCII));
+ buf.writeCharSequence("\r\n*KW", StandardCharsets.US_ASCII);
buf.writeByte(0);
buf.writeShortLE(buf.capacity());
buf.writeShortLE(NoranProtocolDecoder.MSG_CONTROL);
@@ -37,7 +37,7 @@ public class NoranProtocolEncoder extends BaseProtocolEncoder {
buf.writeShortLE(0); // gis port
buf.writeBytes(content.getBytes(StandardCharsets.US_ASCII));
buf.writerIndex(buf.writerIndex() + 50 - content.length());
- buf.writeBytes(Unpooled.copiedBuffer("\r\n", StandardCharsets.US_ASCII));
+ buf.writeCharSequence("\r\n", StandardCharsets.US_ASCII);
return buf;
}
diff --git a/src/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/org/traccar/protocol/SigfoxProtocolDecoder.java
index 5b0855cc3..f18eb015b 100644
--- a/src/org/traccar/protocol/SigfoxProtocolDecoder.java
+++ b/src/org/traccar/protocol/SigfoxProtocolDecoder.java
@@ -60,22 +60,25 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder {
position.setTime(new Date(json.getInt("time") * 1000L));
ByteBuf buf = Unpooled.wrappedBuffer(DataConverter.parseHex(json.getString("data")));
+ try {
+ int type = buf.readUnsignedByte() >> 4;
+ if (type == 0) {
- int type = buf.readUnsignedByte() >> 4;
- if (type == 0) {
+ position.setValid(true);
+ position.setLatitude(buf.readIntLE() * 0.0000001);
+ position.setLongitude(buf.readIntLE() * 0.0000001);
+ position.setCourse(buf.readUnsignedByte() * 2);
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte()));
- position.setValid(true);
- position.setLatitude(buf.readIntLE() * 0.0000001);
- position.setLongitude(buf.readIntLE() * 0.0000001);
- position.setCourse(buf.readUnsignedByte() * 2);
- position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte()));
+ position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.025);
- position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.025);
+ } else {
- } else {
-
- getLastLocation(position, position.getDeviceTime());
+ getLastLocation(position, position.getDeviceTime());
+ }
+ } finally {
+ buf.release();
}
position.set(Position.KEY_RSSI, json.getJsonNumber("rssi").doubleValue());
diff --git a/src/org/traccar/protocol/TlvProtocolDecoder.java b/src/org/traccar/protocol/TlvProtocolDecoder.java
index b682345db..d3ce4e072 100644
--- a/src/org/traccar/protocol/TlvProtocolDecoder.java
+++ b/src/org/traccar/protocol/TlvProtocolDecoder.java
@@ -37,10 +37,10 @@ public class TlvProtocolDecoder extends BaseProtocolDecoder {
private void sendResponse(Channel channel, SocketAddress remoteAddress, String type, String... arguments) {
if (channel != null) {
ByteBuf response = Unpooled.buffer();
- response.writeBytes(Unpooled.copiedBuffer(type, StandardCharsets.US_ASCII));
+ response.writeCharSequence(type, StandardCharsets.US_ASCII);
for (String argument : arguments) {
response.writeByte(argument.length());
- response.writeBytes(Unpooled.copiedBuffer(argument, StandardCharsets.US_ASCII));
+ response.writeCharSequence(argument, StandardCharsets.US_ASCII);
}
response.writeByte(0);
channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
diff --git a/src/org/traccar/protocol/TytanProtocolDecoder.java b/src/org/traccar/protocol/TytanProtocolDecoder.java
index ac94e5ca7..6788fd7b9 100644
--- a/src/org/traccar/protocol/TytanProtocolDecoder.java
+++ b/src/org/traccar/protocol/TytanProtocolDecoder.java
@@ -133,8 +133,7 @@ public class TytanProtocolDecoder extends BaseProtocolDecoder {
int index = buf.readUnsignedByte() >> 3;
if (channel != null) {
- ByteBuf response = Unpooled.copiedBuffer(
- "^" + index, StandardCharsets.US_ASCII);
+ ByteBuf response = Unpooled.copiedBuffer("^" + index, StandardCharsets.US_ASCII);
channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
}