EdgexAgent/device-ble-go/pkg/ble/jsonSender.go

83 lines
2.7 KiB
Go
Raw Normal View History

2025-07-10 20:40:32 +08:00
package ble
import (
"device-ble/internal/interfaces"
"encoding/binary"
"encoding/json"
"fmt"
"strings"
"time"
"github.com/google/uuid"
)
const (
MTU = 247 // 蓝牙模块 MTU 限制为 64 字节
Suffix = "\r\n" // AT 指令后缀 (2字节)
HeaderSize = 4 // 分包头部2 字节索引 + 2 字节总包数
)
var Prefix string = "AT+QBLEGATTSNTFY=0,fff2," // AT 指令前缀 (20字节
var MaxPayload int = MTU - len(Prefix) - len(Suffix) - HeaderSize // 实际载荷大小247 - 20 - 2 - 4 = 221 字节
// Packet 分包结构
type Packet struct {
Index uint16 // 分包索引
Total uint16 // 总分包数
Payload []byte // 数据载荷
}
// splitIntoPackets 将数据分包
func splitIntoPackets(data []byte) []Packet {
var packets []Packet
totalPackets := (len(data) + MaxPayload - 1) / MaxPayload // 向上取整
for i := 0; i < len(data); i += MaxPayload {
end := i + MaxPayload
if end > len(data) {
end = len(data)
}
packet := Packet{
Index: uint16(i / MaxPayload),
Total: uint16(totalPackets),
Payload: data[i:end],
}
packets = append(packets, packet)
}
return packets
}
// SendJSONOverBLE 发送 JSON 数据的主要函数。
func SendJSONOverBLE(sq interfaces.SerialQueueInterface, jsonData interface{}) error {
// 这里需要传入logger参数建议后续重构接口
// 目前先用fmt.Println模拟日志后续可传入logger
tag := uuid.New().String()
dataBytes, err := json.Marshal(jsonData)
if err != nil {
return fmt.Errorf("JSON序列化失败: %v", err)
}
packets := splitIntoPackets(dataBytes)
for _, packet := range packets {
packetData := make([]byte, len(Prefix)+HeaderSize+len(packet.Payload)+len(Suffix))
copy(packetData, Prefix)
binary.BigEndian.PutUint16(packetData[len(Prefix):], packet.Index)
binary.BigEndian.PutUint16(packetData[len(Prefix)+2:], packet.Total)
copy(packetData[len(Prefix)+HeaderSize:], packet.Payload)
copy(packetData[len(Prefix)+HeaderSize+len(packet.Payload):], Suffix)
response, err := sq.SendCommand(packetData, 300*time.Millisecond, 1*time.Millisecond, 100*time.Millisecond)
if strings.Contains(response, "OK") {
fmt.Printf("⚡ 数据包: %v ⬇️ 子包: %d/%d 发送成功, size%d bytes\n", tag, packet.Index+1, packet.Total, len(packetData))
} else if strings.Contains(response, "ERROR") {
fmt.Printf("⛔️ 数据包: %v ⬇️ 子包: %d/%d 发送失败\n", tag, packet.Index+1, packet.Total)
return err
} else {
fmt.Printf("❗❓ 数据包: %v ⬇️ 子包: %d/%d 未知回显:%v, error%v\n", tag, packet.Index+1, packet.Total, response, err)
return err
}
}
fmt.Printf("✅️ All packets of Packet %v sent and verified.\n", tag)
return nil
}