EdgexAgent/device-ble-go/pkg/ble/jsonSender.go
2025-07-10 20:40:32 +08:00

83 lines
2.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}