func()

in ptp/protocol/unicast.go [92:152]


func (p *Signaling) UnmarshalBinary(b []byte) error {
	if len(b) < headerSize+10+tlvHeadSize {
		return fmt.Errorf("not enough data to decode Signaling")
	}
	unmarshalHeader(&p.Header, b)
	if p.SdoIDAndMsgType.MsgType() != MessageSignaling {
		return fmt.Errorf("not a signaling message %v", b)
	}
	p.TargetPortIdentity.ClockIdentity = ClockIdentity(binary.BigEndian.Uint64(b[headerSize:]))
	p.TargetPortIdentity.PortNumber = binary.BigEndian.Uint16(b[headerSize+8:])

	pos := headerSize + 10
	var tlvType TLVType
	for {
		head := TLVHead{}
		// packet can have trailing bytes, let's make sure we don't try to read past given length
		if pos+tlvHeadSize > int(p.MessageLength) {
			break
		}
		tlvType = TLVType(binary.BigEndian.Uint16(b[pos:]))

		switch tlvType {
		case TLVAcknowledgeCancelUnicastTransmission:
			tlv := &AcknowledgeCancelUnicastTransmissionTLV{}
			if err := tlv.UnmarshalBinary(b[pos:]); err != nil {
				return err
			}
			p.TLVs = append(p.TLVs, tlv)
			pos += tlvHeadSize + int(tlv.LengthField)

		case TLVGrantUnicastTransmission:
			tlv := &GrantUnicastTransmissionTLV{}
			if err := tlv.UnmarshalBinary(b[pos:]); err != nil {
				return err
			}
			p.TLVs = append(p.TLVs, tlv)
			pos += tlvHeadSize + int(tlv.LengthField)

		case TLVRequestUnicastTransmission:
			tlv := &RequestUnicastTransmissionTLV{}
			if err := tlv.UnmarshalBinary(b[pos:]); err != nil {
				return err
			}
			p.TLVs = append(p.TLVs, tlv)
			pos += tlvHeadSize + int(tlv.LengthField)
		case TLVCancelUnicastTransmission:
			tlv := &CancelUnicastTransmissionTLV{}
			if err := tlv.UnmarshalBinary(b[pos:]); err != nil {
				return err
			}
			p.TLVs = append(p.TLVs, tlv)
			pos += tlvHeadSize + int(tlv.LengthField)
		default:
			return fmt.Errorf("reading TLV %s (%d) is not yet implemented", head.TLVType, head.TLVType)
		}
	}
	if len(p.TLVs) == 0 {
		return fmt.Errorf("no TLVs read for Signaling message, at least one required")
	}
	return nil
}