package main import ( "encoding/binary" "encoding/hex" "fmt" "github.com/spf13/viper" "joylink.club/bj-rtsts-server/bin/config" "joylink.club/bj-rtsts-server/const/balise_const" "joylink.club/bj-rtsts-server/third_party/message" "joylink.club/bj-rtsts-server/third_party/tcp" "joylink.club/bj-rtsts-server/third_party/train_pc_sim" "joylink.club/bj-rtsts-server/third_party/udp" "log/slog" "strconv" "strings" "time" ) const config_name = "example" var exampleConfig config.ExampleConfig func initConfig() { cnf := viper.New() cnf.SetConfigName(config_name) cnf.SetConfigType("yml") //cnf.AddConfigPath("./bin/config/") //cnf.AddConfigPath("./") cnf.AddConfigPath(".") err := cnf.ReadInConfig() if err != nil { panic(fmt.Errorf("读取配置文件错误: %w", err)) } err = cnf.Unmarshal(&exampleConfig) if err != nil { panic(fmt.Errorf("解析配置文件错误: %w", err)) } slog.Info("成功加载配置", "config", exampleConfig) } var btmCli udp.UdpClient func initBtmTest() { ser := udp.NewServer(fmt.Sprintf("%v:%d", exampleConfig.Btm.LocalIp, exampleConfig.Btm.LocalPort), handleBtmVobcFrames) ser.Listen() btmCli = udp.NewClient(fmt.Sprintf("%v:%v", exampleConfig.Btm.RemoteIp, exampleConfig.Btm.RemotePort)) } var accClient udp.UdpClient func initAccTest() { accClient = udp.NewClient(fmt.Sprintf("%v:%v", exampleConfig.Acc.RemoteIp, exampleConfig.Acc.RemotePort)) go testAcc(accClient, 0.54) } var speedClient udp.UdpClient func initSpeedTest() { speedClient = udp.NewClient(fmt.Sprintf("%v:%v", exampleConfig.Speed.RemoteIp, exampleConfig.Speed.RemotePort)) go testSpeed(speedClient, 30) } var trainpcClient *tcp.TcpClient func initTrainPc() { addr := fmt.Sprintf("%v:%v", exampleConfig.Trainpc.RemoteIp, exampleConfig.Trainpc.RemotePort) client2, err := tcp.StartTcpClient(addr, trainPcDataHandle, trainPcConnErr) if err != nil { fmt.Println("仿真列车pc连接失败", err) return } trainpcClient = client2 circleSendTrainActive() circleSendTrainMockData() go circleSendTrainSpeedPlace() } func circleSendTrainActive() { msg := &message.TrainPcSimBaseMessage{Data: []byte{0x01}, Type: train_pc_sim.RECIVE_TRAIN_CREATE_REMOVE} data := msg.Encode() fmt.Println(fmt.Sprintf("发送列车创建数据:%v", hex.EncodeToString(data))) trainpcClient.Send(data) act := &message.TrainPcSimBaseMessage{Data: make([]byte, 0), Type: train_pc_sim.SENDER_TRAIN_TC_ACTIVE} actData := act.Encode() fmt.Println(fmt.Sprintf("发送列车驾驶室激活:%v", hex.EncodeToString(actData))) trainpcClient.Send(actData) } func circleSendTrainMockData() { msg := &message.TrainPcSimBaseMessage{} msg.Type = train_pc_sim.SENDER_TRAIN_OUTR_INFO data := []byte{0x00, 1} msg.Data = data code := msg.Encode() fmt.Println(fmt.Sprintf("发送列车模拟量输出数据:%v 模拟量下标:%v", hex.EncodeToString(code), 0x00)) trainpcClient.Send(code) //time.Sleep(time.Millisecond * 1000) msg = &message.TrainPcSimBaseMessage{} msg.Type = train_pc_sim.SENDER_TRAIN_OUTR_INFO data = []byte{0x01, 1} msg.Data = data code = msg.Encode() fmt.Println(fmt.Sprintf("发送列车模拟量输出数据:%v 模拟量下标:%v", hex.EncodeToString(code), 0x01)) trainpcClient.Send(code) //time.Sleep(time.Millisecond * 1000) msg = &message.TrainPcSimBaseMessage{} msg.Type = train_pc_sim.SENDER_TRAIN_OUTR_INFO data = []byte{0x02, 0} msg.Data = data code = msg.Encode() fmt.Println(fmt.Sprintf("发送列车模拟量输出数据:%v 模拟量下标:%v", hex.EncodeToString(code), 0x02)) trainpcClient.Send(code) } func circleSendTrainSpeedPlace() { for { data := make([]byte, 0) data = binary.BigEndian.AppendUint16(data, uint16(1)) data = binary.BigEndian.AppendUint32(data, uint32(3)) data = binary.BigEndian.AppendUint32(data, uint32(4)) data = binary.BigEndian.AppendUint32(data, uint32(5)) data = binary.BigEndian.AppendUint32(data, uint32(6)) now := time.Now().UTC() sec := now.Unix() data = binary.BigEndian.AppendUint32(data, uint32(sec)) data = binary.BigEndian.AppendUint16(data, uint16(now.UnixMilli()-sec*1000)) bm := &message.TrainPcSimBaseMessage{Type: train_pc_sim.SENDER_TRAIN_LOCATION_INFO, Data: data} dataCode := bm.Encode() fmt.Println(fmt.Sprintf("发送列车位置信息:%v", hex.EncodeToString(dataCode))) trainpcClient.Send(dataCode) time.Sleep(time.Millisecond * 80) } } func trainPcDataHandle(n int, data []byte) { hexData := hex.EncodeToString(data) slog.Info(fmt.Sprintf("列车pc仿真接口接受数据:%v", hexData)) } func trainPcConnErr(err error) { } func main() { initConfig() //initBtmTest() //initTrainPc() //initAccTest() initSpeedTest() for { } } var testUserBtmMsg = "90007F8181B60B10183280003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" var freeBtmMsg = strings.Repeat("00", balise_const.UserTelegramByteLen) func sendPacket(lifeNum uint32, autoId byte) { userMsg, _ := hex.DecodeString(testUserBtmMsg) msg := &message.BtmVobcMessage{FontTtl: 2, BtmStatus: 0x00, DecodeTime: 10, BackTtl: 2, BtmMsg: userMsg, ResponseTime: 10, VobcLifeNum: lifeNum, BaseBtmVobc: message.BaseBtmVobc{AutoIdFrame: autoId}, MsgSerial: message.GetAutoMessageId()} sendData := msg.Encode() fmt.Println("发送btm vobc len:", len(sendData), "报文:", hex.EncodeToString(sendData), "报文序列号:", msg.MsgSerial) time.Sleep(time.Millisecond * 100) err := btmCli.Send(sendData) if err != nil { fmt.Println(fmt.Sprintf("发送失败%v", err.Error())) } /*freeMsg, _ := hex.DecodeString(freeBtmMsg) msg2 := &message.BtmVobcMsgFree{BtmStatus: 0x00, WorkTemperature: 10, Fun1: uint16(0), Fun2: uint16(0), Fun3: uint16(0), Fun4: uint16(0), FreeMsg: freeMsg, RespTime: 20, VobcLifeNum: lifeNum, BaseBtmVobc: message.BaseBtmVobc{AutoIdFrame: autoId}, MsgSerial: message.GetAutoMessageId()} sendData2 := msg2.Encode() fmt.Println("发送btm vobc 空报文11111:", hex.EncodeToString(sendData2), "len:", len(sendData2), "报文序列号:", msg2.MsgSerial, "atoId=", autoId, "报文序列号:", msg2.MsgSerial) btmCli.Send(sendData2)*/ } func sendPacketFree(lifeNum uint32, autoId byte, msgs byte) { freeMsg, _ := hex.DecodeString(freeBtmMsg) newMsg := msgs + 1 if newMsg > 255 { newMsg = 1 } msg2 := &message.BtmVobcMsgFree{BtmStatus: 0x00, WorkTemperature: 10, Fun1: uint16(0), Fun2: uint16(0), Fun3: uint16(0), Fun4: uint16(0), //FreeMsg: freeMsg, RespTime: 20, VobcLifeNum: lifeNum, BaseBtmVobc: message.BaseBtmVobc{AutoIdFrame: autoId}, MsgSerial: newMsg} FreeMsg: freeMsg, RespTime: 20, VobcLifeNum: lifeNum, BaseBtmVobc: message.BaseBtmVobc{AutoIdFrame: autoId}, MsgSerial: message.GetAutoMessageId()} sendData2 := msg2.Encode() fmt.Println("发送btm vobc 空报文:", hex.EncodeToString(sendData2), "len:", len(sendData2), "报文序列号:", msg2.MsgSerial, "atoId=", autoId, "报文序列号:", msg2.MsgSerial) time.Sleep(time.Millisecond * 100) err := btmCli.Send(sendData2) if err != nil { fmt.Println(fmt.Sprintf("发送失败%v", err.Error())) } } func RequestFramePackets(req *message.BtmVobcReq, vobcLife uint32) { //fmt.Println(fmt.Sprintf("接受 请求帧 frameStatus:%v,messageType:%v,lifeNum:%v,序列号:%v", req.FrameStatus, req.MessageType, req.VobcLifeNum, req.MessageSerial)) if req.FrameStatus == message.REQ_FRAME_STATUS_BOOT && req.MessageType == message.REQ_PACKETS_TYPE_BOOT { fmt.Println("000000000000000000000000000") sendPacketFree(vobcLife, req.AutoIdFrame, req.MessageSerial) } else if req.FrameStatus == message.REQ_FRAME_STATUS_OK { //帧正确,删除之前发送的数据 fmt.Println("11111111111111111111") } else if req.FrameStatus == message.REQ_FRAME_STATUS_ERROR { //帧不正确 重新发送2次,如果2次后仍然不正确,则删除之前发送的数据 fmt.Println("22222222222222222") } } var btmReceiveTime = time.Now().UnixMilli() var vobcNumLife uint32 = 0 func handleBtmVobcFrames(cfs []byte) { fmt.Println(fmt.Sprintf("收到源数据:%v ,请求帧时间:%v ,vobcLife:%v", hex.EncodeToString(cfs), time.Now().UnixMilli()-btmReceiveTime, vobcNumLife)) frameType, dataText, err := message.BtmVobcDecode(cfs) if err != nil { return } if frameType == message.COMMAND_TYPE { idCommand := &message.BtmVobcIdCommand{} idCommand.Decode(dataText) if vobcNumLife <= 0 { vobcNumLife = idCommand.VobcLifeNum } sendPacketFree(vobcNumLife, idCommand.AutoIdFrame, idCommand.AutoIdFrame) //sendPacket(vobcNumLife, idCommand.AutoIdFrame) } else if frameType == message.REQUEST_TYPE { if vobcNumLife <= 0 { return } else { fmt.Println(fmt.Sprintf("准备发送vobcLife:%v", vobcNumLife)) } req := &message.BtmVobcReq{} req.Decode(dataText) fmt.Println(fmt.Sprintf("接受 请求帧 frameStatus:%v,messageType:%v,lifeNum:%v,序列号:%v", req.FrameStatus, req.MessageType, req.VobcLifeNum, req.MessageSerial)) if time.Now().UnixMilli()-btmReceiveTime > 20*1000 { idCommand := &message.BtmVobcIdCommand{} idCommand.Decode(dataText) sendPacket(vobcNumLife, idCommand.AutoIdFrame) } else { RequestFramePackets(req, vobcNumLife) } } else { slog.Error(fmt.Sprintf("btm vobc 解析未知命令帧类型:0x%v,原始数据:%v,长度:%v", strconv.FormatInt(int64(frameType), 16), hex.EncodeToString(cfs), len(cfs))) return } } func testSpeed(client udp.UdpClient, speed float32) { //client = udp.NewClient(fmt.Sprintf("%v:%v", exampleConfig.Speed.RemoteIp, exampleConfig.Speed.RemotePort)) ac := message.ElectricMachinery{Speed: speed, WheelDiameter: 800, IsBack: false} var index int64 for { data := ac.Encode() //fmt.Println(hex.EncodeToString(data)) err := client.Send(data) index++ if index%10 == 0 { slog.Info(fmt.Sprintf("发送speed数据,时间戳:%v,发送次数:%v 数据:%v", time.Now().Unix(), index, hex.EncodeToString(data))) ac = message.ElectricMachinery{Speed: 0, WheelDiameter: 800, IsBack: false} client.Send(ac.Encode()) break } if err != nil { slog.Error("发送数据失败", "err", err) } time.Sleep(time.Millisecond * 200) } } // 加速度计 func testAcc(client udp.UdpClient, acc float32) { //client = udp.NewClient(fmt.Sprintf("%v:%v", exampleConfig.Acc.RemoteIp, exampleConfig.Acc.RemotePort)) ac := message.Accelerometer{Acc: acc} var index int64 for { data := ac.Encode() //fmt.Println(hex.EncodeToString(data)) err := client.Send(data) index++ if index%10 == 0 { slog.Info(fmt.Sprintf("发送acc数据,时间戳:%v,发送次数:%v 数据:%v", time.Now().Unix(), index, hex.EncodeToString(data))) } if err != nil { slog.Error("发送数据失败", "err", err) } time.Sleep(time.Millisecond * 11) } }