anchor.diff:  %%  internal functions
   %%----------------------------------------------------------------------
   
  --spec request(OHost, ORealm, Request, State) -> Reply
  -	when
  -		OHost :: string(),
  -		ORealm :: string(),
  -		Request :: #diameter_nas_app_AAR{},
  +-spec request(Caps, Request, State) -> Reply
  +	when
  +		Caps :: capabilities(),
  +		Request :: #diameter_nas_app_AAR{} | #diameter_nas_app_STR{},
   		State :: state(),
   		Reply :: {reply, Answer, State},
  -		Answer :: #diameter_nas_app_AAA{}.
  +		Answer :: #diameter_nas_app_AAA{} | #diameter_nas_app_STA{}.
   %% @doc Based on the DIAMETER request generate appropriate DIAMETER
   %% answer.
   %% @hidden
  -request(OHost, ORealm, Request, #state{simple_auth_sup = SimpleAuthSup} = State) 
  -		when is_record(Request, diameter_nas_app_AAR)->
  -	#diameter_nas_app_AAR{'Session-Id' = SessId, 'Auth-Request-Type' = Type,
  -			'User-Name' = UserName, 'User-Password' = Password} = Request,
  -	case {UserName, Password} of
  -		{UserName, Password} when (UserName /= undefined andalso
  -				Password /= undefined) ->
  -			start_fsm(SimpleAuthSup, 1, SessId, Type, OHost, ORealm, UserName,
  -				Password, State);
  -		_ ->
  -			Answer = #diameter_nas_app_AAA{
  +request(Caps, Request, State) when is_record(Request, diameter_nas_app_AAR) ->
  +	#diameter_caps{origin_host = {OHost,_}, origin_realm = {ORealm,_}} = Caps,
  +	request1(OHost, ORealm, Request, State);
  +request(Caps, Request, State) when is_record(Request, diameter_nas_app_STR) ->
  +	#diameter_caps{origin_host = {OHost,_}, origin_realm = {ORealm,_}} = Caps,
  +	SessionId = Request#diameter_nas_app_STR.'Session-Id',
  +	try
  +		Username = Request#diameter_nas_app_STR.'User-Name',
  +		F = fun() ->
  +			case mnesia:read(subscriber, Username, write) of
  +				[#subscriber{disconnect = false} = Entry] ->
  +					NewEntry = Entry#subscriber{disconnect = true},
  +					mnesia:write(subscriber, NewEntry, write);
  +				[#subscriber{disconnect = true}] ->
  +					ok
  +			end
  +		end,
  +		mnesia:transaction(F)
  +	of
  +		{atomic, ok} ->
  +			Answer = #diameter_nas_app_STA{'Session-Id' = SessionId,
  +					'Result-Code' = ?'DIAMETER_BASE_RESULT-CODE_SUCCESS',
  +					'Origin-Host' = OHost, 'Origin-Realm' = ORealm},
  +			{reply, Answer, State}
  +	catch
  +		_:_ ->
  +			Answer = #diameter_nas_app_STA{'Session-Id' = SessionId,
   					'Result-Code' = ?'DIAMETER_BASE_RESULT-CODE_UNABLE_TO_COMPLY',
  -					'Origin-Host' = OHost, 'Origin-Realm' = ORealm, 'Session-Id' = SessId},
  +					'Origin-Host' = OHost, 'Origin-Realm' = ORealm},
   			{reply, Answer, State}
   	end.
  +%% @hidden
  +request1(OHost, ORealm, Request, #state{handlers = Handlers} = State) ->
  +	SessionId = get_session_id(Request),
  +	try
  +		#diameter_nas_app_AAR{'Auth-Request-Type' = Type, 'User-Name' = UserName,
  +				'User-Password' = Password} = Request,
  +		case gb_trees:lookup(SessionId, Handlers) of
  +			none ->
  +				SimpleAuthSup = State#state.simple_auth_sup,
  +				case {UserName, Password} of
  +					{UserName, Password} when (UserName /= undefined andalso
  +							Password /= undefined) ->
  +						{Fsm, NewState} = start_fsm(SimpleAuthSup, 1, SessionId, Type, OHost, ORealm, UserName,
  +							Password, State),
  +						Answer = gen_fsm:sync_send_all_state_event(Fsm, diameter_request),
  +						{reply, Answer, NewState};
  +					_ ->
  +						Answer = #diameter_nas_app_AAA{
  +								'Result-Code' = ?'DIAMETER_BASE_RESULT-CODE_UNABLE_TO_COMPLY',
  +								'Origin-Host' = OHost, 'Origin-Realm' = ORealm, 'Session-Id' = SessionId},
  +						{reply, Answer, State}
  +					end;
  +			{value, _Fsm} ->
  +				Answer = #diameter_nas_app_AAA{'Session-Id' = SessionId,
  +						'Auth-Application-Id' = 1, 'Auth-Request-Type' = Type,
  +						'Result-Code' = ?'DIAMETER_BASE_RESULT-CODE_SUCCESS',
  +						'Origin-Host' = OHost, 'Origin-Realm' = ORealm },
  +				{reply, Answer, State}
  +		end
  +	catch
  +		_:_ ->
  +			Error = #diameter_nas_app_AAA{
  +					'Result-Code' = ?'DIAMETER_BASE_RESULT-CODE_UNABLE_TO_COMPLY',
  +					'Origin-Host' = OHost, 'Origin-Realm' = ORealm, 'Session-Id' = SessionId},
  +			{reply, Error, State}
  +	end.
   
   %% @hidden
   -spec start_fsm(AuthSup, AppId, SessionId, AuthRequestType, OHost,
  -		ORealm, UserName, Password, State) -> Result
  +		ORealm, UserName, Password, State) -> NewState
   	when
   		AuthSup :: pid(),
   		AppId :: non_neg_integer(),
  
