mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
DiameterAgent V1DisconnectSession implementation
This commit is contained in:
@@ -165,13 +165,13 @@ func (da *DiameterAgent) handleMessage(c diam.Conn, m *diam.Message) {
|
||||
if da.cgrCfg.DiameterAgentCfg().ASRTempalte != "" {
|
||||
sessID, err := diamDP.FieldAsString([]string{"Session-Id"})
|
||||
if err != nil {
|
||||
utils.Logger.Err(
|
||||
utils.Logger.Warning(
|
||||
fmt.Sprintf("<%s> failed retrieving Session-Id err: %s, message: %s",
|
||||
utils.DiameterAgent, err.Error(), m))
|
||||
writeOnConn(c, diamErr)
|
||||
}
|
||||
// cache message data needed for building up the ASR
|
||||
engine.Cache.Set(utils.CacheDiameterMessages, sessID, &diamMessageData{c, m, reqVars},
|
||||
engine.Cache.Set(utils.CacheDiameterMessages, sessID, &diamMsgData{c, m, reqVars},
|
||||
nil, false, utils.NonTransactional)
|
||||
}
|
||||
// handle MaxActiveReqs
|
||||
@@ -376,8 +376,45 @@ func (da *DiameterAgent) Call(serviceMethod string, args interface{}, reply inte
|
||||
|
||||
// V1DisconnectSession is part of the sessions.SessionSClient
|
||||
func (da *DiameterAgent) V1DisconnectSession(args utils.AttrDisconnectSession, reply *string) (err error) {
|
||||
//m := NewMessage(cmd uint32, 0, appid, 0, 0, m.Dictionary())
|
||||
return utils.ErrNotImplemented
|
||||
ssID, has := args.EventStart[utils.OriginID]
|
||||
if !has {
|
||||
utils.Logger.Info(
|
||||
fmt.Sprintf("<%s> cannot disconnect session, missing OriginID in event: %s",
|
||||
utils.DiameterAgent, utils.ToJSON(args.EventStart)))
|
||||
return utils.ErrMandatoryIeMissing
|
||||
}
|
||||
msg, has := engine.Cache.Get(utils.CacheDiameterMessages, ssID.(string))
|
||||
if !has {
|
||||
utils.Logger.Warning(
|
||||
fmt.Sprintf("<%s> cannot retrieve message from cache with OriginID: <%s>",
|
||||
utils.DiameterAgent, ssID))
|
||||
return utils.ErrMandatoryIeMissing
|
||||
}
|
||||
dmd := msg.(*diamMsgData)
|
||||
aReq := newAgentRequest(
|
||||
newDADataProvider(dmd.c, dmd.m),
|
||||
dmd.vars, nil, nil,
|
||||
da.cgrCfg.GeneralCfg().DefaultTenant,
|
||||
da.cgrCfg.GeneralCfg().DefaultTimezone, da.filterS)
|
||||
nM, err := aReq.AsNavigableMap(da.cgrCfg.DiameterAgentCfg().Templates[da.cgrCfg.DiameterAgentCfg().ASRTempalte])
|
||||
if err != nil {
|
||||
utils.Logger.Warning(
|
||||
fmt.Sprintf("<%s> cannot disconnect session with OriginID: <%s>, err: %s",
|
||||
utils.DiameterAgent, ssID, err.Error()))
|
||||
return utils.ErrServerError
|
||||
}
|
||||
m := diam.NewMessage(dmd.m.Header.CommandCode, 0, dmd.m.Header.ApplicationID, 0, 0, dmd.m.Dictionary())
|
||||
if err = updateDiamMsgFromNavMap(m, nM, da.cgrCfg.GeneralCfg().DefaultTimezone); err != nil {
|
||||
utils.Logger.Warning(
|
||||
fmt.Sprintf("<%s> cannot disconnect session with OriginID: <%s>, err: %s",
|
||||
utils.DiameterAgent, ssID, err.Error()))
|
||||
return utils.ErrServerError
|
||||
}
|
||||
if err = writeOnConn(dmd.c, m); err != nil {
|
||||
return utils.ErrServerError
|
||||
}
|
||||
*reply = utils.OK
|
||||
return
|
||||
}
|
||||
|
||||
// V1GetActiveSessionIDs is part of the sessions.SessionSClient
|
||||
|
||||
@@ -266,11 +266,12 @@ func messageSetAVPsWithPath(m *diam.Message, pathStr []string,
|
||||
}
|
||||
|
||||
// writeOnConn writes the message on connection, logs failures
|
||||
func writeOnConn(c diam.Conn, m *diam.Message) {
|
||||
if _, err := m.WriteTo(c); err != nil {
|
||||
func writeOnConn(c diam.Conn, m *diam.Message) (err error) {
|
||||
if _, err = m.WriteTo(c); err != nil {
|
||||
utils.Logger.Warning(fmt.Sprintf("<%s> failed writing message to %s, err: %s, msg: %s",
|
||||
utils.DiameterAgent, c.RemoteAddr(), err.Error(), m))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// newDADataProvider constructs a DataProvider for a diameter message
|
||||
@@ -404,20 +405,14 @@ func (dP *diameterDP) FieldAsInterface(fldPath []string) (data interface{}, err
|
||||
return
|
||||
}
|
||||
|
||||
// diamAnswer builds up the answer to be sent back to the client
|
||||
func diamAnswer(m *diam.Message, resCode uint32, errFlag bool,
|
||||
rply *config.NavigableMap, tmz string) (a *diam.Message, err error) {
|
||||
a = newDiamAnswer(m, resCode)
|
||||
if errFlag {
|
||||
a.Header.CommandFlags = diam.ErrorFlag
|
||||
}
|
||||
// updateDiamMsgFromNavMap will update the diameter message with items from navigable map
|
||||
func updateDiamMsgFromNavMap(m *diam.Message, navMp *config.NavigableMap, tmz string) (err error) {
|
||||
// write reply into message
|
||||
pathIdx := make(map[string]int) // group items for same path
|
||||
for _, val := range rply.Values() {
|
||||
|
||||
for _, val := range navMp.Values() {
|
||||
nmItms, isNMItems := val.([]*config.NMItem)
|
||||
if !isNMItems {
|
||||
return nil, fmt.Errorf("cannot encode reply value: %s, err: not NMItems", utils.ToJSON(val))
|
||||
return fmt.Errorf("cannot encode reply value: %s, err: not NMItems", utils.ToJSON(val))
|
||||
}
|
||||
// find out the first itm which is not an attribute
|
||||
var itm *config.NMItem
|
||||
@@ -441,20 +436,33 @@ func diamAnswer(m *diam.Message, resCode uint32, errFlag bool,
|
||||
}
|
||||
itmStr, err := utils.IfaceAsString(itm.Data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot convert data: %+v to string, err: %s", itm.Data, err)
|
||||
return fmt.Errorf("cannot convert data: %+v to string, err: %s", itm.Data, err)
|
||||
}
|
||||
var newBranch bool
|
||||
if itm.Config != nil && itm.Config.NewBranch {
|
||||
newBranch = true
|
||||
}
|
||||
if err = messageSetAVPsWithPath(a, itm.Path,
|
||||
if err = messageSetAVPsWithPath(m, itm.Path,
|
||||
itmStr, newBranch, tmz); err != nil {
|
||||
return nil, fmt.Errorf("setting item with path: %+v got err: %s", itm.Path, err.Error())
|
||||
return fmt.Errorf("setting item with path: %+v got err: %s", itm.Path, err.Error())
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// diamAnswer builds up the answer to be sent back to the client
|
||||
func diamAnswer(m *diam.Message, resCode uint32, errFlag bool,
|
||||
rply *config.NavigableMap, tmz string) (a *diam.Message, err error) {
|
||||
a = newDiamAnswer(m, resCode)
|
||||
if errFlag {
|
||||
a.Header.CommandFlags = diam.ErrorFlag
|
||||
}
|
||||
if err = updateDiamMsgFromNavMap(a, rply, tmz); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// negDiamAnswer is used to return the negative answer we need previous to
|
||||
func diamErr(m *diam.Message, resCode uint32,
|
||||
reqVars map[string]interface{},
|
||||
@@ -507,7 +515,7 @@ func newDiamAnswer(m *diam.Message, resCode uint32) *diam.Message {
|
||||
}
|
||||
|
||||
// diamMessageData is cached when data is needed (ie. )
|
||||
type diamMessageData struct {
|
||||
type diamMsgData struct {
|
||||
c diam.Conn
|
||||
m *diam.Message
|
||||
vars map[string]interface{}
|
||||
|
||||
Reference in New Issue
Block a user