285 lines
7.8 KiB
Go
285 lines
7.8 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"io"
|
|
"joylink.club/bj-rtsts-server/third_party/message"
|
|
"joylink.club/bj-rtsts-server/third_party/train_pc_sim"
|
|
"log/slog"
|
|
"net"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type TcpConnHandler = func(conn net.Conn)
|
|
type TcpMsgHandler = func(n int, data []byte)
|
|
|
|
func tcpRunAcceptTask(listen net.Listener, port int, connHandler TcpConnHandler, msgHandler TcpMsgHandler) {
|
|
go func() {
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
slog.Error(fmt.Sprintf("TCP服务端[port:%d]接收连接任务异常:", port), err)
|
|
tcpRunAcceptTask(listen, port, connHandler, msgHandler)
|
|
}
|
|
}()
|
|
for {
|
|
conn, err := listen.Accept()
|
|
if err != nil {
|
|
slog.Error(fmt.Sprintf("TCP服务端[port:%d]接收连接出错:", port), err)
|
|
}
|
|
connHandler(conn)
|
|
tcpRunReadTask(conn, port, msgHandler)
|
|
}
|
|
}()
|
|
}
|
|
|
|
func tcpRunReadTask(conn net.Conn, port int, msgHandler TcpMsgHandler) {
|
|
go func() {
|
|
/* defer func() {
|
|
if err := recover(); err != nil {
|
|
slog.Error(fmt.Sprintf("TCP服务端[port:%d]读数据任务异常:", port), err)
|
|
serConn.Close()
|
|
serConn = nil
|
|
|
|
}
|
|
}()*/
|
|
for {
|
|
data := make([]byte, 1024)
|
|
l, err := conn.Read(data)
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
slog.Warn(fmt.Sprintf("TCP服务端[port:%d]断开[%s]连接:", port, conn.RemoteAddr().String()))
|
|
break
|
|
}
|
|
slog.Error(fmt.Sprintf("TCP服务端[port:%d]读取[%s]数据出错:", port, conn.RemoteAddr().String()), err)
|
|
|
|
}
|
|
msgHandler(l, data)
|
|
}
|
|
}()
|
|
}
|
|
|
|
func StartTcpServer(port int, connHandler TcpConnHandler, msgHandler TcpMsgHandler) (net.Listener, error) {
|
|
listen, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
tcpRunAcceptTask(listen, port, connHandler, msgHandler)
|
|
return listen, err
|
|
}
|
|
|
|
var serConnMap map[int]net.Conn = make(map[int]net.Conn)
|
|
|
|
func createServer(port int, h TcpMsgHandler) {
|
|
StartTcpServer(port, func(conn net.Conn) {
|
|
fmt.Println("TCP服务端接收到连接")
|
|
serConnMap[port] = conn
|
|
|
|
}, h)
|
|
}
|
|
func connTrain() *message.TrainPcSimBaseMessage {
|
|
msg := &message.TrainPcSimBaseMessage{}
|
|
msg.Type = train_pc_sim.RECIVE_TRAIN_CREATE_REMOVE
|
|
msg.Data = []byte{0x01}
|
|
return msg
|
|
}
|
|
func changeDoorMode() *message.TrainPcSimBaseMessage {
|
|
msg := &message.TrainPcSimBaseMessage{}
|
|
msg.Type = train_pc_sim.RECIVE_TRAIN_DOOR_MODE
|
|
msg.Data = []byte{0x02}
|
|
return msg
|
|
}
|
|
|
|
func boolsToByte(flags [8]bool) byte {
|
|
var result uint8
|
|
for index, b := range flags {
|
|
if b {
|
|
result = result + (1 << index)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func pcSimInfoOut() *message.TrainPcSimBaseMessage {
|
|
msg := &message.TrainPcSimBaseMessage{}
|
|
msg.Type = train_pc_sim.RECIVE_TRAIN_INTERFACE_CABINET_OUTR
|
|
data := make([]byte, 0)
|
|
data = append(data, boolsToByte([8]bool{false, false, false, false, false, false, false, false}))
|
|
data = append(data, boolsToByte([8]bool{false, false, false, false, false, false, false, false}))
|
|
data = append(data, boolsToByte([8]bool{false, false, false, false, false, false, false, false}))
|
|
data = append(data, boolsToByte([8]bool{false, false, false, false, false, false, false, false}))
|
|
data = append(data, boolsToByte([8]bool{true, false, false, false, false, false, false, false}))
|
|
msg.Data = data
|
|
return msg
|
|
}
|
|
func pcSimInfoOutReport() *message.TrainPcSimBaseMessage {
|
|
msg := &message.TrainPcSimBaseMessage{}
|
|
msg.Type = train_pc_sim.RECIVE_TRAIN_INTERFACE_CABINET_OUTR_BACK
|
|
data := make([]byte, 0)
|
|
data = append(data, boolsToByte([8]bool{true, true, false, false, false, false, false, false}))
|
|
msg.Data = data
|
|
return msg
|
|
}
|
|
|
|
var autoIncNo = 0
|
|
|
|
func queryBtm() *message.TrainPcSimBaseMessage {
|
|
msg := &message.TrainPcSimBaseMessage{}
|
|
msg.Type = train_pc_sim.RECIVE_TRAIN_QUERY_STATUS
|
|
autoIncNo = autoIncNo + 1
|
|
data := make([]byte, 0)
|
|
data = append(data, 0x62)
|
|
data = append(data, 0x81)
|
|
data = append(data, 0x02)
|
|
data = append(data, byte(autoIncNo)<<3)
|
|
|
|
data = append(data, boolsToByte([8]bool{true, true, false, false, false, false, false, false}))
|
|
data = append(data, 0) //速度低位
|
|
data = append(data, 0) //当前时间高位
|
|
data = append(data, 0) //当前时间
|
|
data = append(data, 0) //当前时间
|
|
data = append(data, 0) //当前时间低位
|
|
data = append(data, 0) //当前时间低位
|
|
data = append(data, 0) //CRC16-H(MSB
|
|
data = append(data, 0) //CRC16-L(LSB)
|
|
msg.Data = data
|
|
return msg
|
|
}
|
|
|
|
func pcSimNumReportOut() *message.TrainPcSimBaseMessage {
|
|
msg := &message.TrainPcSimBaseMessage{}
|
|
msg.Type = train_pc_sim.RECIVE_TRAIN_MOCK_DATA
|
|
sd := uint16(1234)
|
|
data := make([]byte, 2)
|
|
binary.BigEndian.PutUint16(data, sd)
|
|
msg.Data = data
|
|
return msg
|
|
}
|
|
|
|
// 测试创建连接
|
|
/*func TestConn(t *testing.T) {
|
|
createServer(func(n int, data []byte) {
|
|
|
|
})
|
|
select {}
|
|
}*/
|
|
func startService(port int) {
|
|
createServer(port, func(n int, data []byte) {
|
|
msg := &message.TrainPcSimBaseMessage{}
|
|
d := data[:n]
|
|
msg.Decode(d)
|
|
pd := fmt.Sprintf("%X", d)
|
|
|
|
if msg.Type == train_pc_sim.SENDER_TRAIN_TC_ACTIVE {
|
|
fmt.Println("接收驾驶端激活 port:", port)
|
|
|
|
} else if msg.Type == train_pc_sim.SENDER_TRAIN_TC_NOT_ACTIVE {
|
|
fmt.Println("接收驾驶端未激活 port:", port)
|
|
fmt.Println(pd)
|
|
} else if msg.Type == train_pc_sim.SENDER_TRAIN_OUTR_INFO {
|
|
fmt.Println(pd)
|
|
t := msg.Data[0]
|
|
s := msg.Data[1]
|
|
tt := strconv.Itoa(int(t))
|
|
switch t {
|
|
case 0:
|
|
tt = "驾驶台"
|
|
case 1:
|
|
tt = "手柄向前"
|
|
case 2:
|
|
tt = "手柄向后"
|
|
case 14:
|
|
tt = "手柄归零"
|
|
case 4:
|
|
tt = "制动状态"
|
|
}
|
|
fmt.Println("接受列车输出数字量", tt, s, port)
|
|
fmt.Println(pd)
|
|
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_CREATE_REMOVE {
|
|
state := msg.Data[0]
|
|
if state == 0x01 {
|
|
fmt.Println("创建列车 port:", port)
|
|
} else if state == 0x00 {
|
|
fmt.Println("删除列车 port:", port)
|
|
}
|
|
fmt.Println(pd)
|
|
|
|
} else if msg.Type == train_pc_sim.SENDER_TRAIN_HAND_KEY_FORWARD {
|
|
fmt.Println("列车手柄向前 port:", port)
|
|
fmt.Println(pd)
|
|
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_HAND_KEY_CANCLE_FORWARD {
|
|
fmt.Println("列车手柄取消向前 port:", port)
|
|
fmt.Println(pd)
|
|
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_HAND_KEY_BACKWARD {
|
|
fmt.Println("列车手柄向后 port:", port)
|
|
fmt.Println(pd)
|
|
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_HAND_KEY_CACLE_BACKWARD {
|
|
fmt.Println("列车手柄取消向后 port:", port)
|
|
fmt.Println(pd)
|
|
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_BTM_HAS_DATA {
|
|
fmt.Println("有数据应答 port:", port)
|
|
fmt.Println(pd)
|
|
} else if msg.Type == train_pc_sim.RECIVE_TRAIN_BTM_NOT_DATA {
|
|
|
|
} /*else if msg.Type == train_pc_sim.SENDER_TRAIN_LOCATION_INFO {
|
|
fmt.Println("列车速度位置报告")
|
|
fmt.Println(pd)
|
|
mp := message.TrainSpeedPlaceReportMsg{}
|
|
mp.Decode(msg.Data)
|
|
|
|
}*/
|
|
|
|
})
|
|
}
|
|
func main() {
|
|
port1 := 5600
|
|
port2 := 5601
|
|
go startService(port1)
|
|
go startService(port2)
|
|
//reader := bufio.NewReader(os.Stdin)
|
|
var command string
|
|
for {
|
|
|
|
fmt.Scanln(&command)
|
|
if command != "" {
|
|
fmt.Println(command)
|
|
}
|
|
strs := strings.Split(command, ",")
|
|
if len(strs) < 2 {
|
|
fmt.Println("eeeeeeee")
|
|
command = ""
|
|
continue
|
|
}
|
|
p1s, comm := strs[0], strs[1]
|
|
portInt, _ := strconv.Atoi(p1s)
|
|
serConn := serConnMap[portInt]
|
|
command = comm
|
|
if command == "create-train" {
|
|
msg := connTrain()
|
|
serConn.Write(msg.Encode())
|
|
} else if command == "door-mode" {
|
|
msg := changeDoorMode()
|
|
serConn.Write(msg.Encode())
|
|
} else if command == "info-out" {
|
|
msg := pcSimInfoOut()
|
|
serConn.Write(msg.Encode())
|
|
} else if command == "info-out-report" {
|
|
msg := pcSimInfoOutReport()
|
|
serConn.Write(msg.Encode())
|
|
} else if command == "query-btm" {
|
|
msg := queryBtm()
|
|
serConn.Write(msg.Encode())
|
|
} else if command == "num-out" {
|
|
msg := pcSimNumReportOut()
|
|
serConn.Write(msg.Encode())
|
|
|
|
}
|
|
command = ""
|
|
/*content, _ := reader.ReadString('\n')
|
|
if content == "create-train" {
|
|
}*/
|
|
}
|
|
select {}
|
|
}
|