positive.code: 	Children = supervisor:which_children(AuthPortSup),
  	{_, SimpleAuthSup, _, _} = lists:keyfind(ocs_simple_auth_fsm_sup, 1, Children),
  	NewState = State#state{simple_auth_sup = SimpleAuthSup},
  	{noreply, NewState}.
  
  -spec terminate(Reason, State) -> any()
  	when
  
negative.code: 		UserName:: string(),
  		Password :: string(),
  		State :: state(),
  		NewState :: state() | {Fsm, State},
  		Fsm :: undefined | pid().
  start_fsm(AuthSup, AppId, SessId, Type, OHost, ORealm, UserName,
  			Password, #state{handlers = Handlers} = State) ->
  	StartArgs = [diameter, SessId, AppId, Type, OHost, ORealm, UserName, Password],
  	ChildSpec = [StartArgs, []],
  	case supervisor:start_child(AuthSup, ChildSpec) of
  		{ok, Fsm} ->
  			link(Fsm),
  			NewHandlers = gb_trees:enter(SessId, Fsm, Handlers),
  			State#state{handlers = NewHandlers},
  			{Fsm, State};
  		{error, Reason} ->
  			error_logger:error_report(["Error starting session handler",
  					{error, Reason}, {supervisor, AuthSup},{session_id, SessId}]),
  		%	Answer = #diameter_nas_app_AAA{'Session-Id' = SessId,
  		%			'Auth-Application-Id' = 1, 'Auth-Request-Type' = 1,
  		%			'Result-Code' = ?'DIAMETER_BASE_RESULT-CODE_UNABLE_TO_COMPLY',
  		%			'Origin-Host' = OHost, 'Origin-Realm' = ORealm },
  			{undefined, State}
  	end.
  
  -spec get_session_id(Request) -> SessionId
  	when
  		Request :: #diameter_nas_app_AAR{},
  		SessionId :: string().
  %% @doc Return value for session id in Diameter Request.
  %% @hidden
  get_session_id(Request) when is_record(Request, diameter_nas_app_AAR) ->
  	Request#diameter_nas_app_AAR.'Session-Id'.
  
  