From dbeb3dd2e88d28da73ebc1f6843355fb51e5603f Mon Sep 17 00:00:00 2001
From: whycq <913841844@qq.com>
Date: 星期五, 16 八月 2024 08:50:00 +0800
Subject: [PATCH] #
---
.idea/deploymentTargetSelector.xml | 8 +
app/src/main/java/com/example/agvcontroller/StartActivity.java | 2
app/src/main/res/layout/activity_main.xml | 96 ++++++++++++++++++
app/src/main/java/com/example/agvcontroller/socket/NettyServer.java | 2
app/src/main/java/com/example/agvcontroller/protocol/ProtocolDecoder.java | 158 +++++++++++++++++++++++++++++++
5 files changed, 263 insertions(+), 3 deletions(-)
diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
index b268ef3..32ed794 100644
--- a/.idea/deploymentTargetSelector.xml
+++ b/.idea/deploymentTargetSelector.xml
@@ -4,6 +4,14 @@
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
+ <DropdownSelection timestamp="2024-08-15T08:33:10.282255800Z">
+ <Target type="DEFAULT_BOOT">
+ <handle>
+ <DeviceId pluginId="PhysicalDevice" identifier="serial=2MM0223916052360" />
+ </handle>
+ </Target>
+ </DropdownSelection>
+ <DialogSelection />
</SelectionState>
</selectionStates>
</component>
diff --git a/app/src/main/java/com/example/agvcontroller/StartActivity.java b/app/src/main/java/com/example/agvcontroller/StartActivity.java
index adb74d2..f38311e 100644
--- a/app/src/main/java/com/example/agvcontroller/StartActivity.java
+++ b/app/src/main/java/com/example/agvcontroller/StartActivity.java
@@ -52,7 +52,7 @@
}
});
socketManager = new SocketManager();
- socketManager.startServer(8022);
+ socketManager.startServer(8080);
}
@Subscribe(threadMode = ThreadMode.MAIN)
diff --git a/app/src/main/java/com/example/agvcontroller/protocol/ProtocolDecoder.java b/app/src/main/java/com/example/agvcontroller/protocol/ProtocolDecoder.java
new file mode 100644
index 0000000..b710520
--- /dev/null
+++ b/app/src/main/java/com/example/agvcontroller/protocol/ProtocolDecoder.java
@@ -0,0 +1,158 @@
+package com.example.agvcontroller.protocol;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.ByteToMessageDecoder;
+import io.netty.util.ReferenceCountUtil;
+import com.example.agvcontroller.socket.RadixTools;
+
+import java.net.InetSocketAddress;
+import java.util.List;
+
+/**
+ * Created by vincent on 2019-04-10
+ */
+public class ProtocolDecoder extends ByteToMessageDecoder {
+
+ private final int maxFrameLength;
+
+ public ProtocolDecoder(int maxFrameLength){
+ this.maxFrameLength = maxFrameLength;
+ }
+
+ @Override
+ protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+ String ip = ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostAddress();
+// log.info("ip:{} ===>> {}", ip, ByteBufUtil.hexDump(in).toUpperCase());
+
+ int startMark = indexOfStartMark(in);
+ if (startMark == -1){
+ in.skipBytes(in.readableBytes());
+ return;
+ }
+ if (in.readableBytes() > maxFrameLength) {
+ in.skipBytes(in.readableBytes());
+ return;
+ }
+ // 鍘婚櫎鏃犵敤鍓嶇紑鎶ユ枃
+ if (startMark != 0){
+ in.readerIndex(startMark);
+ in.discardReadBytes();
+ }
+ // 绮樺寘澶勭悊
+ in.markReaderIndex();
+ in.readerIndex(PackagePart.CONTENT_LENGTH.getStartIndex());
+ int pacTotalLen = PackagePart.START_SYMBOL.getLen()
+ + PackagePart.CONTENT_LENGTH.getLen()
+ + in.readShortLE()
+ + PackagePart.VALIDE_CODE.getLen()
+ ;
+ in.resetReaderIndex();
+ ByteBuf byteBuf = in.readSlice(pacTotalLen);
+
+ // 鐢熸垚鍜屽垵濮嬪寲娑堟伅鍖呰绫�
+ AgvPackage pac = AgvPackage.valueOfEmpty();
+ pac.setSourceBuff(byteBuf);
+ // 瑙f瀽
+ out.add(analyzeProtocol(pac));
+
+ // byteBuf.resetReaderIndex(); // tip: 濡傛灉 ridx == widx锛屽垯 refCnt = 0
+ in.resetReaderIndex();
+ in.skipBytes(pacTotalLen); // tip: This method will be called till either the input has nothing to read锛屾棤璇紒
+
+ ReferenceCountUtil.retain(in); // 瑙g爜鍣ㄨ嚜鍔ㄩ噴鏀� refCnt - 1
+
+ }
+
+ public AgvPackage analyzeProtocol(AgvPackage pac){
+ ByteBuf byteBuf = pac.getSourceBuff();
+ PacHeader pacHeader = pac.getHeader();
+ // 鍞竴鏍囪瘑鐮�
+ byteBuf.readerIndex(PackagePart.UNIQUENO.getStartIndex());
+ byte[] bytes = new byte[PackagePart.UNIQUENO.getLen()];
+ byteBuf.readBytes(bytes);
+ Utils.reverse(bytes);
+ String uniqueno = String.valueOf(RadixTools.bytesToInt(bytes));
+ if (!Cools.isEmpty(uniqueno)) {
+ pacHeader.setUniqueNo(uniqueno);
+ byteBuf.resetReaderIndex();
+ } else {
+ return pac.setErrorPac(Boolean.TRUE).setPacErrorType(PacErrorType.PAC_ANALYZE_ERROR);
+ }
+ // 鑾峰彇鏍囪瘑绗�
+ byte startSymbol = byteBuf.readByte();
+ DirectionType direction = null;
+ if ((0xEE&0xFF) == (startSymbol&0xFF)) {
+ pacHeader.setStartSymbol(startSymbol);
+ direction = DirectionType.DOWN;
+ } else if ((0xAA&0xFF) == (startSymbol&0xFF)) {
+ pacHeader.setStartSymbol(startSymbol);
+ direction = DirectionType.UP;
+ } else {
+ return pac.setErrorPac(Boolean.TRUE).setPacErrorType(PacErrorType.PAC_ANALYZE_ERROR);
+ }
+ // 鑾峰彇鍗忚浣撻暱搴�
+ int contentLength = byteBuf.readShortLE();
+ if (contentLength >= 0) {
+ pacHeader.setContentLength(contentLength);
+ } else {
+ return pac.setErrorPac(Boolean.TRUE).setPacErrorType(PacErrorType.PAC_ANALYZE_ERROR);
+ }
+ // skip uniqueNo
+ byteBuf.readerIndex(byteBuf.readerIndex() + PackagePart.UNIQUENO.getLen());
+ // 鑾峰彇鏃堕棿鎴�
+ byteBuf.readerIndex(PackagePart.TIMESTAMP.getStartIndex());
+ int timestamp = byteBuf.readIntLE();
+ if (timestamp > 0) {
+ pacHeader.setTimestamp(timestamp);
+ } else {
+ return pac.setErrorPac(Boolean.TRUE).setPacErrorType(PacErrorType.PAC_ANALYZE_ERROR);
+ }
+ // 鑾峰彇鍛戒护鏍囪瘑
+ int commandByte = byteBuf.readByte() & 0xFF;
+ ProtocolType protocolType = ProtocolType.getByCode(commandByte, direction);
+ if (null != protocolType) {
+ pacHeader.setProtocolType(protocolType);
+ } else {
+ return pac.setErrorPac(Boolean.TRUE).setPacErrorType(PacErrorType.PAC_ANALYZE_ERROR);
+ }
+ // 鑾峰彇鍗忚浣�
+ if (contentLength > 0) {
+ ByteBuf body = byteBuf.readSlice(pac.getHeader().getContentLength() - (
+ + PackagePart.UNIQUENO.getLen()
+ + PackagePart.TIMESTAMP.getLen()
+ + PackagePart.COMMAND_MARK.getLen()
+ ));
+ if (null != body && body.readableBytes() >= 0) {
+ pac.getBody().setContent(body);
+ } else {
+ return pac.setErrorPac(Boolean.TRUE).setPacErrorType(PacErrorType.PAC_ANALYZE_ERROR);
+ }
+ }
+ // 鏍¢獙鐮�
+ if(byteBuf.readableBytes() == 2) {
+ pac.setValidCode(byteBuf.readUnsignedShortLE());
+ } else {
+ return pac.setErrorPac(Boolean.TRUE).setPacErrorType(PacErrorType.PAC_ANALYZE_ERROR);
+ }
+ return pac;
+ }
+
+ // 鑾峰彇鏍囪瘑浣嶄笅鏍�
+ private int indexOfStartMark(ByteBuf inputBuffer){
+ int length = inputBuffer.writerIndex();
+ // 鎶ユ枃闀垮害鑷冲皯澶т簬2
+ if (length < 2) {
+ return -1;
+ }
+ int readerIndex = inputBuffer.readerIndex();
+ for(int i = readerIndex; i < length - 1; i ++) {
+ byte b1 = inputBuffer.getByte(i);
+ if ((0xEE&0xFF) == (b1&0xFF) || (0xAA&0xFF) == (b1&0xFF)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+}
diff --git a/app/src/main/java/com/example/agvcontroller/socket/NettyServer.java b/app/src/main/java/com/example/agvcontroller/socket/NettyServer.java
index 06bd508..1f91141 100644
--- a/app/src/main/java/com/example/agvcontroller/socket/NettyServer.java
+++ b/app/src/main/java/com/example/agvcontroller/socket/NettyServer.java
@@ -1,5 +1,6 @@
package com.example.agvcontroller.socket;
+import com.example.agvcontroller.protocol.ProtocolDecoder;
import com.example.agvcontroller.protocol.ProtocolEncoder;
import io.netty.bootstrap.ServerBootstrap;
@@ -37,6 +38,7 @@
ch.pipeline().addLast(new NettyServerHandler()).addLast(new ProtocolEncoder());
}
})
+// .addLast(new NettyServerHandler())
// .childHandler(new ChannelInitializer<Channel>(){
//
// @Override
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 94f6cd6..b74cc54 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -99,10 +99,10 @@
android:backgroundTint="#2196F3" />
<com.google.android.material.button.MaterialButton
- android:id="@+id/btn_force_switch"
+ android:id="@+id/btn_extend_fork"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="鎵嬪姩"
+ android:text="浼稿弶"
android:layout_marginLeft="20sp"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
@@ -112,6 +112,22 @@
android:minWidth="10dp"
android:layout_alignLeft="@+id/btn_rotatopn_left"
android:layout_alignBottom="@+id/btn_go_forward"
+ android:backgroundTint="#2196F3" />
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/btn_collect_fork"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="鏀跺弶"
+ android:layout_marginLeft="20sp"
+ android:layout_centerVertical="true"
+ android:layout_alignParentLeft="true"
+ app:cornerRadius="5dp"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp"
+ android:minWidth="10dp"
+ android:layout_alignLeft="@+id/btn_rotatopn_left"
+ android:layout_alignBottom="@+id/btn_go_backward"
android:backgroundTint="#2196F3" />
</RelativeLayout>
@@ -127,6 +143,82 @@
android:layout_height="0dp"
android:layout_weight="1">
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:gravity="center">
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/btn_model_switch"
+ android:layout_width="wrap_content"
+ android:layout_height="40dp"
+ android:text="鎵嬪姩妯″紡"
+ android:layout_centerHorizontal="true"
+ app:cornerRadius="5dp"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp"
+ android:minWidth="10dp"
+ android:textSize="10sp"
+ android:backgroundTint="#2196F3" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:gravity="center">
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/btn_force_switch"
+ android:layout_width="wrap_content"
+ android:layout_height="40dp"
+ android:text="寮�鍚己鍒�"
+ android:layout_centerHorizontal="true"
+ app:cornerRadius="5dp"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp"
+ android:minWidth="10dp"
+ android:textSize="10sp"
+ android:backgroundTint="#2196F3" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:gravity="center">
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/btn_single_switch"
+ android:layout_width="wrap_content"
+ android:layout_height="40dp"
+ android:text="鍗曡酱浣胯兘"
+ android:layout_centerHorizontal="true"
+ app:cornerRadius="5dp"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp"
+ android:minWidth="10dp"
+ android:textSize="10sp"
+ android:backgroundTint="#2196F3" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:gravity="center">
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/btn_function_switch"
+ android:layout_width="wrap_content"
+ android:layout_height="40dp"
+ android:text="鍔熻兘鍒囨崲"
+ android:layout_centerHorizontal="true"
+ app:cornerRadius="5dp"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp"
+ android:minWidth="10dp"
+ android:textSize="10sp"
+ android:backgroundTint="#2196F3" />
+ </LinearLayout>
+
</LinearLayout>
--
Gitblit v1.9.1