|
| 1 | +// LIR_Handle.go |
| 2 | +package main |
| 3 | + |
| 4 | +import ( |
| 5 | + //"fmt" |
| 6 | + "io" |
| 7 | + "log" |
| 8 | + |
| 9 | + /* |
| 10 | + "github.com/fiorix/go-diameter/v4/diam" |
| 11 | + "github.com/fiorix/go-diameter/v4/diam/avp" |
| 12 | + "github.com/fiorix/go-diameter/v4/diam/datatype" |
| 13 | + _ "github.com/fiorix/go-diameter/v4/diam/dict" |
| 14 | + "github.com/fiorix/go-diameter/v4/diam/sm" |
| 15 | +
|
| 16 | + */ |
| 17 | + "github.com/rakeshgmtke/go-diameter-hss/v4/diam" |
| 18 | + "github.com/rakeshgmtke/go-diameter-hss/v4/diam/avp" |
| 19 | + "github.com/rakeshgmtke/go-diameter-hss/v4/diam/datatype" |
| 20 | + _ "github.com/rakeshgmtke/go-diameter-hss/v4/diam/dict" |
| 21 | + "github.com/rakeshgmtke/go-diameter-hss/v4/diam/sm" |
| 22 | +) |
| 23 | + |
| 24 | +func handleLIR(settings sm.Settings, stats *DiameterStats, enableLogging bool) diam.HandlerFunc { |
| 25 | + |
| 26 | + type LIR struct { |
| 27 | + SessionID datatype.UTF8String `avp:"Session-Id"` |
| 28 | + DRMP datatype.Enumerated `avp:"DRMP"` |
| 29 | + VendorSpecificApplicationID struct { |
| 30 | + VendorId datatype.Unsigned32 `avp:"Vendor-Id"` |
| 31 | + AuthApplicationId datatype.Unsigned32 `avp:"Auth-Application-Id"` |
| 32 | + } `avp:"Vendor-Specific-Application-Id"` |
| 33 | + AuthSessionState datatype.Enumerated `avp:"Auth-Session-State"` |
| 34 | + OriginHost datatype.DiameterIdentity `avp:"Origin-Host"` |
| 35 | + OriginRealm datatype.DiameterIdentity `avp:"Origin-Realm"` |
| 36 | + DestinationRealm datatype.DiameterIdentity `avp:"Destination-Realm"` |
| 37 | + DestinationHost datatype.DiameterIdentity `avp:"Destination-Host"` |
| 38 | + ProxyInfo struct { |
| 39 | + ProxyHost datatype.DiameterIdentity `avp:"Proxy-Host"` |
| 40 | + ProxyState datatype.OctetString `avp:"Proxy-State"` |
| 41 | + } `avp:"Proxy-Info"` |
| 42 | + RouteRecord datatype.DiameterIdentity `avp:"Route-Record,omitempty"` |
| 43 | + OCSupportedFeatures struct { |
| 44 | + OCFeatureVector datatype.Unsigned64 `avp:"OC-Feature-Vector"` |
| 45 | + } `avp:"OC-Supported-Features"` |
| 46 | + SupportedFeatures struct { |
| 47 | + VendorId datatype.Unsigned32 `avp:"Vendor-Id"` |
| 48 | + FeatureListID datatype.Unsigned32 `avp:"Feature-List-ID"` |
| 49 | + FeatureList datatype.Unsigned32 `avp:"Feature-List"` |
| 50 | + } `avp:"Supported-Features"` |
| 51 | + |
| 52 | + PublicIdentity datatype.UTF8String `avp:"Public-Identity"` |
| 53 | + ServerAssignmentType datatype.Enumerated `avp:"Server-Assignment-Type"` |
| 54 | + UserAuthorizationType datatype.Enumerated `avp:"User-Authorization-Type"` |
| 55 | + OriginatingRequest datatype.Enumerated `avp:"Originating-Request"` |
| 56 | + SessionPriority datatype.Enumerated `avp:"Session-Priority"` |
| 57 | + } |
| 58 | + |
| 59 | + return func(c diam.Conn, m *diam.Message) { |
| 60 | + var err error |
| 61 | + var req LIR |
| 62 | + var impu string |
| 63 | + //var impi string |
| 64 | + var scscf_name string |
| 65 | + //var msisdn string |
| 66 | + |
| 67 | + if err := m.Unmarshal(&req); err != nil { |
| 68 | + log.Printf("Failed to parse message from %s: %s\n%s", |
| 69 | + c.RemoteAddr(), err, m) |
| 70 | + return |
| 71 | + } |
| 72 | + |
| 73 | + if enableLogging { |
| 74 | + log.Printf("Received LIR from %s\n%s", c.RemoteAddr(), m) |
| 75 | + } |
| 76 | + Is_PublicIdentity_AVP, _ := m.FindAVP(avp.PublicIdentity, VENDOR_3GPP) // Provide both AVP code and Vendor ID (0 for standard) |
| 77 | + if Is_PublicIdentity_AVP != nil { |
| 78 | + impu = string(req.PublicIdentity) |
| 79 | + } |
| 80 | + |
| 81 | + scscf_name = readSCSCFNameData(impu) |
| 82 | + |
| 83 | + Is_UserAuthorizationType_AVP, _ := m.FindAVP(avp.UserAuthorizationType, VENDOR_3GPP) // Provide both AVP code and Vendor ID (0 for standard) |
| 84 | + //log.Printf("Is_UserAuthorizationType_AVP received: %s : %d", Is_UserAuthorizationType_AVP, req.UserAuthorizationType) |
| 85 | + if Is_UserAuthorizationType_AVP != nil && req.UserAuthorizationType == 2 { |
| 86 | + stats.IncrementReceived("LIR", string(req.OriginHost), "CAPABILITIES-QUERY") |
| 87 | + } else { |
| 88 | + //Is_UserAuthorizationType_AVP == nil && Is_PublicIdentity_AVP != nil { |
| 89 | + stats.IncrementReceived("LIR", string(req.OriginHost), "SCSCF-NAME-QUERY") |
| 90 | + } |
| 91 | + |
| 92 | + if enableLogging { |
| 93 | + log.Printf("from LIR received IMPU: %s STORED SCSCF_NAME : %s ", impu, scscf_name) |
| 94 | + } |
| 95 | + |
| 96 | + //Creating Response |
| 97 | + a := m.Response() |
| 98 | + a.NewAVP(avp.SessionID, avp.Mbit, 0, req.SessionID) |
| 99 | + a.NewAVP(avp.OriginHost, avp.Mbit, 0, settings.OriginHost) |
| 100 | + a.NewAVP(avp.OriginRealm, avp.Mbit, 0, settings.OriginRealm) |
| 101 | + |
| 102 | + //Check is Vendor-Specific-Application-Id present in Request, if yes.. include Vendor-Specific-Application-Id in response also. |
| 103 | + Is_VendorSpecificApplicationID_AVP, _ := m.FindAVP(avp.VendorSpecificApplicationID, 0) // Provide both AVP code and Vendor ID (0 for standard) |
| 104 | + if Is_VendorSpecificApplicationID_AVP != nil { |
| 105 | + a.NewAVP(avp.VendorSpecificApplicationID, avp.Mbit, 0, &diam.GroupedAVP{ |
| 106 | + AVP: []*diam.AVP{ |
| 107 | + diam.NewAVP(avp.AuthApplicationID, avp.Mbit, 0, datatype.Unsigned32(req.VendorSpecificApplicationID.AuthApplicationId)), |
| 108 | + diam.NewAVP(avp.VendorID, avp.Mbit, 0, datatype.Unsigned32(req.VendorSpecificApplicationID.VendorId)), |
| 109 | + }, |
| 110 | + }) |
| 111 | + } |
| 112 | + |
| 113 | + //Check for AuthSessionState AVP present, if yes add AuthSessionState AVP in response |
| 114 | + Is_authSessionState_AVP, _ := m.FindAVP(avp.AuthSessionState, 0) // Provide both AVP code and Vendor ID (0 for standard) |
| 115 | + if Is_authSessionState_AVP != nil { |
| 116 | + a.NewAVP(avp.AuthSessionState, avp.Mbit, 0, req.AuthSessionState) |
| 117 | + } |
| 118 | + |
| 119 | + Is_SupportedFeatures_AVP, _ := m.FindAVP(avp.SupportedFeatures, 0) // Provide both AVP code and Vendor ID (0 for standard) |
| 120 | + if Is_SupportedFeatures_AVP != nil { |
| 121 | + a.NewAVP(avp.SupportedFeatures, avp.Mbit, 0, &diam.GroupedAVP{ |
| 122 | + AVP: []*diam.AVP{ |
| 123 | + diam.NewAVP(avp.VendorID, avp.Mbit, 0, datatype.Unsigned32(req.VendorSpecificApplicationID.VendorId)), |
| 124 | + // diam.NewAVP(avp.VendorId, avp.Mbit, 0, datatype.Unsigned32(req.SupportedFeatures.VendorId)), |
| 125 | + diam.NewAVP(avp.FeatureListID, avp.Mbit, 0, datatype.Unsigned32(req.SupportedFeatures.FeatureListID)), |
| 126 | + diam.NewAVP(avp.FeatureList, avp.Mbit, 0, datatype.Unsigned32(req.SupportedFeatures.FeatureList)), |
| 127 | + }, |
| 128 | + }) |
| 129 | + } |
| 130 | + |
| 131 | + //Is_UserAuthorizationType_AVP, _ := m.FindAVP(avp.UserAuthorizationType, VENDOR_3GPP) // Provide both AVP code and Vendor ID (0 for standard) |
| 132 | + //log.Printf("Is_UserAuthorizationType_AVP received: %s : %d", Is_UserAuthorizationType_AVP, req.UserAuthorizationType) |
| 133 | + //if Is_UserAuthorizationType_AVP != nil || { |
| 134 | + if req.UserAuthorizationType == 2 { |
| 135 | + stats.IncrementReceived("LIA", string(req.OriginHost), "CAPABILITIES-RESP-CODE-2001") |
| 136 | + m.NewAVP(avp.ServerCapabilities, avp.Mbit, VENDOR_3GPP, &diam.GroupedAVP{ |
| 137 | + AVP: []*diam.AVP{ |
| 138 | + diam.NewAVP(avp.MandatoryCapability, avp.Mbit, VENDOR_3GPP, datatype.Unsigned32(MandatoryCapability)), |
| 139 | + //diam.NewAVP(avp.OptionalCapability, avp.Mbit, VENDOR_3GPP, datatype.Unsigned32(1)), |
| 140 | + //diam.NewAVP(avp.ServerName, avp.Mbit, VENDOR_3GPP, datatype.UTF8String("sip:scscf.maavenir.com")), |
| 141 | + }, |
| 142 | + }) |
| 143 | + m.NewAVP(avp.ResultCode, avp.Mbit, 0, datatype.Unsigned32(2001)) |
| 144 | + |
| 145 | + } else if scscf_name != "" { |
| 146 | + //SCSCF_NAME is stored. returning with Stored SCSCF_NAME with Success |
| 147 | + if enableLogging { |
| 148 | + log.Printf("LIA sending SCSCF_NAME is stored", scscf_name) |
| 149 | + } |
| 150 | + stats.IncrementReceived("LIA", string(req.OriginHost), "SCSCF-NAME-RESP-CODE-2001") |
| 151 | + a.NewAVP(avp.ResultCode, avp.Mbit, 0, datatype.Unsigned32(2001)) |
| 152 | + a.NewAVP(avp.ServerName, avp.Mbit, VENDOR_3GPP, datatype.UTF8String(scscf_name)) |
| 153 | + } else { |
| 154 | + //SCSCF_NAME is not stored. returning with DIAMETER_UNREGISTERED_SERVICE. |
| 155 | + stats.IncrementReceived("LIA", string(req.OriginHost), "SCSCF-NAME-RESP-CODE-5003") |
| 156 | + if enableLogging { |
| 157 | + log.Printf("LIA sending SCSCF_NAME is Not stored sending DIAMETER_UNREGISTERED_SERVICE") |
| 158 | + } |
| 159 | + a.NewAVP(avp.ExperimentalResult, avp.Mbit, 0, &diam.GroupedAVP{ |
| 160 | + AVP: []*diam.AVP{ |
| 161 | + diam.NewAVP(avp.VendorID, avp.Mbit, 0, datatype.Unsigned32(0)), |
| 162 | + diam.NewAVP(avp.ExperimentalResultCode, avp.Mbit, 0, datatype.Unsigned32(5003)), |
| 163 | + }, |
| 164 | + }) |
| 165 | + } |
| 166 | + //} |
| 167 | + |
| 168 | + _, err = sendLIA_default(settings, c, a, enableLogging) |
| 169 | + if err != nil { |
| 170 | + log.Printf("LIA sending ERROR %s", err.Error()) |
| 171 | + |
| 172 | + } |
| 173 | + } |
| 174 | +} |
| 175 | + |
| 176 | +func sendLIA_default(settings sm.Settings, w io.Writer, m *diam.Message, enableLogging bool) (n int64, err error) { |
| 177 | + |
| 178 | + if enableLogging { |
| 179 | + log.Printf("inside sendLIA_default func") |
| 180 | + log.Printf("Sending LIA to \n%s", m) |
| 181 | + } |
| 182 | + |
| 183 | + return m.WriteTo(w) |
| 184 | +} |
0 commit comments