wendy512/iec104

asdu UnmarshalBinary failed,

Closed this issue · 5 comments

测试函数 Client 侧 有报错 asdu UnmarshalBinary failed,导致无法进 hanler 处理逻辑

日志如下
s104 client => 2024/11/26 17:58:10 [D]: RX iFrame I[sendNO: 2, recvNO: 6]
cs104 client => 2024/11/26 17:58:10 [D]: RX iFrame I[sendNO: 3, recvNO: 6]
cs104 client => 2024/11/26 17:58:10 [D]: RX iFrame I[sendNO: 4, recvNO: 6]
cs104 client => 2024/11/26 17:58:10 [D]: RX Raw[68 0e 0a 00 0c 00 01 01 14 00 01 00 64 00 00 01]
cs104 client => 2024/11/26 17:58:10 [W]: asdu UnmarshalBinary failed,EOF
cs104 client => 2024/11/26 17:58:10 [D]: RX iFrame I[sendNO: 5, recvNO: 6]
cs104 client => 2024/11/26 17:58:10 [D]: RX Raw[68 0a 0c 00 0c 00 66 01 0a 00 01 00]
cs104 client => 2024/11/26 17:58:10 [D]: RX Raw[68 0a 0e 00 0c 00 67 01 07 00 01 00]
cs104 client => 2024/11/26 17:58:10 [D]: RX iFrame I[sendNO: 6, recvNO: 6]
cs104 client => 2024/11/26 17:58:10 [D]: RX iFrame I[sendNO: 7, recvNO: 6]
cs104 client => 2024/11/26 17:58:10 [D]: TX sFrame S[recvNO: 8]
cs104 client => 2024/11/26 17:58:10 [D]: ASDU TID<C_CI_NA_1> COT

asduPack.SendReplyMirror(c, asdu.ActivationCon) 好像这个回执报文引起的

老哥能否回复一下

具体在哪块代码报的错?

func (ms *IecHandler) OnInterrogation(conn asdu.Connect, pack *asdu.ASDU, quality asdu.QualifierOfInterrogation) error {
	_ = pack.SendReplyMirror(conn, asdu.ActivationCon)
	// TODO
	_ = asdu.Single(conn, false, asdu.CauseOfTransmission{Cause: asdu.InterrogatedByStation}, commonAddr, asdu.SinglePointInfo{
		Ioa:   100,
		Value: true,
		Qds:   asdu.QDSGood,
	})
	_ = asdu.Double(conn, false, asdu.CauseOfTransmission{Cause: asdu.InterrogatedByStation}, commonAddr, asdu.DoublePointInfo{
		Ioa:   200,
		Value: asdu.DPIDeterminedOn,
		Qds:   asdu.QDSGood,
	})
	_ = pack.SendReplyMirror(conn, asdu.ActivationTerm)
	return nil
}  

server 发送激活确认这个报文,client 收到后,解报文会报错

具体报错代码 会走到io.EOF

// fixInfoObjSize fix information object size
func (sf *ASDU) fixInfoObjSize() error {
	// fixed element size
	objSize, err := GetInfoObjSize(sf.Type)
	if err != nil {
		return err
	}

	var size int
	// read the variable structure qualifier
	if sf.Variable.IsSequence {
		size = sf.InfoObjAddrSize + int(sf.Variable.Number)*objSize
	} else {
		size = int(sf.Variable.Number) * (sf.InfoObjAddrSize + objSize)
	}

	switch {
	case size == 0:
		return ErrInfoObjIndexFit
	case size > len(sf.infoObj):
		return io.EOF
	case size < len(sf.infoObj): // not explicitly prohibited
		sf.infoObj = sf.infoObj[:size]
	}

	return nil
}

测试代码问题,已修复

func (ms *myServerHandler) OnInterrogation(conn asdu.Connect, pack *asdu.ASDU, quality asdu.QualifierOfInterrogation) error {
	//_ = pack.SendReplyMirror(conn, asdu.ActivationCon)
	// TODO
	_ = asdu.Single(conn, false, asdu.CauseOfTransmission{Cause: asdu.InterrogatedByStation}, commonAddr, asdu.SinglePointInfo{
		Ioa:   100,
		Value: true,
		Qds:   asdu.QDSGood,
	})
	_ = asdu.Double(conn, false, asdu.CauseOfTransmission{Cause: asdu.InterrogatedByStation}, commonAddr, asdu.DoublePointInfo{
		Ioa:   200,
		Value: asdu.DPIDeterminedOn,
		Qds:   asdu.QDSGood,
	})
	//_ = pack.SendReplyMirror(conn, asdu.ActivationTerm)
	return nil
}