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