// 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.Unsigned32Type: i, err := strconv.Atoi(valStr) if err != nil { return nil, err } return datatype.Enumerated(i).Serialize(), nil case datatype.Unsigned64Type, datatype.Integer64Type: i, err := strconv.ParseInt(valStr, 10, 64) if err != nil { return nil, err } return datatype.Unsigned64(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 TestCCRAsSMGenericEvent(t *testing.T) { ccr := &CCR{ // Bare information, just the one needed for answer SessionId: "ccrasgen1", AuthApplicationId: 4, CCRequestType: 3, } ccr.diamMessage = ccr.AsBareDiameterMessage() ccr.diamMessage.NewAVP("Multiple-Services-Credit-Control", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(446, avp.Mbit, 0, &diam.GroupedAVP{ // Used-Service-Unit AVP: []*diam.AVP{ diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(17)), // CC-Time diam.NewAVP(412, avp.Mbit, 0, datatype.Unsigned64(1341)), // CC-Input-Octets diam.NewAVP(414, avp.Mbit, 0, datatype.Unsigned64(3079)), // CC-Output-Octets }, }), diam.NewAVP(432, avp.Mbit, 0, datatype.Unsigned32(99)), }, }) ccr.diamMessage.NewAVP("Multiple-Services-Credit-Control", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(446, avp.Mbit, 0, &diam.GroupedAVP{ // Used-Service-Unit AVP: []*diam.AVP{ diam.NewAVP(452, avp.Mbit, 0, datatype.Enumerated(0)), // Tariff-Change-Usage diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(20)), // CC-Time diam.NewAVP(412, avp.Mbit, 0, datatype.Unsigned64(8046)), // CC-Input-Octets diam.NewAVP(414, avp.Mbit, 0, datatype.Unsigned64(46193)), // CC-Output-Octets }, }), diam.NewAVP(432, avp.Mbit, 0, datatype.Unsigned32(1)), }, }) ccr.diamMessage.NewAVP("FramedIPAddress", avp.Mbit, 0, datatype.OctetString("0AE40041")) cfgFlds := make([]*config.CfgCdrField, 0) eSMGEv := sessionmanager.SMGenericEvent{"EventName": "DIAMETER_CCR"} if rSMGEv, err := ccr.AsSMGenericEvent(cfgFlds); err != nil { t.Error(err) } else if !reflect.DeepEqual(eSMGEv, rSMGEv) { t.Errorf("Expecting: %+v, received: %+v", eSMGEv, rSMGEv) } cfgFlds = []*config.CfgCdrField{ &config.CfgCdrField{ Tag: "LastUsed", FieldFilter: utils.ParseRSRFieldsMustCompile("~Multiple-Services-Credit-Control>Used-Service-Unit>CC-Input-Octets:s/^(.*)$/test/(test);Multiple-Services-Credit-Control>Rating-Group(1)", utils.INFIELD_SEP), FieldId: "LastUsed", Type: "*handler", HandlerId: "*sum", Value: utils.ParseRSRFieldsMustCompile("Multiple-Services-Credit-Control>Used-Service-Unit>CC-Input-Octets;^|;Multiple-Services-Credit-Control>Used-Service-Unit>CC-Output-Octets", utils.INFIELD_SEP), Mandatory: true, }, } eSMGEv = sessionmanager.SMGenericEvent{"EventName": "DIAMETER_CCR", "LastUsed": "54239"} if rSMGEv, err := ccr.AsSMGenericEvent(cfgFlds); err != nil { t.Error(err) } else if !reflect.DeepEqual(eSMGEv, rSMGEv) { t.Errorf("Expecting: %+v, received: %+v", eSMGEv, rSMGEv) } cfgFlds = []*config.CfgCdrField{ &config.CfgCdrField{ Tag: "LastUsed", FieldFilter: utils.ParseRSRFieldsMustCompile("~Multiple-Services-Credit-Control>Used-Service-Unit>CC-Input-Octets:s/^(.*)$/test/(test);Multiple-Services-Credit-Control>Rating-Group(99)", utils.INFIELD_SEP), FieldId: "LastUsed", Type: "*handler", HandlerId: "*sum", Value: utils.ParseRSRFieldsMustCompile("Multiple-Services-Credit-Control>Used-Service-Unit>CC-Input-Octets;^|;Multiple-Services-Credit-Control>Used-Service-Unit>CC-Output-Octets", utils.INFIELD_SEP), Mandatory: true, }, } eSMGEv = sessionmanager.SMGenericEvent{"EventName": "DIAMETER_CCR", "LastUsed": "4420"} if rSMGEv, err := ccr.AsSMGenericEvent(cfgFlds); err != nil { t.Error(err) } else if !reflect.DeepEqual(eSMGEv, rSMGEv) { t.Errorf("Expecting: %+v, received: %+v", eSMGEv, rSMGEv) } }
func TestMessageSetAVPsWithPath(t *testing.T) { eMessage := diam.NewRequest(diam.CreditControl, 4, nil) eMessage.NewAVP("Session-Id", avp.Mbit, 0, datatype.UTF8String("simuhuawei;1449573472;00002")) m := diam.NewMessage(diam.CreditControl, diam.RequestFlag, 4, eMessage.Header.HopByHopID, eMessage.Header.EndToEndID, nil) if err := messageSetAVPsWithPath(m, []interface{}{"Session-Id", "Unknown"}, "simuhuawei;1449573472;00002", false, "UTC"); err == nil || err.Error() != "Could not find AVP Unknown" { t.Error(err) } if err := messageSetAVPsWithPath(m, []interface{}{"Session-Id"}, "simuhuawei;1449573472;00002", false, "UTC"); err != nil { t.Error(err) } else if !reflect.DeepEqual(eMessage, m) { t.Errorf("Expecting: %+v, received: %+v", eMessage, m) } // test append eMessage.NewAVP("Session-Id", avp.Mbit, 0, datatype.UTF8String("simuhuawei;1449573472;00003")) if err := messageSetAVPsWithPath(m, []interface{}{"Session-Id"}, "simuhuawei;1449573472;00003", true, "UTC"); err != nil { t.Error(err) } else if !reflect.DeepEqual(eMessage, m) { t.Errorf("Expecting: %+v, received: %+v", eMessage, m) } // test overwrite eMessage = diam.NewRequest(diam.CreditControl, 4, nil) eMessage.NewAVP("Session-Id", avp.Mbit, 0, datatype.UTF8String("simuhuawei;1449573472;00002")) m = diam.NewMessage(diam.CreditControl, diam.RequestFlag, 4, eMessage.Header.HopByHopID, eMessage.Header.EndToEndID, nil) if err := messageSetAVPsWithPath(m, []interface{}{"Session-Id"}, "simuhuawei;1449573472;00001", false, "UTC"); err != nil { t.Error(err) } if err := messageSetAVPsWithPath(m, []interface{}{"Session-Id"}, "simuhuawei;1449573472;00002", false, "UTC"); err != nil { t.Error(err) } else if !reflect.DeepEqual(eMessage, m) { t.Errorf("Expecting: %+v, received: %+v", eMessage, m) } eMessage = diam.NewRequest(diam.CreditControl, 4, nil) eMessage.NewAVP("Subscription-Id", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("33708000003")), // Subscription-Id-Data }}) m = diam.NewMessage(diam.CreditControl, diam.RequestFlag, 4, eMessage.Header.HopByHopID, eMessage.Header.EndToEndID, nil) if err := messageSetAVPsWithPath(m, []interface{}{"Subscription-Id", "Subscription-Id-Data"}, "33708000003", false, "UTC"); err != nil { t.Error(err) } else if !reflect.DeepEqual(eMessage, m) { t.Errorf("Expecting: %+v, received: %+v", eMessage, m) } // test append eMessage.NewAVP("Subscription-Id", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(0)), // Subscription-Id-Data }}) if err := messageSetAVPsWithPath(m, []interface{}{"Subscription-Id", "Subscription-Id-Type"}, "0", true, "UTC"); err != nil { t.Error(err) } else if !reflect.DeepEqual(eMessage, m) { t.Errorf("Expecting: %+v, received: %+v", eMessage, m) } // test group append eMessage = diam.NewRequest(diam.CreditControl, 4, nil) eMessage.NewAVP("Subscription-Id", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(0)), // Subscription-Id-Data diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("33708000003")), // Subscription-Id-Data }}) eMsgSrl, _ := eMessage.Serialize() m = diam.NewMessage(diam.CreditControl, diam.RequestFlag, 4, eMessage.Header.HopByHopID, eMessage.Header.EndToEndID, nil) if err := messageSetAVPsWithPath(m, []interface{}{"Subscription-Id", "Subscription-Id-Type"}, "0", false, "UTC"); err != nil { t.Error(err) } if err := messageSetAVPsWithPath(m, []interface{}{"Subscription-Id", "Subscription-Id-Data"}, "33708000003", false, "UTC"); err != nil { t.Error(err) } else { mSrl, _ := m.Serialize() if !bytes.Equal(eMsgSrl, mSrl) { t.Errorf("Expecting: %+v, received: %+v", eMessage, m) } } eMessage = diam.NewRequest(diam.CreditControl, 4, nil) eMessage.NewAVP("Granted-Service-Unit", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(300)), // Subscription-Id-Data }}) m = diam.NewMessage(diam.CreditControl, diam.RequestFlag, 4, eMessage.Header.HopByHopID, eMessage.Header.EndToEndID, nil) if err := messageSetAVPsWithPath(m, []interface{}{"Granted-Service-Unit", "CC-Time"}, "300", false, "UTC"); err != nil { t.Error(err) } else if !reflect.DeepEqual(eMessage, m) { t.Errorf("Expecting: %+v, received: %+v", eMessage, m) } // Multiple append eMessage = diam.NewRequest(diam.CreditControl, 4, nil) eMessage.NewAVP("Multiple-Services-Credit-Control", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(431, avp.Mbit, 0, &diam.GroupedAVP{ // Granted-Service-Unit AVP: []*diam.AVP{ diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(3600)), diam.NewAVP(421, avp.Mbit, 0, datatype.Unsigned64(153600)), // "CC-Total-Octets" }, }), diam.NewAVP(432, avp.Mbit, 0, datatype.Unsigned32(10)), }, }) eMessage.NewAVP("Multiple-Services-Credit-Control", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(431, avp.Mbit, 0, &diam.GroupedAVP{ // Granted-Service-Unit AVP: []*diam.AVP{ diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(2600)), diam.NewAVP(421, avp.Mbit, 0, datatype.Unsigned64(143600)), // "CC-Total-Octets" }, }), diam.NewAVP(432, avp.Mbit, 0, datatype.Unsigned32(11)), // Rating-Group }, }) m = diam.NewMessage(diam.CreditControl, diam.RequestFlag, 4, eMessage.Header.HopByHopID, eMessage.Header.EndToEndID, nil) if err := messageSetAVPsWithPath(m, []interface{}{"Multiple-Services-Credit-Control", "Granted-Service-Unit", "CC-Time"}, "3600", false, "UTC"); err != nil { t.Error(err) } if err := messageSetAVPsWithPath(m, []interface{}{"Multiple-Services-Credit-Control", "Granted-Service-Unit", "CC-Total-Octets"}, "153600", false, "UTC"); err != nil { t.Error(err) } if err := messageSetAVPsWithPath(m, []interface{}{"Multiple-Services-Credit-Control", "Rating-Group"}, "10", false, "UTC"); err != nil { t.Error(err) } if err := messageSetAVPsWithPath(m, []interface{}{"Multiple-Services-Credit-Control", "Granted-Service-Unit", "CC-Time"}, "2600", true, "UTC"); err != nil { t.Error(err) } if err := messageSetAVPsWithPath(m, []interface{}{"Multiple-Services-Credit-Control", "Granted-Service-Unit", "CC-Total-Octets"}, "143600", false, "UTC"); err != nil { t.Error(err) } if err := messageSetAVPsWithPath(m, []interface{}{"Multiple-Services-Credit-Control", "Rating-Group"}, "11", false, "UTC"); err != nil { t.Error(err) } if fmt.Sprintf("%q", eMessage) != fmt.Sprintf("%q", m) { // test with fmt since reflect.DeepEqual does not perform properly here t.Errorf("Expecting: %+v, received: %+v", eMessage, m) } }
func TestDmtAgentSendDataGrpTerminate(t *testing.T) { ccr := diam.NewRequest(diam.CreditControl, 4, nil) ccr.NewAVP(avp.SessionID, avp.Mbit, 0, datatype.UTF8String("testdatagrp")) ccr.NewAVP(avp.OriginHost, avp.Mbit, 0, datatype.DiameterIdentity("CGR-DA")) ccr.NewAVP(avp.OriginRealm, avp.Mbit, 0, datatype.DiameterIdentity("cgrates.org")) ccr.NewAVP(avp.AuthApplicationID, avp.Mbit, 0, datatype.Unsigned32(4)) ccr.NewAVP(avp.ServiceContextID, avp.Mbit, 0, datatype.UTF8String("*****@*****.**")) ccr.NewAVP(avp.CCRequestType, avp.Mbit, 0, datatype.Enumerated(3)) ccr.NewAVP(avp.CCRequestNumber, avp.Mbit, 0, datatype.Unsigned32(1)) ccr.NewAVP(avp.EventTimestamp, avp.Mbit, 0, datatype.Time(time.Date(2016, 1, 5, 11, 30, 10, 0, time.UTC))) ccr.NewAVP(avp.SubscriptionID, avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(avp.SubscriptionIDType, avp.Mbit, 0, datatype.Enumerated(0)), diam.NewAVP(avp.SubscriptionIDData, avp.Mbit, 0, datatype.UTF8String("1001")), // Subscription-Id-Data }}) ccr.NewAVP(avp.SubscriptionID, avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(avp.SubscriptionIDType, avp.Mbit, 0, datatype.Enumerated(1)), diam.NewAVP(avp.SubscriptionIDData, avp.Mbit, 0, datatype.UTF8String("104502200011")), // Subscription-Id-Data }}) ccr.NewAVP(avp.ServiceIdentifier, avp.Mbit, 0, datatype.Unsigned32(0)) ccr.NewAVP(avp.RequestedAction, avp.Mbit, 0, datatype.Enumerated(0)) ccr.NewAVP(avp.RequestedServiceUnit, avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(avp.CCTime, avp.Mbit, 0, datatype.Unsigned32(1))}}) ccr.NewAVP(873, avp.Mbit, 10415, &diam.GroupedAVP{ // AVP: []*diam.AVP{ diam.NewAVP(20300, avp.Mbit, 2011, &diam.GroupedAVP{ // IN-Information AVP: []*diam.AVP{ diam.NewAVP(20302, avp.Mbit, 2011, datatype.UTF8String("22509")), // Calling-Vlr-Number diam.NewAVP(20385, avp.Mbit, 2011, datatype.UTF8String("4002")), // Called-Party-NP }, }), diam.NewAVP(2000, avp.Mbit, 10415, &diam.GroupedAVP{ // SMS-Information AVP: []*diam.AVP{ diam.NewAVP(886, avp.Mbit, 10415, &diam.GroupedAVP{ // Originator-Address AVP: []*diam.AVP{ diam.NewAVP(899, avp.Mbit, 10415, datatype.Enumerated(1)), // Address-Type diam.NewAVP(897, avp.Mbit, 10415, datatype.UTF8String("1003")), // Address-Data }}), diam.NewAVP(1201, avp.Mbit, 10415, &diam.GroupedAVP{ // Recipient-Address AVP: []*diam.AVP{ diam.NewAVP(899, avp.Mbit, 10415, datatype.Enumerated(1)), // Address-Type diam.NewAVP(897, avp.Mbit, 10415, datatype.UTF8String("1002")), // Address-Data }}), }, }), }}) ccr.NewAVP("Multiple-Services-Credit-Control", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(446, avp.Mbit, 0, &diam.GroupedAVP{ // Used-Service-Unit AVP: []*diam.AVP{ diam.NewAVP(452, avp.Mbit, 0, datatype.Enumerated(0)), // Tariff-Change-Usage diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(20)), // CC-Time diam.NewAVP(412, avp.Mbit, 0, datatype.Unsigned64(512)), // CC-Input-Octets diam.NewAVP(414, avp.Mbit, 0, datatype.Unsigned64(0)), // CC-Output-Octets }, }), }, }) if err := dmtClient.SendMessage(ccr); err != nil { t.Error(err) } time.Sleep(time.Duration(3000) * time.Millisecond) msg := dmtClient.ReceivedMessage(rplyTimeout) if msg == nil { t.Fatal("No message returned") } if avps, err := msg.FindAVPsWithPath([]interface{}{"Result-Code"}, dict.UndefinedVendorID); err != nil { t.Error(err) } else if len(avps) == 0 { t.Error("Result-Code not found") } else if resCode := avpValAsString(avps[0]); resCode != "2001" { t.Errorf("Expecting 2001, received: %s", resCode) } }