Pārlūkot izejas kodu

refactor(更新) :
- 增加蓝牙主动断开指令
- 增加关机或重启指令
- 优化蓝牙队列调度器,增加注释说明,明确各个方法和变量的作用

周文健 3 mēneši atpakaļ
vecāks
revīzija
31ed83c9a1

+ 39 - 0
app/src/main/java/com/grkj/iscs_mars/ble/BleCmdManager.kt

@@ -1,5 +1,6 @@
 package com.grkj.iscs_mars.ble
 
+import android.annotation.SuppressLint
 import android.bluetooth.BluetoothGattCharacteristic
 import com.grkj.iscs_mars.BusinessManager
 import com.grkj.iscs_mars.ble.BleConst.REQ_CURRENT_STATUS
@@ -308,6 +309,44 @@ object BleCmdManager {
         }
     }
 
+    /**
+     * 关闭蓝牙请求
+     */
+    @SuppressLint("MissingPermission")
+    fun bleDisconnectReq(mac: String?, callback: CustomBleWriteCallback?) {
+        BusinessManager.getBleDeviceByMac(mac)?.let {
+            BleUtil.Companion.instance?.write(
+                it.bleDevice,
+                cmd = assembleData(
+                    it,
+                    BleConst.REQ_DISCONNECT_BLE
+                ),
+                writeCallback = callback
+            )
+        }
+    }
+
+    /**
+     * 关机或重启请求
+     */
+    @SuppressLint("MissingPermission")
+    fun shutdownOrRebootReq(
+        mac: String?,
+        isShutdown: Boolean = true,
+        callback: CustomBleWriteCallback?
+    ) {
+        BusinessManager.getBleDeviceByMac(mac)?.let {
+            BleUtil.Companion.instance?.write(
+                it.bleDevice,
+                cmd = assembleData(
+                    it,
+                    BleConst.REQ_SHUTDOWN_OR_REBOOT + if (isShutdown) 0x02.toByte() else 0x01.toByte()
+                ),
+                writeCallback = callback
+            )
+        }
+    }
+
     /**
      * 处理设备当前状态
      * 0x01:工作模式 0x02:待机模式 0x03:故障状态

+ 20 - 0
app/src/main/java/com/grkj/iscs_mars/ble/BleConst.kt

@@ -71,4 +71,24 @@ object BleConst {
 
     // 获取固件版本号响应
     val RSP_GET_VERSION = byteArrayOf(0xEE.toByte(), 0x02, 0x03, 0x01)
+
+    /**
+     * 蓝牙断开指令
+     */
+    val REQ_DISCONNECT_BLE = byteArrayOf(0x02.toByte(), 0x01, 0x01, 0xEA.toByte())
+
+    /**
+     * 蓝牙断开回复
+     */
+    val RES_DISCONNECT_BLE = byteArrayOf(0x02.toByte(), 0x02, 0x02, 0xEA.toByte())
+
+    /**
+     * 关机或重启指令
+     */
+    val REQ_SHUTDOWN_OR_REBOOT = byteArrayOf(0x02.toByte(), 0x01, 0x02, 0xEE.toByte())
+
+    /**
+     * 关机回复
+     */
+    val RES_SHUTDOWN_OR_REBOOT = byteArrayOf(0x02.toByte(), 0x02, 0x03, 0xEE.toByte())
 }

+ 58 - 8
app/src/main/java/com/grkj/iscs_mars/ble/BleQueueDispatcher.kt

@@ -11,17 +11,40 @@ import kotlinx.coroutines.Job
 import kotlinx.coroutines.SupervisorJob
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
 
+/**
+ * 蓝牙队列调度器
+ */
 abstract class BleQueueDispatcher {
+    /**
+     * 任务队列
+     */
     private val taskQueue =
         ArrayDeque<Pair<String, MutableList<(Boolean) -> Unit>>>() // mac + callback
+
+    /**
+     * 正在连接的设备
+     */
     private val activeMacs = mutableMapOf<String, MutableList<(Boolean) -> Unit>>()
+
+    /**
+     * 已连接的设备
+     */
     private val connectedMacs = mutableSetOf<String>()
+
+    /**
+     * 断连计划
+     */
     private val pendingDisconnectJobs = mutableMapOf<String, Job>()
 
+    /**
+     * 最大连接数
+     */
     open val maxConnections: Int = 1
+
+    /**
+     * 协程作用域
+     */
     private val dispatcherScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
 
     /**
@@ -30,7 +53,6 @@ abstract class BleQueueDispatcher {
     @Synchronized
     fun submit(mac: String, onResult: (Boolean) -> Unit) {
         LogUtil.i("开始检查钥匙状态:${mac}")
-
         if (activeMacs.containsKey(mac) || taskQueue.any { it.first == mac } || connectedMacs.contains(
                 mac
             )) {
@@ -74,8 +96,14 @@ abstract class BleQueueDispatcher {
         }
     }
 
+    /**
+     * 连接
+     */
     protected abstract fun doConnect(mac: String, callback: (Boolean) -> Unit)
 
+    /**
+     * 移除设备
+     */
     @Synchronized
     fun clear(mac: String) {
         taskQueue.removeIf { it.first == mac }
@@ -84,6 +112,9 @@ abstract class BleQueueDispatcher {
         pendingDisconnectJobs.remove(mac)?.cancel()
     }
 
+    /**
+     * 计划断连
+     */
     @SuppressLint("MissingPermission")
     @Synchronized
     fun scheduleDisconnect(mac: String, delayMillis: Long = 0) {
@@ -112,14 +143,21 @@ abstract class BleQueueDispatcher {
         pendingDisconnectJobs[mac] = job
     }
 
+    /**
+     * 断开设备连接
+     */
     @SuppressLint("MissingPermission")
     private fun disconnectDeviceByMac(mac: String) {
         val device = BleManager.getAllConnectedDevice().find { it.mac == mac }
         if (device != null) {
+            BleCmdManager.bleDisconnectReq(mac, null)
             BleManager.disconnect(device)
         }
     }
 
+    /**
+     * 断开所有连接
+     */
     @Synchronized
     fun disconnectAll(delayMillis: Long = 0) {
         val allMacs = connectedMacs.toList()
@@ -128,17 +166,29 @@ abstract class BleQueueDispatcher {
         }
     }
 
-
+    /**
+     * 是否正在连接
+     */
     fun isConnecting(mac: String): Boolean = activeMacs.containsKey(mac)
-    fun isQueued(mac: String): Boolean = taskQueue.any { it.first == mac }
-    fun isConnected(mac: String): Boolean = connectedMacs.contains(mac)
 
-    fun getConnectedMacs(): List<String> = connectedMacs.toList()
+    /**
+     * 是否在队列中
+     */
+    fun isQueued(mac: String): Boolean = taskQueue.any { it.first == mac }
 
-    fun getActiveMacs(): List<String> = activeMacs.keys.toList()
+    /**
+     * 是否已经连接
+     */
+    fun isConnected(mac: String): Boolean = connectedMacs.contains(mac)
 
+    /**
+     * 是否可以连接
+     */
     fun canConnect(): Boolean = (activeMacs.size + connectedMacs.size) <= maxConnections
 
+    /**
+     * 是否可以断连
+     */
     fun shouldDisconnect(mac: String): Boolean =
         isConnecting(mac) || isQueued(mac) || isConnected(mac)
 }