Browse Source

适配SO库的16K对齐

bjb 2 weeks ago
parent
commit
d9534da3d7

+ 105 - 79
app/src/main/java/com/iscs/comm/CtrlActivity.kt

@@ -35,6 +35,7 @@ import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.graphics.Color
@@ -94,66 +95,74 @@ class CtrlActivity : ComponentActivity() {
     @Composable
     fun CtrlKeySlot(dev: DeviceKeySlot) {
         val status = dev.deviceStatus as DeviceStatusKeySlot
-        LazyVerticalGrid(
-            columns = GridCells.Adaptive(minSize = 180.dp),
-            contentPadding = PaddingValues(10.dp, 10.dp),
-            horizontalArrangement = Arrangement.spacedBy(8.dp),
-            verticalArrangement = Arrangement.spacedBy(8.dp),
-        ) {
-            items(ArrayList(status.slotList.sortedBy { it.ch })) { state ->
-                val isLock = remember { mutableStateOf(state.isSlotLock) }
-                val isUsed = remember { mutableStateOf(state.isUsed) }
-                val listener = object : IDeviceListener() {
-                    override fun onDeviceChanged(device: Device) {
-                        super.onDeviceChanged(device)
-                        if (dev.frame.cmd == device.frame.cmd) {
-                            (device.deviceStatus as DeviceStatusKeySlot).slotList.find { it.ch == state.ch }?.let {
-                                Log.d("xiaoming", "$it")
-                                isLock.value = it.isSlotLock
-                                isUsed.value = it.isUsed
+        Column {
+            Row(modifier = Modifier.padding(horizontal = 10.dp)) {
+                Button({ dev.ctrlSlotLockAndCharge(-1, false, false).writeByFrame() }) { Text("全开") }
+                Spacer(modifier = Modifier.width(10.dp))
+                Button({ dev.ctrlSlotLockAndCharge(-1, true, true).writeByFrame() }) { Text("全关") }
+            }
+            LazyVerticalGrid(
+                columns = GridCells.Adaptive(minSize = 180.dp),
+                contentPadding = PaddingValues(10.dp, 10.dp),
+                horizontalArrangement = Arrangement.spacedBy(8.dp),
+                verticalArrangement = Arrangement.spacedBy(8.dp),
+            ) {
+                items(ArrayList(status.slotList.sortedBy { it.ch })) { state ->
+                    val rfid = remember { mutableStateOf(state.rfid) }
+                    val isLock = remember { mutableStateOf(state.isSlotLock) }
+                    val isUsed = remember { mutableStateOf(state.isUsed) }
+                    val listener = object : IDeviceListener() {
+                        override fun onDeviceChanged(device: Device) {
+                            super.onDeviceChanged(device)
+                            if (dev.frame.cmd == device.frame.cmd) {
+                                (device.deviceStatus as DeviceStatusKeySlot).slotList.find { it.ch == state.ch && it.isChanged }?.let {
+                                    isLock.value = it.isSlotLock
+                                    isUsed.value = it.isUsed
+                                    rfid.value = it.rfid
+                                }
                             }
                         }
                     }
-                }
-                LaunchedEffect("") {
-                    CommManager.addOnDeviceListener(listener)
-                }
+                    LaunchedEffect("") {
+                        CommManager.addOnDeviceListener(listener)
+                    }
 
-                DisposableEffect("") {
-                    onDispose { CommManager.removeOnDeviceListener(listener) }
-                }
-                Card {
-                    Column(
-                        modifier = Modifier
-                            .padding(10.dp)
-                            .aspectRatio(1.3f)
-                            .fillMaxWidth(),
-                    ) {
-                        Row {
-                            Text("${state.ch}路")
-                            Spacer(modifier = Modifier.weight(1f))
-                            Spacer(
-                                modifier = Modifier
-                                    .size(12.dp)
-                                    .clip(RoundedCornerShape(12.dp))
-                                    .background(if (isUsed.value) (if (isLock.value) Color.Red else Color.Blue) else Color.Green)
-                            )
-                        }
-                        Spacer(modifier = Modifier.weight(1f))
-                        Row {
-                            Button({ dev.ctrlSlotLock(state.ch, false).writeByFrame() }) { Text("打开锁") }
-                            Spacer(modifier = Modifier.weight(1f))
-                            Button({ dev.ctrlSlotLock(state.ch, true).writeByFrame() }) { Text("关闭锁") }
-                        }
-                        Row {
-                            Button({ dev.ctrlSlotCharge(state.ch, true).writeByFrame() }) { Text("开充电") }
+                    DisposableEffect("") {
+                        onDispose { CommManager.removeOnDeviceListener(listener) }
+                    }
+                    Card {
+                        Column(
+                            modifier = Modifier
+                                .padding(10.dp)
+                                .aspectRatio(1.3f)
+                                .fillMaxWidth(),
+                        ) {
+                            Row {
+                                Text("${state.ch}路 ${rfid.value}")
+                                Spacer(modifier = Modifier.weight(1f))
+                                Spacer(
+                                    modifier = Modifier
+                                        .size(12.dp)
+                                        .clip(RoundedCornerShape(12.dp))
+                                        .background(if (isUsed.value) (if (isLock.value) Color.Red else Color.Blue) else Color.Green)
+                                )
+                            }
                             Spacer(modifier = Modifier.weight(1f))
-                            Button({ dev.ctrlSlotCharge(state.ch, false).writeByFrame() }) { Text("关充电") }
+                            Row {
+                                Button({ dev.ctrlSlotLock(state.ch, false).writeByFrame() }) { Text("打开锁") }
+                                Spacer(modifier = Modifier.weight(1f))
+                                Button({ dev.ctrlSlotLock(state.ch, true).writeByFrame() }) { Text("关闭锁") }
+                            }
+                            Row {
+                                Button({ dev.ctrlSlotCharge(state.ch, true).writeByFrame() }) { Text("开充电") }
+                                Spacer(modifier = Modifier.weight(1f))
+                                Button({ dev.ctrlSlotCharge(state.ch, false).writeByFrame() }) { Text("关充电") }
+                            }
                         }
                     }
                 }
-            }
 
+            }
         }
     }
 
@@ -176,16 +185,26 @@ class CtrlActivity : ComponentActivity() {
                 verticalArrangement = Arrangement.spacedBy(8.dp),
             ) {
                 items(status) { state ->
+                    var lastRFID = state.rfid
+                    val rfid = remember { mutableStateOf(state.rfid) }
                     val isLock = remember { mutableStateOf(state.isSlotLock) }
                     val isUsed = remember { mutableStateOf(state.isUsed) }
                     val listener = object : IDeviceListener() {
                         override fun onDeviceChanged(device: Device) {
                             super.onDeviceChanged(device)
                             if (dev.frame.cmd == device.frame.cmd) {
-                                (device.deviceStatus as DeviceStatusLockSlot).slotList.find { it.ch == state.ch }?.let {
-                                    Log.d("xiaoming", "$it")
+                                (device.deviceStatus as DeviceStatusLockSlot).slotList.find { it.ch == state.ch && it.isChanged }?.let {
                                     isLock.value = it.isSlotLock
                                     isUsed.value = it.isUsed
+                                    rfid.value = it.rfid
+                                    Log.d("xiaoming", "${state.ch} ${it.isChanged} ${rfid.value} ${lastRFID}")
+                                    // 这里可以做一些其他逻辑,比如如果当前有锁存在,但是没上锁,这里可执行上锁操作
+                                    if (it.isChanged && rfid.value.isNotEmpty() && rfid.value != lastRFID) {
+                                        lastRFID = rfid.value
+                                        dev.ctrlSlotLock(state.ch, true).writeByFrame()
+                                    } else if (rfid.value.isEmpty()) {
+                                        lastRFID = ""
+                                    }
                                 }
                             }
                         }
@@ -198,34 +217,41 @@ class CtrlActivity : ComponentActivity() {
                         onDispose { CommManager.removeOnDeviceListener(listener) }
                     }
                     Card {
-                        Column(
-                            modifier = Modifier
-                                .padding(10.dp)
-                                .aspectRatio(1.2f)
-                                .fillMaxWidth(),
-                        ) {
-                            Row {
-                                Text("${state.ch}路")
-                                Spacer(modifier = Modifier.weight(1f))
-                                Spacer(
-                                    modifier = Modifier
-                                        .size(12.dp)
-                                        .clip(RoundedCornerShape(12.dp))
-                                        .background(if (isUsed.value) (if (isLock.value) Color.Red else Color.Blue) else Color.Green)
-                                )
-                            }
-                            Spacer(modifier = Modifier.weight(1f))
-                            Row {
+                        Box {
+                            Column(
+                                modifier = Modifier
+                                    .padding(10.dp)
+                                    .aspectRatio(1.2f)
+                                    .fillMaxWidth(),
+                            ) {
+                                Row {
+                                    Text("${state.ch}路")
+                                    Spacer(modifier = Modifier.weight(1f))
+                                    Spacer(
+                                        modifier = Modifier
+                                            .size(12.dp)
+                                            .clip(RoundedCornerShape(12.dp))
+                                            .background(if (isUsed.value) (if (isLock.value) Color.Red else Color.Blue) else Color.Green)
+                                    )
+                                }
                                 Spacer(modifier = Modifier.weight(1f))
-                                Switch(
-                                    isLock.value, { value ->
-                                        isLock.value = value
-                                        dev.ctrlSlotLock(state.ch, value).writeByFrame()
-                                    }, modifier = Modifier
-                                        .graphicsLayer(scaleX = 0.5f, 0.5f)
-                                        .offset(30.dp, 30.dp)
-                                )
+                                Row {
+                                    Spacer(modifier = Modifier.weight(1f))
+                                    Switch(
+                                        isLock.value, { value ->
+                                            isLock.value = value
+                                            dev.ctrlSlotLock(state.ch, value).writeByFrame()
+                                        }, modifier = Modifier
+                                            .graphicsLayer(scaleX = 0.5f, 0.5f)
+                                            .offset(30.dp, 30.dp)
+                                    )
+                                }
                             }
+                            Text(
+                                rfid.value, modifier = Modifier
+                                    .padding(start = 10.dp)
+                                    .align(Alignment.CenterStart)
+                            )
                         }
                     }
                 }

+ 2 - 0
transport/build.gradle.kts

@@ -5,6 +5,8 @@ plugins {
 
 android {
     namespace = "com.iscs.comm"
+    // 指定ndk版本,编译SO库16K对齐
+    ndkVersion = "28.1.13356709"
     compileSdk {
         version = release(36)
     }

+ 3 - 0
transport/src/main/cpp/CMakeLists.txt

@@ -5,6 +5,9 @@
 # Sets the minimum CMake version required for this project.
 cmake_minimum_required(VERSION 3.22.1)
 
+# 设置C/C++编译支持64k对齐
+# set(CMAKE_ANDROID_PAGE_SIZE 65536)
+
 # Declares the project name. The project name can be accessed via ${ PROJECT_NAME},
 # Since this is the top level CMakeLists.txt, the project name is also accessible
 # with ${CMAKE_PROJECT_NAME} (both CMake variables are in-sync within the top level

+ 5 - 0
transport/src/main/java/com/iscs/comm/CommManager.kt

@@ -136,6 +136,11 @@ object CommManager {
             // 读取设备属性状态
             val sFrame = writeWithResponse(it.ctrlCheckDeviceStatus())
             it.updateDeviceStatus(sFrame)
+            // 查询底座带读取RFID功能的设备读取REID
+            it.ctrlReadSlotRFID().forEach { frame ->
+                val rFrame = writeWithResponse(frame)
+                it.updateSlotRFID(rFrame)
+            }
             // 设备状态发生变化通知外部
             if (it.isDeviceStatusChanged() && !isInit) deviceChangeListeners.forEach { lis -> lis.onDeviceChanged(it) }
             // 限制轮询的速度

+ 14 - 5
transport/src/main/java/com/iscs/comm/entity/device/Device.kt

@@ -27,11 +27,6 @@ abstract class Device(val frame: Frame) {
      */
     protected var id: Int = -1
 
-    /**
-     * 上一次设备状态
-     */
-    protected var lastDeviceStatus = ""
-
     // 数据初始化操作
     init {
         id = frame.cmd
@@ -51,6 +46,11 @@ abstract class Device(val frame: Frame) {
      */
     abstract fun ctrlCheckDeviceStatus(): Frame
 
+    /**
+     * 构建读取当前底座上设备RFID
+     */
+    abstract fun ctrlReadSlotRFID(): List<Frame>
+
     /**
      * 更新设备信息
      *
@@ -65,6 +65,15 @@ abstract class Device(val frame: Frame) {
      */
     abstract fun updateDeviceStatus(frame: Frame)
 
+    /**
+     * 更新底座读取到的RFID
+     *
+     * @param frame
+     */
+    open fun updateSlotRFID(frame: Frame) {
+
+    }
+
     /**
      * 设备状态是否发生变化
      */

+ 30 - 5
transport/src/main/java/com/iscs/comm/entity/device/DeviceKeySlot.kt

@@ -6,6 +6,9 @@ import com.iscs.comm.entity.device.status.DeviceStatusKeySlot
 import com.iscs.comm.enums.DeviceType
 import com.iscs.comm.extension.buildCheckDeviceCtrlStatus
 import com.iscs.comm.extension.buildCtrlKeySlotLockAndCharge
+import com.iscs.comm.extension.buildReadSlotRFID
+import com.iscs.comm.protocol.CanProtocol.CAN_KEY_RFID_LEFT
+import com.iscs.comm.protocol.CanProtocol.CAN_KEY_RFID_RIGHT
 
 /**
  * 钥匙底座类型的设备
@@ -29,6 +32,16 @@ class DeviceKeySlot(frame: Frame) : Device(frame) {
         return frame.newFrame().apply { cmd = frame.cmd }.buildCheckDeviceCtrlStatus()
     }
 
+    /**
+     * 构建控制读取底座RFID信息的接口
+     */
+    override fun ctrlReadSlotRFID(): List<Frame> {
+        val frames = ArrayList<Frame>()
+        frames.add(frame.newFrame().apply { cmd = frame.cmd }.buildReadSlotRFID(CAN_KEY_RFID_LEFT, 0x00))
+        frames.add(frame.newFrame().apply { cmd = frame.cmd }.buildReadSlotRFID(CAN_KEY_RFID_RIGHT, 0x00))
+        return frames
+    }
+
     /**
      * 更新设备模型操作
      *
@@ -45,16 +58,28 @@ class DeviceKeySlot(frame: Frame) : Device(frame) {
         deviceStatus.updateStatus(frame)
     }
 
+    /**
+     * 更新设备RFID
+     */
+    override fun updateSlotRFID(frame: Frame) {
+        deviceStatus.updateRFID(frame)
+    }
+
     /**
      * 校验设备状态是否发生变化
      */
     override fun isDeviceStatusChanged(): Boolean {
-        val currentDeviceStatus = (deviceStatus as DeviceStatusKeySlot).slotList.toString()
-        if (lastDeviceStatus != currentDeviceStatus) {
-            lastDeviceStatus = currentDeviceStatus
-            return true
+        var isChanged = false
+        (deviceStatus as DeviceStatusKeySlot).slotList.forEach { state ->
+            if (state.lastStatus != state.toString()) {
+                state.isChanged = true
+                state.lastStatus = state.toString()
+                if (!isChanged) isChanged = true
+            } else {
+                state.isChanged = false
+            }
         }
-        return false
+        return isChanged
     }
 
     /**

+ 28 - 5
transport/src/main/java/com/iscs/comm/entity/device/DeviceLockSlot.kt

@@ -1,11 +1,14 @@
 package com.iscs.comm.entity.device
 
+import android.util.Log
 import com.iscs.comm.entity.Frame
 import com.iscs.comm.entity.device.status.DeviceStatus
 import com.iscs.comm.entity.device.status.DeviceStatusLockSlot
 import com.iscs.comm.enums.DeviceType
 import com.iscs.comm.extension.buildCheckDeviceCtrlStatus
 import com.iscs.comm.extension.buildCtrlSlotLock
+import com.iscs.comm.extension.buildReadSlotRFID
+import com.iscs.comm.protocol.CanProtocol.CAN_LOCK_RFID
 
 /**
  * 锁底座设备类型
@@ -27,6 +30,17 @@ class DeviceLockSlot(frame: Frame) : Device(frame) {
         return frame.newFrame().apply { cmd = frame.cmd }.buildCheckDeviceCtrlStatus()
     }
 
+    /**
+     * 构建控制读取底座RFID信息的接口
+     */
+    override fun ctrlReadSlotRFID(): List<Frame> {
+        val frames = ArrayList<Frame>()
+        for (i in 0..4) {
+            frames.add(frame.newFrame().apply { cmd = frame.cmd }.buildReadSlotRFID(CAN_LOCK_RFID, i))
+        }
+        return frames
+    }
+
     /**
      * 更新锁底座设备状态
      */
@@ -38,16 +52,25 @@ class DeviceLockSlot(frame: Frame) : Device(frame) {
         deviceStatus.updateStatus(frame)
     }
 
+    override fun updateSlotRFID(frame: Frame) {
+        deviceStatus.updateRFID(frame)
+    }
+
     /**
      * 校验设备状态是否发生变化
      */
     override fun isDeviceStatusChanged(): Boolean {
-        val currentDeviceStatus = (deviceStatus as DeviceStatusLockSlot).slotList.toString()
-        if (lastDeviceStatus != currentDeviceStatus) {
-            lastDeviceStatus = currentDeviceStatus
-            return true
+        var isChanged = false
+        (deviceStatus as DeviceStatusLockSlot).slotList.forEach { state ->
+            if (state.lastStatus != state.toString()) {
+                state.isChanged = true
+                state.lastStatus = state.toString()
+                if (!isChanged) isChanged = true
+            } else {
+                state.isChanged = false
+            }
         }
-        return false
+        return isChanged
     }
 
     /**

+ 4 - 0
transport/src/main/java/com/iscs/comm/entity/device/DeviceNone.kt

@@ -24,4 +24,8 @@ class DeviceNone(frame: Frame) : Device(frame) {
         return frame.newFrame().apply { cmd = frame.cmd }.buildCheckDeviceCtrlStatus()
     }
 
+    override fun ctrlReadSlotRFID(): List<Frame> {
+        return emptyList()
+    }
+
 }

+ 4 - 2
transport/src/main/java/com/iscs/comm/entity/device/DeviceSupplyCabinet.kt

@@ -3,8 +3,6 @@ package com.iscs.comm.entity.device
 import com.iscs.comm.entity.Frame
 import com.iscs.comm.enums.DeviceType
 import com.iscs.comm.extension.buildCheckDeviceCtrlStatus
-import com.iscs.comm.extension.toHexString
-import com.iscs.comm.utils.ISCSLog
 
 /**
  * 物资柜主板
@@ -18,6 +16,10 @@ class DeviceSupplyCabinet(frame: Frame) : Device(frame) {
         return frame.newFrame().apply { cmd = frame.cmd }.buildCheckDeviceCtrlStatus()
     }
 
+    override fun ctrlReadSlotRFID(): List<Frame> {
+        return emptyList()
+    }
+
     override fun updateDeviceInfo(frame: Frame) {
         // ISCSLog.i("xiaoming", "更新设备信息:${frame.data.toHexString()}")
     }

+ 7 - 0
transport/src/main/java/com/iscs/comm/entity/device/status/DeviceStatus.kt

@@ -13,4 +13,11 @@ abstract class DeviceStatus() {
      * 更新设备状态
      */
     abstract fun updateStatus(frame: Frame)
+
+    /**
+     * 更新RFID
+     */
+    open fun updateRFID(frame: Frame) {
+
+    }
 }

+ 13 - 0
transport/src/main/java/com/iscs/comm/entity/device/status/DeviceStatusKeySlot.kt

@@ -2,6 +2,8 @@ package com.iscs.comm.entity.device.status
 
 import com.iscs.comm.entity.Frame
 import com.iscs.comm.entity.device.status.bean.SlotKeyBean
+import com.iscs.comm.extension.byte2ToInt
+import com.iscs.comm.extension.byteListToHexString
 import com.iscs.comm.extension.toBinaryString
 import java.util.concurrent.ConcurrentLinkedQueue
 
@@ -71,4 +73,15 @@ class DeviceStatusKeySlot : DeviceStatus() {
         }
     }
 
+    override fun updateRFID(frame: Frame) {
+        if (frame.data.size == 13) {
+            val nodeId = frame.data.copyOfRange(6, 8).byte2ToInt()
+            val ch = if (nodeId == 0x6020) 0 else if (nodeId == 0x6024) 1 else -1
+            val value = frame.data.copyOfRange(9, 13).reversed()
+            var rfid = value.byteListToHexString()
+            if (rfid == "00000000") rfid = ""
+            slotList.find { it.ch == ch }?.rfid = rfid
+        }
+    }
+
 }

+ 13 - 0
transport/src/main/java/com/iscs/comm/entity/device/status/DeviceStatusLockSlot.kt

@@ -3,6 +3,8 @@ package com.iscs.comm.entity.device.status
 import android.util.Log
 import com.iscs.comm.entity.Frame
 import com.iscs.comm.entity.device.status.bean.SlotBean
+import com.iscs.comm.extension.byte2ToInt
+import com.iscs.comm.extension.byteListToHexString
 import com.iscs.comm.extension.toBinaryString
 import java.util.concurrent.ConcurrentLinkedQueue
 
@@ -55,4 +57,15 @@ class DeviceStatusLockSlot() : DeviceStatus() {
         }
     }
 
+    override fun updateRFID(frame: Frame) {
+        if (frame.data.size == 13) {
+            val subNode = frame.data[8].toInt()
+            val ch = subNode - 0x00
+            val value = frame.data.copyOfRange(9, 13).reversed()
+            var rfid = value.byteListToHexString()
+            if (rfid == "00000000") rfid = ""
+            slotList.find { it.ch == ch }?.rfid = rfid
+        }
+    }
+
 }

+ 13 - 2
transport/src/main/java/com/iscs/comm/entity/device/status/bean/SlotBean.kt

@@ -12,11 +12,22 @@ open class SlotBean(
     open var ch: Int = -1,
     open var isUsed: Boolean = false,
     open var isSlotLock: Boolean = false,
-    open var isWorked: Boolean = false
+    open var isWorked: Boolean = false,
+    open var rfid: String = ""
 ) {
 
+    /**
+     * 上一次状态
+     */
+    var lastStatus = toString()
+
+    /**
+     * 是否变化了
+     */
+    var isChanged = false
+
     override fun toString(): String {
-        return "SlotBean(ch: $ch, isUsed: $isUsed, isSlotLock: $isSlotLock, isWorked: $isWorked)"
+        return "SlotBean(ch: $ch, isUsed: $isUsed, isSlotLock: $isSlotLock, isWorked: $isWorked, rfid: $rfid)"
     }
 
 }

+ 1 - 1
transport/src/main/java/com/iscs/comm/entity/device/status/bean/SlotKeyBean.kt

@@ -6,7 +6,7 @@ package com.iscs.comm.entity.device.status.bean
 class SlotKeyBean(var isCharging: Boolean = false) : SlotBean() {
 
     override fun toString(): String {
-        return "SlotKeyBean(ch: $ch, isUsed: $isUsed, isSlotLock: $isSlotLock, isWorked: $isWorked, isCharging: $isCharging)"
+        return "SlotKeyBean(ch: $ch, isUsed: $isUsed, isSlotLock: $isSlotLock, isWorked: $isWorked, rfid: $rfid, isCharging: $isCharging)"
     }
 
 }

+ 16 - 8
transport/src/main/java/com/iscs/comm/extension/CommFrameExt.kt

@@ -2,9 +2,10 @@ package com.iscs.comm.extension
 
 import com.iscs.comm.entity.Frame
 import com.iscs.comm.protocol.CanProtocol.CAN_ID_BASE
-import com.iscs.comm.protocol.CanProtocol.CAN_KEY_RW
-import com.iscs.comm.protocol.CanProtocol.CAN_KEY_STATUS
+import com.iscs.comm.protocol.CanProtocol.CAN_LOCK_RFID
 import com.iscs.comm.protocol.CanProtocol.CAN_READ_CMD
+import com.iscs.comm.protocol.CanProtocol.CAN_SLOT_RW
+import com.iscs.comm.protocol.CanProtocol.CAN_SLOT_STATUS
 import com.iscs.comm.protocol.CanProtocol.CAN_WRITE_CMD_2BYTE
 import com.iscs.comm.utils.ISCSLog
 
@@ -22,13 +23,20 @@ fun Frame.buildReadDeviceInfo(): List<Frame> {
     return list
 }
 
+/**
+ * 构建读取放入底座的设备RFID
+ */
+fun Frame.buildReadSlotRFID(rType: Int = CAN_LOCK_RFID, subType: Int): Frame {
+    data = byteArrayOf(CAN_READ_CMD.toByte(), (rType and 0xFF).toByte(), ((rType shr 8) and 0xFF).toByte(), subType.toByte(), 0x00, 0x00, 0x00, 0x00)
+    return this
+}
+
 /**
  * 构建用于读设备控制信息命令
  */
 fun Frame.buildCheckDeviceCtrlStatus(): Frame {
     data = byteArrayOf(
-        CAN_READ_CMD.toByte(), (CAN_KEY_RW and 0xFF).toByte(), ((CAN_KEY_RW shr 8) and 0xFF).toByte(), 0x00,
-        0x00, 0x00, 0x00, 0x00
+        CAN_READ_CMD.toByte(), (CAN_SLOT_RW and 0xFF).toByte(), ((CAN_SLOT_RW shr 8) and 0xFF).toByte(), 0x00, 0x00, 0x00, 0x00, 0x00
     )
     return this
 }
@@ -41,10 +49,10 @@ fun Frame.buildCheckDeviceCtrlStatus(): Frame {
 fun Frame.buildCtrlSlotLock(ch: Int, isLock: Boolean): Frame {
     val value = if (ch == -1) 0xFF.toByte() else (1 shl ch).toByte()
     data = byteArrayOf(
-        CAN_WRITE_CMD_2BYTE.toByte(), (CAN_KEY_RW and 0xFF).toByte(), ((CAN_KEY_RW shr 8) and 0xFF).toByte(), 0x00,
+        CAN_WRITE_CMD_2BYTE.toByte(), (CAN_SLOT_RW and 0xFF).toByte(), ((CAN_SLOT_RW shr 8) and 0xFF).toByte(), 0x00,
         if (isLock) 0xFF.toByte() else 0x00, value, 0x00, 0x00
     )
-    ISCSLog.i("CommFrameExt", "ctrl = ${data.toHexString(" ")}")
+    ISCSLog.i("CommFrameExt", "ctrl = ${data.byteArrayToHexString(" ")}")
     return this
 }
 
@@ -61,7 +69,7 @@ fun Frame.buildCtrlKeySlotLockAndCharge(ch: Int, isLock: Boolean, isCharge: Bool
     val work = if (ch == 0) 0B00000011 else if (ch == 1) 0B00110000 else 0B00110011
     ISCSLog.i("CommFrameExt", "ctrl = ${ctrl.toByte().toBinaryString()} work = ${work.toByte().toBinaryString()}")
     data = byteArrayOf(
-        CAN_WRITE_CMD_2BYTE.toByte(), (CAN_KEY_RW and 0xFF).toByte(), ((CAN_KEY_RW shr 8) and 0xFF).toByte(), 0x00,
+        CAN_WRITE_CMD_2BYTE.toByte(), (CAN_SLOT_RW and 0xFF).toByte(), ((CAN_SLOT_RW shr 8) and 0xFF).toByte(), 0x00,
         ctrl.toByte(), work.toByte(), 0x00, 0x00
     )
     return this
@@ -76,7 +84,7 @@ fun Frame.buildCtrlReadDeviceStatus(): Frame {
         cmd = id
         data = byteArrayOf(
             CAN_READ_CMD.toByte(),
-            (CAN_KEY_STATUS and 0xFF).toByte(), ((CAN_KEY_STATUS shr 8) and 0xFF).toByte(),
+            (CAN_SLOT_STATUS and 0xFF).toByte(), ((CAN_SLOT_STATUS shr 8) and 0xFF).toByte(),
             0x00, 0x00, 0x00, 0x00, 0x00
         )
     }

+ 8 - 1
transport/src/main/java/com/iscs/comm/extension/DataConvertExt.kt

@@ -30,7 +30,14 @@ fun ByteArray.byte2ToInt(isBE: Boolean = true): Int {
 /**
  * 将字节数组转换为16进制字符串
  */
-fun ByteArray.toHexString(sep: String = ""): String {
+fun ByteArray.byteArrayToHexString(sep: String = ""): String {
+    return joinToString(sep) { "%02X".format(it) }
+}
+
+/**
+ * 将Byte列表转为16进制
+ */
+fun List<Byte>.byteListToHexString(sep: String = ""): String {
     return joinToString(sep) { "%02X".format(it) }
 }
 

+ 13 - 4
transport/src/main/java/com/iscs/comm/protocol/CanProtocol.kt

@@ -25,10 +25,19 @@ object CanProtocol {
     // 设备类型
     const val CAN_DEVICE_TYPE = 0x6000
 
-    // 钥匙底座状态获取
-    const val CAN_KEY_STATUS = 0x6010
+    // 底座状态获取
+    const val CAN_SLOT_STATUS = 0x6010
 
-    // 钥匙底座读写标记
-    const val CAN_KEY_RW = 0x6011
+    // 底座读写标记
+    const val CAN_SLOT_RW = 0x6011
+
+    // 读取放入锁底座上的设备RFID
+    const val CAN_LOCK_RFID = 0x6020
+
+    // 读取放入钥匙底座上的设备RFID 左
+    const val CAN_KEY_RFID_LEFT = 0x6020
+
+    // 读取放入钥匙底座上的设备RFID 右
+    const val CAN_KEY_RFID_RIGHT = 0x6024
 
 }