package com.narutohuo.xindazhou.ble.util /** * BLE分包处理器 * * 处理数据包的分包和组包 * 根据新大洲本田蓝牙协议文档的分包协议 */ class BLEPacketSplitter { /** * 分包数据 * * @param data 原始数据 * @param mtu MTU大小(最大传输单元) * @param businessId 业务ID(4字节) * @return 分包后的数据包列表 */ fun splitPacket(data: ByteArray, mtu: Int, businessId: Int): List { val packets = mutableListOf() val totalPackets = (data.size + mtu - 1) / mtu for (i in 0 until totalPackets) { val start = i * mtu val end = minOf(start + mtu, data.size) val packetData = data.sliceArray(start until end) val packet = buildSplitPacket( businessId = businessId, totalPackets = totalPackets, packetIndex = i, data = packetData ) packets.add(packet) } return packets } /** * 构建分包数据包 */ private fun buildSplitPacket( businessId: Int, totalPackets: Int, packetIndex: Int, data: ByteArray ): ByteArray { val packet = mutableListOf() // 包头(0x0A) packet.add(0x0A.toByte()) // 业务ID(4字节,小端序) packet.add((businessId and 0xFF).toByte()) packet.add(((businessId shr 8) and 0xFF).toByte()) packet.add(((businessId shr 16) and 0xFF).toByte()) packet.add(((businessId shr 24) and 0xFF).toByte()) // 总包数(2字节,小端序) packet.add((totalPackets and 0xFF).toByte()) packet.add(((totalPackets shr 8) and 0xFF).toByte()) // 包序号(2字节,小端序) packet.add((packetIndex and 0xFF).toByte()) packet.add(((packetIndex shr 8) and 0xFF).toByte()) // 数据长度(2字节,小端序) val dataLength = data.size packet.add((dataLength and 0xFF).toByte()) packet.add(((dataLength shr 8) and 0xFF).toByte()) // 数据区 packet.addAll(data.toList()) // 应答状态(0x01=ACK) packet.add(0x01.toByte()) // 包校验(异或校验) var checksum = 0x00 for (i in 1 until packet.size) { checksum = checksum xor packet[i].toInt() } packet.add(checksum.toByte()) // 包尾(0x0D) packet.add(0x0D.toByte()) return packet.toByteArray() } /** * 组包数据 * * @param packets 接收到的分包数据(Map<包序号, 数据>) * @return 组包后的完整数据 */ fun combinePackets(packets: Map): ByteArray { val sortedPackets = packets.toSortedMap() val result = mutableListOf() sortedPackets.values.forEach { packetData -> result.addAll(packetData.toList()) } return result.toByteArray() } }