From fb60f37f784cd8cf0328c4dcf4b5c1e3005e55cc Mon Sep 17 00:00:00 2001 From: DanB Date: Wed, 23 Dec 2015 10:20:21 +0100 Subject: [PATCH] Diameter serializeAVPValueFromString with tests --- agents/libdmt.go | 41 +++++++++++++++++++++++++++++++++++++++++ agents/libdmt_test.go | 26 ++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/agents/libdmt.go b/agents/libdmt.go index fe3e7581e..13e2e441d 100644 --- a/agents/libdmt.go +++ b/agents/libdmt.go @@ -27,6 +27,7 @@ import ( "fmt" "math" "math/rand" + "net" "os" "path/filepath" "strconv" @@ -269,6 +270,46 @@ func composedFieldvalue(m *diam.Message, outTpl utils.RSRFields, avpIdx int) str return outVal } +// Used to return the encoded value based on what AVP understands for it's type +func serializeAVPValueFromString(dictAVP *dict.AVP, valStr, timezone string) ([]byte, error) { + switch dictAVP.Data.Type { + case datatype.OctetStringType, datatype.DiameterIdentityType, datatype.DiameterURIType, datatype.IPFilterRuleType, datatype.QoSFilterRuleType, datatype.UTF8StringType: + return []byte(valStr), nil + case datatype.AddressType: + return []byte(net.ParseIP(valStr)), nil + case datatype.EnumeratedType, datatype.Integer32Type, datatype.Integer64Type, datatype.Unsigned32Type, datatype.Unsigned64Type: + i, err := strconv.Atoi(valStr) + if err != nil { + return nil, err + } + return datatype.Enumerated(i).Serialize(), nil + case datatype.Float32Type: + f, err := strconv.ParseFloat(valStr, 32) + if err != nil { + return nil, err + } + return datatype.Float32(f).Serialize(), nil + case datatype.Float64Type: + f, err := strconv.ParseFloat(valStr, 64) + if err != nil { + return nil, err + } + return datatype.Float64(f).Serialize(), nil + case datatype.GroupedType: + return nil, errors.New("GroupedType not supported for serialization") + case datatype.IPv4Type: + return datatype.IPv4(net.ParseIP(valStr)).Serialize(), nil + case datatype.TimeType: + t, err := utils.ParseTimeDetectLayout(valStr, timezone) + if err != nil { + return nil, err + } + return datatype.Time(t).Serialize(), nil + default: + return nil, fmt.Errorf("Unsupported type for serialization: %v", dictAVP.Data.Type) + } +} + func fieldOutVal(m *diam.Message, cfgFld *config.CfgCdrField, extraParam interface{}) (fmtValOut string, err error) { var outVal string switch cfgFld.Type { diff --git a/agents/libdmt_test.go b/agents/libdmt_test.go index cfba48efa..3bbbe1dfc 100644 --- a/agents/libdmt_test.go +++ b/agents/libdmt_test.go @@ -20,6 +20,7 @@ package agents import ( "bytes" + "encoding/binary" "reflect" "testing" "time" @@ -29,6 +30,7 @@ import ( "github.com/fiorix/go-diameter/diam" "github.com/fiorix/go-diameter/diam/avp" "github.com/fiorix/go-diameter/diam/datatype" + "github.com/fiorix/go-diameter/diam/dict" ) func TestDisectUsageForCCR(t *testing.T) { @@ -138,6 +140,24 @@ func TestFieldOutVal(t *testing.T) { } } +func TestSerializeAVPValueFromString(t *testing.T) { + dictAVP, _ := dict.Default.FindAVP(4, "Session-Id") + eValByte := []byte("simuhuawei;1449573472;00002") + if valByte, err := serializeAVPValueFromString(dictAVP, "simuhuawei;1449573472;00002", "UTC"); err != nil { + t.Error(err) + } else if !bytes.Equal(eValByte, valByte) { + t.Errorf("Expecting: %+v, received: %+v", eValByte, valByte) + } + dictAVP, _ = dict.Default.FindAVP(4, "Result-Code") + eValByte = make([]byte, 4) + binary.BigEndian.PutUint32(eValByte, uint32(5031)) + if valByte, err := serializeAVPValueFromString(dictAVP, "5031", "UTC"); err != nil { + t.Error(err) + } else if !bytes.Equal(eValByte, valByte) { + t.Errorf("Expecting: %+v, received: %+v", eValByte, valByte) + } +} + func TestMessageSetAVPsWithPath(t *testing.T) { eMessage := diam.NewRequest(diam.CreditControl, 4, nil) eMessage.NewAVP("Session-Id", avp.Mbit, 0, datatype.UTF8String("simuhuawei;1449573472;00002")) @@ -244,9 +264,11 @@ func TestCCASetProcessorAVPs(t *testing.T) { reqProcessor := &config.DARequestProcessor{Id: "UNIT_TEST", // Set template for tests CCAFields: []*config.CfgCdrField{ &config.CfgCdrField{Tag: "Subscription-Id/Subscription-Id-Type", Type: utils.META_COMPOSED, - Value: utils.ParseRSRFieldsMustCompile("Subscription-Id>Subscription-Id-Type", utils.INFIELD_SEP), Mandatory: true}, + FieldId: "Subscription-Id>Subscription-Id-Type", + Value: utils.ParseRSRFieldsMustCompile("Subscription-Id>Subscription-Id-Type", utils.INFIELD_SEP), Mandatory: true}, &config.CfgCdrField{Tag: "Subscription-Id/Subscription-Id-Data", Type: utils.META_COMPOSED, - Value: utils.ParseRSRFieldsMustCompile("Subscription-Id>Subscription-Id-Data", utils.INFIELD_SEP), Mandatory: true}, + FieldId: "Subscription-Id>Subscription-Id-Data", + Value: utils.ParseRSRFieldsMustCompile("Subscription-Id>Subscription-Id-Data", utils.INFIELD_SEP), Mandatory: true}, }, } eMessage := cca.AsDiameterMessage()