Exemple #1
0
// DecodeFromBytes decodes the bytes of a Diameter AVP.
// It uses the given application id and dictionary for decoding the bytes.
func (a *AVP) DecodeFromBytes(data []byte, application uint32, dictionary *dict.Parser) error {
	dl := len(data)
	if dl < 8 {
		return fmt.Errorf("Not enough data to decode AVP header: %d bytes", dl)
	}
	a.Code = binary.BigEndian.Uint32(data[0:4])
	a.Flags = data[4]
	a.Length = int(uint24to32(data[5:8]))
	if dl < int(a.Length) {
		return fmt.Errorf("Not enough data to decode AVP: %d != %d",
			dl, a.Length)
	}
	data = data[:a.Length] // this cuts padded bytes off
	var hdrLength int
	var payload []byte
	// Read VendorId when required.
	if a.Flags&avp.Vbit == avp.Vbit {
		a.VendorID = binary.BigEndian.Uint32(data[8:12])
		payload = data[12:]
		hdrLength = 12
	} else {
		payload = data[8:]
		hdrLength = 8
	}
	// Find this code in the dictionary.
	dictAVP, err := dictionary.FindAVPWithVendor(application, a.Code, a.VendorID)
	if err != nil {
		return err
	}
	bodyLen := a.Length - hdrLength
	if n := len(payload); n < bodyLen {
		return fmt.Errorf(
			"Not enough data to decode AVP: %d != %d",
			hdrLength, n,
		)
	}
	a.Data, err = datatype.Decode(dictAVP.Data.Type, payload)
	if err != nil {
		return err
	}
	// Handle grouped AVPs.
	if a.Data.Type() == datatype.GroupedType {
		a.Data, err = DecodeGrouped(
			a.Data.(datatype.Grouped),
			application, dictionary,
		)
		if err != nil {
			return err
		}
	}
	return nil
}