On Thu, Sep 12, 2019 at 2:33 AM <afriyie.abra...@gmail.com> wrote: > > Can anyone help me perform dynamic unmarshalling depending on the type of > messages received from a diameter client. In the code below, I have to two > structures which represent two different messages received by a diameter > server. I would like to modify the current code which unmarshals the request > to the struct `var req HandleDERRequest` such that the unmarshalling is done > dynamically either to the `var req HandleDERRequest` or `var challreq > HandleChallRequest`, depending on the received message that matches a > particular structure. I have tried to implement with the code below but it > not working as it should. All the answers are being return at the same time > and this is not what am expecting.
HandleChallRequest is a subset of HandleDERRequest. How do you figure out the received message is a HandleDERRequest? If it is done only by the absence of fields, then you can simply unmarshal a HandleDERRequest, check if certain fields are missing, and if so, copy it to a HandleChallRequest. Or, since HandleDERRequest has more fields, you can embed HandleChallRequest into HandleDERRequest, and if certain fields are missing, use only the HandleChallRequest portion of it. > > func HandleDER(settings sm.Settings) diam.HandlerFunc { > > // If received AVP messages are of this struct format, Unmarshal > message to this structure > > type HandleDERRequest struct { > SessionID datatype.UTF8String `avp:"Session-Id"` > OriginHost datatype.DiameterIdentity `avp:"Origin-Host"` > OriginRealm datatype.DiameterIdentity `avp:"Origin-Realm"` > DestinationHost datatype.DiameterIdentity > `avp:"Destination-Host"` > DestinationRealm datatype.DiameterIdentity > `avp:"Destination-Realm"` > UserName datatype.UTF8String `avp:"User-Name"` > AuthSessionState datatype.Enumerated > `avp:"Auth-Session-State"` > AuthApplicationID datatype.Unsigned32 > `avp:"Auth-Application-Id"` > AuthRequestType datatype.Enumerated > `avp:"Auth-Request-Type"` > EAPPayload datatype.OctetString `avp:"EAP-Payload"` > RATType datatype.Enumerated `avp:"RAT-Type"` > ANID datatype.UTF8String `avp:"ANID"` > } > > // If received AVP messages are of this struct format, Unmarshal > message to this structure > > type HandleChallRequest struct { > SessionID datatype.UTF8String `avp:"Session-Id"` > OriginHost datatype.DiameterIdentity `avp:"Origin-Host"` > OriginRealm datatype.DiameterIdentity `avp:"Origin-Realm"` > DestinationHost datatype.DiameterIdentity > `avp:"Destination-Host"` > DestinationRealm datatype.DiameterIdentity > `avp:"Destination-Realm"` > EAPPayload datatype.OctetString `avp:"EAP-Payload"` > } > > return func(c diam.Conn, m *diam.Message) { > > var err error = nil > var req HandleDERRequest > > var code uint32 = diam.Success > err = m.Unmarshal(&req) > if err != nil { > err = fmt.Errorf("Unmarshal failed: %s", err) > code = diam.UnableToComply > log.Printf("Invalid DER(%d): %s\n", code, err.Error()) > } > a := m.Answer(code) > a.NewAVP(avp.SessionID, avp.Mbit, 0, req.SessionID) > a.NewAVP(avp.OriginHost, avp.Mbit, 0, req.DestinationHost) > a.NewAVP(avp.OriginRealm, avp.Mbit, 0, req.DestinationRealm) > a.NewAVP(avp.OriginStateID, avp.Mbit, 0, settings.OriginStateID) > _, err = AKA_Challenge_Request(settings, c, a) > if err != nil { > log.Printf("Failed to send AAA challenge request: %s", > err.Error()) > } > > var challreq HandleChallageRequest > err = m.Unmarshal(&challreq) > if err != nil { > err = fmt.Errorf("Unmarshal failed: %s", err) > code = diam.UnableToComply > log.Printf("Invalid DER(%d): %s\n", code, err.Error()) > } > a = m.Answer(code) > a.NewAVP(avp.SessionID, avp.Mbit, 0, req.SessionID) > a.NewAVP(avp.OriginHost, avp.Mbit, 0, req.DestinationHost) > a.NewAVP(avp.OriginRealm, avp.Mbit, 0, req.DestinationRealm) > a.NewAVP(avp.OriginStateID, avp.Mbit, 0, settings.OriginStateID) > _, err = AKA_Success_Notification(settings, c, a) > if err != nil { > log.Printf("Failed to send Success Notification: %s", > err.Error()) > } > } > } > > I know there should be an if condition of the return function but I don't > know how to start. Please any idea about how to go about it. > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/ec15b55e-a927-4bc7-a8ea-cc9f172df506%40googlegroups.com. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAMV2RqoX2isLUMNHBOYjZk6tJ82zcuWN%2BcRu4oS%2B%2BmLg-zz%3DiQ%40mail.gmail.com.