123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- package stc
- import (
- "bufio"
- "bytes"
- "encoding/binary"
- "fmt"
- "log"
- "net"
- "os"
- stc "pbx-api-gin/internal/app/stc/operation"
- "syscall"
- "time"
- )
- // Protocol 定义协议数据结构
- type Protocol struct {
- StartBytes [3]byte // 协议开始符
- SourceID uint8 // 源设备号
- DestinationID uint8 // 目的设备号
- MessageID uint8 // 消息号
- DataLength uint16 // 数据长度
- Data []byte // 数据
- Checksum uint8 // 异或校验码
- EndByte uint8 // 协议结束符
- }
- // NewProtocol 创建一个新的 Protocol 实例
- func NewProtocol() *Protocol {
- return &Protocol{
- StartBytes: [3]byte{0x7F, 0x8E, 0x9D},
- EndByte: 0xFE,
- }
- }
- func ConnectStc(ServerAddr string, Port int) {
- //=================================================
- // connect server
- conn := connectServer(ServerAddr, Port)
- defer conn.Close()
- //read msg
- go func(conn net.Conn) {
- readMsg(conn)
- }(conn)
- // send msg
- sendMsg(conn)
- }
- func connectServer(ServerAddr string, Port int) net.Conn {
- // connect server
- conn, err := net.DialTCP("tcp", &net.TCPAddr{
- IP: net.ParseIP("0.0.0.0"),
- Port: 0,
- }, &net.TCPAddr{
- IP: net.ParseIP(ServerAddr),
- Port: Port,
- })
- if err != nil {
- fmt.Println("Error conn server:", err)
- log.Fatal(err)
- }
- fileDesc, _ := conn.File()
- fd := fileDesc.Fd()
- syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
- return conn
- }
- func Sendheartbeat(conn net.Conn) {
- var count uint8
- //init heartbeat data
- protocol := NewProtocol()
- protocol.SourceID = 0x02
- protocol.DestinationID = 0x01
- protocol.MessageID = 0x21
- protocol.DataLength = 0x04
- ticker := time.NewTicker(2 * time.Second)
- defer ticker.Stop()
- for range ticker.C {
- count = count + 1
- protocol.Data = []byte{count, 0x00, 0x00, 0x00}
- encoded, errEn := protocol.Encode()
- if errEn != nil {
- fmt.Println("Encode error:", errEn)
- return
- }
- _, err := conn.Write(encoded)
- if err != nil {
- fmt.Println("send heartbeat err:", err)
- return
- }
- }
- }
- func readMsg(conn net.Conn) {
- for {
- buffer := make([]byte, 1024)
- n, err := conn.Read(buffer)
- if err != nil {
- fmt.Println("Error reading from server:", err)
- return
- }
- fmt.Println("Received from server:", string(buffer[:n]))
- switch buffer[5] {
- case 0x01: //heartbeat
- case 0x02: //STN
- stc.StationAnn([4]byte{buffer[8], buffer[9], buffer[10], buffer[11]})
- case 0x03: //ACTIVE
- stc.Active([1]byte{buffer[8]})
- case 0x05: //SPC
- stc.SpecialAnn([4]byte{buffer[8], buffer[9], buffer[10], buffer[11]})
- case 0x06: //EMG
- stc.EmgMsg([4]byte{buffer[8], buffer[9], buffer[10], buffer[11]})
- case 0x07: //STOP
- stc.AnnStop([4]byte{buffer[8], buffer[9], buffer[10], buffer[11]})
- case 0x08: //DCS
- stc.DcsAnn([4]byte{buffer[8], buffer[9], buffer[10], buffer[11]})
- case 0x09: //SELF CHECK
- stc.SelfCheck([4]byte{buffer[8], buffer[9], buffer[10], buffer[11]})
- case 0x0a: //
- stc.AlarmHandle([4]byte{buffer[8], buffer[9], buffer[10], buffer[11]})
- case 0x0b: //
- stc.AlarmResetAll([4]byte{buffer[8], buffer[9], buffer[10], buffer[11]})
- case 0x0c: //
- stc.RecordStorageConf([4]byte{buffer[8], buffer[9], buffer[10], buffer[11]})
- }
- }
- }
- func sendMsg(conn net.Conn) {
- //heartbeat
- go func(conn net.Conn) {
- Sendheartbeat(conn)
- }(conn)
- scanner := bufio.NewScanner(os.Stdin)
- for scanner.Scan() {
- text := scanner.Text()
- _, err := conn.Write([]byte(text + "\n"))
- if err != nil {
- fmt.Println("send msg err:", err)
- return
- }
- }
- }
- // Encode 将 Protocol 结构体编码为字节切片
- func (p *Protocol) Encode() ([]byte, error) {
- // 初始化字节缓冲区
- var buf bytes.Buffer // 写入协议开始符
- buf.Write(p.StartBytes[:])
- // 写入源设备号、目的设备号和消息号
- binary.Write(&buf, binary.BigEndian, p.SourceID)
- binary.Write(&buf, binary.BigEndian, p.DestinationID)
- binary.Write(&buf, binary.BigEndian, p.MessageID)
- // 写入数据长度
- binary.Write(&buf, binary.BigEndian, p.DataLength)
- // 写入数据
- buf.Write(p.Data[:])
- // 计算校验码
- checksum := p.CalculateChecksum()
- p.Checksum = checksum // 写入校验码
- binary.Write(&buf, binary.BigEndian, p.Checksum)
- // 写入协议结束符
- binary.Write(&buf, binary.BigEndian, p.EndByte)
- return buf.Bytes(), nil
- }
- // CalculateChecksum 计算校验码
- func (p *Protocol) CalculateChecksum() uint8 {
- // 初始化校验码
- checksum := uint8(0)
- // 跳过协议开始符
- data := append([]byte{byte(p.SourceID), byte(p.DestinationID), byte(p.MessageID)},
- append([]byte{byte(p.DataLength >> 8), byte(p.DataLength)}, p.Data...)...)
- // 计算校验码
- for _, b := range data {
- checksum ^= b
- }
- return checksum
- }
- // Decode 解码字节切片为 Protocol 结构体
- func Decode(data []byte) (*Protocol, error) {
- if len(data) < 10 { // 最小长度:3(StartBytes) +1(SourceID) +1(DestinationID) +1(MessageID) +2(DataLength) +1(Checksum) +1(EndByte)
- return nil, fmt.Errorf("data too short")
- }
- p := NewProtocol()
- // 读取协议开始符
- copy(p.StartBytes[:], data[:3])
- // 读取源设备号、目的设备号和消息号
- p.SourceID = data[3]
- p.DestinationID = data[4]
- p.MessageID = data[5]
- // 读取数据长度
- p.DataLength = binary.BigEndian.Uint16(data[6:8])
- // 读取数据
- dataLength := int(p.DataLength)
- if len(data) < 10+dataLength {
- return nil, fmt.Errorf("data length mismatch")
- }
- p.Data = data[8 : 8+dataLength]
- // 读取校验码
- p.Checksum = data[8+dataLength]
- // 读取协议结束符
- p.EndByte = data[9+dataLength]
- // 验证校验码
- if p.Checksum != p.CalculateChecksum() {
- return nil, fmt.Errorf("checksum mismatch")
- }
- return p, nil
- }
|