// Converts itself into DiameterMessage func (self *CCA) AsDiameterMessage() (*diam.Message, error) { if _, err := self.diamMessage.NewAVP("Session-Id", avp.Mbit, 0, datatype.UTF8String(self.SessionId)); err != nil { return nil, err } if _, err := self.diamMessage.NewAVP("Origin-Host", avp.Mbit, 0, datatype.DiameterIdentity(self.OriginHost)); err != nil { return nil, err } if _, err := self.diamMessage.NewAVP("Origin-Realm", avp.Mbit, 0, datatype.DiameterIdentity(self.OriginRealm)); err != nil { return nil, err } if _, err := self.diamMessage.NewAVP("Auth-Application-Id", avp.Mbit, 0, datatype.Unsigned32(self.AuthApplicationId)); err != nil { return nil, err } if _, err := self.diamMessage.NewAVP("CC-Request-Type", avp.Mbit, 0, datatype.Enumerated(self.CCRequestType)); err != nil { return nil, err } if _, err := self.diamMessage.NewAVP("CC-Request-Number", avp.Mbit, 0, datatype.Enumerated(self.CCRequestNumber)); err != nil { return nil, err } if _, err := self.diamMessage.NewAVP(avp.ResultCode, avp.Mbit, 0, datatype.Unsigned32(self.ResultCode)); err != nil { return nil, err } ccTimeAvp, err := self.diamMessage.Dictionary().FindAVP(self.diamMessage.Header.ApplicationID, "CC-Time") if err != nil { return nil, err } if _, err := self.diamMessage.NewAVP("Granted-Service-Unit", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(ccTimeAvp.Code, avp.Mbit, 0, datatype.Unsigned32(self.GrantedServiceUnit.CCTime))}}); err != nil { return nil, err } return self.diamMessage, nil }
func TestFieldOutVal(t *testing.T) { m := diam.NewRequest(diam.CreditControl, 4, nil) m.NewAVP("Session-Id", avp.Mbit, 0, datatype.UTF8String("simuhuawei;1449573472;00002")) m.NewAVP("Subscription-Id", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(0)), // Subscription-Id-Type diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("33708000003")), // Subscription-Id-Data }}) m.NewAVP("Subscription-Id", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(1)), // Subscription-Id-Type diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("208708000003")), // Subscription-Id-Data }}) m.NewAVP("Service-Identifier", avp.Mbit, 0, datatype.Unsigned32(0)) m.NewAVP("Requested-Service-Unit", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(360))}}) // CC-Time cfgFld := &config.CfgCdrField{Tag: "StaticTest", Type: utils.META_COMPOSED, FieldId: utils.TOR, Value: utils.ParseRSRFieldsMustCompile("^*voice", utils.INFIELD_SEP), Mandatory: true} eOut := "*voice" if fldOut, err := fieldOutVal(m, cfgFld, time.Duration(0)); err != nil { t.Error(err) } else if fldOut != eOut { t.Errorf("Expecting: %s, received: %s", eOut, fldOut) } cfgFld = &config.CfgCdrField{Tag: "ComposedTest", Type: utils.META_COMPOSED, FieldId: utils.DESTINATION, Value: utils.ParseRSRFieldsMustCompile("Requested-Service-Unit>CC-Time", utils.INFIELD_SEP), Mandatory: true} eOut = "360" if fldOut, err := fieldOutVal(m, cfgFld, time.Duration(0)); err != nil { t.Error(err) } else if fldOut != eOut { t.Errorf("Expecting: %s, received: %s", eOut, fldOut) } // Without filter, we shoud get always the first subscriptionId cfgFld = &config.CfgCdrField{Tag: "Grouped1", Type: utils.MetaGrouped, FieldId: "Account", Value: utils.ParseRSRFieldsMustCompile("Subscription-Id>Subscription-Id-Data", utils.INFIELD_SEP), Mandatory: true} eOut = "33708000003" if fldOut, err := fieldOutVal(m, cfgFld, time.Duration(0)); err != nil { t.Error(err) } else if fldOut != eOut { t.Errorf("Expecting: %s, received: %s", eOut, fldOut) } // Without groupedAVP, we shoud get the first subscriptionId cfgFld = &config.CfgCdrField{Tag: "Grouped2", Type: utils.MetaGrouped, FieldId: "Account", FieldFilter: utils.ParseRSRFieldsMustCompile("Subscription-Id>Subscription-Id-Type(1)", utils.INFIELD_SEP), Value: utils.ParseRSRFieldsMustCompile("Subscription-Id>Subscription-Id-Data", utils.INFIELD_SEP), Mandatory: true} eOut = "208708000003" if fldOut, err := fieldOutVal(m, cfgFld, time.Duration(0)); err != nil { t.Error(err) } else if fldOut != eOut { t.Errorf("Expecting: %s, received: %s", eOut, fldOut) } }
// AsBareDiameterMessage converts CCA into a bare DiameterMessage func (self *CCA) AsBareDiameterMessage() *diam.Message { var m diam.Message utils.Clone(self.diamMessage, &m) m.NewAVP(avp.SessionID, avp.Mbit, 0, datatype.UTF8String(self.SessionId)) m.NewAVP(avp.OriginHost, avp.Mbit, 0, datatype.DiameterIdentity(self.OriginHost)) m.NewAVP(avp.OriginRealm, avp.Mbit, 0, datatype.DiameterIdentity(self.OriginRealm)) m.NewAVP(avp.AuthApplicationID, avp.Mbit, 0, datatype.Unsigned32(self.AuthApplicationId)) m.NewAVP(avp.CCRequestType, avp.Mbit, 0, datatype.Enumerated(self.CCRequestType)) m.NewAVP(avp.CCRequestNumber, avp.Mbit, 0, datatype.Enumerated(self.CCRequestNumber)) m.NewAVP(avp.ResultCode, avp.Mbit, 0, datatype.Unsigned32(self.ResultCode)) return &m }
func storedCdrToCCR(cdr *engine.StoredCdr, originHost, originRealm string, vendorId int, productName string, firmwareRev int, debitInterval time.Duration, callEnded bool) *diam.Message { sid := "session;" + strconv.Itoa(int(rand.Uint32())) reqType, reqNr, ccTime := disectUsageForCCR(cdr.Usage, debitInterval, callEnded) m := diam.NewRequest(272, 4, nil) m.NewAVP(avp.SessionID, avp.Mbit, 0, datatype.UTF8String(sid)) m.NewAVP(avp.OriginHost, avp.Mbit, 0, datatype.DiameterIdentity(originHost)) m.NewAVP(avp.OriginRealm, avp.Mbit, 0, datatype.DiameterIdentity(originRealm)) m.NewAVP(avp.DestinationHost, avp.Mbit, 0, datatype.DiameterIdentity(originHost)) m.NewAVP(avp.DestinationRealm, avp.Mbit, 0, datatype.DiameterIdentity(originRealm)) m.NewAVP(avp.AuthApplicationID, avp.Mbit, 0, datatype.Unsigned32(4)) m.NewAVP(avp.ServiceContextID, avp.Mbit, 0, datatype.UTF8String("*****@*****.**")) m.NewAVP(avp.CCRequestType, avp.Mbit, 0, datatype.Enumerated(reqType)) m.NewAVP(avp.CCRequestNumber, avp.Mbit, 0, datatype.Enumerated(reqNr)) m.NewAVP(avp.EventTimestamp, avp.Mbit, 0, datatype.Time(cdr.AnswerTime)) m.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(cdr.Account)), }}) m.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("20921006232651")), }}) m.NewAVP(avp.ServiceIdentifier, avp.Mbit, 0, datatype.Unsigned32(0)) m.NewAVP(avp.RequestedServiceUnit, avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(avp.CCTime, avp.Mbit, 0, datatype.Unsigned32(ccTime))}}) /* m.NewAVP(avp.ServiceInformation, avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(20300, avp.Mbit, 0, &diam.GroupedAVP{ // IN-Information AVP: []*diam.AVP{ diam.NewAVP(avp.CallingPartyAddress, avp.Mbit, 0, datatype.UTF8String(cdr.Account)), diam.NewAVP(avp.CalledPartyAddress, avp.Mbit, 0, datatype.UTF8String(cdr.Destination)), diam.NewAVP(20327, avp.Mbit, 0, datatype.UTF8String(cdr.Destination)), // Real-Called-Number diam.NewAVP(20339, avp.Mbit, 0, datatype.Unsigned32(0)), // Charge-Flow-Type diam.NewAVP(20302, avp.Mbit, 0, datatype.UTF8String("33657954968")), // Calling-Vlr-Number diam.NewAVP(20303, avp.Mbit, 0, datatype.UTF8String("31901485301525")), // Calling-CellID-Or-SAI diam.NewAVP(avp.BearerCapability, avp.Mbit, 0, datatype.UTF8String("31901485301525")), diam.NewAVP(20321, avp.Mbit, 0, datatype.UTF8String("31901485301525")), // Call-Reference-Number diam.NewAVP(avp.MSCAddress, avp.Mbit, 0, datatype.UTF8String("")), diam.NewAVP(20324, avp.Mbit, 0, datatype.UTF8String("0")), // Time-Zone diam.NewAVP(20385, avp.Mbit, 0, datatype.UTF8String("")), // Called-Party-NP diam.NewAVP(20386, avp.Mbit, 0, datatype.UTF8String("20091020120101")), // SSP-Time }, }), }}) */ return m }
func TestDmtAgentDryRun1(t *testing.T) { if !*testIntegration { return } ccr := diam.NewRequest(diam.CreditControl, 4, nil) ccr.NewAVP(avp.SessionID, avp.Mbit, 0, datatype.UTF8String("cgrates;1451911932;00082")) 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("pubsub1")) // Match specific DryRun profile ccr.NewAVP(avp.CCRequestType, avp.Mbit, 0, datatype.Enumerated(4)) ccr.NewAVP(avp.CCRequestNumber, avp.Mbit, 0, datatype.Unsigned32(0)) ccr.NewAVP(avp.EventTimestamp, avp.Mbit, 0, datatype.Time(time.Date(2016, 1, 5, 11, 30, 10, 0, time.UTC))) if _, err := ccr.NewAVP("Framed-IP-Address", avp.Mbit, 0, datatype.UTF8String("10.228.16.4")); err != nil { t.Error(err) } if err := dmtClient.SendMessage(ccr); err != nil { t.Error(err) } time.Sleep(time.Duration(100) * time.Millisecond) msg := dmtClient.ReceivedMessage() 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") } else if strResult := avpValAsString(avps[0]); strResult != "300" { // Result-Code set in the template t.Errorf("Expecting 300, received: %s", strResult) } }
// Used when sending from client to agent func (self *CCR) AsDiameterMessage() (*diam.Message, error) { m := self.AsBareDiameterMessage() if _, err := m.NewAVP("Destination-Host", avp.Mbit, 0, datatype.DiameterIdentity(self.DestinationHost)); err != nil { return nil, err } if _, err := m.NewAVP("Destination-Realm", avp.Mbit, 0, datatype.DiameterIdentity(self.DestinationRealm)); err != nil { return nil, err } if _, err := m.NewAVP("Service-Context-Id", avp.Mbit, 0, datatype.UTF8String(self.ServiceContextId)); err != nil { return nil, err } if _, err := m.NewAVP("Event-Timestamp", avp.Mbit, 0, datatype.Time(self.EventTimestamp)); err != nil { return nil, err } for _, subscriptionId := range self.SubscriptionId { if _, err := m.NewAVP("Subscription-Id", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(subscriptionId.SubscriptionIdType)), // Subscription-Id-Type diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String(subscriptionId.SubscriptionIdData)), // Subscription-Id-Data }}); err != nil { return nil, err } } if _, err := m.NewAVP("Service-Identifier", avp.Mbit, 0, datatype.Unsigned32(self.ServiceIdentifier)); err != nil { return nil, err } if _, err := m.NewAVP("Requested-Service-Unit", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(self.RequestedServiceUnit.CCTime))}}); err != nil { // CC-Time return nil, err } if _, err := m.NewAVP("Used-Service-Unit", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(self.UsedServiceUnit.CCTime))}}); err != nil { // CC-Time return nil, err } if _, err := m.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(831, avp.Mbit, 10415, datatype.UTF8String(self.ServiceInformation.INInformation.CallingPartyAddress)), // Calling-Party-Address diam.NewAVP(832, avp.Mbit, 10415, datatype.UTF8String(self.ServiceInformation.INInformation.CalledPartyAddress)), // Called-Party-Address diam.NewAVP(20327, avp.Mbit, 2011, datatype.UTF8String(self.ServiceInformation.INInformation.RealCalledNumber)), // Real-Called-Number diam.NewAVP(20339, avp.Mbit, 2011, datatype.Unsigned32(self.ServiceInformation.INInformation.ChargeFlowType)), // Charge-Flow-Type diam.NewAVP(20302, avp.Mbit, 2011, datatype.UTF8String(self.ServiceInformation.INInformation.CallingVlrNumber)), // Calling-Vlr-Number diam.NewAVP(20303, avp.Mbit, 2011, datatype.UTF8String(self.ServiceInformation.INInformation.CallingCellIDOrSAI)), // Calling-CellID-Or-SAI diam.NewAVP(20313, avp.Mbit, 2011, datatype.UTF8String(self.ServiceInformation.INInformation.BearerCapability)), // Bearer-Capability diam.NewAVP(20321, avp.Mbit, 2011, datatype.UTF8String(self.ServiceInformation.INInformation.CallReferenceNumber)), // Call-Reference-Number diam.NewAVP(20322, avp.Mbit, 2011, datatype.UTF8String(self.ServiceInformation.INInformation.MSCAddress)), // MSC-Address diam.NewAVP(20324, avp.Mbit, 2011, datatype.Unsigned32(self.ServiceInformation.INInformation.TimeZone)), // Time-Zone diam.NewAVP(20385, avp.Mbit, 2011, datatype.UTF8String(self.ServiceInformation.INInformation.CalledPartyNP)), // Called-Party-NP diam.NewAVP(20386, avp.Mbit, 2011, datatype.UTF8String(self.ServiceInformation.INInformation.SSPTime)), // SSP-Time }, }), }}); err != nil { return nil, err } return m, nil }
// Handler for meta functions func metaHandler(m *diam.Message, tag, arg string, dur time.Duration) (string, error) { switch tag { case META_CCR_USAGE: var ok bool var reqType datatype.Enumerated var reqNr, reqUnit, usedUnit datatype.Unsigned32 if ccReqTypeAvp, err := m.FindAVP("CC-Request-Type", 0); err != nil { return "", err } else if ccReqTypeAvp == nil { return "", errors.New("CC-Request-Type not found") } else if reqType, ok = ccReqTypeAvp.Data.(datatype.Enumerated); !ok { return "", fmt.Errorf("CC-Request-Type must be Enumerated and not %v", ccReqTypeAvp.Data.Type()) } if ccReqNrAvp, err := m.FindAVP("CC-Request-Number", 0); err != nil { return "", err } else if ccReqNrAvp == nil { return "", errors.New("CC-Request-Number not found") } else if reqNr, ok = ccReqNrAvp.Data.(datatype.Unsigned32); !ok { return "", fmt.Errorf("CC-Request-Number must be Unsigned32 and not %v", ccReqNrAvp.Data.Type()) } switch reqType { case datatype.Enumerated(1), datatype.Enumerated(2): if reqUnitAVPs, err := m.FindAVPsWithPath([]interface{}{"Requested-Service-Unit", "CC-Time"}, dict.UndefinedVendorID); err != nil { return "", err } else if len(reqUnitAVPs) == 0 { return "", errors.New("Requested-Service-Unit>CC-Time not found") } else if reqUnit, ok = reqUnitAVPs[0].Data.(datatype.Unsigned32); !ok { return "", fmt.Errorf("Requested-Service-Unit>CC-Time must be Unsigned32 and not %v", reqUnitAVPs[0].Data.Type()) } case datatype.Enumerated(3), datatype.Enumerated(4): if usedUnitAVPs, err := m.FindAVPsWithPath([]interface{}{"Used-Service-Unit", "CC-Time"}, dict.UndefinedVendorID); err != nil { return "", err } else if len(usedUnitAVPs) != 0 { if usedUnit, ok = usedUnitAVPs[0].Data.(datatype.Unsigned32); !ok { return "", fmt.Errorf("Used-Service-Unit>CC-Time must be Unsigned32 and not %v", usedUnitAVPs[0].Data.Type()) } } } usage := usageFromCCR(int(reqType), int(reqNr), int(reqUnit), int(usedUnit), dur) return strconv.FormatFloat(usage.Seconds(), 'f', -1, 64), nil } return "", nil }
// AsBareDiameterMessage converts CCR into a bare DiameterMessage // Compatible with the required fields of CCA func (self *CCR) AsBareDiameterMessage() *diam.Message { m := diam.NewRequest(diam.CreditControl, 4, nil) m.NewAVP(avp.SessionID, avp.Mbit, 0, datatype.UTF8String(self.SessionId)) m.NewAVP(avp.OriginHost, avp.Mbit, 0, datatype.DiameterIdentity(self.OriginHost)) m.NewAVP(avp.OriginRealm, avp.Mbit, 0, datatype.DiameterIdentity(self.OriginRealm)) m.NewAVP(avp.AuthApplicationID, avp.Mbit, 0, datatype.Unsigned32(self.AuthApplicationId)) m.NewAVP(avp.CCRequestType, avp.Mbit, 0, datatype.Enumerated(self.CCRequestType)) m.NewAVP(avp.CCRequestNumber, avp.Mbit, 0, datatype.Unsigned32(self.CCRequestNumber)) return m }
func TestCCASetProcessorAVPs(t *testing.T) { ccr := &CCR{ // Bare information, just the one needed for answer SessionId: "routinga;1442095190;1476802709", AuthApplicationId: 4, CCRequestType: 1, CCRequestNumber: 0, } ccr.diamMessage = ccr.AsBareDiameterMessage() ccr.diamMessage.NewAVP("Subscription-Id", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(0)), // Subscription-Id-Type diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("33708000003")), // Subscription-Id-Data }}) ccr.debitInterval = time.Duration(300) * time.Second cca := NewBareCCAFromCCR(ccr, "CGR-DA", "cgrates.org") 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, 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, FieldId: "Subscription-Id>Subscription-Id-Data", Value: utils.ParseRSRFieldsMustCompile("Subscription-Id>Subscription-Id-Data", utils.INFIELD_SEP), Mandatory: true}, }, } eMessage := cca.AsDiameterMessage() eMessage.NewAVP("Subscription-Id", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(0)), // Subscription-Id-Type diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("33708000003")), // Subscription-Id-Data }}) if err := cca.SetProcessorAVPs(reqProcessor, map[string]string{}); err != nil { t.Error(err) } else if ccaMsg := cca.AsDiameterMessage(); !reflect.DeepEqual(eMessage, ccaMsg) { t.Errorf("Expecting: %+v, received: %+v", eMessage, ccaMsg) } }
// 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 TestDmtAgentSendCCRSMSWrongAccount(t *testing.T) { ccr := diam.NewRequest(diam.CreditControl, 4, nil) ccr.NewAVP(avp.SessionID, avp.Mbit, 0, datatype.UTF8String("testccr3")) 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(4)) ccr.NewAVP(avp.CCRequestNumber, avp.Mbit, 0, datatype.Unsigned32(0)) 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("non_existent")), // 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("49602200011")), // 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("49780029555")), // Address-Data }}), }, }), }}) if err := dmtClient.SendMessage(ccr); err != nil { t.Error(err) } time.Sleep(time.Duration(100) * time.Millisecond) msg := dmtClient.ReceivedMessage(rplyTimeout) // Discard the received message so we can test next one 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") } else if strResult := avpValAsString(avps[0]); strResult != "5030" { // Result-Code set in the template t.Errorf("Expecting 5030, received: %s", strResult) } }
func TestDmtAgentSendCCRSimpaEvent(t *testing.T) { ccr := diam.NewRequest(diam.CreditControl, 4, nil) ccr.NewAVP(avp.SessionID, avp.Mbit, 0, datatype.UTF8String("testccr5")) 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.DestinationRealm, avp.Mbit, 0, datatype.DiameterIdentity("routing1.huawei.com")) 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(4)) ccr.NewAVP(avp.CCRequestNumber, avp.Mbit, 0, datatype.Unsigned32(0)) ccr.NewAVP(avp.EventTimestamp, avp.Mbit, 0, datatype.Time(time.Date(2016, 1, 13, 16, 47, 58, 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.ServiceIdentifier, avp.Mbit, 0, datatype.Unsigned32(0)) ccr.NewAVP(avp.RequestedAction, avp.Mbit, 0, datatype.Enumerated(1)) ccr.NewAVP(avp.RequestedServiceUnit, avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(avp.CCMoney, avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(avp.UnitValue, avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(avp.ValueDigits, avp.Mbit, 0, datatype.Integer64(10000)), diam.NewAVP(avp.Exponent, avp.Mbit, 0, datatype.Integer32(-5)), }, }), diam.NewAVP(avp.CurrencyCode, avp.Mbit, 0, datatype.Unsigned32(33)), }, }), }, }) ccr.NewAVP(873, avp.Mbit, 10415, &diam.GroupedAVP{ // Service-Information 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(29000, avp.Mbit, 2011, &diam.GroupedAVP{ // MC-Information AVP: []*diam.AVP{ diam.NewAVP(20938, avp.Mbit, 2011, datatype.OctetString("0x38924012914528")), // HighLayerCharacteristics diam.NewAVP(29002, avp.Mbit, 2011, datatype.UTF8String("12928471313847173")), // MC-Service-Id diam.NewAVP(29003, avp.Mbit, 2011, datatype.UTF8String("SPV123456012123")), // TransparentData diam.NewAVP(1201, avp.Mbit, 10415, &diam.GroupedAVP{ // MC-Information AVP: []*diam.AVP{ diam.NewAVP(899, avp.Mbit, 10415, datatype.Enumerated(0)), // Address-Type diam.NewAVP(897, avp.Mbit, 10415, datatype.UTF8String("33780029555")), // Address-Data }, }), }, }), }}) if err := dmtClient.SendMessage(ccr); err != nil { t.Error(err) } time.Sleep(time.Duration(*waitRater) * time.Millisecond) msg := dmtClient.ReceivedMessage(rplyTimeout) // Discard the received message so we can test next one 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") } else if strResult := avpValAsString(avps[0]); strResult != "2001" { // Result-Code set in the template t.Errorf("Expecting 2001, received: %s", strResult) } }
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) } }
func TestDmtAgentSendCCRSMS(t *testing.T) { ccr := diam.NewRequest(diam.CreditControl, 4, nil) ccr.NewAVP(avp.SessionID, avp.Mbit, 0, datatype.UTF8String("testccr2")) 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(4)) ccr.NewAVP(avp.CCRequestNumber, avp.Mbit, 0, datatype.Unsigned32(0)) 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 }}), }, }), }}) if err := dmtClient.SendMessage(ccr); err != nil { t.Error(err) } time.Sleep(time.Duration(100) * time.Millisecond) dmtClient.ReceivedMessage(rplyTimeout) // Discard the received message so we can test next one /* if msg == nil { t.Fatal("No message returned") } if avps, err := msg.FindAVPsWithPath([]interface{}{"Granted-Service-Unit", "CC-Time"}, dict.UndefinedVendorID); err != nil { t.Error(err) } else if len(avps) == 0 { t.Error("Granted-Service-Unit not found") } else if strCCTime := avpValAsString(avps[0]); strCCTime != "0" { t.Errorf("Expecting 0, received: %s", strCCTime) } var acnt *engine.Account attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001"} eAcntVal := 9.205 if err := apierRpc.Call("ApierV2.GetAccount", attrs, &acnt); err != nil { t.Error(err) } else if acnt.BalanceMap[utils.MONETARY].GetTotalValue() != eAcntVal { // Should also consider derived charges which double the cost of 6m10s - 2x0.7584 t.Errorf("Expected: %f, received: %f", eAcntVal, acnt.BalanceMap[utils.MONETARY].GetTotalValue()) } */ var cdrs []*engine.ExternalCDR req := utils.RPCCDRsFilter{RunIDs: []string{utils.META_DEFAULT}, ToRs: []string{utils.SMS}} if err := apierRpc.Call("ApierV2.GetCdrs", req, &cdrs); err != nil { t.Error("Unexpected error: ", err.Error()) } else if len(cdrs) != 1 { t.Error("Unexpected number of CDRs returned: ", len(cdrs)) } else { if cdrs[0].Usage != "1" { t.Errorf("Unexpected CDR Usage received, cdr: %+v ", cdrs[0]) } if cdrs[0].Cost != 0.6 { t.Errorf("Unexpected CDR Cost received, cdr: %+v ", cdrs[0]) } } }
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) } }
// Used when sending from client to agent func (self *CCR) AsDiameterMessage() (*diam.Message, error) { m := diam.NewRequest(diam.CreditControl, 4, nil) if _, err := m.NewAVP("Session-Id", avp.Mbit, 0, datatype.UTF8String(self.SessionId)); err != nil { return nil, err } if _, err := m.NewAVP("Origin-Host", avp.Mbit, 0, datatype.DiameterIdentity(self.OriginHost)); err != nil { return nil, err } if _, err := m.NewAVP("Origin-Realm", avp.Mbit, 0, datatype.DiameterIdentity(self.OriginRealm)); err != nil { return nil, err } if _, err := m.NewAVP("Destination-Host", avp.Mbit, 0, datatype.DiameterIdentity(self.DestinationHost)); err != nil { return nil, err } if _, err := m.NewAVP("Destination-Realm", avp.Mbit, 0, datatype.DiameterIdentity(self.DestinationRealm)); err != nil { return nil, err } if _, err := m.NewAVP("Auth-Application-Id", avp.Mbit, 0, datatype.Unsigned32(self.AuthApplicationId)); err != nil { return nil, err } if _, err := m.NewAVP("Service-Context-Id", avp.Mbit, 0, datatype.UTF8String(self.ServiceContextId)); err != nil { return nil, err } if _, err := m.NewAVP("CC-Request-Type", avp.Mbit, 0, datatype.Enumerated(self.CCRequestType)); err != nil { return nil, err } if _, err := m.NewAVP("CC-Request-Number", avp.Mbit, 0, datatype.Enumerated(self.CCRequestNumber)); err != nil { return nil, err } if _, err := m.NewAVP("Event-Timestamp", avp.Mbit, 0, datatype.Time(self.EventTimestamp)); err != nil { return nil, err } subscriptionIdType, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "Subscription-Id-Type") if err != nil { return nil, err } subscriptionIdData, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "Subscription-Id-Data") if err != nil { return nil, err } for _, subscriptionId := range self.SubscriptionId { if _, err := m.NewAVP("Subscription-Id", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(subscriptionIdType.Code, avp.Mbit, 0, datatype.Enumerated(subscriptionId.SubscriptionIdType)), diam.NewAVP(subscriptionIdData.Code, avp.Mbit, 0, datatype.UTF8String(subscriptionId.SubscriptionIdData)), }}); err != nil { return nil, err } } if _, err := m.NewAVP("Service-Identifier", avp.Mbit, 0, datatype.Unsigned32(self.ServiceIdentifier)); err != nil { return nil, err } ccTimeAvp, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "CC-Time") if err != nil { return nil, err } if _, err := m.NewAVP("Requested-Service-Unit", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(ccTimeAvp.Code, avp.Mbit, 0, datatype.Unsigned32(self.RequestedServiceUnit.CCTime))}}); err != nil { return nil, err } inInformation, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "IN-Information") if err != nil { return nil, err } callingPartyAddress, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "Calling-Party-Address") if err != nil { return nil, err } calledPartyAddress, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "Called-Party-Address") if err != nil { return nil, err } realCalledNumber, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "Real-Called-Number") if err != nil { return nil, err } chargeFlowType, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "Charge-Flow-Type") if err != nil { return nil, err } callingVlrNumber, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "Calling-Vlr-Number") if err != nil { return nil, err } callingCellIdOrSai, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "Calling-CellID-Or-SAI") if err != nil { return nil, err } bearerCapability, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "Bearer-Capability") if err != nil { return nil, err } callReferenceNumber, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "Call-Reference-Number") if err != nil { return nil, err } mscAddress, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "MSC-Address") if err != nil { return nil, err } timeZone, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "Time-Zone") if err != nil { return nil, err } calledPartyNP, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "Called-Party-NP") if err != nil { return nil, err } sspTime, err := m.Dictionary().FindAVP(m.Header.ApplicationID, "SSP-Time") if err != nil { return nil, err } if _, err := m.NewAVP("Service-Information", avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(inInformation.Code, avp.Mbit, 0, &diam.GroupedAVP{ AVP: []*diam.AVP{ diam.NewAVP(callingPartyAddress.Code, avp.Mbit, 0, datatype.UTF8String(self.ServiceInformation.INInformation.CallingPartyAddress)), diam.NewAVP(calledPartyAddress.Code, avp.Mbit, 0, datatype.UTF8String(self.ServiceInformation.INInformation.CalledPartyAddress)), diam.NewAVP(realCalledNumber.Code, avp.Mbit, 0, datatype.UTF8String(self.ServiceInformation.INInformation.RealCalledNumber)), diam.NewAVP(chargeFlowType.Code, avp.Mbit, 0, datatype.Unsigned32(self.ServiceInformation.INInformation.ChargeFlowType)), diam.NewAVP(callingVlrNumber.Code, avp.Mbit, 0, datatype.UTF8String(self.ServiceInformation.INInformation.CallingVlrNumber)), diam.NewAVP(callingCellIdOrSai.Code, avp.Mbit, 0, datatype.UTF8String(self.ServiceInformation.INInformation.CallingCellIDOrSAI)), diam.NewAVP(bearerCapability.Code, avp.Mbit, 0, datatype.UTF8String(self.ServiceInformation.INInformation.BearerCapability)), diam.NewAVP(callReferenceNumber.Code, avp.Mbit, 0, datatype.UTF8String(self.ServiceInformation.INInformation.CallReferenceNumber)), diam.NewAVP(mscAddress.Code, avp.Mbit, 0, datatype.UTF8String(self.ServiceInformation.INInformation.MSCAddress)), diam.NewAVP(timeZone.Code, avp.Mbit, 0, datatype.UTF8String(self.ServiceInformation.INInformation.TimeZone)), diam.NewAVP(calledPartyNP.Code, avp.Mbit, 0, datatype.UTF8String(self.ServiceInformation.INInformation.CalledPartyNP)), diam.NewAVP(sspTime.Code, avp.Mbit, 0, datatype.UTF8String(self.ServiceInformation.INInformation.SSPTime)), }, }), }}); err != nil { return nil, err } return m, nil }
func TestDmtAgentDryRun1(t *testing.T) { ccr := diam.NewRequest(diam.CreditControl, 4, nil) ccr.NewAVP(avp.SessionID, avp.Mbit, 0, datatype.UTF8String("cgrates;1451911932;00082")) 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.DestinationRealm, avp.Mbit, 0, datatype.DiameterIdentity("cgrates.org")) ccr.NewAVP(avp.DestinationHost, avp.Mbit, 0, datatype.DiameterIdentity("CGR-DA")) ccr.NewAVP(avp.UserName, avp.Mbit, 0, datatype.UTF8String("CGR-DA")) ccr.NewAVP(avp.AuthApplicationID, avp.Mbit, 0, datatype.Unsigned32(4)) ccr.NewAVP(avp.ServiceContextID, avp.Mbit, 0, datatype.UTF8String("pubsub1")) // Match specific DryRun profile ccr.NewAVP(avp.CCRequestType, avp.Mbit, 0, datatype.Enumerated(2)) 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.TerminationCause, avp.Mbit, 0, datatype.Enumerated(1)) ccr.NewAVP(443, avp.Mbit, 0, &diam.GroupedAVP{ // Subscription-Id AVP: []*diam.AVP{ diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(0)), // Subscription-Id-Type diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("1001")), // Subscription-Id-Data }}) ccr.NewAVP(443, avp.Mbit, 0, &diam.GroupedAVP{ // Subscription-Id AVP: []*diam.AVP{ diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(1)), // Subscription-Id-Type diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("208123456789")), // Subscription-Id-Data }}) ccr.NewAVP(439, avp.Mbit, 0, datatype.Unsigned32(0)) // Service-Identifier ccr.NewAVP(437, avp.Mbit, 0, &diam.GroupedAVP{ // Requested-Service-Unit AVP: []*diam.AVP{ diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(300)), // CC-Time }}) ccr.NewAVP(873, avp.Mbit|avp.Vbit, 10415, &diam.GroupedAVP{ // Service-information AVP: []*diam.AVP{ diam.NewAVP(20300, avp.Mbit, 2011, &diam.GroupedAVP{ // IN-Information AVP: []*diam.AVP{ diam.NewAVP(20336, avp.Mbit, 2011, datatype.UTF8String("1001")), // CallingPartyAdress diam.NewAVP(20337, avp.Mbit, 2011, datatype.UTF8String("1002")), // CalledPartyAdress diam.NewAVP(20339, avp.Mbit, 2011, datatype.Unsigned32(0)), // ChargeFlowType diam.NewAVP(20302, avp.Mbit, 2011, datatype.UTF8String("33609004940")), // CallingVlrNumber diam.NewAVP(20303, avp.Mbit, 2011, datatype.UTF8String("208104941749984")), // CallingCellID diam.NewAVP(20313, avp.Mbit, 2011, datatype.OctetString("0x8090a3")), // BearerCapability diam.NewAVP(20321, avp.Mbit, 2011, datatype.OctetString("0x401c4132ed665")), // CallreferenceNumber diam.NewAVP(20322, avp.Mbit, 2011, datatype.UTF8String("33609004940")), // MSCAddress diam.NewAVP(20386, avp.Mbit, 2011, datatype.UTF8String("20160501010101")), // SSPTime diam.NewAVP(20938, avp.Mbit, 2011, datatype.OctetString("0x00000001")), // HighLayerCharacteristics diam.NewAVP(20324, avp.Mbit, 2011, datatype.Integer32(8)), // Time-Zone }, }), }}) if _, err := ccr.NewAVP("Framed-IP-Address", avp.Mbit, 0, datatype.UTF8String("10.228.16.4")); err != nil { t.Error(err) } for i := 0; i < *interations; i++ { if err := dmtClient.SendMessage(ccr); err != nil { t.Error(err) } 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") } else if strResult := avpValAsString(avps[0]); strResult != "300" { // Result-Code set in the template t.Errorf("Expecting 300, received: %s", strResult) } */ } }